]> Pileus Git - ~andy/linux/commitdiff
Merge remote-tracking branch 'asoc/topic/davinci' into asoc-next
authorMark Brown <broonie@opensource.wolfsonmicro.com>
Tue, 23 Apr 2013 18:25:29 +0000 (19:25 +0100)
committerMark Brown <broonie@opensource.wolfsonmicro.com>
Tue, 23 Apr 2013 18:25:29 +0000 (19:25 +0100)
345 files changed:
Documentation/DocBook/device-drivers.tmpl
Documentation/kernel-parameters.txt
Documentation/scsi/LICENSE.qla2xxx
MAINTAINERS
Makefile
arch/arc/include/asm/irqflags.h
arch/arm/boot/dts/imx28-m28evk.dts
arch/arm/boot/dts/imx28-sps1.dts
arch/arm/boot/dts/imx6qdl.dtsi
arch/arm/boot/dts/kirkwood-iomega_ix2_200.dts
arch/arm/include/asm/glue-cache.h
arch/arm/include/asm/hardware/iop3xx.h
arch/arm/include/asm/pgtable-3level.h
arch/arm/include/asm/tlbflush.h
arch/arm/kernel/hw_breakpoint.c
arch/arm/kernel/perf_event.c
arch/arm/kernel/sched_clock.c
arch/arm/kernel/setup.c
arch/arm/kernel/tcm.c
arch/arm/kvm/arm.c
arch/arm/kvm/coproc.c
arch/arm/mach-highbank/hotplug.c
arch/arm/mach-imx/clk-imx35.c
arch/arm/mach-imx/clk-imx6q.c
arch/arm/mach-kirkwood/board-iomega_ix2_200.c
arch/arm/mach-mvebu/irq-armada-370-xp.c
arch/arm/mach-s3c24xx/include/mach/irqs.h
arch/arm/mach-s3c24xx/irq.c
arch/arm/mm/Kconfig
arch/arm/mm/Makefile
arch/arm/mm/cache-feroceon-l2.c
arch/arm/mm/cache-v3.S [deleted file]
arch/arm/mm/cache-v4.S
arch/arm/mm/mmu.c
arch/arm/mm/proc-arm740.S
arch/arm/mm/proc-arm920.S
arch/arm/mm/proc-arm926.S
arch/arm/mm/proc-mohawk.S
arch/arm/mm/proc-sa1100.S
arch/arm/mm/proc-syms.c
arch/arm/mm/proc-v6.S
arch/arm/mm/proc-xsc3.S
arch/arm/mm/proc-xscale.S
arch/arm/mm/tcm.h [moved from arch/arm/kernel/tcm.h with 100% similarity]
arch/avr32/include/asm/io.h
arch/c6x/include/asm/irqflags.h
arch/ia64/kernel/palinfo.c
arch/m68k/include/asm/gpio.h
arch/powerpc/kernel/entry_64.S
arch/powerpc/kernel/process.c
arch/powerpc/kernel/signal_32.c
arch/powerpc/kernel/signal_64.c
arch/powerpc/kernel/tm.S
arch/powerpc/kvm/e500.h
arch/powerpc/kvm/e500_mmu_host.c
arch/powerpc/kvm/e500mc.c
arch/powerpc/platforms/pseries/lpar.c
arch/s390/include/asm/io.h
arch/s390/include/asm/pgtable.h
arch/sparc/include/asm/Kbuild
arch/sparc/include/asm/cputime.h [deleted file]
arch/sparc/include/asm/emergency-restart.h [deleted file]
arch/sparc/include/asm/mutex.h [deleted file]
arch/sparc/include/asm/pgtable_64.h
arch/sparc/include/asm/serial.h [deleted file]
arch/sparc/include/asm/smp_32.h
arch/sparc/include/asm/switch_to_64.h
arch/sparc/include/asm/tlbflush_64.h
arch/sparc/include/uapi/asm/Kbuild
arch/sparc/include/uapi/asm/types.h [deleted file]
arch/sparc/kernel/smp_64.c
arch/sparc/lib/bitext.c
arch/sparc/mm/iommu.c
arch/sparc/mm/srmmu.c
arch/sparc/mm/tlb.c
arch/sparc/mm/tsb.c
arch/sparc/mm/ultra.S
arch/tile/include/asm/irqflags.h
arch/x86/Kconfig
arch/x86/boot/compressed/eboot.c
arch/x86/include/asm/efi.h
arch/x86/include/asm/paravirt.h
arch/x86/include/asm/paravirt_types.h
arch/x86/include/asm/tlb.h
arch/x86/include/uapi/asm/bootparam.h
arch/x86/kernel/cpu/mshyperv.c
arch/x86/kernel/cpu/perf_event_intel.c
arch/x86/kernel/cpu/perf_event_intel_ds.c
arch/x86/kernel/microcode_core_early.c
arch/x86/kernel/paravirt.c
arch/x86/kernel/setup.c
arch/x86/lguest/boot.c
arch/x86/mm/fault.c
arch/x86/mm/pageattr-test.c
arch/x86/mm/pageattr.c
arch/x86/mm/pgtable.c
arch/x86/platform/efi/efi.c
arch/x86/xen/mmu.c
block/blk-core.c
block/blk-sysfs.c
block/partition-generic.c
crypto/gcm.c
drivers/ata/ata_piix.c
drivers/ata/libata-core.c
drivers/ata/libata-scsi.c
drivers/base/regmap/regmap.c
drivers/block/loop.c
drivers/block/mtip32xx/mtip32xx.c
drivers/block/mtip32xx/mtip32xx.h
drivers/block/rbd.c
drivers/char/hpet.c
drivers/cpufreq/intel_pstate.c
drivers/crypto/ux500/cryp/cryp_core.c
drivers/dma/at_hdmac.c
drivers/dma/omap-dma.c
drivers/dma/pl330.c
drivers/firmware/Kconfig
drivers/firmware/efivars.c
drivers/gpio/gpio-pca953x.c
drivers/gpu/drm/drm_fb_helper.c
drivers/gpu/drm/mgag200/mgag200_mode.c
drivers/gpu/drm/nouveau/nv50_display.c
drivers/gpu/drm/udl/udl_connector.c
drivers/hwspinlock/hwspinlock_core.c
drivers/idle/intel_idle.c
drivers/input/tablet/wacom_wac.c
drivers/irqchip/irq-gic.c
drivers/md/dm.c
drivers/md/raid5.c
drivers/misc/vmw_vmci/Kconfig
drivers/mtd/mtdchar.c
drivers/net/bonding/bond_main.c
drivers/net/can/mcp251x.c
drivers/net/can/sja1000/sja1000_of_platform.c
drivers/net/ethernet/8390/ax88796.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
drivers/net/ethernet/emulex/benet/be_main.c
drivers/net/ethernet/freescale/fec.c
drivers/net/ethernet/intel/e100.c
drivers/net/ethernet/intel/igb/igb.h
drivers/net/ethernet/intel/igb/igb_main.c
drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
drivers/net/ethernet/marvell/Kconfig
drivers/net/ethernet/marvell/mvneta.c
drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c
drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c
drivers/net/ethernet/qlogic/qlge/qlge.h
drivers/net/ethernet/qlogic/qlge/qlge_ethtool.c
drivers/net/ethernet/qlogic/qlge/qlge_main.c
drivers/net/ethernet/stmicro/stmmac/mmc_core.c
drivers/net/ethernet/ti/cpsw.c
drivers/net/hyperv/netvsc.c
drivers/net/hyperv/netvsc_drv.c
drivers/net/hyperv/rndis_filter.c
drivers/net/tun.c
drivers/net/usb/cdc_mbim.c
drivers/net/usb/qmi_wwan.c
drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h
drivers/net/wireless/ath/ath9k/dfs_pattern_detector.c
drivers/net/wireless/ath/ath9k/dfs_pri_detector.c
drivers/net/wireless/ath/ath9k/htc_drv_init.c
drivers/net/wireless/ath/ath9k/main.c
drivers/net/wireless/b43/phy_n.c
drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
drivers/net/wireless/mwifiex/scan.c
drivers/net/wireless/rt2x00/Kconfig
drivers/net/wireless/rt2x00/Makefile
drivers/net/wireless/rt2x00/rt2400pci.c
drivers/net/wireless/rt2x00/rt2500pci.c
drivers/net/wireless/rt2x00/rt2800pci.c
drivers/net/wireless/rt2x00/rt2x00mmio.c [new file with mode: 0644]
drivers/net/wireless/rt2x00/rt2x00mmio.h [new file with mode: 0644]
drivers/net/wireless/rt2x00/rt2x00pci.c
drivers/net/wireless/rt2x00/rt2x00pci.h
drivers/net/wireless/rt2x00/rt61pci.c
drivers/platform/x86/hp-wmi.c
drivers/platform/x86/thinkpad_acpi.c
drivers/remoteproc/Kconfig
drivers/remoteproc/remoteproc_core.c
drivers/remoteproc/ste_modem_rproc.c
drivers/s390/net/qeth_core.h
drivers/s390/net/qeth_core_main.c
drivers/s390/net/qeth_l2_main.c
drivers/s390/net/qeth_l3_main.c
drivers/sbus/char/bbc_i2c.c
drivers/scsi/ibmvscsi/ibmvscsi.c
drivers/scsi/ipr.c
drivers/scsi/libsas/sas_expander.c
drivers/scsi/lpfc/lpfc_sli.c
drivers/scsi/qla2xxx/qla_attr.c
drivers/scsi/qla2xxx/qla_dbg.c
drivers/scsi/qla2xxx/qla_def.h
drivers/scsi/qla2xxx/qla_gbl.h
drivers/scsi/qla2xxx/qla_init.c
drivers/scsi/qla2xxx/qla_mbx.c
drivers/scsi/qla2xxx/qla_version.h
drivers/scsi/st.c
drivers/ssb/driver_chipcommon_pmu.c
drivers/target/target_core_alua.c
drivers/tty/mxser.c
drivers/tty/serial/8250/8250_pnp.c
drivers/tty/serial/omap-serial.c
drivers/vfio/pci/vfio_pci.c
drivers/vhost/tcm_vhost.c
drivers/video/fbmem.c
drivers/video/mmp/core.c
drivers/watchdog/Kconfig
drivers/xen/events.c
fs/binfmt_elf.c
fs/bio.c
fs/btrfs/tree-log.c
fs/cifs/connect.c
fs/ecryptfs/miscdev.c
fs/hfsplus/extents.c
fs/hugetlbfs/inode.c
fs/inode.c
fs/namespace.c
fs/nfs/nfs4client.c
fs/nfs/nfs4proc.c
fs/nfs/nfs4state.c
fs/proc/array.c
fs/proc/generic.c
include/asm-generic/tlb.h
include/linux/ata.h
include/linux/blktrace_api.h
include/linux/capability.h
include/linux/efi.h
include/linux/ftrace.h
include/linux/kexec.h
include/linux/libata.h
include/linux/mm.h
include/linux/netfilter/ipset/ip_set_ahash.h
include/linux/preempt.h
include/linux/proc_fs.h
include/linux/sched.h
include/linux/security.h
include/linux/spinlock_up.h
include/linux/ssb/ssb_driver_chipcommon.h
include/linux/swiotlb.h
include/linux/ucs2_string.h [new file with mode: 0644]
include/net/addrconf.h
include/net/irda/irlmp.h
include/net/iucv/af_iucv.h
include/net/scm.h
include/trace/events/block.h
include/trace/events/sched.h
include/uapi/linux/fuse.h
kernel/capability.c
kernel/events/core.c
kernel/events/internal.h
kernel/events/ring_buffer.c
kernel/hrtimer.c
kernel/kexec.c
kernel/kprobes.c
kernel/kthread.c
kernel/sched/clock.c
kernel/sched/core.c
kernel/sched/cputime.c
kernel/signal.c
kernel/smpboot.c
kernel/sys.c
kernel/trace/blktrace.c
kernel/trace/ftrace.c
kernel/trace/trace.c
kernel/trace/trace_stack.c
kernel/user_namespace.c
lib/Kconfig
lib/Makefile
lib/kobject.c
lib/swiotlb.c
lib/ucs2_string.c [new file with mode: 0644]
mm/hugetlb.c
mm/memory.c
mm/vmscan.c
net/802/mrp.c
net/atm/common.c
net/ax25/af_ax25.c
net/batman-adv/main.c
net/batman-adv/main.h
net/batman-adv/routing.c
net/batman-adv/translation-table.c
net/batman-adv/vis.c
net/bluetooth/af_bluetooth.c
net/bluetooth/rfcomm/sock.c
net/bluetooth/sco.c
net/bridge/br_if.c
net/bridge/br_private.h
net/bridge/br_stp_if.c
net/caif/caif_socket.c
net/can/gw.c
net/core/dev.c
net/core/rtnetlink.c
net/ipv4/devinet.c
net/ipv4/esp4.c
net/ipv4/ip_fragment.c
net/ipv4/netfilter/ipt_rpfilter.c
net/ipv4/syncookies.c
net/ipv4/tcp_input.c
net/ipv4/tcp_output.c
net/ipv6/addrconf.c
net/ipv6/addrconf_core.c
net/ipv6/netfilter/ip6t_rpfilter.c
net/ipv6/reassembly.c
net/ipv6/tcp_ipv6.c
net/irda/af_irda.c
net/irda/iriap.c
net/irda/irlmp.c
net/iucv/af_iucv.c
net/l2tp/l2tp_ip6.c
net/llc/af_llc.c
net/mac80211/iface.c
net/mac80211/mlme.c
net/netfilter/ipset/ip_set_bitmap_ipmac.c
net/netfilter/ipset/ip_set_hash_ipportnet.c
net/netfilter/ipset/ip_set_hash_net.c
net/netfilter/ipset/ip_set_hash_netiface.c
net/netfilter/ipset/ip_set_hash_netport.c
net/netfilter/ipset/ip_set_list_set.c
net/netfilter/nf_conntrack_sip.c
net/netfilter/nf_nat_core.c
net/netrom/af_netrom.c
net/nfc/llcp/sock.c
net/openvswitch/datapath.c
net/openvswitch/flow.c
net/rose/af_rose.c
net/sched/cls_fw.c
net/sunrpc/clnt.c
net/tipc/socket.c
net/vmw_vsock/af_vsock.c
net/vmw_vsock/vmci_transport.c
net/wireless/sme.c
scripts/checkpatch.pl
security/capability.c
security/security.c
security/selinux/hooks.c
sound/core/pcm_native.c
sound/soc/soc-utils.c
sound/usb/mixer_quirks.c
sound/usb/quirks.c
tools/power/x86/turbostat/turbostat.c

index 7514dbf0a6796c4e216a175fa79db0ed3ff470d9..c36892c072dad4aaff9b2e34f3653ac88c915190 100644 (file)
@@ -227,7 +227,7 @@ X!Isound/sound_firmware.c
   <chapter id="uart16x50">
      <title>16x50 UART Driver</title>
 !Edrivers/tty/serial/serial_core.c
-!Edrivers/tty/serial/8250/8250.c
+!Edrivers/tty/serial/8250/8250_core.c
   </chapter>
 
   <chapter id="fbdev">
index 4609e81dbc37fc2dbfa005ff607890df3a8bbc6b..8ccbf27aead4def123c94eaf0de40e39db40199f 100644 (file)
@@ -596,9 +596,6 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
                        is selected automatically. Check
                        Documentation/kdump/kdump.txt for further details.
 
-       crashkernel_low=size[KMG]
-                       [KNL, x86] parts under 4G.
-
        crashkernel=range1:size1[,range2:size2,...][@offset]
                        [KNL] Same as above, but depends on the memory
                        in the running system. The syntax of range is
@@ -606,6 +603,26 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
                        a memory unit (amount[KMG]). See also
                        Documentation/kdump/kdump.txt for an example.
 
+       crashkernel=size[KMG],high
+                       [KNL, x86_64] range could be above 4G. Allow kernel
+                       to allocate physical memory region from top, so could
+                       be above 4G if system have more than 4G ram installed.
+                       Otherwise memory region will be allocated below 4G, if
+                       available.
+                       It will be ignored if crashkernel=X is specified.
+       crashkernel=size[KMG],low
+                       [KNL, x86_64] range under 4G. When crashkernel=X,high
+                       is passed, kernel could allocate physical memory region
+                       above 4G, that cause second kernel crash on system
+                       that require some amount of low memory, e.g. swiotlb
+                       requires at least 64M+32K low memory.  Kernel would
+                       try to allocate 72M below 4G automatically.
+                       This one let user to specify own low range under 4G
+                       for second kernel instead.
+                       0: to disable low allocation.
+                       It will be ignored when crashkernel=X,high is not used
+                       or memory reserved is below 4G.
+
        cs89x0_dma=     [HW,NET]
                        Format: <dma>
 
@@ -788,6 +805,12 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
        edd=            [EDD]
                        Format: {"off" | "on" | "skip[mbr]"}
 
+       efi_no_storage_paranoia [EFI; X86]
+                       Using this parameter you can use more than 50% of
+                       your efi variable storage. Use this parameter only if
+                       you are really sure that your UEFI does sane gc and
+                       fulfills the spec otherwise your board may brick.
+
        eisa_irq_edge=  [PARISC,HW]
                        See header of drivers/parisc/eisa.c.
 
index 27a91cf43d6d66ce4137e9335988175b096423a4..5020b7b5a24410f5cac04c2a8cbc849b3546a8e8 100644 (file)
@@ -1,4 +1,4 @@
-Copyright (c) 2003-2012 QLogic Corporation
+Copyright (c) 2003-2013 QLogic Corporation
 QLogic Linux FC-FCoE Driver
 
 This program includes a device driver for Linux 3.x.
index c6108c319db948d0ca8821fd0fa1b53db7f255b8..8bdd7a7ef2f4687aa26ee66a70fe8ad428e14890 100644 (file)
@@ -4941,6 +4941,12 @@ W:       logfs.org
 S:     Maintained
 F:     fs/logfs/
 
+LPC32XX MACHINE SUPPORT
+M:     Roland Stigge <stigge@antcom.de>
+L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+S:     Maintained
+F:     arch/arm/mach-lpc32xx/
+
 LSILOGIC MPT FUSION DRIVERS (FC/SAS/SPI)
 M:     Nagalakshmi Nandigama <Nagalakshmi.Nandigama@lsi.com>
 M:     Sreekanth Reddy <Sreekanth.Reddy@lsi.com>
@@ -6951,7 +6957,6 @@ F:        drivers/scsi/st*
 
 SCTP PROTOCOL
 M:     Vlad Yasevich <vyasevich@gmail.com>
-M:     Sridhar Samudrala <sri@us.ibm.com>
 M:     Neil Horman <nhorman@tuxdriver.com>
 L:     linux-sctp@vger.kernel.org
 W:     http://lksctp.sourceforge.net
index 6db672b15bdaa447cafe1c6413b0fc56f2e9d2fd..46263d808876a957083da89b42dde63f51d2ef26 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 3
 PATCHLEVEL = 9
 SUBLEVEL = 0
-EXTRAVERSION = -rc6
+EXTRAVERSION = -rc8
 NAME = Unicycling Gorilla
 
 # *DOCUMENTATION*
@@ -513,7 +513,8 @@ ifeq ($(KBUILD_EXTMOD),)
 # Carefully list dependencies so we do not try to build scripts twice
 # in parallel
 PHONY += scripts
-scripts: scripts_basic include/config/auto.conf include/config/tristate.conf
+scripts: scripts_basic include/config/auto.conf include/config/tristate.conf \
+        asm-generic
        $(Q)$(MAKE) $(build)=$(@)
 
 # Objects we will link into vmlinux / subdirs we need to visit
index ccd84806b62fe9635472e6bbc00e0dc5643683ff..eac071668201a143bf0e93367cd277441b520fb8 100644 (file)
@@ -39,7 +39,7 @@ static inline long arch_local_irq_save(void)
        "       flag.nz %0              \n"
        : "=r"(temp), "=r"(flags)
        : "n"((STATUS_E1_MASK | STATUS_E2_MASK))
-       : "cc");
+       : "memory", "cc");
 
        return flags;
 }
@@ -53,7 +53,8 @@ static inline void arch_local_irq_restore(unsigned long flags)
        __asm__ __volatile__(
        "       flag %0                 \n"
        :
-       : "r"(flags));
+       : "r"(flags)
+       : "memory");
 }
 
 /*
@@ -73,7 +74,8 @@ static inline void arch_local_irq_disable(void)
        "       and %0, %0, %1          \n"
        "       flag %0                 \n"
        : "=&r"(temp)
-       : "n"(~(STATUS_E1_MASK | STATUS_E2_MASK)));
+       : "n"(~(STATUS_E1_MASK | STATUS_E2_MASK))
+       : "memory");
 }
 
 /*
@@ -85,7 +87,9 @@ static inline long arch_local_save_flags(void)
 
        __asm__ __volatile__(
        "       lr  %0, [status32]      \n"
-       : "=&r"(temp));
+       : "=&r"(temp)
+       :
+       : "memory");
 
        return temp;
 }
index 6ce3d17c3a29c19c80ef6a04484fd59ec5e8765a..fd36e1cca1042306476c54d4038603780af358a1 100644 (file)
                        i2c0: i2c@80058000 {
                                pinctrl-names = "default";
                                pinctrl-0 = <&i2c0_pins_a>;
-                               clock-frequency = <400000>;
                                status = "okay";
 
                                sgtl5000: codec@0a {
index e6cde8aa7ffff5c3a2b670e2584c7475a8419525..6c6a5442800ad78adfe13ada4cf44a2cfd3cfbc5 100644 (file)
@@ -70,7 +70,6 @@
                        i2c0: i2c@80058000 {
                                pinctrl-names = "default";
                                pinctrl-0 = <&i2c0_pins_a>;
-                               clock-frequency = <400000>;
                                status = "okay";
 
                                rtc: rtc@51 {
index 06ec460b4581c4163e4053953e84acfaad01a76b..281a223591ff83d5a9eef96c6775c77c99a356ad 100644 (file)
@@ -91,6 +91,7 @@
                        compatible = "arm,cortex-a9-twd-timer";
                        reg = <0x00a00600 0x20>;
                        interrupts = <1 13 0xf01>;
+                       clocks = <&clks 15>;
                };
 
                L2: l2-cache@00a02000 {
index 93c3afbef9eeecc4b0b3741c2bc2360717da81b9..3694e94f6e99dc93aaf91985f55c6245830a92af 100644 (file)
                                marvell,function = "gpio";
                        };
                        pmx_led_rebuild_brt_ctrl_1: pmx-led-rebuild-brt-ctrl-1 {
-                               marvell,pins = "mpp44";
+                               marvell,pins = "mpp46";
                                marvell,function = "gpio";
                        };
                        pmx_led_rebuild_brt_ctrl_2: pmx-led-rebuild-brt-ctrl-2 {
-                               marvell,pins = "mpp45";
+                               marvell,pins = "mpp47";
                                marvell,function = "gpio";
                        };
 
                        gpios = <&gpio0 16 0>;
                        linux,default-trigger = "default-on";
                };
-               health_led1 {
+               rebuild_led {
+                       label = "status:white:rebuild_led";
+                       gpios = <&gpio1 4 0>;
+               };
+               health_led {
                        label = "status:red:health_led";
                        gpios = <&gpio1 5 0>;
                };
-               health_led2 {
-                       label = "status:white:health_led";
-                       gpios = <&gpio1 4 0>;
-               };
                backup_led {
                        label = "status:blue:backup_led";
                        gpios = <&gpio0 15 0>;
index cca9f15704ed82bb2726ce8898611be42d28b5ff..ea289e1435e742807f48550200582de5630bf817 100644 (file)
 #undef _CACHE
 #undef MULTI_CACHE
 
-#if defined(CONFIG_CPU_CACHE_V3)
-# ifdef _CACHE
-#  define MULTI_CACHE 1
-# else
-#  define _CACHE v3
-# endif
-#endif
-
 #if defined(CONFIG_CPU_CACHE_V4)
 # ifdef _CACHE
 #  define MULTI_CACHE 1
index 02fe2fbe2477078b4fa8da59c6f2a416fdb71913..ed94b1a366ae62d9535c66847ebe85abf4f4f0c0 100644 (file)
@@ -37,7 +37,7 @@ extern int iop3xx_get_init_atu(void);
  * IOP3XX processor registers
  */
 #define IOP3XX_PERIPHERAL_PHYS_BASE    0xffffe000
-#define IOP3XX_PERIPHERAL_VIRT_BASE    0xfeffe000
+#define IOP3XX_PERIPHERAL_VIRT_BASE    0xfedfe000
 #define IOP3XX_PERIPHERAL_SIZE         0x00002000
 #define IOP3XX_PERIPHERAL_UPPER_PA (IOP3XX_PERIPHERAL_PHYS_BASE +\
                                        IOP3XX_PERIPHERAL_SIZE - 1)
index 6ef8afd1b64cbc3c27ea025d81d0e67d43f0400a..86b8fe398b9514d89a9032658f6bb3ad221b069e 100644 (file)
 #define L_PTE_S2_MT_WRITETHROUGH (_AT(pteval_t, 0xa) << 2) /* MemAttr[3:0] */
 #define L_PTE_S2_MT_WRITEBACK   (_AT(pteval_t, 0xf) << 2) /* MemAttr[3:0] */
 #define L_PTE_S2_RDONLY                 (_AT(pteval_t, 1) << 6)   /* HAP[1]   */
-#define L_PTE_S2_RDWR           (_AT(pteval_t, 2) << 6)   /* HAP[2:1] */
+#define L_PTE_S2_RDWR           (_AT(pteval_t, 3) << 6)   /* HAP[2:1] */
 
 /*
  * Hyp-mode PL2 PTE definitions for LPAE.
index 9e9c041358ca8789e4a6798aaf871007795e8fb9..ab865e65a84c1d0aa735b512b0fbc528de699dad 100644 (file)
@@ -14,7 +14,6 @@
 
 #include <asm/glue.h>
 
-#define TLB_V3_PAGE    (1 << 0)
 #define TLB_V4_U_PAGE  (1 << 1)
 #define TLB_V4_D_PAGE  (1 << 2)
 #define TLB_V4_I_PAGE  (1 << 3)
@@ -22,7 +21,6 @@
 #define TLB_V6_D_PAGE  (1 << 5)
 #define TLB_V6_I_PAGE  (1 << 6)
 
-#define TLB_V3_FULL    (1 << 8)
 #define TLB_V4_U_FULL  (1 << 9)
 #define TLB_V4_D_FULL  (1 << 10)
 #define TLB_V4_I_FULL  (1 << 11)
@@ -52,7 +50,6 @@
  *     =============
  *
  *     We have the following to choose from:
- *       v3    - ARMv3
  *       v4    - ARMv4 without write buffer
  *       v4wb  - ARMv4 with write buffer without I TLB flush entry instruction
  *       v4wbi - ARMv4 with write buffer with I TLB flush entry instruction
@@ -330,7 +327,6 @@ static inline void local_flush_tlb_all(void)
        if (tlb_flag(TLB_WB))
                dsb();
 
-       tlb_op(TLB_V3_FULL, "c6, c0, 0", zero);
        tlb_op(TLB_V4_U_FULL | TLB_V6_U_FULL, "c8, c7, 0", zero);
        tlb_op(TLB_V4_D_FULL | TLB_V6_D_FULL, "c8, c6, 0", zero);
        tlb_op(TLB_V4_I_FULL | TLB_V6_I_FULL, "c8, c5, 0", zero);
@@ -351,9 +347,8 @@ static inline void local_flush_tlb_mm(struct mm_struct *mm)
        if (tlb_flag(TLB_WB))
                dsb();
 
-       if (possible_tlb_flags & (TLB_V3_FULL|TLB_V4_U_FULL|TLB_V4_D_FULL|TLB_V4_I_FULL)) {
+       if (possible_tlb_flags & (TLB_V4_U_FULL|TLB_V4_D_FULL|TLB_V4_I_FULL)) {
                if (cpumask_test_cpu(get_cpu(), mm_cpumask(mm))) {
-                       tlb_op(TLB_V3_FULL, "c6, c0, 0", zero);
                        tlb_op(TLB_V4_U_FULL, "c8, c7, 0", zero);
                        tlb_op(TLB_V4_D_FULL, "c8, c6, 0", zero);
                        tlb_op(TLB_V4_I_FULL, "c8, c5, 0", zero);
@@ -385,9 +380,8 @@ local_flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr)
        if (tlb_flag(TLB_WB))
                dsb();
 
-       if (possible_tlb_flags & (TLB_V3_PAGE|TLB_V4_U_PAGE|TLB_V4_D_PAGE|TLB_V4_I_PAGE|TLB_V4_I_FULL) &&
+       if (possible_tlb_flags & (TLB_V4_U_PAGE|TLB_V4_D_PAGE|TLB_V4_I_PAGE|TLB_V4_I_FULL) &&
            cpumask_test_cpu(smp_processor_id(), mm_cpumask(vma->vm_mm))) {
-               tlb_op(TLB_V3_PAGE, "c6, c0, 0", uaddr);
                tlb_op(TLB_V4_U_PAGE, "c8, c7, 1", uaddr);
                tlb_op(TLB_V4_D_PAGE, "c8, c6, 1", uaddr);
                tlb_op(TLB_V4_I_PAGE, "c8, c5, 1", uaddr);
@@ -418,7 +412,6 @@ static inline void local_flush_tlb_kernel_page(unsigned long kaddr)
        if (tlb_flag(TLB_WB))
                dsb();
 
-       tlb_op(TLB_V3_PAGE, "c6, c0, 0", kaddr);
        tlb_op(TLB_V4_U_PAGE, "c8, c7, 1", kaddr);
        tlb_op(TLB_V4_D_PAGE, "c8, c6, 1", kaddr);
        tlb_op(TLB_V4_I_PAGE, "c8, c5, 1", kaddr);
index 5dc1aa6f0f7d75e9339094a1da1b61eb018f32f3..1fd749ee4a1bb96c1740f4a131fde1d3cd53bfb0 100644 (file)
@@ -1043,7 +1043,7 @@ static int dbg_cpu_pm_notify(struct notifier_block *self, unsigned long action,
        return NOTIFY_OK;
 }
 
-static struct notifier_block __cpuinitdata dbg_cpu_pm_nb = {
+static struct notifier_block dbg_cpu_pm_nb = {
        .notifier_call = dbg_cpu_pm_notify,
 };
 
index 146157dfe27c6c991b8507c2c3f248d810754cc0..8c3094d0f7b78426e367e2cf3ed538e54d686cbd 100644 (file)
@@ -253,7 +253,10 @@ validate_event(struct pmu_hw_events *hw_events,
        struct arm_pmu *armpmu = to_arm_pmu(event->pmu);
        struct pmu *leader_pmu = event->group_leader->pmu;
 
-       if (event->pmu != leader_pmu || event->state <= PERF_EVENT_STATE_OFF)
+       if (event->pmu != leader_pmu || event->state < PERF_EVENT_STATE_OFF)
+               return 1;
+
+       if (event->state == PERF_EVENT_STATE_OFF && !event->attr.enable_on_exec)
                return 1;
 
        return armpmu->get_event_idx(hw_events, event) >= 0;
index bd6f56b9ec2101534b7477c11c9f6ef0a3a6e68b..59d2adb764a995f9174a6494bd2bcc1974c10e73 100644 (file)
@@ -45,12 +45,12 @@ static u32 notrace jiffy_sched_clock_read(void)
 
 static u32 __read_mostly (*read_sched_clock)(void) = jiffy_sched_clock_read;
 
-static inline u64 cyc_to_ns(u64 cyc, u32 mult, u32 shift)
+static inline u64 notrace cyc_to_ns(u64 cyc, u32 mult, u32 shift)
 {
        return (cyc * mult) >> shift;
 }
 
-static unsigned long long cyc_to_sched_clock(u32 cyc, u32 mask)
+static unsigned long long notrace cyc_to_sched_clock(u32 cyc, u32 mask)
 {
        u64 epoch_ns;
        u32 epoch_cyc;
index d343a6c3a6d1f26ec10ca55f914785b65b4fa473..234e339196c0b8fbf0c10a920db0342f3411083f 100644 (file)
@@ -56,7 +56,6 @@
 #include <asm/virt.h>
 
 #include "atags.h"
-#include "tcm.h"
 
 
 #if defined(CONFIG_FPE_NWFPE) || defined(CONFIG_FPE_FASTFPE)
@@ -798,8 +797,6 @@ void __init setup_arch(char **cmdline_p)
 
        reserve_crashkernel();
 
-       tcm_init();
-
 #ifdef CONFIG_MULTI_IRQ_HANDLER
        handle_arch_irq = mdesc->handle_irq;
 #endif
index 30ae6bb4a310c12723b7bc7ca26ea91ae25bb770..f50f19e5c138839bede270baf3531a41aa5af7c4 100644 (file)
@@ -17,7 +17,6 @@
 #include <asm/mach/map.h>
 #include <asm/memory.h>
 #include <asm/system_info.h>
-#include "tcm.h"
 
 static struct gen_pool *tcm_pool;
 static bool dtcm_present;
index 5a936988eb24d1e62e5ae248ff6e4a3db59667b9..c1fe498983ac84c21334d87b1cd9cd6c8c3abc3f 100644 (file)
@@ -201,6 +201,7 @@ int kvm_dev_ioctl_check_extension(long ext)
                break;
        case KVM_CAP_ARM_SET_DEVICE_ADDR:
                r = 1;
+               break;
        case KVM_CAP_NR_VCPUS:
                r = num_online_cpus();
                break;
index 4ea9a982269c8f9c9c56808f92b464a025356533..7bed7556077a20002f0e1a6cea2c5a43b05b9102 100644 (file)
@@ -79,11 +79,11 @@ static bool access_dcsw(struct kvm_vcpu *vcpu,
        u32 val;
        int cpu;
 
-       cpu = get_cpu();
-
        if (!p->is_write)
                return read_from_write_only(vcpu, p);
 
+       cpu = get_cpu();
+
        cpumask_setall(&vcpu->arch.require_dcache_flush);
        cpumask_clear_cpu(cpu, &vcpu->arch.require_dcache_flush);
 
index f30c528433967e43b1f1afa1050c13feefbbe914..890cae23c12aee40b3f0d675e54d590b13965a5c 100644 (file)
@@ -28,13 +28,11 @@ extern void secondary_startup(void);
  */
 void __ref highbank_cpu_die(unsigned int cpu)
 {
-       flush_cache_all();
-
        highbank_set_cpu_jump(cpu, phys_to_virt(0));
-       highbank_set_core_pwr();
 
-       cpu_do_idle();
+       flush_cache_louis();
+       highbank_set_core_pwr();
 
-       /* We should never return from idle */
-       panic("highbank: cpu %d unexpectedly exit from shutdown\n", cpu);
+       while (1)
+               cpu_do_idle();
 }
index e13a8fa5e62c5aa4f04b0aba66f4e77df0ac24ce..2193c834f55ccc68dcbd35cb3ebb1d68dc9f35d6 100644 (file)
@@ -257,6 +257,7 @@ int __init mx35_clocks_init(void)
        clk_register_clkdev(clk[wdog_gate], NULL, "imx2-wdt.0");
        clk_register_clkdev(clk[nfc_div], NULL, "imx25-nand.0");
        clk_register_clkdev(clk[csi_gate], NULL, "mx3-camera.0");
+       clk_register_clkdev(clk[admux_gate], "audmux", NULL);
 
        clk_prepare_enable(clk[spba_gate]);
        clk_prepare_enable(clk[gpio1_gate]);
@@ -265,6 +266,7 @@ int __init mx35_clocks_init(void)
        clk_prepare_enable(clk[iim_gate]);
        clk_prepare_enable(clk[emi_gate]);
        clk_prepare_enable(clk[max_gate]);
+       clk_prepare_enable(clk[iomuxc_gate]);
 
        /*
         * SCC is needed to boot via mmc after a watchdog reset. The clock code
index 2f9ff93a4e6134773befacb68c4dd4ec5c14bb90..d38e54f5b6d7f1dbbbd245a91db8be9a2408b28f 100644 (file)
@@ -115,7 +115,7 @@ static const char *gpu2d_core_sels[]        = { "axi", "pll3_usb_otg", "pll2_pfd0_352m"
 static const char *gpu3d_core_sels[]   = { "mmdc_ch0_axi", "pll3_usb_otg", "pll2_pfd1_594m", "pll2_pfd2_396m", };
 static const char *gpu3d_shader_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll2_pfd1_594m", "pll2_pfd9_720m", };
 static const char *ipu_sels[]          = { "mmdc_ch0_axi", "pll2_pfd2_396m", "pll3_120m", "pll3_pfd1_540m", };
-static const char *ldb_di_sels[]       = { "pll5_video", "pll2_pfd0_352m", "pll2_pfd2_396m", "mmdc_ch1_axi", "pll3_pfd1_540m", };
+static const char *ldb_di_sels[]       = { "pll5_video", "pll2_pfd0_352m", "pll2_pfd2_396m", "mmdc_ch1_axi", "pll3_usb_otg", };
 static const char *ipu_di_pre_sels[]   = { "mmdc_ch0_axi", "pll3_usb_otg", "pll5_video", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll3_pfd1_540m", };
 static const char *ipu1_di0_sels[]     = { "ipu1_di0_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", };
 static const char *ipu1_di1_sels[]     = { "ipu1_di1_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", };
@@ -443,7 +443,6 @@ int __init mx6q_clocks_init(void)
 
        clk_register_clkdev(clk[gpt_ipg], "ipg", "imx-gpt.0");
        clk_register_clkdev(clk[gpt_ipg_per], "per", "imx-gpt.0");
-       clk_register_clkdev(clk[twd], NULL, "smp_twd");
        clk_register_clkdev(clk[cko1_sel], "cko1_sel", NULL);
        clk_register_clkdev(clk[ahb], "ahb", NULL);
        clk_register_clkdev(clk[cko1], "cko1", NULL);
index f655b2637b0e2b4822efc185c499095c44bc6b9e..e5f70415905a998e919b5b4aabe8d3121fa8a81e 100644 (file)
@@ -20,10 +20,15 @@ static struct mv643xx_eth_platform_data iomega_ix2_200_ge00_data = {
        .duplex         = DUPLEX_FULL,
 };
 
+static struct mv643xx_eth_platform_data iomega_ix2_200_ge01_data = {
+        .phy_addr       = MV643XX_ETH_PHY_ADDR(11),
+};
+
 void __init iomega_ix2_200_init(void)
 {
        /*
         * Basic setup. Needs to be called early.
         */
-       kirkwood_ge01_init(&iomega_ix2_200_ge00_data);
+       kirkwood_ge00_init(&iomega_ix2_200_ge00_data);
+       kirkwood_ge01_init(&iomega_ix2_200_ge01_data);
 }
index 6a9195e10579a8263b3446ccc443bd1d1381f784..d5970f5a1e8d5ea8010c8f243853ec3a28d6bb30 100644 (file)
@@ -61,7 +61,6 @@ static struct irq_domain *armada_370_xp_mpic_domain;
  */
 static void armada_370_xp_irq_mask(struct irq_data *d)
 {
-#ifdef CONFIG_SMP
        irq_hw_number_t hwirq = irqd_to_hwirq(d);
 
        if (hwirq != ARMADA_370_XP_TIMER0_PER_CPU_IRQ)
@@ -70,15 +69,10 @@ static void armada_370_xp_irq_mask(struct irq_data *d)
        else
                writel(hwirq, per_cpu_int_base +
                                ARMADA_370_XP_INT_SET_MASK_OFFS);
-#else
-       writel(irqd_to_hwirq(d),
-              per_cpu_int_base + ARMADA_370_XP_INT_SET_MASK_OFFS);
-#endif
 }
 
 static void armada_370_xp_irq_unmask(struct irq_data *d)
 {
-#ifdef CONFIG_SMP
        irq_hw_number_t hwirq = irqd_to_hwirq(d);
 
        if (hwirq != ARMADA_370_XP_TIMER0_PER_CPU_IRQ)
@@ -87,10 +81,6 @@ static void armada_370_xp_irq_unmask(struct irq_data *d)
        else
                writel(hwirq, per_cpu_int_base +
                                ARMADA_370_XP_INT_CLEAR_MASK_OFFS);
-#else
-       writel(irqd_to_hwirq(d),
-              per_cpu_int_base + ARMADA_370_XP_INT_CLEAR_MASK_OFFS);
-#endif
 }
 
 #ifdef CONFIG_SMP
@@ -146,7 +136,11 @@ static int armada_370_xp_mpic_irq_map(struct irq_domain *h,
                                      unsigned int virq, irq_hw_number_t hw)
 {
        armada_370_xp_irq_mask(irq_get_irq_data(virq));
-       writel(hw, main_int_base + ARMADA_370_XP_INT_SET_ENABLE_OFFS);
+       if (hw != ARMADA_370_XP_TIMER0_PER_CPU_IRQ)
+               writel(hw, per_cpu_int_base +
+                       ARMADA_370_XP_INT_CLEAR_MASK_OFFS);
+       else
+               writel(hw, main_int_base + ARMADA_370_XP_INT_SET_ENABLE_OFFS);
        irq_set_status_flags(virq, IRQ_LEVEL);
 
        if (hw == ARMADA_370_XP_TIMER0_PER_CPU_IRQ) {
index b7a9f4d469e816bf6ca1f389f31d9280d06ecc46..1e73f5fa865983cd0a79fae37623af0f4a0ebbaf 100644 (file)
 
 #if defined(CONFIG_CPU_S3C2416)
 #define NR_IRQS (IRQ_S3C2416_I2S1 + 1)
-#elif defined(CONFIG_CPU_S3C2443)
-#define NR_IRQS (IRQ_S3C2443_AC97+1)
 #else
-#define NR_IRQS (IRQ_S3C2440_AC97+1)
+#define NR_IRQS (IRQ_S3C2443_AC97 + 1)
 #endif
 
 /* compatibility define. */
index cb9f5e011e73a1fb5f055dc6a3c6498aa095f7e0..d8ba9bee4c7e61434aa90852ce7f4e66ff4a5ebd 100644 (file)
@@ -500,7 +500,7 @@ struct s3c_irq_intc *s3c24xx_init_intc(struct device_node *np,
                base = (void *)0xfd000000;
 
                intc->reg_mask = base + 0xa4;
-               intc->reg_pending = base + 0x08;
+               intc->reg_pending = base + 0xa8;
                irq_num = 20;
                irq_start = S3C2410_IRQ(32);
                irq_offset = 4;
index 025d173287307afdb5db4bc0b7a9679511629c11..4045c4931a300d3381848dc2ff3d39403096c2d9 100644 (file)
@@ -43,7 +43,7 @@ config CPU_ARM740T
        depends on !MMU
        select CPU_32v4T
        select CPU_ABRT_LV4T
-       select CPU_CACHE_V3     # although the core is v4t
+       select CPU_CACHE_V4
        select CPU_CP15_MPU
        select CPU_PABRT_LEGACY
        help
@@ -469,9 +469,6 @@ config CPU_PABRT_V7
        bool
 
 # The cache model
-config CPU_CACHE_V3
-       bool
-
 config CPU_CACHE_V4
        bool
 
index 4e333fa2756f4de16b4005ca65e1eb44cff0c579..9e51be96f635b5945b978bed2c6978fd3d2b61ba 100644 (file)
@@ -33,7 +33,6 @@ obj-$(CONFIG_CPU_PABRT_LEGACY)        += pabort-legacy.o
 obj-$(CONFIG_CPU_PABRT_V6)     += pabort-v6.o
 obj-$(CONFIG_CPU_PABRT_V7)     += pabort-v7.o
 
-obj-$(CONFIG_CPU_CACHE_V3)     += cache-v3.o
 obj-$(CONFIG_CPU_CACHE_V4)     += cache-v4.o
 obj-$(CONFIG_CPU_CACHE_V4WT)   += cache-v4wt.o
 obj-$(CONFIG_CPU_CACHE_V4WB)   += cache-v4wb.o
index dd3d59122cc374c80ad487ad57bc3f5fbc580325..48bc3c0a87ce321cc2e37c257bf217dc085307e6 100644 (file)
@@ -343,6 +343,7 @@ void __init feroceon_l2_init(int __l2_wt_override)
        outer_cache.inv_range = feroceon_l2_inv_range;
        outer_cache.clean_range = feroceon_l2_clean_range;
        outer_cache.flush_range = feroceon_l2_flush_range;
+       outer_cache.inv_all = l2_inv_all;
 
        enable_l2();
 
diff --git a/arch/arm/mm/cache-v3.S b/arch/arm/mm/cache-v3.S
deleted file mode 100644 (file)
index 8a3fade..0000000
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- *  linux/arch/arm/mm/cache-v3.S
- *
- *  Copyright (C) 1997-2002 Russell king
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include <linux/linkage.h>
-#include <linux/init.h>
-#include <asm/page.h>
-#include "proc-macros.S"
-
-/*
- *     flush_icache_all()
- *
- *     Unconditionally clean and invalidate the entire icache.
- */
-ENTRY(v3_flush_icache_all)
-       mov     pc, lr
-ENDPROC(v3_flush_icache_all)
-
-/*
- *     flush_user_cache_all()
- *
- *     Invalidate all cache entries in a particular address
- *     space.
- *
- *     - mm    - mm_struct describing address space
- */
-ENTRY(v3_flush_user_cache_all)
-       /* FALLTHROUGH */
-/*
- *     flush_kern_cache_all()
- *
- *     Clean and invalidate the entire cache.
- */
-ENTRY(v3_flush_kern_cache_all)
-       /* FALLTHROUGH */
-
-/*
- *     flush_user_cache_range(start, end, flags)
- *
- *     Invalidate a range of cache entries in the specified
- *     address space.
- *
- *     - start - start address (may not be aligned)
- *     - end   - end address (exclusive, may not be aligned)
- *     - flags - vma_area_struct flags describing address space
- */
-ENTRY(v3_flush_user_cache_range)
-       mov     ip, #0
-       mcreq   p15, 0, ip, c7, c0, 0           @ flush ID cache
-       mov     pc, lr
-
-/*
- *     coherent_kern_range(start, end)
- *
- *     Ensure coherency between the Icache and the Dcache in the
- *     region described by start.  If you have non-snooping
- *     Harvard caches, you need to implement this function.
- *
- *     - start  - virtual start address
- *     - end    - virtual end address
- */
-ENTRY(v3_coherent_kern_range)
-       /* FALLTHROUGH */
-
-/*
- *     coherent_user_range(start, end)
- *
- *     Ensure coherency between the Icache and the Dcache in the
- *     region described by start.  If you have non-snooping
- *     Harvard caches, you need to implement this function.
- *
- *     - start  - virtual start address
- *     - end    - virtual end address
- */
-ENTRY(v3_coherent_user_range)
-       mov     r0, #0
-       mov     pc, lr
-
-/*
- *     flush_kern_dcache_area(void *page, size_t size)
- *
- *     Ensure no D cache aliasing occurs, either with itself or
- *     the I cache
- *
- *     - addr  - kernel address
- *     - size  - region size
- */
-ENTRY(v3_flush_kern_dcache_area)
-       /* FALLTHROUGH */
-
-/*
- *     dma_flush_range(start, end)
- *
- *     Clean and invalidate the specified virtual address range.
- *
- *     - start  - virtual start address
- *     - end    - virtual end address
- */
-ENTRY(v3_dma_flush_range)
-       mov     r0, #0
-       mcr     p15, 0, r0, c7, c0, 0           @ flush ID cache
-       mov     pc, lr
-
-/*
- *     dma_unmap_area(start, size, dir)
- *     - start - kernel virtual start address
- *     - size  - size of region
- *     - dir   - DMA direction
- */
-ENTRY(v3_dma_unmap_area)
-       teq     r2, #DMA_TO_DEVICE
-       bne     v3_dma_flush_range
-       /* FALLTHROUGH */
-
-/*
- *     dma_map_area(start, size, dir)
- *     - start - kernel virtual start address
- *     - size  - size of region
- *     - dir   - DMA direction
- */
-ENTRY(v3_dma_map_area)
-       mov     pc, lr
-ENDPROC(v3_dma_unmap_area)
-ENDPROC(v3_dma_map_area)
-
-       .globl  v3_flush_kern_cache_louis
-       .equ    v3_flush_kern_cache_louis, v3_flush_kern_cache_all
-
-       __INITDATA
-
-       @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
-       define_cache_functions v3
index 43e5d77be677a329f497f9829364f392b254fa75..a7ba68f59f0cd8564fa2a12b84e0e2b3f13b6860 100644 (file)
@@ -58,7 +58,7 @@ ENTRY(v4_flush_kern_cache_all)
 ENTRY(v4_flush_user_cache_range)
 #ifdef CONFIG_CPU_CP15
        mov     ip, #0
-       mcreq   p15, 0, ip, c7, c7, 0           @ flush ID cache
+       mcr     p15, 0, ip, c7, c7, 0           @ flush ID cache
        mov     pc, lr
 #else
        /* FALLTHROUGH */
index 78978945492a2a105f1a9a2d18e81cd76dc1e7b6..a84ff763ac399b72778ed8e6f7a3571676ac5ffa 100644 (file)
@@ -34,6 +34,7 @@
 #include <asm/mach/pci.h>
 
 #include "mm.h"
+#include "tcm.h"
 
 /*
  * empty_zero_page is a special page that is used for
@@ -1277,6 +1278,7 @@ void __init paging_init(struct machine_desc *mdesc)
        dma_contiguous_remap();
        devicemaps_init(mdesc);
        kmap_init();
+       tcm_init();
 
        top_pmd = pmd_off_k(0xffff0000);
 
index dc5de5d53f20c4865f6522d86fa96e7d9495071e..fde2d2a794cfbc0b43c31619fff9668172aebad3 100644 (file)
@@ -77,24 +77,27 @@ __arm740_setup:
        mcr     p15, 0, r0, c6, c0              @ set area 0, default
 
        ldr     r0, =(CONFIG_DRAM_BASE & 0xFFFFF000) @ base[31:12] of RAM
-       ldr     r1, =(CONFIG_DRAM_SIZE >> 12)   @ size of RAM (must be >= 4KB)
-       mov     r2, #10                         @ 11 is the minimum (4KB)
-1:     add     r2, r2, #1                      @ area size *= 2
-       mov     r1, r1, lsr #1
+       ldr     r3, =(CONFIG_DRAM_SIZE >> 12)   @ size of RAM (must be >= 4KB)
+       mov     r4, #10                         @ 11 is the minimum (4KB)
+1:     add     r4, r4, #1                      @ area size *= 2
+       movs    r3, r3, lsr #1
        bne     1b                              @ count not zero r-shift
-       orr     r0, r0, r2, lsl #1              @ the area register value
+       orr     r0, r0, r4, lsl #1              @ the area register value
        orr     r0, r0, #1                      @ set enable bit
        mcr     p15, 0, r0, c6, c1              @ set area 1, RAM
 
        ldr     r0, =(CONFIG_FLASH_MEM_BASE & 0xFFFFF000) @ base[31:12] of FLASH
-       ldr     r1, =(CONFIG_FLASH_SIZE >> 12)  @ size of FLASH (must be >= 4KB)
-       mov     r2, #10                         @ 11 is the minimum (4KB)
-1:     add     r2, r2, #1                      @ area size *= 2
-       mov     r1, r1, lsr #1
+       ldr     r3, =(CONFIG_FLASH_SIZE >> 12)  @ size of FLASH (must be >= 4KB)
+       cmp     r3, #0
+       moveq   r0, #0
+       beq     2f
+       mov     r4, #10                         @ 11 is the minimum (4KB)
+1:     add     r4, r4, #1                      @ area size *= 2
+       movs    r3, r3, lsr #1
        bne     1b                              @ count not zero r-shift
-       orr     r0, r0, r2, lsl #1              @ the area register value
+       orr     r0, r0, r4, lsl #1              @ the area register value
        orr     r0, r0, #1                      @ set enable bit
-       mcr     p15, 0, r0, c6, c2              @ set area 2, ROM/FLASH
+2:     mcr     p15, 0, r0, c6, c2              @ set area 2, ROM/FLASH
 
        mov     r0, #0x06
        mcr     p15, 0, r0, c2, c0              @ Region 1&2 cacheable
@@ -137,13 +140,14 @@ __arm740_proc_info:
        .long   0x41807400
        .long   0xfffffff0
        .long   0
+       .long   0
        b       __arm740_setup
        .long   cpu_arch_name
        .long   cpu_elf_name
-       .long   HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT
+       .long   HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB | HWCAP_26BIT
        .long   cpu_arm740_name
        .long   arm740_processor_functions
        .long   0
        .long   0
-       .long   v3_cache_fns                    @ cache model
+       .long   v4_cache_fns                    @ cache model
        .size   __arm740_proc_info, . - __arm740_proc_info
index 2c3b9421ab5eca938dfe9289fc39472259ada3c1..2556cf1c2da1c8f40c09edbe7d43b7c0286f355f 100644 (file)
@@ -387,7 +387,7 @@ ENTRY(cpu_arm920_set_pte_ext)
 /* Suspend/resume support: taken from arch/arm/plat-s3c24xx/sleep.S */
 .globl cpu_arm920_suspend_size
 .equ   cpu_arm920_suspend_size, 4 * 3
-#ifdef CONFIG_PM_SLEEP
+#ifdef CONFIG_ARM_CPU_SUSPEND
 ENTRY(cpu_arm920_do_suspend)
        stmfd   sp!, {r4 - r6, lr}
        mrc     p15, 0, r4, c13, c0, 0  @ PID
index f1803f7e29728460965675b6722a978d0cc33dcd..344c8a548cc0ef95aea9653d883b26c629f016dd 100644 (file)
@@ -402,7 +402,7 @@ ENTRY(cpu_arm926_set_pte_ext)
 /* Suspend/resume support: taken from arch/arm/plat-s3c24xx/sleep.S */
 .globl cpu_arm926_suspend_size
 .equ   cpu_arm926_suspend_size, 4 * 3
-#ifdef CONFIG_PM_SLEEP
+#ifdef CONFIG_ARM_CPU_SUSPEND
 ENTRY(cpu_arm926_do_suspend)
        stmfd   sp!, {r4 - r6, lr}
        mrc     p15, 0, r4, c13, c0, 0  @ PID
index 82f9cdc751d6421d01bcb4eca3de51dd211f1868..0b60dd3d742a1d909e4ffdf8d5162cd052754098 100644 (file)
@@ -350,7 +350,7 @@ ENTRY(cpu_mohawk_set_pte_ext)
 
 .globl cpu_mohawk_suspend_size
 .equ   cpu_mohawk_suspend_size, 4 * 6
-#ifdef CONFIG_PM_SLEEP
+#ifdef CONFIG_ARM_CPU_SUSPEND
 ENTRY(cpu_mohawk_do_suspend)
        stmfd   sp!, {r4 - r9, lr}
        mrc     p14, 0, r4, c6, c0, 0   @ clock configuration, for turbo mode
index 3aa0da11fd8473376405d6fe57b76b777ca1cf93..d92dfd081429294200875ddedfbd6beb4fd98735 100644 (file)
@@ -172,7 +172,7 @@ ENTRY(cpu_sa1100_set_pte_ext)
 
 .globl cpu_sa1100_suspend_size
 .equ   cpu_sa1100_suspend_size, 4 * 3
-#ifdef CONFIG_PM_SLEEP
+#ifdef CONFIG_ARM_CPU_SUSPEND
 ENTRY(cpu_sa1100_do_suspend)
        stmfd   sp!, {r4 - r6, lr}
        mrc     p15, 0, r4, c3, c0, 0           @ domain ID
index 3e6210b4d6d4cc713ba524ab3966760ad1d6f6f8..054b491ff7649ca067ff821770aec80a4da42102 100644 (file)
@@ -17,7 +17,9 @@
 
 #ifndef MULTI_CPU
 EXPORT_SYMBOL(cpu_dcache_clean_area);
+#ifdef CONFIG_MMU
 EXPORT_SYMBOL(cpu_set_pte_ext);
+#endif
 #else
 EXPORT_SYMBOL(processor);
 #endif
index bcaaa8de93250fb73dbab83b3b0d07a74ccd70fc..5c07ee4fe3eb5cd004d5a81780c5f255527150cb 100644 (file)
@@ -138,7 +138,7 @@ ENTRY(cpu_v6_set_pte_ext)
 /* Suspend/resume support: taken from arch/arm/mach-s3c64xx/sleep.S */
 .globl cpu_v6_suspend_size
 .equ   cpu_v6_suspend_size, 4 * 6
-#ifdef CONFIG_PM_SLEEP
+#ifdef CONFIG_ARM_CPU_SUSPEND
 ENTRY(cpu_v6_do_suspend)
        stmfd   sp!, {r4 - r9, lr}
        mrc     p15, 0, r4, c13, c0, 0  @ FCSE/PID
index eb93d6487f3598fcb0cc6e92c0f3e23faa36fb11..e8efd83b6f252f00b85b29eb45d24bbd4919d4ae 100644 (file)
@@ -413,7 +413,7 @@ ENTRY(cpu_xsc3_set_pte_ext)
 
 .globl cpu_xsc3_suspend_size
 .equ   cpu_xsc3_suspend_size, 4 * 6
-#ifdef CONFIG_PM_SLEEP
+#ifdef CONFIG_ARM_CPU_SUSPEND
 ENTRY(cpu_xsc3_do_suspend)
        stmfd   sp!, {r4 - r9, lr}
        mrc     p14, 0, r4, c6, c0, 0   @ clock configuration, for turbo mode
index 25510361aa181e7200d6f69a64d41ff6b8f8a8a6..e766f889bfd6d1b4159c6724a975468dbba56892 100644 (file)
@@ -528,7 +528,7 @@ ENTRY(cpu_xscale_set_pte_ext)
 
 .globl cpu_xscale_suspend_size
 .equ   cpu_xscale_suspend_size, 4 * 6
-#ifdef CONFIG_PM_SLEEP
+#ifdef CONFIG_ARM_CPU_SUSPEND
 ENTRY(cpu_xscale_do_suspend)
        stmfd   sp!, {r4 - r9, lr}
        mrc     p14, 0, r4, c6, c0, 0   @ clock configuration, for turbo mode
similarity index 100%
rename from arch/arm/kernel/tcm.h
rename to arch/arm/mm/tcm.h
index cf60d0a9f1767ca8d8ba8e3e810526539022313f..fc6483f83ccca748a3dc4319bb1ee849f8435654 100644 (file)
@@ -165,6 +165,10 @@ BUILDIO_IOPORT(l, u32)
 #define readw_be                       __raw_readw
 #define readl_be                       __raw_readl
 
+#define writeb_relaxed                 writeb
+#define writew_relaxed                 writew
+#define writel_relaxed                 writel
+
 #define writeb_be                      __raw_writeb
 #define writew_be                      __raw_writew
 #define writel_be                      __raw_writel
index cf78e09e18c3613fe027cd3ac458ed4a4a15c01b..2c71d5634ec299e181d53a4a2ca430563d385b05 100644 (file)
@@ -27,7 +27,7 @@ static inline unsigned long arch_local_save_flags(void)
 /* set interrupt enabled status */
 static inline void arch_local_irq_restore(unsigned long flags)
 {
-       asm volatile (" mvc .s2 %0,CSR\n" : : "b"(flags));
+       asm volatile (" mvc .s2 %0,CSR\n" : : "b"(flags) : "memory");
 }
 
 /* unconditionally enable interrupts */
index 77597e5ea60aca9429f29c26ec7973bf89a19683..79521d5499f94e906c7a0fece9cfe206d7629c79 100644 (file)
@@ -849,17 +849,6 @@ static palinfo_entry_t palinfo_entries[]={
 
 #define NR_PALINFO_ENTRIES     (int) ARRAY_SIZE(palinfo_entries)
 
-/*
- * this array is used to keep track of the proc entries we create. This is
- * required in the module mode when we need to remove all entries. The procfs code
- * does not do recursion of deletion
- *
- * Notes:
- *     - +1 accounts for the cpuN directory entry in /proc/pal
- */
-#define NR_PALINFO_PROC_ENTRIES        (NR_CPUS*(NR_PALINFO_ENTRIES+1))
-
-static struct proc_dir_entry *palinfo_proc_entries[NR_PALINFO_PROC_ENTRIES];
 static struct proc_dir_entry *palinfo_dir;
 
 /*
@@ -971,60 +960,32 @@ palinfo_read_entry(char *page, char **start, off_t off, int count, int *eof, voi
 static void __cpuinit
 create_palinfo_proc_entries(unsigned int cpu)
 {
-#      define CPUSTR   "cpu%d"
-
        pal_func_cpu_u_t f;
-       struct proc_dir_entry **pdir;
        struct proc_dir_entry *cpu_dir;
        int j;
-       char cpustr[sizeof(CPUSTR)];
-
-
-       /*
-        * we keep track of created entries in a depth-first order for
-        * cleanup purposes. Each entry is stored into palinfo_proc_entries
-        */
-       sprintf(cpustr,CPUSTR, cpu);
+       char cpustr[3+4+1];     /* cpu numbers are up to 4095 on itanic */
+       sprintf(cpustr, "cpu%d", cpu);
 
        cpu_dir = proc_mkdir(cpustr, palinfo_dir);
+       if (!cpu_dir)
+               return;
 
        f.req_cpu = cpu;
 
-       /*
-        * Compute the location to store per cpu entries
-        * We dont store the top level entry in this list, but
-        * remove it finally after removing all cpu entries.
-        */
-       pdir = &palinfo_proc_entries[cpu*(NR_PALINFO_ENTRIES+1)];
-       *pdir++ = cpu_dir;
        for (j=0; j < NR_PALINFO_ENTRIES; j++) {
                f.func_id = j;
-               *pdir = create_proc_read_entry(
-                               palinfo_entries[j].name, 0, cpu_dir,
-                               palinfo_read_entry, (void *)f.value);
-               pdir++;
+               create_proc_read_entry(
+                       palinfo_entries[j].name, 0, cpu_dir,
+                       palinfo_read_entry, (void *)f.value);
        }
 }
 
 static void
 remove_palinfo_proc_entries(unsigned int hcpu)
 {
-       int j;
-       struct proc_dir_entry *cpu_dir, **pdir;
-
-       pdir = &palinfo_proc_entries[hcpu*(NR_PALINFO_ENTRIES+1)];
-       cpu_dir = *pdir;
-       *pdir++=NULL;
-       for (j=0; j < (NR_PALINFO_ENTRIES); j++) {
-               if ((*pdir)) {
-                       remove_proc_entry ((*pdir)->name, cpu_dir);
-                       *pdir ++= NULL;
-               }
-       }
-
-       if (cpu_dir) {
-               remove_proc_entry(cpu_dir->name, palinfo_dir);
-       }
+       char cpustr[3+4+1];     /* cpu numbers are up to 4095 on itanic */
+       sprintf(cpustr, "cpu%d", hcpu);
+       remove_proc_subtree(cpustr, palinfo_dir);
 }
 
 static int __cpuinit palinfo_cpu_callback(struct notifier_block *nfb,
@@ -1058,6 +1019,8 @@ palinfo_init(void)
 
        printk(KERN_INFO "PAL Information Facility v%s\n", PALINFO_VERSION);
        palinfo_dir = proc_mkdir("pal", NULL);
+       if (!palinfo_dir)
+               return -ENOMEM;
 
        /* Create palinfo dirs in /proc for all online cpus */
        for_each_online_cpu(i) {
@@ -1073,22 +1036,8 @@ palinfo_init(void)
 static void __exit
 palinfo_exit(void)
 {
-       int i = 0;
-
-       /* remove all nodes: depth first pass. Could optimize this  */
-       for_each_online_cpu(i) {
-               remove_palinfo_proc_entries(i);
-       }
-
-       /*
-        * Remove the top level entry finally
-        */
-       remove_proc_entry(palinfo_dir->name, NULL);
-
-       /*
-        * Unregister from cpu notifier callbacks
-        */
        unregister_hotcpu_notifier(&palinfo_cpu_notifier);
+       remove_proc_subtree("pal", NULL);
 }
 
 module_init(palinfo_init);
index 4395ffc51fdbc4739ae5f22257c42a6f76b06a41..8cc83431805b73eb44d777d8749e6fc3de66fbbe 100644 (file)
@@ -86,4 +86,24 @@ static inline int gpio_cansleep(unsigned gpio)
        return gpio < MCFGPIO_PIN_MAX ? 0 : __gpio_cansleep(gpio);
 }
 
+static inline int gpio_request_one(unsigned gpio, unsigned long flags, const char *label)
+{
+       int err;
+
+       err = gpio_request(gpio, label);
+       if (err)
+               return err;
+
+       if (flags & GPIOF_DIR_IN)
+               err = gpio_direction_input(gpio);
+       else
+               err = gpio_direction_output(gpio,
+                       (flags & GPIOF_INIT_HIGH) ? 1 : 0);
+
+       if (err)
+               gpio_free(gpio);
+
+       return err;
+}
+
 #endif
index 256c5bf0adb7a87cb0429bc02c435f3cfecbd3b5..04d69c4a5ac2d6326839d8bcf23342ff509926ce 100644 (file)
@@ -304,7 +304,7 @@ syscall_exit_work:
        subi    r12,r12,TI_FLAGS
 
 4:     /* Anything else left to do? */
-       SET_DEFAULT_THREAD_PPR(r3, r9)          /* Set thread.ppr = 3 */
+       SET_DEFAULT_THREAD_PPR(r3, r10)         /* Set thread.ppr = 3 */
        andi.   r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP)
        beq     .ret_from_except_lite
 
@@ -657,7 +657,7 @@ resume_kernel:
        /* Clear _TIF_EMULATE_STACK_STORE flag */
        lis     r11,_TIF_EMULATE_STACK_STORE@h
        addi    r5,r9,TI_FLAGS
-       ldarx   r4,0,r5
+0:     ldarx   r4,0,r5
        andc    r4,r4,r11
        stdcx.  r4,0,r5
        bne-    0b
index 59dd545fdde188761e140c2f6969b9b9e348662b..16e77a81ab4f29d5090b3f65b600d738fe6ed9cf 100644 (file)
@@ -555,10 +555,12 @@ static inline void tm_recheckpoint_new_task(struct task_struct *new)
                new->thread.regs->msr |=
                        (MSR_FP | new->thread.fpexc_mode);
        }
+#ifdef CONFIG_ALTIVEC
        if (msr & MSR_VEC) {
                do_load_up_transact_altivec(&new->thread);
                new->thread.regs->msr |= MSR_VEC;
        }
+#endif
        /* We may as well turn on VSX too since all the state is restored now */
        if (msr & MSR_VSX)
                new->thread.regs->msr |= MSR_VSX;
index 3acb28e245b411d65ebcc8c68bfeec802e7f4737..95068bf569adc17cf51d7e32bd650daaba234b17 100644 (file)
@@ -866,10 +866,12 @@ static long restore_tm_user_regs(struct pt_regs *regs,
                do_load_up_transact_fpu(&current->thread);
                regs->msr |= (MSR_FP | current->thread.fpexc_mode);
        }
+#ifdef CONFIG_ALTIVEC
        if (msr & MSR_VEC) {
                do_load_up_transact_altivec(&current->thread);
                regs->msr |= MSR_VEC;
        }
+#endif
 
        return 0;
 }
index 995f8543cb57ed869b603fee7c5d178c1d1af066..c1794286098ca2f78c5e32f4c01b0891ca04fc78 100644 (file)
@@ -522,10 +522,12 @@ static long restore_tm_sigcontexts(struct pt_regs *regs,
                do_load_up_transact_fpu(&current->thread);
                regs->msr |= (MSR_FP | current->thread.fpexc_mode);
        }
+#ifdef CONFIG_ALTIVEC
        if (msr & MSR_VEC) {
                do_load_up_transact_altivec(&current->thread);
                regs->msr |= MSR_VEC;
        }
+#endif
 
        return err;
 }
index 84dbace657ce197fb7a71d17e61042e87fb271c8..2da67e7a16d58650e10a0b6113b705bd88a6f2d3 100644 (file)
@@ -309,6 +309,7 @@ _GLOBAL(tm_recheckpoint)
        or      r5, r6, r5                      /* Set MSR.FP+.VSX/.VEC */
        mtmsr   r5
 
+#ifdef CONFIG_ALTIVEC
        /* FP and VEC registers:  These are recheckpointed from thread.fpr[]
         * and thread.vr[] respectively.  The thread.transact_fpr[] version
         * is more modern, and will be loaded subsequently by any FPUnavailable
@@ -323,6 +324,7 @@ _GLOBAL(tm_recheckpoint)
        REST_32VRS(0, r5, r3)                   /* r5 scratch, r3 THREAD ptr */
        ld      r5, THREAD_VRSAVE(r3)
        mtspr   SPRN_VRSAVE, r5
+#endif
 
 dont_restore_vec:
        andi.   r0, r4, MSR_FP
index 41cefd43655ff2616478778295072a1509d0f1ad..33db48a8ce241e1ee9ee0bce50bf991bb550b332 100644 (file)
 #define E500_PID_NUM   3
 #define E500_TLB_NUM   2
 
-#define E500_TLB_VALID 1
-#define E500_TLB_BITMAP 2
+/* entry is mapped somewhere in host TLB */
+#define E500_TLB_VALID         (1 << 0)
+/* TLB1 entry is mapped by host TLB1, tracked by bitmaps */
+#define E500_TLB_BITMAP                (1 << 1)
+/* TLB1 entry is mapped by host TLB0 */
 #define E500_TLB_TLB0          (1 << 2)
 
 struct tlbe_ref {
-       pfn_t pfn;
-       unsigned int flags; /* E500_TLB_* */
+       pfn_t pfn;              /* valid only for TLB0, except briefly */
+       unsigned int flags;     /* E500_TLB_* */
 };
 
 struct tlbe_priv {
-       struct tlbe_ref ref; /* TLB0 only -- TLB1 uses tlb_refs */
+       struct tlbe_ref ref;
 };
 
 #ifdef CONFIG_KVM_E500V2
@@ -63,17 +66,6 @@ struct kvmppc_vcpu_e500 {
 
        unsigned int gtlb_nv[E500_TLB_NUM];
 
-       /*
-        * information associated with each host TLB entry --
-        * TLB1 only for now.  If/when guest TLB1 entries can be
-        * mapped with host TLB0, this will be used for that too.
-        *
-        * We don't want to use this for guest TLB0 because then we'd
-        * have the overhead of doing the translation again even if
-        * the entry is still in the guest TLB (e.g. we swapped out
-        * and back, and our host TLB entries got evicted).
-        */
-       struct tlbe_ref *tlb_refs[E500_TLB_NUM];
        unsigned int host_tlb1_nv;
 
        u32 svr;
index a222edfb9a9bce72e7d642b05853398b493bc679..1c6a9d729df4a26ca3ad6c9f1c94008d681f7d42 100644 (file)
@@ -193,8 +193,11 @@ void inval_gtlbe_on_host(struct kvmppc_vcpu_e500 *vcpu_e500, int tlbsel,
        struct tlbe_ref *ref = &vcpu_e500->gtlb_priv[tlbsel][esel].ref;
 
        /* Don't bother with unmapped entries */
-       if (!(ref->flags & E500_TLB_VALID))
-               return;
+       if (!(ref->flags & E500_TLB_VALID)) {
+               WARN(ref->flags & (E500_TLB_BITMAP | E500_TLB_TLB0),
+                    "%s: flags %x\n", __func__, ref->flags);
+               WARN_ON(tlbsel == 1 && vcpu_e500->g2h_tlb1_map[esel]);
+       }
 
        if (tlbsel == 1 && ref->flags & E500_TLB_BITMAP) {
                u64 tmp = vcpu_e500->g2h_tlb1_map[esel];
@@ -248,7 +251,7 @@ static inline void kvmppc_e500_ref_setup(struct tlbe_ref *ref,
                                         pfn_t pfn)
 {
        ref->pfn = pfn;
-       ref->flags = E500_TLB_VALID;
+       ref->flags |= E500_TLB_VALID;
 
        if (tlbe_is_writable(gtlbe))
                kvm_set_pfn_dirty(pfn);
@@ -257,6 +260,7 @@ static inline void kvmppc_e500_ref_setup(struct tlbe_ref *ref,
 static inline void kvmppc_e500_ref_release(struct tlbe_ref *ref)
 {
        if (ref->flags & E500_TLB_VALID) {
+               /* FIXME: don't log bogus pfn for TLB1 */
                trace_kvm_booke206_ref_release(ref->pfn, ref->flags);
                ref->flags = 0;
        }
@@ -274,36 +278,23 @@ static void clear_tlb1_bitmap(struct kvmppc_vcpu_e500 *vcpu_e500)
 
 static void clear_tlb_privs(struct kvmppc_vcpu_e500 *vcpu_e500)
 {
-       int tlbsel = 0;
-       int i;
-
-       for (i = 0; i < vcpu_e500->gtlb_params[tlbsel].entries; i++) {
-               struct tlbe_ref *ref =
-                       &vcpu_e500->gtlb_priv[tlbsel][i].ref;
-               kvmppc_e500_ref_release(ref);
-       }
-}
-
-static void clear_tlb_refs(struct kvmppc_vcpu_e500 *vcpu_e500)
-{
-       int stlbsel = 1;
+       int tlbsel;
        int i;
 
-       kvmppc_e500_tlbil_all(vcpu_e500);
-
-       for (i = 0; i < host_tlb_params[stlbsel].entries; i++) {
-               struct tlbe_ref *ref =
-                       &vcpu_e500->tlb_refs[stlbsel][i];
-               kvmppc_e500_ref_release(ref);
+       for (tlbsel = 0; tlbsel <= 1; tlbsel++) {
+               for (i = 0; i < vcpu_e500->gtlb_params[tlbsel].entries; i++) {
+                       struct tlbe_ref *ref =
+                               &vcpu_e500->gtlb_priv[tlbsel][i].ref;
+                       kvmppc_e500_ref_release(ref);
+               }
        }
-
-       clear_tlb_privs(vcpu_e500);
 }
 
 void kvmppc_core_flush_tlb(struct kvm_vcpu *vcpu)
 {
        struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
-       clear_tlb_refs(vcpu_e500);
+       kvmppc_e500_tlbil_all(vcpu_e500);
+       clear_tlb_privs(vcpu_e500);
        clear_tlb1_bitmap(vcpu_e500);
 }
 
@@ -458,8 +449,6 @@ static inline int kvmppc_e500_shadow_map(struct kvmppc_vcpu_e500 *vcpu_e500,
                gvaddr &= ~((tsize_pages << PAGE_SHIFT) - 1);
        }
 
-       /* Drop old ref and setup new one. */
-       kvmppc_e500_ref_release(ref);
        kvmppc_e500_ref_setup(ref, gtlbe, pfn);
 
        kvmppc_e500_setup_stlbe(&vcpu_e500->vcpu, gtlbe, tsize,
@@ -507,14 +496,15 @@ static int kvmppc_e500_tlb1_map_tlb1(struct kvmppc_vcpu_e500 *vcpu_e500,
        if (unlikely(vcpu_e500->host_tlb1_nv >= tlb1_max_shadow_size()))
                vcpu_e500->host_tlb1_nv = 0;
 
-       vcpu_e500->tlb_refs[1][sesel] = *ref;
-       vcpu_e500->g2h_tlb1_map[esel] |= (u64)1 << sesel;
-       vcpu_e500->gtlb_priv[1][esel].ref.flags |= E500_TLB_BITMAP;
        if (vcpu_e500->h2g_tlb1_rmap[sesel]) {
-               unsigned int idx = vcpu_e500->h2g_tlb1_rmap[sesel];
+               unsigned int idx = vcpu_e500->h2g_tlb1_rmap[sesel] - 1;
                vcpu_e500->g2h_tlb1_map[idx] &= ~(1ULL << sesel);
        }
-       vcpu_e500->h2g_tlb1_rmap[sesel] = esel;
+
+       vcpu_e500->gtlb_priv[1][esel].ref.flags |= E500_TLB_BITMAP;
+       vcpu_e500->g2h_tlb1_map[esel] |= (u64)1 << sesel;
+       vcpu_e500->h2g_tlb1_rmap[sesel] = esel + 1;
+       WARN_ON(!(ref->flags & E500_TLB_VALID));
 
        return sesel;
 }
@@ -526,13 +516,12 @@ static int kvmppc_e500_tlb1_map(struct kvmppc_vcpu_e500 *vcpu_e500,
                u64 gvaddr, gfn_t gfn, struct kvm_book3e_206_tlb_entry *gtlbe,
                struct kvm_book3e_206_tlb_entry *stlbe, int esel)
 {
-       struct tlbe_ref ref;
+       struct tlbe_ref *ref = &vcpu_e500->gtlb_priv[1][esel].ref;
        int sesel;
        int r;
 
-       ref.flags = 0;
        r = kvmppc_e500_shadow_map(vcpu_e500, gvaddr, gfn, gtlbe, 1, stlbe,
-                                  &ref);
+                                  ref);
        if (r)
                return r;
 
@@ -544,7 +533,7 @@ static int kvmppc_e500_tlb1_map(struct kvmppc_vcpu_e500 *vcpu_e500,
        }
 
        /* Otherwise map into TLB1 */
-       sesel = kvmppc_e500_tlb1_map_tlb1(vcpu_e500, &ref, esel);
+       sesel = kvmppc_e500_tlb1_map_tlb1(vcpu_e500, ref, esel);
        write_stlbe(vcpu_e500, gtlbe, stlbe, 1, sesel);
 
        return 0;
@@ -565,7 +554,7 @@ void kvmppc_mmu_map(struct kvm_vcpu *vcpu, u64 eaddr, gpa_t gpaddr,
        case 0:
                priv = &vcpu_e500->gtlb_priv[tlbsel][esel];
 
-               /* Triggers after clear_tlb_refs or on initial mapping */
+               /* Triggers after clear_tlb_privs or on initial mapping */
                if (!(priv->ref.flags & E500_TLB_VALID)) {
                        kvmppc_e500_tlb0_map(vcpu_e500, esel, &stlbe);
                } else {
@@ -665,35 +654,16 @@ int e500_mmu_host_init(struct kvmppc_vcpu_e500 *vcpu_e500)
                host_tlb_params[0].entries / host_tlb_params[0].ways;
        host_tlb_params[1].sets = 1;
 
-       vcpu_e500->tlb_refs[0] =
-               kzalloc(sizeof(struct tlbe_ref) * host_tlb_params[0].entries,
-                       GFP_KERNEL);
-       if (!vcpu_e500->tlb_refs[0])
-               goto err;
-
-       vcpu_e500->tlb_refs[1] =
-               kzalloc(sizeof(struct tlbe_ref) * host_tlb_params[1].entries,
-                       GFP_KERNEL);
-       if (!vcpu_e500->tlb_refs[1])
-               goto err;
-
        vcpu_e500->h2g_tlb1_rmap = kzalloc(sizeof(unsigned int) *
                                           host_tlb_params[1].entries,
                                           GFP_KERNEL);
        if (!vcpu_e500->h2g_tlb1_rmap)
-               goto err;
+               return -EINVAL;
 
        return 0;
-
-err:
-       kfree(vcpu_e500->tlb_refs[0]);
-       kfree(vcpu_e500->tlb_refs[1]);
-       return -EINVAL;
 }
 
 void e500_mmu_host_uninit(struct kvmppc_vcpu_e500 *vcpu_e500)
 {
        kfree(vcpu_e500->h2g_tlb1_rmap);
-       kfree(vcpu_e500->tlb_refs[0]);
-       kfree(vcpu_e500->tlb_refs[1]);
 }
index 1f89d26e65fb72534e130ed755bfe3874740316f..2f4baa074b2ebf0bf9cfe497055afbe9460ec4a5 100644 (file)
@@ -108,6 +108,8 @@ void kvmppc_mmu_msr_notify(struct kvm_vcpu *vcpu, u32 old_msr)
 {
 }
 
+static DEFINE_PER_CPU(struct kvm_vcpu *, last_vcpu_on_cpu);
+
 void kvmppc_core_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
 {
        struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
@@ -136,8 +138,11 @@ void kvmppc_core_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
        mtspr(SPRN_GDEAR, vcpu->arch.shared->dar);
        mtspr(SPRN_GESR, vcpu->arch.shared->esr);
 
-       if (vcpu->arch.oldpir != mfspr(SPRN_PIR))
+       if (vcpu->arch.oldpir != mfspr(SPRN_PIR) ||
+           __get_cpu_var(last_vcpu_on_cpu) != vcpu) {
                kvmppc_e500_tlbil_all(vcpu_e500);
+               __get_cpu_var(last_vcpu_on_cpu) = vcpu;
+       }
 
        kvmppc_load_guest_fp(vcpu);
 }
index 0da39fed355aa25fc17e516cf52d66042ddcc0e4..299731e9036b5e4361d7a49ca52938d0953d96e4 100644 (file)
@@ -186,7 +186,13 @@ static long pSeries_lpar_hpte_remove(unsigned long hpte_group)
                                           (0x1UL << 4), &dummy1, &dummy2);
                if (lpar_rc == H_SUCCESS)
                        return i;
-               BUG_ON(lpar_rc != H_NOT_FOUND);
+
+               /*
+                * The test for adjunct partition is performed before the
+                * ANDCOND test.  H_RESOURCE may be returned, so we need to
+                * check for that as well.
+                */
+               BUG_ON(lpar_rc != H_NOT_FOUND && lpar_rc != H_RESOURCE);
 
                slot_offset++;
                slot_offset &= 0x7;
index 27cb32185ce1d950e5a6097198a1864a69e6594b..379d96e2105ea1d60f79a4cd881593a188a61c01 100644 (file)
@@ -50,10 +50,6 @@ void unxlate_dev_mem_ptr(unsigned long phys, void *addr);
 #define ioremap_nocache(addr, size)    ioremap(addr, size)
 #define ioremap_wc                     ioremap_nocache
 
-/* TODO: s390 cannot support io_remap_pfn_range... */
-#define io_remap_pfn_range(vma, vaddr, pfn, size, prot)               \
-       remap_pfn_range(vma, vaddr, pfn, size, prot)
-
 static inline void __iomem *ioremap(unsigned long offset, unsigned long size)
 {
        return (void __iomem *) offset;
index 4a5443118cfb039d4b5e53f63b7470c292c4a431..3cb47cf02530b6f390af7ac65c0ac92f89cf275c 100644 (file)
@@ -57,6 +57,10 @@ extern unsigned long zero_page_mask;
         (((unsigned long)(vaddr)) &zero_page_mask))))
 #define __HAVE_COLOR_ZERO_PAGE
 
+/* TODO: s390 cannot support io_remap_pfn_range... */
+#define io_remap_pfn_range(vma, vaddr, pfn, size, prot)               \
+       remap_pfn_range(vma, vaddr, pfn, size, prot)
+
 #endif /* !__ASSEMBLY__ */
 
 /*
index e26d430ce2fdb94b7c85281db75367acf41e2321..ff18e3cfb6b1ffe3e75df94fdd68319b912ab1d8 100644 (file)
@@ -2,11 +2,16 @@
 
 
 generic-y += clkdev.h
+generic-y += cputime.h
 generic-y += div64.h
+generic-y += emergency-restart.h
 generic-y += exec.h
 generic-y += local64.h
+generic-y += mutex.h
 generic-y += irq_regs.h
 generic-y += local.h
 generic-y += module.h
+generic-y += serial.h
 generic-y += trace_clock.h
+generic-y += types.h
 generic-y += word-at-a-time.h
diff --git a/arch/sparc/include/asm/cputime.h b/arch/sparc/include/asm/cputime.h
deleted file mode 100644 (file)
index 1a642b8..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __SPARC_CPUTIME_H
-#define __SPARC_CPUTIME_H
-
-#include <asm-generic/cputime.h>
-
-#endif /* __SPARC_CPUTIME_H */
diff --git a/arch/sparc/include/asm/emergency-restart.h b/arch/sparc/include/asm/emergency-restart.h
deleted file mode 100644 (file)
index 108d8c4..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef _ASM_EMERGENCY_RESTART_H
-#define _ASM_EMERGENCY_RESTART_H
-
-#include <asm-generic/emergency-restart.h>
-
-#endif /* _ASM_EMERGENCY_RESTART_H */
diff --git a/arch/sparc/include/asm/mutex.h b/arch/sparc/include/asm/mutex.h
deleted file mode 100644 (file)
index 458c1f7..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-/*
- * Pull in the generic implementation for the mutex fastpath.
- *
- * TODO: implement optimized primitives instead, or leave the generic
- * implementation in place, or pick the atomic_xchg() based generic
- * implementation. (see asm-generic/mutex-xchg.h for details)
- */
-
-#include <asm-generic/mutex-dec.h>
index 08fcce90316b36654dea14af5525a94a0cded6e8..7619f2f792aff549905ca49d1a70b3cd7514979c 100644 (file)
@@ -915,6 +915,7 @@ static inline int io_remap_pfn_range(struct vm_area_struct *vma,
        return remap_pfn_range(vma, from, phys_base >> PAGE_SHIFT, size, prot);
 }
 
+#include <asm/tlbflush.h>
 #include <asm-generic/pgtable.h>
 
 /* We provide our own get_unmapped_area to cope with VA holes and
diff --git a/arch/sparc/include/asm/serial.h b/arch/sparc/include/asm/serial.h
deleted file mode 100644 (file)
index f90d61c..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __SPARC_SERIAL_H
-#define __SPARC_SERIAL_H
-
-#define BASE_BAUD ( 1843200 / 16 )
-
-#endif /* __SPARC_SERIAL_H */
index b73da3c5f10a9140ba730836d3e496af3e2358c6..3c8917f054dee450fcc48e7f50d189b88bc19401 100644 (file)
@@ -36,7 +36,6 @@ typedef void (*smpfunc_t)(unsigned long, unsigned long, unsigned long,
                       unsigned long, unsigned long);
 
 void cpu_panic(void);
-extern void smp4m_irq_rotate(int cpu);
 
 /*
  *     General functions that each host system must provide.
@@ -46,7 +45,6 @@ void sun4m_init_smp(void);
 void sun4d_init_smp(void);
 
 void smp_callin(void);
-void smp_boot_cpus(void);
 void smp_store_cpu_info(int);
 
 void smp_resched_interrupt(void);
@@ -107,9 +105,6 @@ extern int hard_smp_processor_id(void);
 
 #define raw_smp_processor_id()         (current_thread_info()->cpu)
 
-#define prof_multiplier(__cpu)         cpu_data(__cpu).multiplier
-#define prof_counter(__cpu)            cpu_data(__cpu).counter
-
 void smp_setup_cpu_possible_map(void);
 
 #endif /* !(__ASSEMBLY__) */
index cad36f56fa03e6605797c4dca13f5127048b47d7..c7de3323819c5389a8c1855f09aa542cd67f4d41 100644 (file)
@@ -18,8 +18,7 @@ do {                                          \
         * and 2 stores in this critical code path.  -DaveM
         */
 #define switch_to(prev, next, last)                                    \
-do {   flush_tlb_pending();                                            \
-       save_and_clear_fpu();                                           \
+do {   save_and_clear_fpu();                                           \
        /* If you are tempted to conditionalize the following */        \
        /* so that ASI is only written if it changes, think again. */   \
        __asm__ __volatile__("wr %%g0, %0, %%asi"                       \
index 2ef463494153a65adec7c7a59a37c0095fda2649..f0d6a9700f4c8351e20be4743d9782c590b9e016 100644 (file)
 struct tlb_batch {
        struct mm_struct *mm;
        unsigned long tlb_nr;
+       unsigned long active;
        unsigned long vaddrs[TLB_BATCH_NR];
 };
 
 extern void flush_tsb_kernel_range(unsigned long start, unsigned long end);
 extern void flush_tsb_user(struct tlb_batch *tb);
+extern void flush_tsb_user_page(struct mm_struct *mm, unsigned long vaddr);
 
 /* TLB flush operations. */
 
-extern void flush_tlb_pending(void);
+static inline void flush_tlb_mm(struct mm_struct *mm)
+{
+}
+
+static inline void flush_tlb_page(struct vm_area_struct *vma,
+                                 unsigned long vmaddr)
+{
+}
+
+static inline void flush_tlb_range(struct vm_area_struct *vma,
+                                  unsigned long start, unsigned long end)
+{
+}
+
+#define __HAVE_ARCH_ENTER_LAZY_MMU_MODE
 
-#define flush_tlb_range(vma,start,end) \
-       do { (void)(start); flush_tlb_pending(); } while (0)
-#define flush_tlb_page(vma,addr)       flush_tlb_pending()
-#define flush_tlb_mm(mm)               flush_tlb_pending()
+extern void flush_tlb_pending(void);
+extern void arch_enter_lazy_mmu_mode(void);
+extern void arch_leave_lazy_mmu_mode(void);
+#define arch_flush_lazy_mmu_mode()      do {} while (0)
 
 /* Local cpu only.  */
 extern void __flush_tlb_all(void);
-
+extern void __flush_tlb_page(unsigned long context, unsigned long vaddr);
 extern void __flush_tlb_kernel_range(unsigned long start, unsigned long end);
 
 #ifndef CONFIG_SMP
@@ -38,15 +54,24 @@ do {        flush_tsb_kernel_range(start,end); \
        __flush_tlb_kernel_range(start,end); \
 } while (0)
 
+static inline void global_flush_tlb_page(struct mm_struct *mm, unsigned long vaddr)
+{
+       __flush_tlb_page(CTX_HWBITS(mm->context), vaddr);
+}
+
 #else /* CONFIG_SMP */
 
 extern void smp_flush_tlb_kernel_range(unsigned long start, unsigned long end);
+extern void smp_flush_tlb_page(struct mm_struct *mm, unsigned long vaddr);
 
 #define flush_tlb_kernel_range(start, end) \
 do {   flush_tsb_kernel_range(start,end); \
        smp_flush_tlb_kernel_range(start, end); \
 } while (0)
 
+#define global_flush_tlb_page(mm, vaddr) \
+       smp_flush_tlb_page(mm, vaddr)
+
 #endif /* ! CONFIG_SMP */
 
 #endif /* _SPARC64_TLBFLUSH_H */
index ce175aff71b75e29fdf65cf70d8a17f2a07c5d2a..b5843ee09fb53a6e4438b29140adbd34d9c887c1 100644 (file)
@@ -44,7 +44,6 @@ header-y += swab.h
 header-y += termbits.h
 header-y += termios.h
 header-y += traps.h
-header-y += types.h
 header-y += uctx.h
 header-y += unistd.h
 header-y += utrap.h
diff --git a/arch/sparc/include/uapi/asm/types.h b/arch/sparc/include/uapi/asm/types.h
deleted file mode 100644 (file)
index 383d156..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-#ifndef _SPARC_TYPES_H
-#define _SPARC_TYPES_H
-/*
- * This file is never included by application software unless
- * explicitly requested (e.g., via linux/types.h) in which case the
- * application is Linux specific so (user-) name space pollution is
- * not a major issue.  However, for interoperability, libraries still
- * need to be careful to avoid a name clashes.
- */
-
-#if defined(__sparc__)
-
-#include <asm-generic/int-ll64.h>
-
-#endif /* defined(__sparc__) */
-
-#endif /* defined(_SPARC_TYPES_H) */
index 537eb66abd0654054aef7402ffaf857ad3971a85..ca64d2a86ec03e4189b88367906456e99de77a14 100644 (file)
@@ -849,7 +849,7 @@ void smp_tsb_sync(struct mm_struct *mm)
 }
 
 extern unsigned long xcall_flush_tlb_mm;
-extern unsigned long xcall_flush_tlb_pending;
+extern unsigned long xcall_flush_tlb_page;
 extern unsigned long xcall_flush_tlb_kernel_range;
 extern unsigned long xcall_fetch_glob_regs;
 extern unsigned long xcall_fetch_glob_pmu;
@@ -1074,23 +1074,56 @@ local_flush_and_out:
        put_cpu();
 }
 
+struct tlb_pending_info {
+       unsigned long ctx;
+       unsigned long nr;
+       unsigned long *vaddrs;
+};
+
+static void tlb_pending_func(void *info)
+{
+       struct tlb_pending_info *t = info;
+
+       __flush_tlb_pending(t->ctx, t->nr, t->vaddrs);
+}
+
 void smp_flush_tlb_pending(struct mm_struct *mm, unsigned long nr, unsigned long *vaddrs)
 {
        u32 ctx = CTX_HWBITS(mm->context);
+       struct tlb_pending_info info;
        int cpu = get_cpu();
 
+       info.ctx = ctx;
+       info.nr = nr;
+       info.vaddrs = vaddrs;
+
        if (mm == current->mm && atomic_read(&mm->mm_users) == 1)
                cpumask_copy(mm_cpumask(mm), cpumask_of(cpu));
        else
-               smp_cross_call_masked(&xcall_flush_tlb_pending,
-                                     ctx, nr, (unsigned long) vaddrs,
-                                     mm_cpumask(mm));
+               smp_call_function_many(mm_cpumask(mm), tlb_pending_func,
+                                      &info, 1);
 
        __flush_tlb_pending(ctx, nr, vaddrs);
 
        put_cpu();
 }
 
+void smp_flush_tlb_page(struct mm_struct *mm, unsigned long vaddr)
+{
+       unsigned long context = CTX_HWBITS(mm->context);
+       int cpu = get_cpu();
+
+       if (mm == current->mm && atomic_read(&mm->mm_users) == 1)
+               cpumask_copy(mm_cpumask(mm), cpumask_of(cpu));
+       else
+               smp_cross_call_masked(&xcall_flush_tlb_page,
+                                     context, vaddr, 0,
+                                     mm_cpumask(mm));
+       __flush_tlb_page(context, vaddr);
+
+       put_cpu();
+}
+
 void smp_flush_tlb_kernel_range(unsigned long start, unsigned long end)
 {
        start &= PAGE_MASK;
index 48d00e72ce15ba41304f8390ab29324402f052b2..8ec4e9c0251a3e414acf58327b0fd167890caa95 100644 (file)
@@ -119,11 +119,7 @@ void bit_map_clear(struct bit_map *t, int offset, int len)
 
 void bit_map_init(struct bit_map *t, unsigned long *map, int size)
 {
-
-       if ((size & 07) != 0)
-               BUG();
-       memset(map, 0, size>>3);
-
+       bitmap_zero(map, size);
        memset(t, 0, sizeof *t);
        spin_lock_init(&t->lock);
        t->map = map;
index 0f4f7191fbbad93d6600ac409f6baae24c911d5e..28f96f27c7683e1201d5ca6e53409e391594aff4 100644 (file)
@@ -34,7 +34,7 @@
 #define IOMMU_RNGE     IOMMU_RNGE_256MB
 #define IOMMU_START    0xF0000000
 #define IOMMU_WINSIZE  (256*1024*1024U)
-#define IOMMU_NPTES    (IOMMU_WINSIZE/PAGE_SIZE)       /* 64K PTEs, 265KB */
+#define IOMMU_NPTES    (IOMMU_WINSIZE/PAGE_SIZE)       /* 64K PTEs, 256KB */
 #define IOMMU_ORDER    6                               /* 4096 * (1<<6) */
 
 /* srmmu.c */
index c38bb72e3e80e4c122ea469a4edaba8e18cc3939..036c2797dece1c6443894b9e3ce95c066e4142fe 100644 (file)
@@ -280,7 +280,9 @@ static void __init srmmu_nocache_init(void)
                SRMMU_NOCACHE_ALIGN_MAX, 0UL);
        memset(srmmu_nocache_pool, 0, srmmu_nocache_size);
 
-       srmmu_nocache_bitmap = __alloc_bootmem(bitmap_bits >> 3, SMP_CACHE_BYTES, 0UL);
+       srmmu_nocache_bitmap =
+               __alloc_bootmem(BITS_TO_LONGS(bitmap_bits) * sizeof(long),
+                               SMP_CACHE_BYTES, 0UL);
        bit_map_init(&srmmu_nocache_map, srmmu_nocache_bitmap, bitmap_bits);
 
        srmmu_swapper_pg_dir = __srmmu_get_nocache(SRMMU_PGD_TABLE_SIZE, SRMMU_PGD_TABLE_SIZE);
index ba6ae7ffdc2c9d5d1e3bbbb8d2af3b68a2f2572e..272aa4f7657e2c3bbba5772809e8798c657a32c8 100644 (file)
@@ -24,11 +24,17 @@ static DEFINE_PER_CPU(struct tlb_batch, tlb_batch);
 void flush_tlb_pending(void)
 {
        struct tlb_batch *tb = &get_cpu_var(tlb_batch);
+       struct mm_struct *mm = tb->mm;
 
-       if (tb->tlb_nr) {
-               flush_tsb_user(tb);
+       if (!tb->tlb_nr)
+               goto out;
 
-               if (CTX_VALID(tb->mm->context)) {
+       flush_tsb_user(tb);
+
+       if (CTX_VALID(mm->context)) {
+               if (tb->tlb_nr == 1) {
+                       global_flush_tlb_page(mm, tb->vaddrs[0]);
+               } else {
 #ifdef CONFIG_SMP
                        smp_flush_tlb_pending(tb->mm, tb->tlb_nr,
                                              &tb->vaddrs[0]);
@@ -37,12 +43,30 @@ void flush_tlb_pending(void)
                                            tb->tlb_nr, &tb->vaddrs[0]);
 #endif
                }
-               tb->tlb_nr = 0;
        }
 
+       tb->tlb_nr = 0;
+
+out:
        put_cpu_var(tlb_batch);
 }
 
+void arch_enter_lazy_mmu_mode(void)
+{
+       struct tlb_batch *tb = &__get_cpu_var(tlb_batch);
+
+       tb->active = 1;
+}
+
+void arch_leave_lazy_mmu_mode(void)
+{
+       struct tlb_batch *tb = &__get_cpu_var(tlb_batch);
+
+       if (tb->tlb_nr)
+               flush_tlb_pending();
+       tb->active = 0;
+}
+
 static void tlb_batch_add_one(struct mm_struct *mm, unsigned long vaddr,
                              bool exec)
 {
@@ -60,6 +84,12 @@ static void tlb_batch_add_one(struct mm_struct *mm, unsigned long vaddr,
                nr = 0;
        }
 
+       if (!tb->active) {
+               global_flush_tlb_page(mm, vaddr);
+               flush_tsb_user_page(mm, vaddr);
+               return;
+       }
+
        if (nr == 0)
                tb->mm = mm;
 
index 428982b9becfe267b33ad2745efb36b5dc861a11..2cc3bce5ee914a158a16960c4ece028cc959b83a 100644 (file)
@@ -7,11 +7,10 @@
 #include <linux/preempt.h>
 #include <linux/slab.h>
 #include <asm/page.h>
-#include <asm/tlbflush.h>
-#include <asm/tlb.h>
-#include <asm/mmu_context.h>
 #include <asm/pgtable.h>
+#include <asm/mmu_context.h>
 #include <asm/tsb.h>
+#include <asm/tlb.h>
 #include <asm/oplib.h>
 
 extern struct tsb swapper_tsb[KERNEL_TSB_NENTRIES];
@@ -46,23 +45,27 @@ void flush_tsb_kernel_range(unsigned long start, unsigned long end)
        }
 }
 
-static void __flush_tsb_one(struct tlb_batch *tb, unsigned long hash_shift,
-                           unsigned long tsb, unsigned long nentries)
+static void __flush_tsb_one_entry(unsigned long tsb, unsigned long v,
+                                 unsigned long hash_shift,
+                                 unsigned long nentries)
 {
-       unsigned long i;
+       unsigned long tag, ent, hash;
 
-       for (i = 0; i < tb->tlb_nr; i++) {
-               unsigned long v = tb->vaddrs[i];
-               unsigned long tag, ent, hash;
+       v &= ~0x1UL;
+       hash = tsb_hash(v, hash_shift, nentries);
+       ent = tsb + (hash * sizeof(struct tsb));
+       tag = (v >> 22UL);
 
-               v &= ~0x1UL;
+       tsb_flush(ent, tag);
+}
 
-               hash = tsb_hash(v, hash_shift, nentries);
-               ent = tsb + (hash * sizeof(struct tsb));
-               tag = (v >> 22UL);
+static void __flush_tsb_one(struct tlb_batch *tb, unsigned long hash_shift,
+                           unsigned long tsb, unsigned long nentries)
+{
+       unsigned long i;
 
-               tsb_flush(ent, tag);
-       }
+       for (i = 0; i < tb->tlb_nr; i++)
+               __flush_tsb_one_entry(tsb, tb->vaddrs[i], hash_shift, nentries);
 }
 
 void flush_tsb_user(struct tlb_batch *tb)
@@ -90,6 +93,30 @@ void flush_tsb_user(struct tlb_batch *tb)
        spin_unlock_irqrestore(&mm->context.lock, flags);
 }
 
+void flush_tsb_user_page(struct mm_struct *mm, unsigned long vaddr)
+{
+       unsigned long nentries, base, flags;
+
+       spin_lock_irqsave(&mm->context.lock, flags);
+
+       base = (unsigned long) mm->context.tsb_block[MM_TSB_BASE].tsb;
+       nentries = mm->context.tsb_block[MM_TSB_BASE].tsb_nentries;
+       if (tlb_type == cheetah_plus || tlb_type == hypervisor)
+               base = __pa(base);
+       __flush_tsb_one_entry(base, vaddr, PAGE_SHIFT, nentries);
+
+#if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE)
+       if (mm->context.tsb_block[MM_TSB_HUGE].tsb) {
+               base = (unsigned long) mm->context.tsb_block[MM_TSB_HUGE].tsb;
+               nentries = mm->context.tsb_block[MM_TSB_HUGE].tsb_nentries;
+               if (tlb_type == cheetah_plus || tlb_type == hypervisor)
+                       base = __pa(base);
+               __flush_tsb_one_entry(base, vaddr, HPAGE_SHIFT, nentries);
+       }
+#endif
+       spin_unlock_irqrestore(&mm->context.lock, flags);
+}
+
 #define HV_PGSZ_IDX_BASE       HV_PGSZ_IDX_8K
 #define HV_PGSZ_MASK_BASE      HV_PGSZ_MASK_8K
 
index f8e13d421fcbf415dd49a50bc2ed4aaf2b3b6494..432aa0cb1b38caa75076938700c60761699dc920 100644 (file)
@@ -52,6 +52,33 @@ __flush_tlb_mm:              /* 18 insns */
        nop
        nop
 
+       .align          32
+       .globl          __flush_tlb_page
+__flush_tlb_page:      /* 22 insns */
+       /* %o0 = context, %o1 = vaddr */
+       rdpr            %pstate, %g7
+       andn            %g7, PSTATE_IE, %g2
+       wrpr            %g2, %pstate
+       mov             SECONDARY_CONTEXT, %o4
+       ldxa            [%o4] ASI_DMMU, %g2
+       stxa            %o0, [%o4] ASI_DMMU
+       andcc           %o1, 1, %g0
+       andn            %o1, 1, %o3
+       be,pn           %icc, 1f
+        or             %o3, 0x10, %o3
+       stxa            %g0, [%o3] ASI_IMMU_DEMAP
+1:     stxa            %g0, [%o3] ASI_DMMU_DEMAP
+       membar          #Sync
+       stxa            %g2, [%o4] ASI_DMMU
+       sethi           %hi(KERNBASE), %o4
+       flush           %o4
+       retl
+        wrpr           %g7, 0x0, %pstate
+       nop
+       nop
+       nop
+       nop
+
        .align          32
        .globl          __flush_tlb_pending
 __flush_tlb_pending:   /* 26 insns */
@@ -203,6 +230,31 @@ __cheetah_flush_tlb_mm: /* 19 insns */
        retl
         wrpr           %g7, 0x0, %pstate
 
+__cheetah_flush_tlb_page:      /* 22 insns */
+       /* %o0 = context, %o1 = vaddr */
+       rdpr            %pstate, %g7
+       andn            %g7, PSTATE_IE, %g2
+       wrpr            %g2, 0x0, %pstate
+       wrpr            %g0, 1, %tl
+       mov             PRIMARY_CONTEXT, %o4
+       ldxa            [%o4] ASI_DMMU, %g2
+       srlx            %g2, CTX_PGSZ1_NUC_SHIFT, %o3
+       sllx            %o3, CTX_PGSZ1_NUC_SHIFT, %o3
+       or              %o0, %o3, %o0   /* Preserve nucleus page size fields */
+       stxa            %o0, [%o4] ASI_DMMU
+       andcc           %o1, 1, %g0
+       be,pn           %icc, 1f
+        andn           %o1, 1, %o3
+       stxa            %g0, [%o3] ASI_IMMU_DEMAP
+1:     stxa            %g0, [%o3] ASI_DMMU_DEMAP       
+       membar          #Sync
+       stxa            %g2, [%o4] ASI_DMMU
+       sethi           %hi(KERNBASE), %o4
+       flush           %o4
+       wrpr            %g0, 0, %tl
+       retl
+        wrpr           %g7, 0x0, %pstate
+
 __cheetah_flush_tlb_pending:   /* 27 insns */
        /* %o0 = context, %o1 = nr, %o2 = vaddrs[] */
        rdpr            %pstate, %g7
@@ -269,6 +321,20 @@ __hypervisor_flush_tlb_mm: /* 10 insns */
        retl
         nop
 
+__hypervisor_flush_tlb_page: /* 11 insns */
+       /* %o0 = context, %o1 = vaddr */
+       mov             %o0, %g2
+       mov             %o1, %o0              /* ARG0: vaddr + IMMU-bit */
+       mov             %g2, %o1              /* ARG1: mmu context */
+       mov             HV_MMU_ALL, %o2       /* ARG2: flags */
+       srlx            %o0, PAGE_SHIFT, %o0
+       sllx            %o0, PAGE_SHIFT, %o0
+       ta              HV_MMU_UNMAP_ADDR_TRAP
+       brnz,pn         %o0, __hypervisor_tlb_tl0_error
+        mov            HV_MMU_UNMAP_ADDR_TRAP, %o1
+       retl
+        nop
+
 __hypervisor_flush_tlb_pending: /* 16 insns */
        /* %o0 = context, %o1 = nr, %o2 = vaddrs[] */
        sllx            %o1, 3, %g1
@@ -339,6 +405,13 @@ cheetah_patch_cachetlbops:
        call            tlb_patch_one
         mov            19, %o2
 
+       sethi           %hi(__flush_tlb_page), %o0
+       or              %o0, %lo(__flush_tlb_page), %o0
+       sethi           %hi(__cheetah_flush_tlb_page), %o1
+       or              %o1, %lo(__cheetah_flush_tlb_page), %o1
+       call            tlb_patch_one
+        mov            22, %o2
+
        sethi           %hi(__flush_tlb_pending), %o0
        or              %o0, %lo(__flush_tlb_pending), %o0
        sethi           %hi(__cheetah_flush_tlb_pending), %o1
@@ -397,10 +470,9 @@ xcall_flush_tlb_mm:        /* 21 insns */
        nop
        nop
 
-       .globl          xcall_flush_tlb_pending
-xcall_flush_tlb_pending:       /* 21 insns */
-       /* %g5=context, %g1=nr, %g7=vaddrs[] */
-       sllx            %g1, 3, %g1
+       .globl          xcall_flush_tlb_page
+xcall_flush_tlb_page:  /* 17 insns */
+       /* %g5=context, %g1=vaddr */
        mov             PRIMARY_CONTEXT, %g4
        ldxa            [%g4] ASI_DMMU, %g2
        srlx            %g2, CTX_PGSZ1_NUC_SHIFT, %g4
@@ -408,20 +480,16 @@ xcall_flush_tlb_pending:  /* 21 insns */
        or              %g5, %g4, %g5
        mov             PRIMARY_CONTEXT, %g4
        stxa            %g5, [%g4] ASI_DMMU
-1:     sub             %g1, (1 << 3), %g1
-       ldx             [%g7 + %g1], %g5
-       andcc           %g5, 0x1, %g0
+       andcc           %g1, 0x1, %g0
        be,pn           %icc, 2f
-
-        andn           %g5, 0x1, %g5
+        andn           %g1, 0x1, %g5
        stxa            %g0, [%g5] ASI_IMMU_DEMAP
 2:     stxa            %g0, [%g5] ASI_DMMU_DEMAP
        membar          #Sync
-       brnz,pt         %g1, 1b
-        nop
        stxa            %g2, [%g4] ASI_DMMU
        retry
        nop
+       nop
 
        .globl          xcall_flush_tlb_kernel_range
 xcall_flush_tlb_kernel_range:  /* 25 insns */
@@ -656,15 +724,13 @@ __hypervisor_xcall_flush_tlb_mm: /* 21 insns */
        membar          #Sync
        retry
 
-       .globl          __hypervisor_xcall_flush_tlb_pending
-__hypervisor_xcall_flush_tlb_pending: /* 21 insns */
-       /* %g5=ctx, %g1=nr, %g7=vaddrs[], %g2,%g3,%g4,g6=scratch */
-       sllx            %g1, 3, %g1
+       .globl          __hypervisor_xcall_flush_tlb_page
+__hypervisor_xcall_flush_tlb_page: /* 17 insns */
+       /* %g5=ctx, %g1=vaddr */
        mov             %o0, %g2
        mov             %o1, %g3
        mov             %o2, %g4
-1:     sub             %g1, (1 << 3), %g1
-       ldx             [%g7 + %g1], %o0        /* ARG0: virtual address */
+       mov             %g1, %o0                /* ARG0: virtual address */
        mov             %g5, %o1                /* ARG1: mmu context */
        mov             HV_MMU_ALL, %o2         /* ARG2: flags */
        srlx            %o0, PAGE_SHIFT, %o0
@@ -673,8 +739,6 @@ __hypervisor_xcall_flush_tlb_pending: /* 21 insns */
        mov             HV_MMU_UNMAP_ADDR_TRAP, %g6
        brnz,a,pn       %o0, __hypervisor_tlb_xcall_error
         mov            %o0, %g5
-       brnz,pt         %g1, 1b
-        nop
        mov             %g2, %o0
        mov             %g3, %o1
        mov             %g4, %o2
@@ -757,6 +821,13 @@ hypervisor_patch_cachetlbops:
        call            tlb_patch_one
         mov            10, %o2
 
+       sethi           %hi(__flush_tlb_page), %o0
+       or              %o0, %lo(__flush_tlb_page), %o0
+       sethi           %hi(__hypervisor_flush_tlb_page), %o1
+       or              %o1, %lo(__hypervisor_flush_tlb_page), %o1
+       call            tlb_patch_one
+        mov            11, %o2
+
        sethi           %hi(__flush_tlb_pending), %o0
        or              %o0, %lo(__flush_tlb_pending), %o0
        sethi           %hi(__hypervisor_flush_tlb_pending), %o1
@@ -788,12 +859,12 @@ hypervisor_patch_cachetlbops:
        call            tlb_patch_one
         mov            21, %o2
 
-       sethi           %hi(xcall_flush_tlb_pending), %o0
-       or              %o0, %lo(xcall_flush_tlb_pending), %o0
-       sethi           %hi(__hypervisor_xcall_flush_tlb_pending), %o1
-       or              %o1, %lo(__hypervisor_xcall_flush_tlb_pending), %o1
+       sethi           %hi(xcall_flush_tlb_page), %o0
+       or              %o0, %lo(xcall_flush_tlb_page), %o0
+       sethi           %hi(__hypervisor_xcall_flush_tlb_page), %o1
+       or              %o1, %lo(__hypervisor_xcall_flush_tlb_page), %o1
        call            tlb_patch_one
-        mov            21, %o2
+        mov            17, %o2
 
        sethi           %hi(xcall_flush_tlb_kernel_range), %o0
        or              %o0, %lo(xcall_flush_tlb_kernel_range), %o0
index 241c0bb60b12e5cf4e9eedce50279d648d313e25..c96f9bbb760d54d79b2c0cc7208bf4e37964de9c 100644 (file)
 #include <asm/percpu.h>
 #include <arch/spr_def.h>
 
-/* Set and clear kernel interrupt masks. */
+/*
+ * Set and clear kernel interrupt masks.
+ *
+ * NOTE: __insn_mtspr() is a compiler builtin marked as a memory
+ * clobber.  We rely on it being equivalent to a compiler barrier in
+ * this code since arch_local_irq_save() and friends must act as
+ * compiler barriers.  This compiler semantic is baked into enough
+ * places that the compiler will maintain it going forward.
+ */
 #if CHIP_HAS_SPLIT_INTR_MASK()
 #if INT_PERF_COUNT < 32 || INT_AUX_PERF_COUNT < 32 || INT_MEM_ERROR >= 32
 # error Fix assumptions about which word various interrupts are in
index 70c0f3da0476a35ba93546689bb4b06b5f576bba..15b5cef4aa3857a386cb77cffd2ba74243b532c7 100644 (file)
@@ -1549,6 +1549,7 @@ config X86_SMAP
 config EFI
        bool "EFI runtime service support"
        depends on ACPI
+       select UCS2_STRING
        ---help---
          This enables the kernel to use EFI runtime services that are
          available (such as the EFI variable services).
index c205035a6b96b836ef683ddf8592dbc9c82200e6..8615f7581820d44ef7cd652c8ef2662310ac5122 100644 (file)
@@ -251,6 +251,51 @@ static void find_bits(unsigned long mask, u8 *pos, u8 *size)
        *size = len;
 }
 
+static efi_status_t setup_efi_vars(struct boot_params *params)
+{
+       struct setup_data *data;
+       struct efi_var_bootdata *efidata;
+       u64 store_size, remaining_size, var_size;
+       efi_status_t status;
+
+       if (!sys_table->runtime->query_variable_info)
+               return EFI_UNSUPPORTED;
+
+       data = (struct setup_data *)(unsigned long)params->hdr.setup_data;
+
+       while (data && data->next)
+               data = (struct setup_data *)(unsigned long)data->next;
+
+       status = efi_call_phys4(sys_table->runtime->query_variable_info,
+                               EFI_VARIABLE_NON_VOLATILE |
+                               EFI_VARIABLE_BOOTSERVICE_ACCESS |
+                               EFI_VARIABLE_RUNTIME_ACCESS, &store_size,
+                               &remaining_size, &var_size);
+
+       if (status != EFI_SUCCESS)
+               return status;
+
+       status = efi_call_phys3(sys_table->boottime->allocate_pool,
+                               EFI_LOADER_DATA, sizeof(*efidata), &efidata);
+
+       if (status != EFI_SUCCESS)
+               return status;
+
+       efidata->data.type = SETUP_EFI_VARS;
+       efidata->data.len = sizeof(struct efi_var_bootdata) -
+               sizeof(struct setup_data);
+       efidata->data.next = 0;
+       efidata->store_size = store_size;
+       efidata->remaining_size = remaining_size;
+       efidata->max_var_size = var_size;
+
+       if (data)
+               data->next = (unsigned long)efidata;
+       else
+               params->hdr.setup_data = (unsigned long)efidata;
+
+}
+
 static efi_status_t setup_efi_pci(struct boot_params *params)
 {
        efi_pci_io_protocol *pci;
@@ -1157,6 +1202,8 @@ struct boot_params *efi_main(void *handle, efi_system_table_t *_table,
 
        setup_graphics(boot_params);
 
+       setup_efi_vars(boot_params);
+
        setup_efi_pci(boot_params);
 
        status = efi_call_phys3(sys_table->boottime->allocate_pool,
index 60c89f30c727458df128543a6302e95aeede8758..2fb5d5884e2331b7d6d299621bfb5c91fa701bf2 100644 (file)
@@ -102,6 +102,13 @@ extern void efi_call_phys_epilog(void);
 extern void efi_unmap_memmap(void);
 extern void efi_memory_uc(u64 addr, unsigned long size);
 
+struct efi_var_bootdata {
+       struct setup_data data;
+       u64 store_size;
+       u64 remaining_size;
+       u64 max_var_size;
+};
+
 #ifdef CONFIG_EFI
 
 static inline bool efi_is_native(void)
index 5edd1742cfd02a9368ca28e604366fb428904ad8..7361e47db79f50158ada1cdde859c4871b99ee51 100644 (file)
@@ -703,7 +703,10 @@ static inline void arch_leave_lazy_mmu_mode(void)
        PVOP_VCALL0(pv_mmu_ops.lazy_mode.leave);
 }
 
-void arch_flush_lazy_mmu_mode(void);
+static inline void arch_flush_lazy_mmu_mode(void)
+{
+       PVOP_VCALL0(pv_mmu_ops.lazy_mode.flush);
+}
 
 static inline void __set_fixmap(unsigned /* enum fixed_addresses */ idx,
                                phys_addr_t phys, pgprot_t flags)
index 142236ed83af580c06e2e00893501e3fc38b0e65..b3b0ec1dac86d91ac6289b961afefe65f1f48d11 100644 (file)
@@ -91,6 +91,7 @@ struct pv_lazy_ops {
        /* Set deferred update mode, used for batching operations. */
        void (*enter)(void);
        void (*leave)(void);
+       void (*flush)(void);
 };
 
 struct pv_time_ops {
@@ -679,6 +680,7 @@ void paravirt_end_context_switch(struct task_struct *next);
 
 void paravirt_enter_lazy_mmu(void);
 void paravirt_leave_lazy_mmu(void);
+void paravirt_flush_lazy_mmu(void);
 
 void _paravirt_nop(void);
 u32 _paravirt_ident_32(u32);
index 4fef20773b8f9fcf104702ac2d8ef0c29a05c235..c7797307fc2ba5b24adacced83c9587bc5d2a8de 100644 (file)
@@ -7,7 +7,7 @@
 
 #define tlb_flush(tlb)                                                 \
 {                                                                      \
-       if (tlb->fullmm == 0)                                           \
+       if (!tlb->fullmm && !tlb->need_flush_all)                       \
                flush_tlb_mm_range(tlb->mm, tlb->start, tlb->end, 0UL); \
        else                                                            \
                flush_tlb_mm_range(tlb->mm, 0UL, TLB_FLUSH_ALL, 0UL);   \
index c15ddaf907107134d6cd2f8d86f554e510a6f848..08744242b8d24c9111d2275ff6d84752d725584e 100644 (file)
@@ -6,6 +6,7 @@
 #define SETUP_E820_EXT                 1
 #define SETUP_DTB                      2
 #define SETUP_PCI                      3
+#define SETUP_EFI_VARS                 4
 
 /* ram_size flags */
 #define RAMDISK_IMAGE_START_MASK       0x07FF
index a7d26d83fb700b254eca03d9ff5e8f6d56f7a0c5..8f4be53ea04b84f4eaa7a78a4bcd6e6e625c9afc 100644 (file)
@@ -35,13 +35,6 @@ static bool __init ms_hyperv_platform(void)
        if (!boot_cpu_has(X86_FEATURE_HYPERVISOR))
                return false;
 
-       /*
-        * Xen emulates Hyper-V to support enlightened Windows.
-        * Check to see first if we are on a Xen Hypervisor.
-        */
-       if (xen_cpuid_base())
-               return false;
-
        cpuid(HYPERV_CPUID_VENDOR_AND_MAX_FUNCTIONS,
              &eax, &hyp_signature[0], &hyp_signature[1], &hyp_signature[2]);
 
@@ -82,12 +75,6 @@ static void __init ms_hyperv_init_platform(void)
 
        if (ms_hyperv.features & HV_X64_MSR_TIME_REF_COUNT_AVAILABLE)
                clocksource_register_hz(&hyperv_cs, NSEC_PER_SEC/100);
-#if IS_ENABLED(CONFIG_HYPERV)
-       /*
-        * Setup the IDT for hypervisor callback.
-        */
-       alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR, hyperv_callback_vector);
-#endif
 }
 
 const __refconst struct hypervisor_x86 x86_hyper_ms_hyperv = {
@@ -103,6 +90,11 @@ static irq_handler_t vmbus_isr;
 
 void hv_register_vmbus_handler(int irq, irq_handler_t handler)
 {
+       /*
+        * Setup the IDT for hypervisor callback.
+        */
+       alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR, hyperv_callback_vector);
+
        vmbus_irq = irq;
        vmbus_isr = handler;
 }
index dab7580c47aee2e71e501afbfa94c17e2790777d..cc45deb791b01d103c01cbc527f8bfd023d51879 100644 (file)
@@ -153,8 +153,14 @@ static struct event_constraint intel_gen_event_constraints[] __read_mostly =
 };
 
 static struct extra_reg intel_snb_extra_regs[] __read_mostly = {
-       INTEL_EVENT_EXTRA_REG(0xb7, MSR_OFFCORE_RSP_0, 0x3fffffffffull, RSP_0),
-       INTEL_EVENT_EXTRA_REG(0xbb, MSR_OFFCORE_RSP_1, 0x3fffffffffull, RSP_1),
+       INTEL_EVENT_EXTRA_REG(0xb7, MSR_OFFCORE_RSP_0, 0x3f807f8fffull, RSP_0),
+       INTEL_EVENT_EXTRA_REG(0xbb, MSR_OFFCORE_RSP_1, 0x3f807f8fffull, RSP_1),
+       EVENT_EXTRA_END
+};
+
+static struct extra_reg intel_snbep_extra_regs[] __read_mostly = {
+       INTEL_EVENT_EXTRA_REG(0xb7, MSR_OFFCORE_RSP_0, 0x3fffff8fffull, RSP_0),
+       INTEL_EVENT_EXTRA_REG(0xbb, MSR_OFFCORE_RSP_1, 0x3fffff8fffull, RSP_1),
        EVENT_EXTRA_END
 };
 
@@ -2097,7 +2103,10 @@ __init int intel_pmu_init(void)
                x86_pmu.event_constraints = intel_snb_event_constraints;
                x86_pmu.pebs_constraints = intel_snb_pebs_event_constraints;
                x86_pmu.pebs_aliases = intel_pebs_aliases_snb;
-               x86_pmu.extra_regs = intel_snb_extra_regs;
+               if (boot_cpu_data.x86_model == 45)
+                       x86_pmu.extra_regs = intel_snbep_extra_regs;
+               else
+                       x86_pmu.extra_regs = intel_snb_extra_regs;
                /* all extra regs are per-cpu when HT is on */
                x86_pmu.er_flags |= ERF_HAS_RSP_1;
                x86_pmu.er_flags |= ERF_NO_HT_SHARING;
@@ -2123,7 +2132,10 @@ __init int intel_pmu_init(void)
                x86_pmu.event_constraints = intel_ivb_event_constraints;
                x86_pmu.pebs_constraints = intel_ivb_pebs_event_constraints;
                x86_pmu.pebs_aliases = intel_pebs_aliases_snb;
-               x86_pmu.extra_regs = intel_snb_extra_regs;
+               if (boot_cpu_data.x86_model == 62)
+                       x86_pmu.extra_regs = intel_snbep_extra_regs;
+               else
+                       x86_pmu.extra_regs = intel_snb_extra_regs;
                /* all extra regs are per-cpu when HT is on */
                x86_pmu.er_flags |= ERF_HAS_RSP_1;
                x86_pmu.er_flags |= ERF_NO_HT_SHARING;
index b05a575d56f42f4543504b999a3b4875de110772..26830f3af0df70eebb438ddc82f74240b49d618e 100644 (file)
@@ -314,10 +314,11 @@ int intel_pmu_drain_bts_buffer(void)
        if (top <= at)
                return 0;
 
+       memset(&regs, 0, sizeof(regs));
+
        ds->bts_index = ds->bts_buffer_base;
 
        perf_sample_data_init(&data, 0, event->hw.last_period);
-       regs.ip     = 0;
 
        /*
         * Prepare a generic sample, i.e. fill in the invariant fields.
index 577db8417d15b41fd71cce1f0bc813ba959c5b70..833d51d6ee065b908fa70ac1075a3acf6d2721a4 100644 (file)
@@ -45,9 +45,6 @@ static int __cpuinit x86_vendor(void)
        u32 eax = 0x00000000;
        u32 ebx, ecx = 0, edx;
 
-       if (!have_cpuid_p())
-               return X86_VENDOR_UNKNOWN;
-
        native_cpuid(&eax, &ebx, &ecx, &edx);
 
        if (CPUID_IS(CPUID_INTEL1, CPUID_INTEL2, CPUID_INTEL3, ebx, ecx, edx))
@@ -59,18 +56,45 @@ static int __cpuinit x86_vendor(void)
        return X86_VENDOR_UNKNOWN;
 }
 
+static int __cpuinit x86_family(void)
+{
+       u32 eax = 0x00000001;
+       u32 ebx, ecx = 0, edx;
+       int x86;
+
+       native_cpuid(&eax, &ebx, &ecx, &edx);
+
+       x86 = (eax >> 8) & 0xf;
+       if (x86 == 15)
+               x86 += (eax >> 20) & 0xff;
+
+       return x86;
+}
+
 void __init load_ucode_bsp(void)
 {
-       int vendor = x86_vendor();
+       int vendor, x86;
+
+       if (!have_cpuid_p())
+               return;
 
-       if (vendor == X86_VENDOR_INTEL)
+       vendor = x86_vendor();
+       x86 = x86_family();
+
+       if (vendor == X86_VENDOR_INTEL && x86 >= 6)
                load_ucode_intel_bsp();
 }
 
 void __cpuinit load_ucode_ap(void)
 {
-       int vendor = x86_vendor();
+       int vendor, x86;
+
+       if (!have_cpuid_p())
+               return;
+
+       vendor = x86_vendor();
+       x86 = x86_family();
 
-       if (vendor == X86_VENDOR_INTEL)
+       if (vendor == X86_VENDOR_INTEL && x86 >= 6)
                load_ucode_intel_ap();
 }
index 17fff18a103104431c0e10e1543af6f027f64f72..8bfb335f74bb377776adb4b6b1da98dc17ed82ae 100644 (file)
@@ -263,6 +263,18 @@ void paravirt_leave_lazy_mmu(void)
        leave_lazy(PARAVIRT_LAZY_MMU);
 }
 
+void paravirt_flush_lazy_mmu(void)
+{
+       preempt_disable();
+
+       if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_MMU) {
+               arch_leave_lazy_mmu_mode();
+               arch_enter_lazy_mmu_mode();
+       }
+
+       preempt_enable();
+}
+
 void paravirt_start_context_switch(struct task_struct *prev)
 {
        BUG_ON(preemptible());
@@ -292,18 +304,6 @@ enum paravirt_lazy_mode paravirt_get_lazy_mode(void)
        return this_cpu_read(paravirt_lazy_mode);
 }
 
-void arch_flush_lazy_mmu_mode(void)
-{
-       preempt_disable();
-
-       if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_MMU) {
-               arch_leave_lazy_mmu_mode();
-               arch_enter_lazy_mmu_mode();
-       }
-
-       preempt_enable();
-}
-
 struct pv_info pv_info = {
        .name = "bare hardware",
        .paravirt_enabled = 0,
@@ -475,6 +475,7 @@ struct pv_mmu_ops pv_mmu_ops = {
        .lazy_mode = {
                .enter = paravirt_nop,
                .leave = paravirt_nop,
+               .flush = paravirt_nop,
        },
 
        .set_fixmap = native_set_fixmap,
index 90d8cc930f5ed134735f7697e016a83e5657dcb8..fae9134a2de91f7b420fb554bb33f356de661f8f 100644 (file)
@@ -507,11 +507,14 @@ static void __init memblock_x86_reserve_range_setup_data(void)
 /*
  * Keep the crash kernel below this limit.  On 32 bits earlier kernels
  * would limit the kernel to the low 512 MiB due to mapping restrictions.
+ * On 64bit, old kexec-tools need to under 896MiB.
  */
 #ifdef CONFIG_X86_32
-# define CRASH_KERNEL_ADDR_MAX (512 << 20)
+# define CRASH_KERNEL_ADDR_LOW_MAX     (512 << 20)
+# define CRASH_KERNEL_ADDR_HIGH_MAX    (512 << 20)
 #else
-# define CRASH_KERNEL_ADDR_MAX MAXMEM
+# define CRASH_KERNEL_ADDR_LOW_MAX     (896UL<<20)
+# define CRASH_KERNEL_ADDR_HIGH_MAX    MAXMEM
 #endif
 
 static void __init reserve_crashkernel_low(void)
@@ -521,19 +524,35 @@ static void __init reserve_crashkernel_low(void)
        unsigned long long low_base = 0, low_size = 0;
        unsigned long total_low_mem;
        unsigned long long base;
+       bool auto_set = false;
        int ret;
 
        total_low_mem = memblock_mem_size(1UL<<(32-PAGE_SHIFT));
+       /* crashkernel=Y,low */
        ret = parse_crashkernel_low(boot_command_line, total_low_mem,
                                                &low_size, &base);
-       if (ret != 0 || low_size <= 0)
-               return;
+       if (ret != 0) {
+               /*
+                * two parts from lib/swiotlb.c:
+                *      swiotlb size: user specified with swiotlb= or default.
+                *      swiotlb overflow buffer: now is hardcoded to 32k.
+                *              We round it to 8M for other buffers that
+                *              may need to stay low too.
+                */
+               low_size = swiotlb_size_or_default() + (8UL<<20);
+               auto_set = true;
+       } else {
+               /* passed with crashkernel=0,low ? */
+               if (!low_size)
+                       return;
+       }
 
        low_base = memblock_find_in_range(low_size, (1ULL<<32),
                                        low_size, alignment);
 
        if (!low_base) {
-               pr_info("crashkernel low reservation failed - No suitable area found.\n");
+               if (!auto_set)
+                       pr_info("crashkernel low reservation failed - No suitable area found.\n");
 
                return;
        }
@@ -554,14 +573,22 @@ static void __init reserve_crashkernel(void)
        const unsigned long long alignment = 16<<20;    /* 16M */
        unsigned long long total_mem;
        unsigned long long crash_size, crash_base;
+       bool high = false;
        int ret;
 
        total_mem = memblock_phys_mem_size();
 
+       /* crashkernel=XM */
        ret = parse_crashkernel(boot_command_line, total_mem,
                        &crash_size, &crash_base);
-       if (ret != 0 || crash_size <= 0)
-               return;
+       if (ret != 0 || crash_size <= 0) {
+               /* crashkernel=X,high */
+               ret = parse_crashkernel_high(boot_command_line, total_mem,
+                               &crash_size, &crash_base);
+               if (ret != 0 || crash_size <= 0)
+                       return;
+               high = true;
+       }
 
        /* 0 means: find the address automatically */
        if (crash_base <= 0) {
@@ -569,7 +596,9 @@ static void __init reserve_crashkernel(void)
                 *  kexec want bzImage is below CRASH_KERNEL_ADDR_MAX
                 */
                crash_base = memblock_find_in_range(alignment,
-                              CRASH_KERNEL_ADDR_MAX, crash_size, alignment);
+                                       high ? CRASH_KERNEL_ADDR_HIGH_MAX :
+                                              CRASH_KERNEL_ADDR_LOW_MAX,
+                                       crash_size, alignment);
 
                if (!crash_base) {
                        pr_info("crashkernel reservation failed - No suitable area found.\n");
index 1cbd89ca5569f2ce5d76a4bed1f21d6d52ed63e5..7114c63f047d06432a453884c4500474ea9681ea 100644 (file)
@@ -1334,6 +1334,7 @@ __init void lguest_init(void)
        pv_mmu_ops.read_cr3 = lguest_read_cr3;
        pv_mmu_ops.lazy_mode.enter = paravirt_enter_lazy_mmu;
        pv_mmu_ops.lazy_mode.leave = lguest_leave_lazy_mmu_mode;
+       pv_mmu_ops.lazy_mode.flush = paravirt_flush_lazy_mmu;
        pv_mmu_ops.pte_update = lguest_pte_update;
        pv_mmu_ops.pte_update_defer = lguest_pte_update;
 
index 2b97525246d43c3397f9d2149adf859b24b2842b..0e883364abb5752d4ac07b031d241d6bd00585ab 100644 (file)
@@ -378,10 +378,12 @@ static noinline __kprobes int vmalloc_fault(unsigned long address)
        if (pgd_none(*pgd_ref))
                return -1;
 
-       if (pgd_none(*pgd))
+       if (pgd_none(*pgd)) {
                set_pgd(pgd, *pgd_ref);
-       else
+               arch_flush_lazy_mmu_mode();
+       } else {
                BUG_ON(pgd_page_vaddr(*pgd) != pgd_page_vaddr(*pgd_ref));
+       }
 
        /*
         * Below here mismatches are bugs because these lower tables
index b0086567271c9956b2196e3ba302e4a77009e811..0e38951e65eb0940bf57a3f6d8c8d01dff0674c7 100644 (file)
@@ -68,7 +68,7 @@ static int print_split(struct split_state *s)
                        s->gpg++;
                        i += GPS/PAGE_SIZE;
                } else if (level == PG_LEVEL_2M) {
-                       if (!(pte_val(*pte) & _PAGE_PSE)) {
+                       if ((pte_val(*pte) & _PAGE_PRESENT) && !(pte_val(*pte) & _PAGE_PSE)) {
                                printk(KERN_ERR
                                        "%lx level %d but not PSE %Lx\n",
                                        addr, level, (u64)pte_val(*pte));
index 091934e1d0d97ca26570eb9962aa1890e08e7bd8..fb4e73ec24d8d1b8b894b6c09f7c082a49dc1dcf 100644 (file)
@@ -467,7 +467,7 @@ try_preserve_large_page(pte_t *kpte, unsigned long address,
         * We are safe now. Check whether the new pgprot is the same:
         */
        old_pte = *kpte;
-       old_prot = new_prot = req_prot = pte_pgprot(old_pte);
+       old_prot = req_prot = pte_pgprot(old_pte);
 
        pgprot_val(req_prot) &= ~pgprot_val(cpa->mask_clr);
        pgprot_val(req_prot) |= pgprot_val(cpa->mask_set);
@@ -478,12 +478,12 @@ try_preserve_large_page(pte_t *kpte, unsigned long address,
         * a non present pmd. The canon_pgprot will clear _PAGE_GLOBAL
         * for the ancient hardware that doesn't support it.
         */
-       if (pgprot_val(new_prot) & _PAGE_PRESENT)
-               pgprot_val(new_prot) |= _PAGE_PSE | _PAGE_GLOBAL;
+       if (pgprot_val(req_prot) & _PAGE_PRESENT)
+               pgprot_val(req_prot) |= _PAGE_PSE | _PAGE_GLOBAL;
        else
-               pgprot_val(new_prot) &= ~(_PAGE_PSE | _PAGE_GLOBAL);
+               pgprot_val(req_prot) &= ~(_PAGE_PSE | _PAGE_GLOBAL);
 
-       new_prot = canon_pgprot(new_prot);
+       req_prot = canon_pgprot(req_prot);
 
        /*
         * old_pte points to the large page base address. So we need
@@ -1413,6 +1413,8 @@ void kernel_map_pages(struct page *page, int numpages, int enable)
         * but that can deadlock->flush only current cpu:
         */
        __flush_tlb_all();
+
+       arch_flush_lazy_mmu_mode();
 }
 
 #ifdef CONFIG_HIBERNATION
index 193350b51f90af74508a8ec97217085bf3acdbab..17fda6a8b3c2df13adaee439b0ad6ab9f50796cb 100644 (file)
@@ -58,6 +58,13 @@ void ___pte_free_tlb(struct mmu_gather *tlb, struct page *pte)
 void ___pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd)
 {
        paravirt_release_pmd(__pa(pmd) >> PAGE_SHIFT);
+       /*
+        * NOTE! For PAE, any changes to the top page-directory-pointer-table
+        * entries need a full cr3 reload to flush.
+        */
+#ifdef CONFIG_X86_PAE
+       tlb->need_flush_all = 1;
+#endif
        tlb_remove_page(tlb, virt_to_page(pmd));
 }
 
index 5f2ecaf3f9d8609ccdc7a56e4d232fd13bdd8dcc..e4a86a677ce163ec5f911fb14db65590d813aee1 100644 (file)
@@ -41,6 +41,7 @@
 #include <linux/io.h>
 #include <linux/reboot.h>
 #include <linux/bcd.h>
+#include <linux/ucs2_string.h>
 
 #include <asm/setup.h>
 #include <asm/efi.h>
 
 #define EFI_DEBUG      1
 
+/*
+ * There's some additional metadata associated with each
+ * variable. Intel's reference implementation is 60 bytes - bump that
+ * to account for potential alignment constraints
+ */
+#define VAR_METADATA_SIZE 64
+
 struct efi __read_mostly efi = {
        .mps        = EFI_INVALID_TABLE_ADDR,
        .acpi       = EFI_INVALID_TABLE_ADDR,
@@ -69,6 +77,13 @@ struct efi_memory_map memmap;
 static struct efi efi_phys __initdata;
 static efi_system_table_t efi_systab __initdata;
 
+static u64 efi_var_store_size;
+static u64 efi_var_remaining_size;
+static u64 efi_var_max_var_size;
+static u64 boot_used_size;
+static u64 boot_var_size;
+static u64 active_size;
+
 unsigned long x86_efi_facility;
 
 /*
@@ -98,6 +113,15 @@ static int __init setup_add_efi_memmap(char *arg)
 }
 early_param("add_efi_memmap", setup_add_efi_memmap);
 
+static bool efi_no_storage_paranoia;
+
+static int __init setup_storage_paranoia(char *arg)
+{
+       efi_no_storage_paranoia = true;
+       return 0;
+}
+early_param("efi_no_storage_paranoia", setup_storage_paranoia);
+
 
 static efi_status_t virt_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc)
 {
@@ -162,8 +186,53 @@ static efi_status_t virt_efi_get_next_variable(unsigned long *name_size,
                                               efi_char16_t *name,
                                               efi_guid_t *vendor)
 {
-       return efi_call_virt3(get_next_variable,
-                             name_size, name, vendor);
+       efi_status_t status;
+       static bool finished = false;
+       static u64 var_size;
+
+       status = efi_call_virt3(get_next_variable,
+                               name_size, name, vendor);
+
+       if (status == EFI_NOT_FOUND) {
+               finished = true;
+               if (var_size < boot_used_size) {
+                       boot_var_size = boot_used_size - var_size;
+                       active_size += boot_var_size;
+               } else {
+                       printk(KERN_WARNING FW_BUG  "efi: Inconsistent initial sizes\n");
+               }
+       }
+
+       if (boot_used_size && !finished) {
+               unsigned long size;
+               u32 attr;
+               efi_status_t s;
+               void *tmp;
+
+               s = virt_efi_get_variable(name, vendor, &attr, &size, NULL);
+
+               if (s != EFI_BUFFER_TOO_SMALL || !size)
+                       return status;
+
+               tmp = kmalloc(size, GFP_ATOMIC);
+
+               if (!tmp)
+                       return status;
+
+               s = virt_efi_get_variable(name, vendor, &attr, &size, tmp);
+
+               if (s == EFI_SUCCESS && (attr & EFI_VARIABLE_NON_VOLATILE)) {
+                       var_size += size;
+                       var_size += ucs2_strsize(name, 1024);
+                       active_size += size;
+                       active_size += VAR_METADATA_SIZE;
+                       active_size += ucs2_strsize(name, 1024);
+               }
+
+               kfree(tmp);
+       }
+
+       return status;
 }
 
 static efi_status_t virt_efi_set_variable(efi_char16_t *name,
@@ -172,9 +241,34 @@ static efi_status_t virt_efi_set_variable(efi_char16_t *name,
                                          unsigned long data_size,
                                          void *data)
 {
-       return efi_call_virt5(set_variable,
-                             name, vendor, attr,
-                             data_size, data);
+       efi_status_t status;
+       u32 orig_attr = 0;
+       unsigned long orig_size = 0;
+
+       status = virt_efi_get_variable(name, vendor, &orig_attr, &orig_size,
+                                      NULL);
+
+       if (status != EFI_BUFFER_TOO_SMALL)
+               orig_size = 0;
+
+       status = efi_call_virt5(set_variable,
+                               name, vendor, attr,
+                               data_size, data);
+
+       if (status == EFI_SUCCESS) {
+               if (orig_size) {
+                       active_size -= orig_size;
+                       active_size -= ucs2_strsize(name, 1024);
+                       active_size -= VAR_METADATA_SIZE;
+               }
+               if (data_size) {
+                       active_size += data_size;
+                       active_size += ucs2_strsize(name, 1024);
+                       active_size += VAR_METADATA_SIZE;
+               }
+       }
+
+       return status;
 }
 
 static efi_status_t virt_efi_query_variable_info(u32 attr,
@@ -682,6 +776,9 @@ void __init efi_init(void)
        char vendor[100] = "unknown";
        int i = 0;
        void *tmp;
+       struct setup_data *data;
+       struct efi_var_bootdata *efi_var_data;
+       u64 pa_data;
 
 #ifdef CONFIG_X86_32
        if (boot_params.efi_info.efi_systab_hi ||
@@ -699,6 +796,22 @@ void __init efi_init(void)
        if (efi_systab_init(efi_phys.systab))
                return;
 
+       pa_data = boot_params.hdr.setup_data;
+       while (pa_data) {
+               data = early_ioremap(pa_data, sizeof(*efi_var_data));
+               if (data->type == SETUP_EFI_VARS) {
+                       efi_var_data = (struct efi_var_bootdata *)data;
+
+                       efi_var_store_size = efi_var_data->store_size;
+                       efi_var_remaining_size = efi_var_data->remaining_size;
+                       efi_var_max_var_size = efi_var_data->max_var_size;
+               }
+               pa_data = data->next;
+               early_iounmap(data, sizeof(*efi_var_data));
+       }
+
+       boot_used_size = efi_var_store_size - efi_var_remaining_size;
+
        set_bit(EFI_SYSTEM_TABLES, &x86_efi_facility);
 
        /*
@@ -999,3 +1112,48 @@ u64 efi_mem_attributes(unsigned long phys_addr)
        }
        return 0;
 }
+
+/*
+ * Some firmware has serious problems when using more than 50% of the EFI
+ * variable store, i.e. it triggers bugs that can brick machines. Ensure that
+ * we never use more than this safe limit.
+ *
+ * Return EFI_SUCCESS if it is safe to write 'size' bytes to the variable
+ * store.
+ */
+efi_status_t efi_query_variable_store(u32 attributes, unsigned long size)
+{
+       efi_status_t status;
+       u64 storage_size, remaining_size, max_size;
+
+       status = efi.query_variable_info(attributes, &storage_size,
+                                        &remaining_size, &max_size);
+       if (status != EFI_SUCCESS)
+               return status;
+
+       if (!max_size && remaining_size > size)
+               printk_once(KERN_ERR FW_BUG "Broken EFI implementation"
+                           " is returning MaxVariableSize=0\n");
+       /*
+        * Some firmware implementations refuse to boot if there's insufficient
+        * space in the variable store. We account for that by refusing the
+        * write if permitting it would reduce the available space to under
+        * 50%. However, some firmware won't reclaim variable space until
+        * after the used (not merely the actively used) space drops below
+        * a threshold. We can approximate that case with the value calculated
+        * above. If both the firmware and our calculations indicate that the
+        * available space would drop below 50%, refuse the write.
+        */
+
+       if (!storage_size || size > remaining_size ||
+           (max_size && size > max_size))
+               return EFI_OUT_OF_RESOURCES;
+
+       if (!efi_no_storage_paranoia &&
+           ((active_size + size + VAR_METADATA_SIZE > storage_size / 2) &&
+            (remaining_size - size < storage_size / 2)))
+               return EFI_OUT_OF_RESOURCES;
+
+       return EFI_SUCCESS;
+}
+EXPORT_SYMBOL_GPL(efi_query_variable_store);
index 6afbb2ca9a0ac450f79c6628b7cd9cd7c2ceeccf..e006c18d288a39ebec3343b2c240eced7a6fec34 100644 (file)
@@ -1748,14 +1748,18 @@ static void *m2v(phys_addr_t maddr)
 }
 
 /* Set the page permissions on an identity-mapped pages */
-static void set_page_prot(void *addr, pgprot_t prot)
+static void set_page_prot_flags(void *addr, pgprot_t prot, unsigned long flags)
 {
        unsigned long pfn = __pa(addr) >> PAGE_SHIFT;
        pte_t pte = pfn_pte(pfn, prot);
 
-       if (HYPERVISOR_update_va_mapping((unsigned long)addr, pte, 0))
+       if (HYPERVISOR_update_va_mapping((unsigned long)addr, pte, flags))
                BUG();
 }
+static void set_page_prot(void *addr, pgprot_t prot)
+{
+       return set_page_prot_flags(addr, prot, UVMF_NONE);
+}
 #ifdef CONFIG_X86_32
 static void __init xen_map_identity_early(pmd_t *pmd, unsigned long max_pfn)
 {
@@ -1839,12 +1843,12 @@ static void __init check_pt_base(unsigned long *pt_base, unsigned long *pt_end,
                                 unsigned long addr)
 {
        if (*pt_base == PFN_DOWN(__pa(addr))) {
-               set_page_prot((void *)addr, PAGE_KERNEL);
+               set_page_prot_flags((void *)addr, PAGE_KERNEL, UVMF_INVLPG);
                clear_page((void *)addr);
                (*pt_base)++;
        }
        if (*pt_end == PFN_DOWN(__pa(addr))) {
-               set_page_prot((void *)addr, PAGE_KERNEL);
+               set_page_prot_flags((void *)addr, PAGE_KERNEL, UVMF_INVLPG);
                clear_page((void *)addr);
                (*pt_end)--;
        }
@@ -2196,6 +2200,7 @@ static const struct pv_mmu_ops xen_mmu_ops __initconst = {
        .lazy_mode = {
                .enter = paravirt_enter_lazy_mmu,
                .leave = xen_leave_lazy_mmu,
+               .flush = paravirt_flush_lazy_mmu,
        },
 
        .set_fixmap = xen_set_fixmap,
index 074b758efc42cf116d61f4755f0107f491890980..7c288358a745ad2312e93080201e341cf2b69207 100644 (file)
@@ -39,6 +39,7 @@
 
 EXPORT_TRACEPOINT_SYMBOL_GPL(block_bio_remap);
 EXPORT_TRACEPOINT_SYMBOL_GPL(block_rq_remap);
+EXPORT_TRACEPOINT_SYMBOL_GPL(block_bio_complete);
 EXPORT_TRACEPOINT_SYMBOL_GPL(block_unplug);
 
 DEFINE_IDA(blk_queue_ida);
index 6206a934eb8c85a2f21636759f1b64afe8e3fb70..5efc5a647183b688fe0e4312c7ad5bcb3dad403b 100644 (file)
@@ -229,6 +229,8 @@ queue_store_##name(struct request_queue *q, const char *page, size_t count) \
        unsigned long val;                                              \
        ssize_t ret;                                                    \
        ret = queue_var_store(&val, page, count);                       \
+       if (ret < 0)                                                    \
+                return ret;                                            \
        if (neg)                                                        \
                val = !val;                                             \
                                                                        \
index ae95ee6a58aad6d005affa10bb270bdf1008e986..789cdea05893bb8e3420ede5d1aa65e7af408e1b 100644 (file)
@@ -257,7 +257,6 @@ void delete_partition(struct gendisk *disk, int partno)
 
        hd_struct_put(part);
 }
-EXPORT_SYMBOL(delete_partition);
 
 static ssize_t whole_disk_show(struct device *dev,
                               struct device_attribute *attr, char *buf)
index 137ad1ec54383ceda3e515490ffc794a0242f907..13ccbda34ff979fbeb037b88ae400f4e248789a7 100644 (file)
@@ -44,6 +44,7 @@ struct crypto_rfc4543_ctx {
 
 struct crypto_rfc4543_req_ctx {
        u8 auth_tag[16];
+       u8 assocbuf[32];
        struct scatterlist cipher[1];
        struct scatterlist payload[2];
        struct scatterlist assoc[2];
@@ -1133,9 +1134,19 @@ static struct aead_request *crypto_rfc4543_crypt(struct aead_request *req,
        scatterwalk_crypto_chain(payload, dst, vdst == req->iv + 8, 2);
        assoclen += 8 + req->cryptlen - (enc ? 0 : authsize);
 
-       sg_init_table(assoc, 2);
-       sg_set_page(assoc, sg_page(req->assoc), req->assoc->length,
-                   req->assoc->offset);
+       if (req->assoc->length == req->assoclen) {
+               sg_init_table(assoc, 2);
+               sg_set_page(assoc, sg_page(req->assoc), req->assoc->length,
+                           req->assoc->offset);
+       } else {
+               BUG_ON(req->assoclen > sizeof(rctx->assocbuf));
+
+               scatterwalk_map_and_copy(rctx->assocbuf, req->assoc, 0,
+                                        req->assoclen, 0);
+
+               sg_init_table(assoc, 2);
+               sg_set_buf(assoc, rctx->assocbuf, req->assoclen);
+       }
        scatterwalk_crypto_chain(assoc, payload, 0, 2);
 
        aead_request_set_tfm(subreq, ctx->child);
index ffdd32d22602296875ff395a1fdc08e32509c393..2f48123d74c4c85d84180e3e7a39c712a1b7a175 100644 (file)
@@ -150,6 +150,7 @@ enum piix_controller_ids {
        tolapai_sata,
        piix_pata_vmw,                  /* PIIX4 for VMware, spurious DMA_ERR */
        ich8_sata_snb,
+       ich8_2port_sata_snb,
 };
 
 struct piix_map_db {
@@ -304,7 +305,7 @@ static const struct pci_device_id piix_pci_tbl[] = {
        /* SATA Controller IDE (Lynx Point) */
        { 0x8086, 0x8c01, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_snb },
        /* SATA Controller IDE (Lynx Point) */
-       { 0x8086, 0x8c08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
+       { 0x8086, 0x8c08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata_snb },
        /* SATA Controller IDE (Lynx Point) */
        { 0x8086, 0x8c09, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
        /* SATA Controller IDE (Lynx Point-LP) */
@@ -439,6 +440,7 @@ static const struct piix_map_db *piix_map_db_table[] = {
        [ich8m_apple_sata]      = &ich8m_apple_map_db,
        [tolapai_sata]          = &tolapai_map_db,
        [ich8_sata_snb]         = &ich8_map_db,
+       [ich8_2port_sata_snb]   = &ich8_2port_map_db,
 };
 
 static struct pci_bits piix_enable_bits[] = {
@@ -1242,6 +1244,16 @@ static struct ata_port_info piix_port_info[] = {
                .udma_mask      = ATA_UDMA6,
                .port_ops       = &piix_sata_ops,
        },
+
+       [ich8_2port_sata_snb] =
+       {
+               .flags          = PIIX_SATA_FLAGS | PIIX_FLAG_SIDPR
+                                       | PIIX_FLAG_PIO16,
+               .pio_mask       = ATA_PIO4,
+               .mwdma_mask     = ATA_MWDMA2,
+               .udma_mask      = ATA_UDMA6,
+               .port_ops       = &piix_sata_ops,
+       },
 };
 
 #define AHCI_PCI_BAR 5
index 497adea1f0d641452f8b107d135af6a30c8164bd..63c743baf920217181bdb6fcd7cde0f3dc61d0c6 100644 (file)
@@ -2329,7 +2329,7 @@ int ata_dev_configure(struct ata_device *dev)
                 * from SATA Settings page of Identify Device Data Log.
                 */
                if (ata_id_has_devslp(dev->id)) {
-                       u8 sata_setting[ATA_SECT_SIZE];
+                       u8 *sata_setting = ap->sector_buf;
                        int i, j;
 
                        dev->flags |= ATA_DFLAG_DEVSLP;
@@ -2439,6 +2439,9 @@ int ata_dev_configure(struct ata_device *dev)
                dev->max_sectors = min_t(unsigned int, ATA_MAX_SECTORS_128,
                                         dev->max_sectors);
 
+       if (dev->horkage & ATA_HORKAGE_MAX_SEC_LBA48)
+               dev->max_sectors = ATA_MAX_SECTORS_LBA48;
+
        if (ap->ops->dev_config)
                ap->ops->dev_config(dev);
 
@@ -4100,6 +4103,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
        /* Weird ATAPI devices */
        { "TORiSAN DVD-ROM DRD-N216", NULL,     ATA_HORKAGE_MAX_SEC_128 },
        { "QUANTUM DAT    DAT72-000", NULL,     ATA_HORKAGE_ATAPI_MOD16_DMA },
+       { "Slimtype DVD A  DS8A8SH", NULL,      ATA_HORKAGE_MAX_SEC_LBA48 },
 
        /* Devices we expect to fail diagnostics */
 
index 318b41358187739fe0671fe1c0be118668575da8..ff44787e5a457930dc8580ed72cb09386a8acf13 100644 (file)
@@ -532,8 +532,8 @@ int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg)
                        struct scsi_sense_hdr sshdr;
                        scsi_normalize_sense(sensebuf, SCSI_SENSE_BUFFERSIZE,
                                             &sshdr);
-                       if (sshdr.sense_key == 0 &&
-                           sshdr.asc == 0 && sshdr.ascq == 0)
+                       if (sshdr.sense_key == RECOVERED_ERROR &&
+                           sshdr.asc == 0 && sshdr.ascq == 0x1d)
                                cmd_result &= ~SAM_STAT_CHECK_CONDITION;
                }
 
@@ -618,8 +618,8 @@ int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg)
                        struct scsi_sense_hdr sshdr;
                        scsi_normalize_sense(sensebuf, SCSI_SENSE_BUFFERSIZE,
                                                &sshdr);
-                       if (sshdr.sense_key == 0 &&
-                               sshdr.asc == 0 && sshdr.ascq == 0)
+                       if (sshdr.sense_key == RECOVERED_ERROR &&
+                           sshdr.asc == 0 && sshdr.ascq == 0x1d)
                                cmd_result &= ~SAM_STAT_CHECK_CONDITION;
                }
 
index d34adef1e63e2bee55aa3cd5a9e7f2d98912103b..58cfb3232428f05b702d5b7b3a569429b9f8fe5c 100644 (file)
@@ -943,7 +943,8 @@ static int _regmap_raw_write(struct regmap *map, unsigned int reg,
                unsigned int ival;
                int val_bytes = map->format.val_bytes;
                for (i = 0; i < val_len / val_bytes; i++) {
-                       ival = map->format.parse_val(val + (i * val_bytes));
+                       memcpy(map->work_buf, val + (i * val_bytes), val_bytes);
+                       ival = map->format.parse_val(map->work_buf);
                        ret = regcache_write(map, reg + (i * map->reg_stride),
                                             ival);
                        if (ret) {
index 2c127f9c3f3bf9e5966172e5255efa3a0d35b595..dfe758382eafe71861f244f3436ce2db06f5f541 100644 (file)
@@ -1051,29 +1051,12 @@ static int loop_clr_fd(struct loop_device *lo)
        lo->lo_state = Lo_unbound;
        /* This is safe: open() is still holding a reference. */
        module_put(THIS_MODULE);
+       if (lo->lo_flags & LO_FLAGS_PARTSCAN && bdev)
+               ioctl_by_bdev(bdev, BLKRRPART, 0);
        lo->lo_flags = 0;
        if (!part_shift)
                lo->lo_disk->flags |= GENHD_FL_NO_PART_SCAN;
        mutex_unlock(&lo->lo_ctl_mutex);
-
-       /*
-        * Remove all partitions, since BLKRRPART won't remove user
-        * added partitions when max_part=0
-        */
-       if (bdev) {
-               struct disk_part_iter piter;
-               struct hd_struct *part;
-
-               mutex_lock_nested(&bdev->bd_mutex, 1);
-               invalidate_partition(bdev->bd_disk, 0);
-               disk_part_iter_init(&piter, bdev->bd_disk,
-                                       DISK_PITER_INCL_EMPTY);
-               while ((part = disk_part_iter_next(&piter)))
-                       delete_partition(bdev->bd_disk, part->partno);
-               disk_part_iter_exit(&piter);
-               mutex_unlock(&bdev->bd_mutex);
-       }
-
        /*
         * Need not hold lo_ctl_mutex to fput backing file.
         * Calling fput holding lo_ctl_mutex triggers a circular
index 92250af84e7d151a8da57ed2cf6d22d8e3313e9d..32c678028e53c36ec8a52183799ad97642c666e8 100644 (file)
 /* Device instance number, incremented each time a device is probed. */
 static int instance;
 
+struct list_head online_list;
+struct list_head removing_list;
+spinlock_t dev_lock;
+
 /*
  * Global variable used to hold the major block device number
  * allocated in mtip_init().
  */
 static int mtip_major;
 static struct dentry *dfs_parent;
+static struct dentry *dfs_device_status;
 
 static u32 cpu_use[NR_CPUS];
 
@@ -243,40 +248,31 @@ static inline void release_slot(struct mtip_port *port, int tag)
 /*
  * Reset the HBA (without sleeping)
  *
- * Just like hba_reset, except does not call sleep, so can be
- * run from interrupt/tasklet context.
- *
  * @dd Pointer to the driver data structure.
  *
  * return value
  *     0       The reset was successful.
  *     -1      The HBA Reset bit did not clear.
  */
-static int hba_reset_nosleep(struct driver_data *dd)
+static int mtip_hba_reset(struct driver_data *dd)
 {
        unsigned long timeout;
 
-       /* Chip quirk: quiesce any chip function */
-       mdelay(10);
-
        /* Set the reset bit */
        writel(HOST_RESET, dd->mmio + HOST_CTL);
 
        /* Flush */
        readl(dd->mmio + HOST_CTL);
 
-       /*
-        * Wait 10ms then spin for up to 1 second
-        * waiting for reset acknowledgement
-        */
-       timeout = jiffies + msecs_to_jiffies(1000);
-       mdelay(10);
-       while ((readl(dd->mmio + HOST_CTL) & HOST_RESET)
-                && time_before(jiffies, timeout))
-               mdelay(1);
+       /* Spin for up to 2 seconds, waiting for reset acknowledgement */
+       timeout = jiffies + msecs_to_jiffies(2000);
+       do {
+               mdelay(10);
+               if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag))
+                       return -1;
 
-       if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag))
-               return -1;
+       } while ((readl(dd->mmio + HOST_CTL) & HOST_RESET)
+                && time_before(jiffies, timeout));
 
        if (readl(dd->mmio + HOST_CTL) & HOST_RESET)
                return -1;
@@ -481,7 +477,7 @@ static void mtip_restart_port(struct mtip_port *port)
                dev_warn(&port->dd->pdev->dev,
                        "PxCMD.CR not clear, escalating reset\n");
 
-               if (hba_reset_nosleep(port->dd))
+               if (mtip_hba_reset(port->dd))
                        dev_err(&port->dd->pdev->dev,
                                "HBA reset escalation failed.\n");
 
@@ -527,6 +523,26 @@ static void mtip_restart_port(struct mtip_port *port)
 
 }
 
+static int mtip_device_reset(struct driver_data *dd)
+{
+       int rv = 0;
+
+       if (mtip_check_surprise_removal(dd->pdev))
+               return 0;
+
+       if (mtip_hba_reset(dd) < 0)
+               rv = -EFAULT;
+
+       mdelay(1);
+       mtip_init_port(dd->port);
+       mtip_start_port(dd->port);
+
+       /* Enable interrupts on the HBA. */
+       writel(readl(dd->mmio + HOST_CTL) | HOST_IRQ_EN,
+                                       dd->mmio + HOST_CTL);
+       return rv;
+}
+
 /*
  * Helper function for tag logging
  */
@@ -632,7 +648,7 @@ static void mtip_timeout_function(unsigned long int data)
        if (cmdto_cnt) {
                print_tags(port->dd, "timed out", tagaccum, cmdto_cnt);
                if (!test_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags)) {
-                       mtip_restart_port(port);
+                       mtip_device_reset(port->dd);
                        wake_up_interruptible(&port->svc_wait);
                }
                clear_bit(MTIP_PF_EH_ACTIVE_BIT, &port->flags);
@@ -1283,11 +1299,11 @@ static int mtip_exec_internal_command(struct mtip_port *port,
        int rv = 0, ready2go = 1;
        struct mtip_cmd *int_cmd = &port->commands[MTIP_TAG_INTERNAL];
        unsigned long to;
+       struct driver_data *dd = port->dd;
 
        /* Make sure the buffer is 8 byte aligned. This is asic specific. */
        if (buffer & 0x00000007) {
-               dev_err(&port->dd->pdev->dev,
-                       "SG buffer is not 8 byte aligned\n");
+               dev_err(&dd->pdev->dev, "SG buffer is not 8 byte aligned\n");
                return -EFAULT;
        }
 
@@ -1300,23 +1316,21 @@ static int mtip_exec_internal_command(struct mtip_port *port,
                mdelay(100);
        } while (time_before(jiffies, to));
        if (!ready2go) {
-               dev_warn(&port->dd->pdev->dev,
+               dev_warn(&dd->pdev->dev,
                        "Internal cmd active. new cmd [%02X]\n", fis->command);
                return -EBUSY;
        }
        set_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags);
        port->ic_pause_timer = 0;
 
-       if (fis->command == ATA_CMD_SEC_ERASE_UNIT)
-               clear_bit(MTIP_PF_SE_ACTIVE_BIT, &port->flags);
-       else if (fis->command == ATA_CMD_DOWNLOAD_MICRO)
-               clear_bit(MTIP_PF_DM_ACTIVE_BIT, &port->flags);
+       clear_bit(MTIP_PF_SE_ACTIVE_BIT, &port->flags);
+       clear_bit(MTIP_PF_DM_ACTIVE_BIT, &port->flags);
 
        if (atomic == GFP_KERNEL) {
                if (fis->command != ATA_CMD_STANDBYNOW1) {
                        /* wait for io to complete if non atomic */
                        if (mtip_quiesce_io(port, 5000) < 0) {
-                               dev_warn(&port->dd->pdev->dev,
+                               dev_warn(&dd->pdev->dev,
                                        "Failed to quiesce IO\n");
                                release_slot(port, MTIP_TAG_INTERNAL);
                                clear_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags);
@@ -1361,58 +1375,84 @@ static int mtip_exec_internal_command(struct mtip_port *port,
        /* Issue the command to the hardware */
        mtip_issue_non_ncq_command(port, MTIP_TAG_INTERNAL);
 
-       /* Poll if atomic, wait_for_completion otherwise */
        if (atomic == GFP_KERNEL) {
                /* Wait for the command to complete or timeout. */
-               if (wait_for_completion_timeout(
+               if (wait_for_completion_interruptible_timeout(
                                &wait,
-                               msecs_to_jiffies(timeout)) == 0) {
-                       dev_err(&port->dd->pdev->dev,
-                               "Internal command did not complete [%d] "
-                               "within timeout of  %lu ms\n",
-                               atomic, timeout);
-                       if (mtip_check_surprise_removal(port->dd->pdev) ||
+                               msecs_to_jiffies(timeout)) <= 0) {
+                       if (rv == -ERESTARTSYS) { /* interrupted */
+                               dev_err(&dd->pdev->dev,
+                                       "Internal command [%02X] was interrupted after %lu ms\n",
+                                       fis->command, timeout);
+                               rv = -EINTR;
+                               goto exec_ic_exit;
+                       } else if (rv == 0) /* timeout */
+                               dev_err(&dd->pdev->dev,
+                                       "Internal command did not complete [%02X] within timeout of  %lu ms\n",
+                                       fis->command, timeout);
+                       else
+                               dev_err(&dd->pdev->dev,
+                                       "Internal command [%02X] wait returned code [%d] after %lu ms - unhandled\n",
+                                       fis->command, rv, timeout);
+
+                       if (mtip_check_surprise_removal(dd->pdev) ||
                                test_bit(MTIP_DDF_REMOVE_PENDING_BIT,
-                                               &port->dd->dd_flag)) {
+                                               &dd->dd_flag)) {
+                               dev_err(&dd->pdev->dev,
+                                       "Internal command [%02X] wait returned due to SR\n",
+                                       fis->command);
                                rv = -ENXIO;
                                goto exec_ic_exit;
                        }
+                       mtip_device_reset(dd); /* recover from timeout issue */
                        rv = -EAGAIN;
+                       goto exec_ic_exit;
                }
        } else {
+               u32 hba_stat, port_stat;
+
                /* Spin for <timeout> checking if command still outstanding */
                timeout = jiffies + msecs_to_jiffies(timeout);
                while ((readl(port->cmd_issue[MTIP_TAG_INTERNAL])
                                & (1 << MTIP_TAG_INTERNAL))
                                && time_before(jiffies, timeout)) {
-                       if (mtip_check_surprise_removal(port->dd->pdev)) {
+                       if (mtip_check_surprise_removal(dd->pdev)) {
                                rv = -ENXIO;
                                goto exec_ic_exit;
                        }
                        if ((fis->command != ATA_CMD_STANDBYNOW1) &&
                                test_bit(MTIP_DDF_REMOVE_PENDING_BIT,
-                                               &port->dd->dd_flag)) {
+                                               &dd->dd_flag)) {
                                rv = -ENXIO;
                                goto exec_ic_exit;
                        }
-                       if (readl(port->mmio + PORT_IRQ_STAT) & PORT_IRQ_ERR) {
-                               atomic_inc(&int_cmd->active); /* error */
-                               break;
+                       port_stat = readl(port->mmio + PORT_IRQ_STAT);
+                       if (!port_stat)
+                               continue;
+
+                       if (port_stat & PORT_IRQ_ERR) {
+                               dev_err(&dd->pdev->dev,
+                                       "Internal command [%02X] failed\n",
+                                       fis->command);
+                               mtip_device_reset(dd);
+                               rv = -EIO;
+                               goto exec_ic_exit;
+                       } else {
+                               writel(port_stat, port->mmio + PORT_IRQ_STAT);
+                               hba_stat = readl(dd->mmio + HOST_IRQ_STAT);
+                               if (hba_stat)
+                                       writel(hba_stat,
+                                               dd->mmio + HOST_IRQ_STAT);
                        }
+                       break;
                }
        }
 
-       if (atomic_read(&int_cmd->active) > 1) {
-               dev_err(&port->dd->pdev->dev,
-                       "Internal command [%02X] failed\n", fis->command);
-               rv = -EIO;
-       }
        if (readl(port->cmd_issue[MTIP_TAG_INTERNAL])
                        & (1 << MTIP_TAG_INTERNAL)) {
                rv = -ENXIO;
-               if (!test_bit(MTIP_DDF_REMOVE_PENDING_BIT,
-                                       &port->dd->dd_flag)) {
-                       mtip_restart_port(port);
+               if (!test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag)) {
+                       mtip_device_reset(dd);
                        rv = -EAGAIN;
                }
        }
@@ -1724,7 +1764,8 @@ static int mtip_get_smart_attr(struct mtip_port *port, unsigned int id,
  *      -EINVAL                Invalid parameters passed in, trim not supported
  *      -EIO           Error submitting trim request to hw
  */
-static int mtip_send_trim(struct driver_data *dd, unsigned int lba, unsigned int len)
+static int mtip_send_trim(struct driver_data *dd, unsigned int lba,
+                               unsigned int len)
 {
        int i, rv = 0;
        u64 tlba, tlen, sect_left;
@@ -1810,45 +1851,6 @@ static bool mtip_hw_get_capacity(struct driver_data *dd, sector_t *sectors)
        return (bool) !!port->identify_valid;
 }
 
-/*
- * Reset the HBA.
- *
- * Resets the HBA by setting the HBA Reset bit in the Global
- * HBA Control register. After setting the HBA Reset bit the
- * function waits for 1 second before reading the HBA Reset
- * bit to make sure it has cleared. If HBA Reset is not clear
- * an error is returned. Cannot be used in non-blockable
- * context.
- *
- * @dd Pointer to the driver data structure.
- *
- * return value
- *     0  The reset was successful.
- *     -1 The HBA Reset bit did not clear.
- */
-static int mtip_hba_reset(struct driver_data *dd)
-{
-       mtip_deinit_port(dd->port);
-
-       /* Set the reset bit */
-       writel(HOST_RESET, dd->mmio + HOST_CTL);
-
-       /* Flush */
-       readl(dd->mmio + HOST_CTL);
-
-       /* Wait for reset to clear */
-       ssleep(1);
-
-       /* Check the bit has cleared */
-       if (readl(dd->mmio + HOST_CTL) & HOST_RESET) {
-               dev_err(&dd->pdev->dev,
-                       "Reset bit did not clear.\n");
-               return -1;
-       }
-
-       return 0;
-}
-
 /*
  * Display the identify command data.
  *
@@ -2710,6 +2712,100 @@ static ssize_t mtip_hw_show_status(struct device *dev,
 
 static DEVICE_ATTR(status, S_IRUGO, mtip_hw_show_status, NULL);
 
+/* debugsfs entries */
+
+static ssize_t show_device_status(struct device_driver *drv, char *buf)
+{
+       int size = 0;
+       struct driver_data *dd, *tmp;
+       unsigned long flags;
+       char id_buf[42];
+       u16 status = 0;
+
+       spin_lock_irqsave(&dev_lock, flags);
+       size += sprintf(&buf[size], "Devices Present:\n");
+       list_for_each_entry_safe(dd, tmp, &online_list, online_list) {
+               if (dd->pdev) {
+                       if (dd->port &&
+                           dd->port->identify &&
+                           dd->port->identify_valid) {
+                               strlcpy(id_buf,
+                                       (char *) (dd->port->identify + 10), 21);
+                               status = *(dd->port->identify + 141);
+                       } else {
+                               memset(id_buf, 0, 42);
+                               status = 0;
+                       }
+
+                       if (dd->port &&
+                           test_bit(MTIP_PF_REBUILD_BIT, &dd->port->flags)) {
+                               size += sprintf(&buf[size],
+                                       " device %s %s (ftl rebuild %d %%)\n",
+                                       dev_name(&dd->pdev->dev),
+                                       id_buf,
+                                       status);
+                       } else {
+                               size += sprintf(&buf[size],
+                                       " device %s %s\n",
+                                       dev_name(&dd->pdev->dev),
+                                       id_buf);
+                       }
+               }
+       }
+
+       size += sprintf(&buf[size], "Devices Being Removed:\n");
+       list_for_each_entry_safe(dd, tmp, &removing_list, remove_list) {
+               if (dd->pdev) {
+                       if (dd->port &&
+                           dd->port->identify &&
+                           dd->port->identify_valid) {
+                               strlcpy(id_buf,
+                                       (char *) (dd->port->identify+10), 21);
+                               status = *(dd->port->identify + 141);
+                       } else {
+                               memset(id_buf, 0, 42);
+                               status = 0;
+                       }
+
+                       if (dd->port &&
+                           test_bit(MTIP_PF_REBUILD_BIT, &dd->port->flags)) {
+                               size += sprintf(&buf[size],
+                                       " device %s %s (ftl rebuild %d %%)\n",
+                                       dev_name(&dd->pdev->dev),
+                                       id_buf,
+                                       status);
+                       } else {
+                               size += sprintf(&buf[size],
+                                       " device %s %s\n",
+                                       dev_name(&dd->pdev->dev),
+                                       id_buf);
+                       }
+               }
+       }
+       spin_unlock_irqrestore(&dev_lock, flags);
+
+       return size;
+}
+
+static ssize_t mtip_hw_read_device_status(struct file *f, char __user *ubuf,
+                                               size_t len, loff_t *offset)
+{
+       int size = *offset;
+       char buf[MTIP_DFS_MAX_BUF_SIZE];
+
+       if (!len || *offset)
+               return 0;
+
+       size += show_device_status(NULL, buf);
+
+       *offset = size <= len ? size : len;
+       size = copy_to_user(ubuf, buf, *offset);
+       if (size)
+               return -EFAULT;
+
+       return *offset;
+}
+
 static ssize_t mtip_hw_read_registers(struct file *f, char __user *ubuf,
                                  size_t len, loff_t *offset)
 {
@@ -2804,6 +2900,13 @@ static ssize_t mtip_hw_read_flags(struct file *f, char __user *ubuf,
        return *offset;
 }
 
+static const struct file_operations mtip_device_status_fops = {
+       .owner  = THIS_MODULE,
+       .open   = simple_open,
+       .read   = mtip_hw_read_device_status,
+       .llseek = no_llseek,
+};
+
 static const struct file_operations mtip_regs_fops = {
        .owner  = THIS_MODULE,
        .open   = simple_open,
@@ -4161,6 +4264,7 @@ static int mtip_pci_probe(struct pci_dev *pdev,
        const struct cpumask *node_mask;
        int cpu, i = 0, j = 0;
        int my_node = NUMA_NO_NODE;
+       unsigned long flags;
 
        /* Allocate memory for this devices private data. */
        my_node = pcibus_to_node(pdev->bus);
@@ -4218,6 +4322,9 @@ static int mtip_pci_probe(struct pci_dev *pdev,
        dd->pdev        = pdev;
        dd->numa_node   = my_node;
 
+       INIT_LIST_HEAD(&dd->online_list);
+       INIT_LIST_HEAD(&dd->remove_list);
+
        memset(dd->workq_name, 0, 32);
        snprintf(dd->workq_name, 31, "mtipq%d", dd->instance);
 
@@ -4305,6 +4412,14 @@ static int mtip_pci_probe(struct pci_dev *pdev,
        instance++;
        if (rv != MTIP_FTL_REBUILD_MAGIC)
                set_bit(MTIP_DDF_INIT_DONE_BIT, &dd->dd_flag);
+       else
+               rv = 0; /* device in rebuild state, return 0 from probe */
+
+       /* Add to online list even if in ftl rebuild */
+       spin_lock_irqsave(&dev_lock, flags);
+       list_add(&dd->online_list, &online_list);
+       spin_unlock_irqrestore(&dev_lock, flags);
+
        goto done;
 
 block_initialize_err:
@@ -4338,9 +4453,15 @@ static void mtip_pci_remove(struct pci_dev *pdev)
 {
        struct driver_data *dd = pci_get_drvdata(pdev);
        int counter = 0;
+       unsigned long flags;
 
        set_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag);
 
+       spin_lock_irqsave(&dev_lock, flags);
+       list_del_init(&dd->online_list);
+       list_add(&dd->remove_list, &removing_list);
+       spin_unlock_irqrestore(&dev_lock, flags);
+
        if (mtip_check_surprise_removal(pdev)) {
                while (!test_bit(MTIP_DDF_CLEANUP_BIT, &dd->dd_flag)) {
                        counter++;
@@ -4366,6 +4487,10 @@ static void mtip_pci_remove(struct pci_dev *pdev)
 
        pci_disable_msi(pdev);
 
+       spin_lock_irqsave(&dev_lock, flags);
+       list_del_init(&dd->remove_list);
+       spin_unlock_irqrestore(&dev_lock, flags);
+
        kfree(dd);
        pcim_iounmap_regions(pdev, 1 << MTIP_ABAR);
 }
@@ -4513,6 +4638,11 @@ static int __init mtip_init(void)
 
        pr_info(MTIP_DRV_NAME " Version " MTIP_DRV_VERSION "\n");
 
+       spin_lock_init(&dev_lock);
+
+       INIT_LIST_HEAD(&online_list);
+       INIT_LIST_HEAD(&removing_list);
+
        /* Allocate a major block device number to use with this driver. */
        error = register_blkdev(0, MTIP_DRV_NAME);
        if (error <= 0) {
@@ -4522,11 +4652,18 @@ static int __init mtip_init(void)
        }
        mtip_major = error;
 
-       if (!dfs_parent) {
-               dfs_parent = debugfs_create_dir("rssd", NULL);
-               if (IS_ERR_OR_NULL(dfs_parent)) {
-                       pr_warn("Error creating debugfs parent\n");
-                       dfs_parent = NULL;
+       dfs_parent = debugfs_create_dir("rssd", NULL);
+       if (IS_ERR_OR_NULL(dfs_parent)) {
+               pr_warn("Error creating debugfs parent\n");
+               dfs_parent = NULL;
+       }
+       if (dfs_parent) {
+               dfs_device_status = debugfs_create_file("device_status",
+                                       S_IRUGO, dfs_parent, NULL,
+                                       &mtip_device_status_fops);
+               if (IS_ERR_OR_NULL(dfs_device_status)) {
+                       pr_err("Error creating device_status node\n");
+                       dfs_device_status = NULL;
                }
        }
 
index 3bffff5f670cc66f55f01ca5953f9d47702468ac..8e8334c9dd0f08139c9061bfced2111fe661c208 100644 (file)
@@ -129,9 +129,9 @@ enum {
        MTIP_PF_EH_ACTIVE_BIT       = 1, /* error handling */
        MTIP_PF_SE_ACTIVE_BIT       = 2, /* secure erase */
        MTIP_PF_DM_ACTIVE_BIT       = 3, /* download microcde */
-       MTIP_PF_PAUSE_IO      = ((1 << MTIP_PF_IC_ACTIVE_BIT) | \
-                               (1 << MTIP_PF_EH_ACTIVE_BIT) | \
-                               (1 << MTIP_PF_SE_ACTIVE_BIT) | \
+       MTIP_PF_PAUSE_IO      = ((1 << MTIP_PF_IC_ACTIVE_BIT) |
+                               (1 << MTIP_PF_EH_ACTIVE_BIT) |
+                               (1 << MTIP_PF_SE_ACTIVE_BIT) |
                                (1 << MTIP_PF_DM_ACTIVE_BIT)),
 
        MTIP_PF_SVC_THD_ACTIVE_BIT  = 4,
@@ -144,9 +144,9 @@ enum {
        MTIP_DDF_REMOVE_PENDING_BIT = 1,
        MTIP_DDF_OVER_TEMP_BIT      = 2,
        MTIP_DDF_WRITE_PROTECT_BIT  = 3,
-       MTIP_DDF_STOP_IO      = ((1 << MTIP_DDF_REMOVE_PENDING_BIT) | \
-                               (1 << MTIP_DDF_SEC_LOCK_BIT) | \
-                               (1 << MTIP_DDF_OVER_TEMP_BIT) | \
+       MTIP_DDF_STOP_IO      = ((1 << MTIP_DDF_REMOVE_PENDING_BIT) |
+                               (1 << MTIP_DDF_SEC_LOCK_BIT) |
+                               (1 << MTIP_DDF_OVER_TEMP_BIT) |
                                (1 << MTIP_DDF_WRITE_PROTECT_BIT)),
 
        MTIP_DDF_CLEANUP_BIT        = 5,
@@ -180,7 +180,7 @@ struct mtip_work {
 
 #define MTIP_TRIM_TIMEOUT_MS           240000
 #define MTIP_MAX_TRIM_ENTRIES          8
-#define MTIP_MAX_TRIM_ENTRY_LEN        0xfff8
+#define MTIP_MAX_TRIM_ENTRY_LEN                0xfff8
 
 struct mtip_trim_entry {
        u32 lba;   /* starting lba of region */
@@ -501,6 +501,10 @@ struct driver_data {
        atomic_t irq_workers_active;
 
        int isr_binding;
+
+       struct list_head online_list; /* linkage for online list */
+
+       struct list_head remove_list; /* linkage for removing list */
 };
 
 #endif
index f556f8a8b3f9b476949c6133f39778c49502e380..b7b7a88d9f689cdd3697ac8074de1887e7d50c15 100644 (file)
@@ -1742,9 +1742,10 @@ static int rbd_img_request_submit(struct rbd_img_request *img_request)
        struct rbd_device *rbd_dev = img_request->rbd_dev;
        struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc;
        struct rbd_obj_request *obj_request;
+       struct rbd_obj_request *next_obj_request;
 
        dout("%s: img %p\n", __func__, img_request);
-       for_each_obj_request(img_request, obj_request) {
+       for_each_obj_request_safe(img_request, obj_request, next_obj_request) {
                int ret;
 
                obj_request->callback = rbd_img_obj_callback;
index e3f9a99b8522e41dd2a4005142ea396838f26bbf..d784650d14f0d113c5d852e47d9dd676741e3b4f 100644 (file)
@@ -373,26 +373,14 @@ static int hpet_mmap(struct file *file, struct vm_area_struct *vma)
        struct hpet_dev *devp;
        unsigned long addr;
 
-       if (((vma->vm_end - vma->vm_start) != PAGE_SIZE) || vma->vm_pgoff)
-               return -EINVAL;
-
        devp = file->private_data;
        addr = devp->hd_hpets->hp_hpet_phys;
 
        if (addr & (PAGE_SIZE - 1))
                return -ENOSYS;
 
-       vma->vm_flags |= VM_IO;
        vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
-
-       if (io_remap_pfn_range(vma, vma->vm_start, addr >> PAGE_SHIFT,
-                                       PAGE_SIZE, vma->vm_page_prot)) {
-               printk(KERN_ERR "%s: io_remap_pfn_range failed\n",
-                       __func__);
-               return -EAGAIN;
-       }
-
-       return 0;
+       return vm_iomap_memory(vma, addr, PAGE_SIZE);
 #else
        return -ENOSYS;
 #endif
index ad72922919ed79b181a83467dea455216676d56c..6133ef5cf671ba6caf7cf79c67c8afa903fdc23e 100644 (file)
@@ -502,7 +502,6 @@ static inline void intel_pstate_set_sample_time(struct cpudata *cpu)
 
        sample_time = cpu->pstate_policy->sample_rate_ms;
        delay = msecs_to_jiffies(sample_time);
-       delay -= jiffies % delay;
        mod_timer_pinned(&cpu->timer, jiffies + delay);
 }
 
index 8bc5fef07e7a797f7cdde6e8f3f15445afde4993..22c9063e012064a07fb114f5568e6dac23093bc7 100644 (file)
@@ -1750,7 +1750,7 @@ static struct platform_driver cryp_driver = {
        .shutdown = ux500_cryp_shutdown,
        .driver = {
                .owner = THIS_MODULE,
-               .name  = "cryp1"
+               .name  = "cryp1",
                .pm    = &ux500_cryp_pm,
        }
 };
index 6e13f262139a89acabf4c512ce8461d62e810a61..88cfc61329d20fb137a46ff852569bf8b567c60a 100644 (file)
@@ -310,8 +310,6 @@ static void atc_complete_all(struct at_dma_chan *atchan)
 
        dev_vdbg(chan2dev(&atchan->chan_common), "complete all\n");
 
-       BUG_ON(atc_chan_is_enabled(atchan));
-
        /*
         * Submit queued descriptors ASAP, i.e. before we go through
         * the completed ones.
@@ -368,6 +366,9 @@ static void atc_advance_work(struct at_dma_chan *atchan)
 {
        dev_vdbg(chan2dev(&atchan->chan_common), "advance_work\n");
 
+       if (atc_chan_is_enabled(atchan))
+               return;
+
        if (list_empty(&atchan->active_list) ||
            list_is_singular(&atchan->active_list)) {
                atc_complete_all(atchan);
@@ -1078,9 +1079,7 @@ static void atc_issue_pending(struct dma_chan *chan)
                return;
 
        spin_lock_irqsave(&atchan->lock, flags);
-       if (!atc_chan_is_enabled(atchan)) {
-               atc_advance_work(atchan);
-       }
+       atc_advance_work(atchan);
        spin_unlock_irqrestore(&atchan->lock, flags);
 }
 
index c4b4fd2acc42b8fc605ccc70a71907ab3668794c..08b43bf3715816951d23cc71dd49ca9b810b55f1 100644 (file)
@@ -276,12 +276,20 @@ static void omap_dma_issue_pending(struct dma_chan *chan)
 
        spin_lock_irqsave(&c->vc.lock, flags);
        if (vchan_issue_pending(&c->vc) && !c->desc) {
-               struct omap_dmadev *d = to_omap_dma_dev(chan->device);
-               spin_lock(&d->lock);
-               if (list_empty(&c->node))
-                       list_add_tail(&c->node, &d->pending);
-               spin_unlock(&d->lock);
-               tasklet_schedule(&d->task);
+               /*
+                * c->cyclic is used only by audio and in this case the DMA need
+                * to be started without delay.
+                */
+               if (!c->cyclic) {
+                       struct omap_dmadev *d = to_omap_dma_dev(chan->device);
+                       spin_lock(&d->lock);
+                       if (list_empty(&c->node))
+                               list_add_tail(&c->node, &d->pending);
+                       spin_unlock(&d->lock);
+                       tasklet_schedule(&d->task);
+               } else {
+                       omap_dma_start_desc(c);
+               }
        }
        spin_unlock_irqrestore(&c->vc.lock, flags);
 }
index 7181531227595475a907a4955b69324bb5c5e460..5dbc5946c4c3d9931585ac2440f64274f477fe02 100644 (file)
@@ -2882,7 +2882,7 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
 {
        struct dma_pl330_platdata *pdat;
        struct dma_pl330_dmac *pdmac;
-       struct dma_pl330_chan *pch;
+       struct dma_pl330_chan *pch, *_p;
        struct pl330_info *pi;
        struct dma_device *pd;
        struct resource *res;
@@ -2984,7 +2984,16 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
        ret = dma_async_device_register(pd);
        if (ret) {
                dev_err(&adev->dev, "unable to register DMAC\n");
-               goto probe_err2;
+               goto probe_err3;
+       }
+
+       if (adev->dev.of_node) {
+               ret = of_dma_controller_register(adev->dev.of_node,
+                                        of_dma_pl330_xlate, pdmac);
+               if (ret) {
+                       dev_err(&adev->dev,
+                       "unable to register DMA to the generic DT DMA helpers\n");
+               }
        }
 
        dev_info(&adev->dev,
@@ -2995,16 +3004,21 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
                pi->pcfg.data_bus_width / 8, pi->pcfg.num_chan,
                pi->pcfg.num_peri, pi->pcfg.num_events);
 
-       ret = of_dma_controller_register(adev->dev.of_node,
-                                        of_dma_pl330_xlate, pdmac);
-       if (ret) {
-               dev_err(&adev->dev,
-               "unable to register DMA to the generic DT DMA helpers\n");
-               goto probe_err2;
-       }
-
        return 0;
+probe_err3:
+       amba_set_drvdata(adev, NULL);
 
+       /* Idle the DMAC */
+       list_for_each_entry_safe(pch, _p, &pdmac->ddma.channels,
+                       chan.device_node) {
+
+               /* Remove the channel */
+               list_del(&pch->chan.device_node);
+
+               /* Flush the channel */
+               pl330_control(&pch->chan, DMA_TERMINATE_ALL, 0);
+               pl330_free_chan_resources(&pch->chan);
+       }
 probe_err2:
        pl330_del(pi);
 probe_err1:
@@ -3023,8 +3037,10 @@ static int pl330_remove(struct amba_device *adev)
        if (!pdmac)
                return 0;
 
-       of_dma_controller_free(adev->dev.of_node);
+       if (adev->dev.of_node)
+               of_dma_controller_free(adev->dev.of_node);
 
+       dma_async_device_unregister(&pdmac->ddma);
        amba_set_drvdata(adev, NULL);
 
        /* Idle the DMAC */
index 42c759a4d047f6754ddf8676a390d8d0dcdffafb..3e532002e4d1c01a3d21cd84c3a4a5e22e5e2440 100644 (file)
@@ -39,6 +39,7 @@ config FIRMWARE_MEMMAP
 config EFI_VARS
        tristate "EFI Variable Support via sysfs"
        depends on EFI
+       select UCS2_STRING
        default n
        help
          If you say Y here, you are able to get EFI (Extensible Firmware
index 7acafb80fd4c79b19b1c53551bb5e7e8612af707..182ce9471175870f3ce4c0ab14ad81ddcbb1f197 100644 (file)
@@ -80,6 +80,7 @@
 #include <linux/slab.h>
 #include <linux/pstore.h>
 #include <linux/ctype.h>
+#include <linux/ucs2_string.h>
 
 #include <linux/fs.h>
 #include <linux/ramfs.h>
@@ -172,51 +173,6 @@ static void efivar_update_sysfs_entries(struct work_struct *);
 static DECLARE_WORK(efivar_work, efivar_update_sysfs_entries);
 static bool efivar_wq_enabled = true;
 
-/* Return the number of unicode characters in data */
-static unsigned long
-utf16_strnlen(efi_char16_t *s, size_t maxlength)
-{
-       unsigned long length = 0;
-
-       while (*s++ != 0 && length < maxlength)
-               length++;
-       return length;
-}
-
-static inline unsigned long
-utf16_strlen(efi_char16_t *s)
-{
-       return utf16_strnlen(s, ~0UL);
-}
-
-/*
- * Return the number of bytes is the length of this string
- * Note: this is NOT the same as the number of unicode characters
- */
-static inline unsigned long
-utf16_strsize(efi_char16_t *data, unsigned long maxlength)
-{
-       return utf16_strnlen(data, maxlength/sizeof(efi_char16_t)) * sizeof(efi_char16_t);
-}
-
-static inline int
-utf16_strncmp(const efi_char16_t *a, const efi_char16_t *b, size_t len)
-{
-       while (1) {
-               if (len == 0)
-                       return 0;
-               if (*a < *b)
-                       return -1;
-               if (*a > *b)
-                       return 1;
-               if (*a == 0) /* implies *b == 0 */
-                       return 0;
-               a++;
-               b++;
-               len--;
-       }
-}
-
 static bool
 validate_device_path(struct efi_variable *var, int match, u8 *buffer,
                     unsigned long len)
@@ -268,7 +224,7 @@ validate_load_option(struct efi_variable *var, int match, u8 *buffer,
        u16 filepathlength;
        int i, desclength = 0, namelen;
 
-       namelen = utf16_strnlen(var->VariableName, sizeof(var->VariableName));
+       namelen = ucs2_strnlen(var->VariableName, sizeof(var->VariableName));
 
        /* Either "Boot" or "Driver" followed by four digits of hex */
        for (i = match; i < match+4; i++) {
@@ -291,7 +247,7 @@ validate_load_option(struct efi_variable *var, int match, u8 *buffer,
         * 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;
+       desclength = ucs2_strsize((efi_char16_t *)(buffer + 6), len - 6) + 2;
 
        /* Each boot entry must have a descriptor */
        if (!desclength)
@@ -436,24 +392,12 @@ static efi_status_t
 check_var_size_locked(struct efivars *efivars, u32 attributes,
                        unsigned long size)
 {
-       u64 storage_size, remaining_size, max_size;
-       efi_status_t status;
        const struct efivar_operations *fops = efivars->ops;
 
-       if (!efivars->ops->query_variable_info)
+       if (!efivars->ops->query_variable_store)
                return EFI_UNSUPPORTED;
 
-       status = fops->query_variable_info(attributes, &storage_size,
-                                          &remaining_size, &max_size);
-
-       if (status != EFI_SUCCESS)
-               return status;
-
-       if (!storage_size || size > remaining_size || size > max_size ||
-           (remaining_size - size) < (storage_size / 2))
-               return EFI_OUT_OF_RESOURCES;
-
-       return status;
+       return fops->query_variable_store(attributes, size);
 }
 
 
@@ -593,7 +537,7 @@ efivar_store_raw(struct efivar_entry *entry, const char *buf, size_t count)
        spin_lock_irq(&efivars->lock);
 
        status = check_var_size_locked(efivars, new_var->Attributes,
-              new_var->DataSize + utf16_strsize(new_var->VariableName, 1024));
+              new_var->DataSize + ucs2_strsize(new_var->VariableName, 1024));
 
        if (status == EFI_SUCCESS || status == EFI_UNSUPPORTED)
                status = efivars->ops->set_variable(new_var->VariableName,
@@ -771,7 +715,7 @@ static ssize_t efivarfs_file_write(struct file *file,
         * QueryVariableInfo() isn't supported by the firmware.
         */
 
-       varsize = datasize + utf16_strsize(var->var.VariableName, 1024);
+       varsize = datasize + ucs2_strsize(var->var.VariableName, 1024);
        status = check_var_size(efivars, attributes, varsize);
 
        if (status != EFI_SUCCESS) {
@@ -1223,7 +1167,7 @@ static int efivarfs_fill_super(struct super_block *sb, void *data, int silent)
 
                inode = NULL;
 
-               len = utf16_strlen(entry->var.VariableName);
+               len = ucs2_strlen(entry->var.VariableName);
 
                /* name, plus '-', plus GUID, plus NUL*/
                name = kmalloc(len + 1 + GUID_LEN + 1, GFP_ATOMIC);
@@ -1481,8 +1425,8 @@ static int efi_pstore_erase(enum pstore_type_id type, u64 id, int count,
 
                if (efi_guidcmp(entry->var.VendorGuid, vendor))
                        continue;
-               if (utf16_strncmp(entry->var.VariableName, efi_name,
-                                 utf16_strlen(efi_name))) {
+               if (ucs2_strncmp(entry->var.VariableName, efi_name,
+                                 ucs2_strlen(efi_name))) {
                        /*
                         * Check if an old format,
                         * which doesn't support holding
@@ -1494,8 +1438,8 @@ static int efi_pstore_erase(enum pstore_type_id type, u64 id, int count,
                        for (i = 0; i < DUMP_NAME_LEN; i++)
                                efi_name_old[i] = name_old[i];
 
-                       if (utf16_strncmp(entry->var.VariableName, efi_name_old,
-                                         utf16_strlen(efi_name_old)))
+                       if (ucs2_strncmp(entry->var.VariableName, efi_name_old,
+                                         ucs2_strlen(efi_name_old)))
                                continue;
                }
 
@@ -1573,8 +1517,8 @@ static ssize_t efivar_create(struct file *filp, struct kobject *kobj,
         * Does this variable already exist?
         */
        list_for_each_entry_safe(search_efivar, n, &efivars->list, list) {
-               strsize1 = utf16_strsize(search_efivar->var.VariableName, 1024);
-               strsize2 = utf16_strsize(new_var->VariableName, 1024);
+               strsize1 = ucs2_strsize(search_efivar->var.VariableName, 1024);
+               strsize2 = ucs2_strsize(new_var->VariableName, 1024);
                if (strsize1 == strsize2 &&
                        !memcmp(&(search_efivar->var.VariableName),
                                new_var->VariableName, strsize1) &&
@@ -1590,7 +1534,7 @@ static ssize_t efivar_create(struct file *filp, struct kobject *kobj,
        }
 
        status = check_var_size_locked(efivars, new_var->Attributes,
-              new_var->DataSize + utf16_strsize(new_var->VariableName, 1024));
+              new_var->DataSize + ucs2_strsize(new_var->VariableName, 1024));
 
        if (status && status != EFI_UNSUPPORTED) {
                spin_unlock_irq(&efivars->lock);
@@ -1614,7 +1558,7 @@ static ssize_t efivar_create(struct file *filp, struct kobject *kobj,
 
        /* Create the entry in sysfs.  Locking is not required here */
        status = efivar_create_sysfs_entry(efivars,
-                                          utf16_strsize(new_var->VariableName,
+                                          ucs2_strsize(new_var->VariableName,
                                                         1024),
                                           new_var->VariableName,
                                           &new_var->VendorGuid);
@@ -1644,8 +1588,8 @@ static ssize_t efivar_delete(struct file *filp, struct kobject *kobj,
         * Does this variable already exist?
         */
        list_for_each_entry_safe(search_efivar, n, &efivars->list, list) {
-               strsize1 = utf16_strsize(search_efivar->var.VariableName, 1024);
-               strsize2 = utf16_strsize(del_var->VariableName, 1024);
+               strsize1 = ucs2_strsize(search_efivar->var.VariableName, 1024);
+               strsize2 = ucs2_strsize(del_var->VariableName, 1024);
                if (strsize1 == strsize2 &&
                        !memcmp(&(search_efivar->var.VariableName),
                                del_var->VariableName, strsize1) &&
@@ -1691,9 +1635,9 @@ static bool variable_is_present(efi_char16_t *variable_name, efi_guid_t *vendor)
        unsigned long strsize1, strsize2;
        bool found = false;
 
-       strsize1 = utf16_strsize(variable_name, 1024);
+       strsize1 = ucs2_strsize(variable_name, 1024);
        list_for_each_entry_safe(entry, n, &efivars->list, list) {
-               strsize2 = utf16_strsize(entry->var.VariableName, 1024);
+               strsize2 = ucs2_strsize(entry->var.VariableName, 1024);
                if (strsize1 == strsize2 &&
                        !memcmp(variable_name, &(entry->var.VariableName),
                                strsize2) &&
@@ -2131,7 +2075,7 @@ efivars_init(void)
        ops.get_variable = efi.get_variable;
        ops.set_variable = efi.set_variable;
        ops.get_next_variable = efi.get_next_variable;
-       ops.query_variable_info = efi.query_variable_info;
+       ops.query_variable_store = efi_query_variable_store;
 
        error = register_efivars(&__efivars, &ops, efi_kobj);
        if (error)
index 24059462c87fb23f6481304ae8d1bf819c2785e4..9391cf16e990db6a46870004754df0983568bd8e 100644 (file)
@@ -575,7 +575,7 @@ static int pca953x_irq_setup(struct pca953x_chip *chip,
                                                chip->gpio_chip.ngpio,
                                                irq_base,
                                                &pca953x_irq_simple_ops,
-                                               NULL);
+                                               chip);
                if (!chip->domain)
                        return -ENODEV;
 
index 59d6b9bf204bbd2d76b8440b3f7d435def394fe7..892ff9f959754263eb318da91347cbfffcc25ae7 100644 (file)
@@ -1544,10 +1544,10 @@ int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper)
        if (!fb_helper->fb)
                return 0;
 
-       drm_modeset_lock_all(dev);
+       mutex_lock(&fb_helper->dev->mode_config.mutex);
        if (!drm_fb_helper_is_bound(fb_helper)) {
                fb_helper->delayed_hotplug = true;
-               drm_modeset_unlock_all(dev);
+               mutex_unlock(&fb_helper->dev->mode_config.mutex);
                return 0;
        }
        DRM_DEBUG_KMS("\n");
@@ -1558,9 +1558,11 @@ int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper)
 
        count = drm_fb_helper_probe_connector_modes(fb_helper, max_width,
                                                    max_height);
+       mutex_unlock(&fb_helper->dev->mode_config.mutex);
+
+       drm_modeset_lock_all(dev);
        drm_setup_crtcs(fb_helper);
        drm_modeset_unlock_all(dev);
-
        drm_fb_helper_set_par(fb_helper->fbdev);
 
        return 0;
index fe22bb780e1d048efc76e92d7296ab98f94294db..78d8e919509fb1e0a5b6df59d9782693593cbdae 100644 (file)
@@ -751,8 +751,6 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc,
        int i;
        unsigned char misc = 0;
        unsigned char ext_vga[6];
-       unsigned char ext_vga_index24;
-       unsigned char dac_index90 = 0;
        u8 bppshift;
 
        static unsigned char dacvalue[] = {
@@ -803,7 +801,6 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc,
                option2 = 0x0000b000;
                break;
        case G200_ER:
-               dac_index90 = 0;
                break;
        }
 
@@ -852,10 +849,8 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc,
                WREG_DAC(i, dacvalue[i]);
        }
 
-       if (mdev->type == G200_ER) {
-               WREG_DAC(0x90, dac_index90);
-       }
-
+       if (mdev->type == G200_ER)
+               WREG_DAC(0x90, 0);
 
        if (option)
                pci_write_config_dword(dev->pdev, PCI_MGA_OPTION, option);
@@ -952,8 +947,6 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc,
        if (mdev->type == G200_WB)
                ext_vga[1] |= 0x88;
 
-       ext_vga_index24 = 0x05;
-
        /* Set pixel clocks */
        misc = 0x2d;
        WREG8(MGA_MISC_OUT, misc);
@@ -965,7 +958,7 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc,
        }
 
        if (mdev->type == G200_ER)
-               WREG_ECRT(24, ext_vga_index24);
+               WREG_ECRT(0x24, 0x5);
 
        if (mdev->type == G200_EV) {
                WREG_ECRT(6, 0);
index 7f0e6c3f37d1fae4983bd6d8270364e52f00fc30..1ddc03e51bf47789b65992db64a3784cf0dad424 100644 (file)
@@ -479,7 +479,7 @@ nv50_display_flip_wait(void *data)
 {
        struct nv50_display_flip *flip = data;
        if (nouveau_bo_rd32(flip->disp->sync, flip->chan->addr / 4) ==
-                                             flip->chan->data);
+                                             flip->chan->data)
                return true;
        usleep_range(1, 2);
        return false;
index fe5cdbcf263605b7b5ec853b4d5f354f7c754b13..b44d548c56f8e43a3e14878622c8f8ed3507bf35 100644 (file)
@@ -61,6 +61,10 @@ static int udl_get_modes(struct drm_connector *connector)
        int ret;
 
        edid = (struct edid *)udl_get_edid(udl);
+       if (!edid) {
+               drm_mode_connector_update_edid_property(connector, NULL);
+               return 0;
+       }
 
        /*
         * We only read the main block, but if the monitor reports extension
index db713c0dfba4d6c6272ac19c79b793595a9cdad7..461a0d739d75b0d646d9197a89ed6852f932be07 100644 (file)
@@ -416,6 +416,8 @@ static int __hwspin_lock_request(struct hwspinlock *hwlock)
        ret = pm_runtime_get_sync(dev);
        if (ret < 0) {
                dev_err(dev, "%s: can't power on device\n", __func__);
+               pm_runtime_put_noidle(dev);
+               module_put(dev->driver->owner);
                return ret;
        }
 
index 5d66750138647d619d9521922a3d2c5421db73e4..1a38dd7dfe4e56c9b749cac1e741fe4ad092024c 100644 (file)
@@ -465,6 +465,7 @@ static const struct x86_cpu_id intel_idle_ids[] = {
        ICPU(0x3c, idle_cpu_hsw),
        ICPU(0x3f, idle_cpu_hsw),
        ICPU(0x45, idle_cpu_hsw),
+       ICPU(0x46, idle_cpu_hsw),
        {}
 };
 MODULE_DEVICE_TABLE(x86cpu, intel_idle_ids);
index 1daa97913b7d20068845865a405387404fffe1d8..0bfd8cf252002d4095dc699cf8277931b1ec00a0 100644 (file)
@@ -359,7 +359,7 @@ static int wacom_intuos_inout(struct wacom_wac *wacom)
                case 0x802: /* Intuos4 General Pen */
                case 0x804: /* Intuos4 Marker Pen */
                case 0x40802: /* Intuos4 Classic Pen */
-               case 0x18803: /* DTH2242 Grip Pen */
+               case 0x18802: /* DTH2242 Grip Pen */
                case 0x022:
                        wacom->tool[idx] = BTN_TOOL_PEN;
                        break;
@@ -1912,7 +1912,7 @@ static const struct wacom_features wacom_features_0xBB =
        { "Wacom Intuos4 12x19",  WACOM_PKGLEN_INTUOS,    97536, 60960, 2047,
          63, INTUOS4L, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
 static const struct wacom_features wacom_features_0xBC =
-       { "Wacom Intuos4 WL",     WACOM_PKGLEN_INTUOS,    40840, 25400, 2047,
+       { "Wacom Intuos4 WL",     WACOM_PKGLEN_INTUOS,    40640, 25400, 2047,
          63, INTUOS4, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
 static const struct wacom_features wacom_features_0x26 =
        { "Wacom Intuos5 touch S", WACOM_PKGLEN_INTUOS,  31496, 19685, 2047,
@@ -2144,7 +2144,7 @@ const struct usb_device_id wacom_ids[] = {
        { USB_DEVICE_WACOM(0x44) },
        { USB_DEVICE_WACOM(0x45) },
        { USB_DEVICE_WACOM(0x59) },
-       { USB_DEVICE_WACOM(0x5D) },
+       { USB_DEVICE_DETAILED(0x5D, USB_CLASS_HID, 0, 0) },
        { USB_DEVICE_WACOM(0xB0) },
        { USB_DEVICE_WACOM(0xB1) },
        { USB_DEVICE_WACOM(0xB2) },
@@ -2209,7 +2209,7 @@ const struct usb_device_id wacom_ids[] = {
        { USB_DEVICE_WACOM(0x47) },
        { USB_DEVICE_WACOM(0xF4) },
        { USB_DEVICE_WACOM(0xF8) },
-       { USB_DEVICE_WACOM(0xF6) },
+       { USB_DEVICE_DETAILED(0xF6, USB_CLASS_HID, 0, 0) },
        { USB_DEVICE_WACOM(0xFA) },
        { USB_DEVICE_LENOVO(0x6004) },
        { }
index a32e0d5aa45f43eb71c91ab9020696436212ae95..fc6aebf1e4b2630493b8e3ff89a2f76650019ef9 100644 (file)
@@ -236,7 +236,8 @@ static int gic_retrigger(struct irq_data *d)
        if (gic_arch_extn.irq_retrigger)
                return gic_arch_extn.irq_retrigger(d);
 
-       return -ENXIO;
+       /* the genirq layer expects 0 if we can't retrigger in hardware */
+       return 0;
 }
 
 #ifdef CONFIG_SMP
index 7e469260fe5eba5272ab56f74d9bd1c38fc2cfbf..9a0bdad9ad8fad49eaf8ee0d0ad916df247f0f3c 100644 (file)
@@ -611,6 +611,7 @@ static void dec_pending(struct dm_io *io, int error)
                        queue_io(md, bio);
                } else {
                        /* done with normal IO or empty flush */
+                       trace_block_bio_complete(md->queue, bio, io_error);
                        bio_endio(bio, io_error);
                }
        }
index 24909eb13fec1b0bf22e40caa4ff7a76967f80e4..f4e87bfc7567923944d2fce13da4c7d636479566 100644 (file)
@@ -184,6 +184,8 @@ static void return_io(struct bio *return_bi)
                return_bi = bi->bi_next;
                bi->bi_next = NULL;
                bi->bi_size = 0;
+               trace_block_bio_complete(bdev_get_queue(bi->bi_bdev),
+                                        bi, 0);
                bio_endio(bi, 0);
                bi = return_bi;
        }
@@ -3914,6 +3916,8 @@ static void raid5_align_endio(struct bio *bi, int error)
        rdev_dec_pending(rdev, conf->mddev);
 
        if (!error && uptodate) {
+               trace_block_bio_complete(bdev_get_queue(raid_bi->bi_bdev),
+                                        raid_bi, 0);
                bio_endio(raid_bi, 0);
                if (atomic_dec_and_test(&conf->active_aligned_reads))
                        wake_up(&conf->wait_for_stripe);
@@ -4382,6 +4386,8 @@ static void make_request(struct mddev *mddev, struct bio * bi)
                if ( rw == WRITE )
                        md_write_end(mddev);
 
+               trace_block_bio_complete(bdev_get_queue(bi->bi_bdev),
+                                        bi, 0);
                bio_endio(bi, 0);
        }
 }
@@ -4758,8 +4764,11 @@ static int  retry_aligned_read(struct r5conf *conf, struct bio *raid_bio)
                handled++;
        }
        remaining = raid5_dec_bi_active_stripes(raid_bio);
-       if (remaining == 0)
+       if (remaining == 0) {
+               trace_block_bio_complete(bdev_get_queue(raid_bio->bi_bdev),
+                                        raid_bio, 0);
                bio_endio(raid_bio, 0);
+       }
        if (atomic_dec_and_test(&conf->active_aligned_reads))
                wake_up(&conf->wait_for_stripe);
        return handled;
index 39c2ecadb273d374b41be572bee6431e7b81e784..ea98f7e9ccd19d6ef8ea862616bcc4c0f3055b8d 100644 (file)
@@ -4,7 +4,7 @@
 
 config VMWARE_VMCI
        tristate "VMware VMCI Driver"
-       depends on X86 && PCI
+       depends on X86 && PCI && NET
        help
          This is VMware's Virtual Machine Communication Interface.  It enables
          high-speed communication between host and guest in a virtual
index 92ab30ab00dcab1d0bc6405a94bbe3aeffcfb128..dc571ebc1aa0be8680f4a20397653e9d4a7f84cf 100644 (file)
@@ -1123,33 +1123,6 @@ static unsigned long mtdchar_get_unmapped_area(struct file *file,
 }
 #endif
 
-static inline unsigned long get_vm_size(struct vm_area_struct *vma)
-{
-       return vma->vm_end - vma->vm_start;
-}
-
-static inline resource_size_t get_vm_offset(struct vm_area_struct *vma)
-{
-       return (resource_size_t) vma->vm_pgoff << PAGE_SHIFT;
-}
-
-/*
- * Set a new vm offset.
- *
- * Verify that the incoming offset really works as a page offset,
- * and that the offset and size fit in a resource_size_t.
- */
-static inline int set_vm_offset(struct vm_area_struct *vma, resource_size_t off)
-{
-       pgoff_t pgoff = off >> PAGE_SHIFT;
-       if (off != (resource_size_t) pgoff << PAGE_SHIFT)
-               return -EINVAL;
-       if (off + get_vm_size(vma) - 1 < off)
-               return -EINVAL;
-       vma->vm_pgoff = pgoff;
-       return 0;
-}
-
 /*
  * set up a mapping for shared memory segments
  */
@@ -1159,45 +1132,17 @@ static int mtdchar_mmap(struct file *file, struct vm_area_struct *vma)
        struct mtd_file_info *mfi = file->private_data;
        struct mtd_info *mtd = mfi->mtd;
        struct map_info *map = mtd->priv;
-       resource_size_t start, off;
-       unsigned long len, vma_len;
 
         /* This is broken because it assumes the MTD device is map-based
           and that mtd->priv is a valid struct map_info.  It should be
           replaced with something that uses the mtd_get_unmapped_area()
           operation properly. */
        if (0 /*mtd->type == MTD_RAM || mtd->type == MTD_ROM*/) {
-               off = get_vm_offset(vma);
-               start = map->phys;
-               len = PAGE_ALIGN((start & ~PAGE_MASK) + map->size);
-               start &= PAGE_MASK;
-               vma_len = get_vm_size(vma);
-
-               /* Overflow in off+len? */
-               if (vma_len + off < off)
-                       return -EINVAL;
-               /* Does it fit in the mapping? */
-               if (vma_len + off > len)
-                       return -EINVAL;
-
-               off += start;
-               /* Did that overflow? */
-               if (off < start)
-                       return -EINVAL;
-               if (set_vm_offset(vma, off) < 0)
-                       return -EINVAL;
-               vma->vm_flags |= VM_IO | VM_DONTEXPAND | VM_DONTDUMP;
-
 #ifdef pgprot_noncached
-               if (file->f_flags & O_DSYNC || off >= __pa(high_memory))
+               if (file->f_flags & O_DSYNC || map->phys >= __pa(high_memory))
                        vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
 #endif
-               if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT,
-                                      vma->vm_end - vma->vm_start,
-                                      vma->vm_page_prot))
-                       return -EAGAIN;
-
-               return 0;
+               return vm_iomap_memory(vma, map->phys, map->size);
        }
        return -ENOSYS;
 #else
index 171b10f167a501a75fe8c7639c6d8dba0953f4b3..dbbea0eec134f1b2f0225161a33111264450f48e 100644 (file)
@@ -846,8 +846,10 @@ static void bond_mc_swap(struct bonding *bond, struct slave *new_active,
                if (bond->dev->flags & IFF_ALLMULTI)
                        dev_set_allmulti(old_active->dev, -1);
 
+               netif_addr_lock_bh(bond->dev);
                netdev_for_each_mc_addr(ha, bond->dev)
                        dev_mc_del(old_active->dev, ha->addr);
+               netif_addr_unlock_bh(bond->dev);
        }
 
        if (new_active) {
@@ -858,8 +860,10 @@ static void bond_mc_swap(struct bonding *bond, struct slave *new_active,
                if (bond->dev->flags & IFF_ALLMULTI)
                        dev_set_allmulti(new_active->dev, 1);
 
+               netif_addr_lock_bh(bond->dev);
                netdev_for_each_mc_addr(ha, bond->dev)
                        dev_mc_add(new_active->dev, ha->addr);
+               netif_addr_unlock_bh(bond->dev);
        }
 }
 
@@ -1901,11 +1905,29 @@ err_dest_symlinks:
        bond_destroy_slave_symlinks(bond_dev, slave_dev);
 
 err_detach:
+       if (!USES_PRIMARY(bond->params.mode)) {
+               netif_addr_lock_bh(bond_dev);
+               bond_mc_list_flush(bond_dev, slave_dev);
+               netif_addr_unlock_bh(bond_dev);
+       }
+       bond_del_vlans_from_slave(bond, slave_dev);
        write_lock_bh(&bond->lock);
        bond_detach_slave(bond, new_slave);
+       if (bond->primary_slave == new_slave)
+               bond->primary_slave = NULL;
        write_unlock_bh(&bond->lock);
+       if (bond->curr_active_slave == new_slave) {
+               read_lock(&bond->lock);
+               write_lock_bh(&bond->curr_slave_lock);
+               bond_change_active_slave(bond, NULL);
+               bond_select_active_slave(bond);
+               write_unlock_bh(&bond->curr_slave_lock);
+               read_unlock(&bond->lock);
+       }
+       slave_disable_netpoll(new_slave);
 
 err_close:
+       slave_dev->priv_flags &= ~IFF_BONDING;
        dev_close(slave_dev);
 
 err_unset_master:
@@ -3168,11 +3190,20 @@ static int bond_slave_netdev_event(unsigned long event,
                                   struct net_device *slave_dev)
 {
        struct slave *slave = bond_slave_get_rtnl(slave_dev);
-       struct bonding *bond = slave->bond;
-       struct net_device *bond_dev = slave->bond->dev;
+       struct bonding *bond;
+       struct net_device *bond_dev;
        u32 old_speed;
        u8 old_duplex;
 
+       /* A netdev event can be generated while enslaving a device
+        * before netdev_rx_handler_register is called in which case
+        * slave will be NULL
+        */
+       if (!slave)
+               return NOTIFY_DONE;
+       bond_dev = slave->bond->dev;
+       bond = slave->bond;
+
        switch (event) {
        case NETDEV_UNREGISTER:
                if (bond->setup_by_slave)
@@ -3286,20 +3317,22 @@ static int bond_xmit_hash_policy_l2(struct sk_buff *skb, int count)
  */
 static int bond_xmit_hash_policy_l23(struct sk_buff *skb, int count)
 {
-       struct ethhdr *data = (struct ethhdr *)skb->data;
-       struct iphdr *iph;
-       struct ipv6hdr *ipv6h;
+       const struct ethhdr *data;
+       const struct iphdr *iph;
+       const struct ipv6hdr *ipv6h;
        u32 v6hash;
-       __be32 *s, *d;
+       const __be32 *s, *d;
 
        if (skb->protocol == htons(ETH_P_IP) &&
-           skb_network_header_len(skb) >= sizeof(*iph)) {
+           pskb_network_may_pull(skb, sizeof(*iph))) {
                iph = ip_hdr(skb);
+               data = (struct ethhdr *)skb->data;
                return ((ntohl(iph->saddr ^ iph->daddr) & 0xffff) ^
                        (data->h_dest[5] ^ data->h_source[5])) % count;
        } else if (skb->protocol == htons(ETH_P_IPV6) &&
-                  skb_network_header_len(skb) >= sizeof(*ipv6h)) {
+                  pskb_network_may_pull(skb, sizeof(*ipv6h))) {
                ipv6h = ipv6_hdr(skb);
+               data = (struct ethhdr *)skb->data;
                s = &ipv6h->saddr.s6_addr32[0];
                d = &ipv6h->daddr.s6_addr32[0];
                v6hash = (s[1] ^ d[1]) ^ (s[2] ^ d[2]) ^ (s[3] ^ d[3]);
@@ -3318,33 +3351,36 @@ static int bond_xmit_hash_policy_l23(struct sk_buff *skb, int count)
 static int bond_xmit_hash_policy_l34(struct sk_buff *skb, int count)
 {
        u32 layer4_xor = 0;
-       struct iphdr *iph;
-       struct ipv6hdr *ipv6h;
-       __be32 *s, *d;
-       __be16 *layer4hdr;
+       const struct iphdr *iph;
+       const struct ipv6hdr *ipv6h;
+       const __be32 *s, *d;
+       const __be16 *l4 = NULL;
+       __be16 _l4[2];
+       int noff = skb_network_offset(skb);
+       int poff;
 
        if (skb->protocol == htons(ETH_P_IP) &&
-           skb_network_header_len(skb) >= sizeof(*iph)) {
+           pskb_may_pull(skb, noff + sizeof(*iph))) {
                iph = ip_hdr(skb);
-               if (!ip_is_fragment(iph) &&
-                   (iph->protocol == IPPROTO_TCP ||
-                    iph->protocol == IPPROTO_UDP) &&
-                   (skb_headlen(skb) - skb_network_offset(skb) >=
-                    iph->ihl * sizeof(u32) + sizeof(*layer4hdr) * 2)) {
-                       layer4hdr = (__be16 *)((u32 *)iph + iph->ihl);
-                       layer4_xor = ntohs(*layer4hdr ^ *(layer4hdr + 1));
+               poff = proto_ports_offset(iph->protocol);
+
+               if (!ip_is_fragment(iph) && poff >= 0) {
+                       l4 = skb_header_pointer(skb, noff + (iph->ihl << 2) + poff,
+                                               sizeof(_l4), &_l4);
+                       if (l4)
+                               layer4_xor = ntohs(l4[0] ^ l4[1]);
                }
                return (layer4_xor ^
                        ((ntohl(iph->saddr ^ iph->daddr)) & 0xffff)) % count;
        } else if (skb->protocol == htons(ETH_P_IPV6) &&
-                  skb_network_header_len(skb) >= sizeof(*ipv6h)) {
+                  pskb_may_pull(skb, noff + sizeof(*ipv6h))) {
                ipv6h = ipv6_hdr(skb);
-               if ((ipv6h->nexthdr == IPPROTO_TCP ||
-                    ipv6h->nexthdr == IPPROTO_UDP) &&
-                   (skb_headlen(skb) - skb_network_offset(skb) >=
-                    sizeof(*ipv6h) + sizeof(*layer4hdr) * 2)) {
-                       layer4hdr = (__be16 *)(ipv6h + 1);
-                       layer4_xor = ntohs(*layer4hdr ^ *(layer4hdr + 1));
+               poff = proto_ports_offset(ipv6h->nexthdr);
+               if (poff >= 0) {
+                       l4 = skb_header_pointer(skb, noff + sizeof(*ipv6h) + poff,
+                                               sizeof(_l4), &_l4);
+                       if (l4)
+                               layer4_xor = ntohs(l4[0] ^ l4[1]);
                }
                s = &ipv6h->saddr.s6_addr32[0];
                d = &ipv6h->daddr.s6_addr32[0];
@@ -4846,9 +4882,18 @@ static int __net_init bond_net_init(struct net *net)
 static void __net_exit bond_net_exit(struct net *net)
 {
        struct bond_net *bn = net_generic(net, bond_net_id);
+       struct bonding *bond, *tmp_bond;
+       LIST_HEAD(list);
 
        bond_destroy_sysfs(bn);
        bond_destroy_proc_dir(bn);
+
+       /* Kill off any bonds created after unregistering bond rtnl ops */
+       rtnl_lock();
+       list_for_each_entry_safe(bond, tmp_bond, &bn->dev_list, bond_list)
+               unregister_netdevice_queue(bond->dev, &list);
+       unregister_netdevice_many(&list);
+       rtnl_unlock();
 }
 
 static struct pernet_operations bond_net_ops = {
@@ -4902,8 +4947,8 @@ static void __exit bonding_exit(void)
 
        bond_destroy_debugfs();
 
-       unregister_pernet_subsys(&bond_net_ops);
        rtnl_link_unregister(&bond_link_ops);
+       unregister_pernet_subsys(&bond_net_ops);
 
 #ifdef CONFIG_NET_POLL_CONTROLLER
        /*
index f32b9fc6a983205151feabc8512e1fac5a7df88a..9aa0c64c33c81c9f296ed5f08b0d3666ee989816 100644 (file)
@@ -929,6 +929,7 @@ static int mcp251x_open(struct net_device *net)
        struct mcp251x_priv *priv = netdev_priv(net);
        struct spi_device *spi = priv->spi;
        struct mcp251x_platform_data *pdata = spi->dev.platform_data;
+       unsigned long flags;
        int ret;
 
        ret = open_candev(net);
@@ -945,9 +946,14 @@ static int mcp251x_open(struct net_device *net)
        priv->tx_skb = NULL;
        priv->tx_len = 0;
 
+       flags = IRQF_ONESHOT;
+       if (pdata->irq_flags)
+               flags |= pdata->irq_flags;
+       else
+               flags |= IRQF_TRIGGER_FALLING;
+
        ret = request_threaded_irq(spi->irq, NULL, mcp251x_can_ist,
-                 pdata->irq_flags ? pdata->irq_flags : IRQF_TRIGGER_FALLING,
-                 DEVICE_NAME, priv);
+                                  flags, DEVICE_NAME, priv);
        if (ret) {
                dev_err(&spi->dev, "failed to acquire irq %d\n", spi->irq);
                if (pdata->transceiver_enable)
index 6433b81256cdafd1cfe35fcc1a37d0a378411f59..8e0c4a0019397f61af74d44da1b60ca0c61032d2 100644 (file)
@@ -96,8 +96,8 @@ static int sja1000_ofp_probe(struct platform_device *ofdev)
        struct net_device *dev;
        struct sja1000_priv *priv;
        struct resource res;
-       const u32 *prop;
-       int err, irq, res_size, prop_size;
+       u32 prop;
+       int err, irq, res_size;
        void __iomem *base;
 
        err = of_address_to_resource(np, 0, &res);
@@ -138,27 +138,27 @@ static int sja1000_ofp_probe(struct platform_device *ofdev)
        priv->read_reg = sja1000_ofp_read_reg;
        priv->write_reg = sja1000_ofp_write_reg;
 
-       prop = of_get_property(np, "nxp,external-clock-frequency", &prop_size);
-       if (prop && (prop_size ==  sizeof(u32)))
-               priv->can.clock.freq = *prop / 2;
+       err = of_property_read_u32(np, "nxp,external-clock-frequency", &prop);
+       if (!err)
+               priv->can.clock.freq = prop / 2;
        else
                priv->can.clock.freq = SJA1000_OFP_CAN_CLOCK; /* default */
 
-       prop = of_get_property(np, "nxp,tx-output-mode", &prop_size);
-       if (prop && (prop_size == sizeof(u32)))
-               priv->ocr |= *prop & OCR_MODE_MASK;
+       err = of_property_read_u32(np, "nxp,tx-output-mode", &prop);
+       if (!err)
+               priv->ocr |= prop & OCR_MODE_MASK;
        else
                priv->ocr |= OCR_MODE_NORMAL; /* default */
 
-       prop = of_get_property(np, "nxp,tx-output-config", &prop_size);
-       if (prop && (prop_size == sizeof(u32)))
-               priv->ocr |= (*prop << OCR_TX_SHIFT) & OCR_TX_MASK;
+       err = of_property_read_u32(np, "nxp,tx-output-config", &prop);
+       if (!err)
+               priv->ocr |= (prop << OCR_TX_SHIFT) & OCR_TX_MASK;
        else
                priv->ocr |= OCR_TX0_PULLDOWN; /* default */
 
-       prop = of_get_property(np, "nxp,clock-out-frequency", &prop_size);
-       if (prop && (prop_size == sizeof(u32)) && *prop) {
-               u32 divider = priv->can.clock.freq * 2 / *prop;
+       err = of_property_read_u32(np, "nxp,clock-out-frequency", &prop);
+       if (!err && prop) {
+               u32 divider = priv->can.clock.freq * 2 / prop;
 
                if (divider > 1)
                        priv->cdr |= divider / 2 - 1;
@@ -168,8 +168,7 @@ static int sja1000_ofp_probe(struct platform_device *ofdev)
                priv->cdr |= CDR_CLK_OFF; /* default */
        }
 
-       prop = of_get_property(np, "nxp,no-comparator-bypass", NULL);
-       if (!prop)
+       if (!of_property_read_bool(np, "nxp,no-comparator-bypass"))
                priv->cdr |= CDR_CBP; /* default */
 
        priv->irq_flags = IRQF_SHARED;
index cab306a9888ea5a5ac0036058eaa0290968dbbec..e1d26433d61921b3e0460421212006bcb5e0e9ee 100644 (file)
@@ -828,7 +828,7 @@ static int ax_probe(struct platform_device *pdev)
        struct ei_device *ei_local;
        struct ax_device *ax;
        struct resource *irq, *mem, *mem2;
-       resource_size_t mem_size, mem2_size = 0;
+       unsigned long mem_size, mem2_size = 0;
        int ret = 0;
 
        dev = ax__alloc_ei_netdev(sizeof(struct ax_device));
index 4046f97378c29fa737d7123347ba1e940bd8e46d..57619dd4a92b0ef08ff0b990ae26db355bb732f3 100644 (file)
@@ -2614,6 +2614,9 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
                        }
                }
 
+               /* initialize FW coalescing state machines in RAM */
+               bnx2x_update_coalesce(bp);
+
                /* setup the leading queue */
                rc = bnx2x_setup_leading(bp);
                if (rc) {
@@ -4580,11 +4583,11 @@ static void storm_memset_hc_disable(struct bnx2x *bp, u8 port,
        u32 enable_flag = disable ? 0 : (1 << HC_INDEX_DATA_HC_ENABLED_SHIFT);
        u32 addr = BAR_CSTRORM_INTMEM +
                   CSTORM_STATUS_BLOCK_DATA_FLAGS_OFFSET(fw_sb_id, sb_index);
-       u16 flags = REG_RD16(bp, addr);
+       u8 flags = REG_RD8(bp, addr);
        /* clear and set */
        flags &= ~HC_INDEX_DATA_HC_ENABLED;
        flags |= enable_flag;
-       REG_WR16(bp, addr, flags);
+       REG_WR8(bp, addr, flags);
        DP(NETIF_MSG_IFUP,
           "port %x fw_sb_id %d sb_index %d disable %d\n",
           port, fw_sb_id, sb_index, disable);
index 77ebae0ac64aa9a4e681a506129c5a835d85ef4e..0283f343b0d1efd82be8f7fcb8b392823d0111e0 100644 (file)
@@ -13437,13 +13437,7 @@ static void bnx2x_check_kr2_wa(struct link_params *params,
 {
        struct bnx2x *bp = params->bp;
        u16 base_page, next_page, not_kr2_device, lane;
-       int sigdet = bnx2x_warpcore_get_sigdet(phy, params);
-
-       if (!sigdet) {
-               if (!(vars->link_attr_sync & LINK_ATTR_SYNC_KR2_ENABLE))
-                       bnx2x_kr2_recovery(params, vars, phy);
-               return;
-       }
+       int sigdet;
 
        /* Once KR2 was disabled, wait 5 seconds before checking KR2 recovery
         * since some switches tend to reinit the AN process and clear the
@@ -13454,6 +13448,16 @@ static void bnx2x_check_kr2_wa(struct link_params *params,
                vars->check_kr2_recovery_cnt--;
                return;
        }
+
+       sigdet = bnx2x_warpcore_get_sigdet(phy, params);
+       if (!sigdet) {
+               if (!(vars->link_attr_sync & LINK_ATTR_SYNC_KR2_ENABLE)) {
+                       bnx2x_kr2_recovery(params, vars, phy);
+                       DP(NETIF_MSG_LINK, "No sigdet\n");
+               }
+               return;
+       }
+
        lane = bnx2x_get_warpcore_lane(phy, params);
        CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_AER_BLOCK,
                          MDIO_AER_BLOCK_AER_REG, lane);
index e81a747ea8ce0ee4461fea92565fa32b15ea6682..c50696b396f1cb88196d4f682d61d902d0da9fc6 100644 (file)
@@ -4947,7 +4947,7 @@ static void bnx2x_after_function_update(struct bnx2x *bp)
                                  q);
        }
 
-       if (!NO_FCOE(bp)) {
+       if (!NO_FCOE(bp) && CNIC_ENABLED(bp)) {
                fp = &bp->fp[FCOE_IDX(bp)];
                queue_params.q_obj = &bnx2x_sp_obj(bp, fp).q_obj;
 
@@ -9878,6 +9878,10 @@ static int bnx2x_prev_unload_common(struct bnx2x *bp)
                                REG_RD(bp, NIG_REG_NIG_INT_STS_CLR_0);
                        }
                }
+               if (!CHIP_IS_E1x(bp))
+                       /* block FW from writing to host */
+                       REG_WR(bp, PGLUE_B_REG_INTERNAL_PFID_ENABLE_MASTER, 0);
+
                /* wait until BRB is empty */
                tmp_reg = REG_RD(bp, BRB1_REG_NUM_OF_FULL_BLOCKS);
                while (timer_count) {
@@ -13354,6 +13358,7 @@ static int bnx2x_unregister_cnic(struct net_device *dev)
        RCU_INIT_POINTER(bp->cnic_ops, NULL);
        mutex_unlock(&bp->cnic_mutex);
        synchronize_rcu();
+       bp->cnic_enabled = false;
        kfree(bp->cnic_kwq);
        bp->cnic_kwq = NULL;
 
index 08e54f3d288bc9a2e23faa8bb954dcb4bd8cf584..2886c9b63f9099059d3c8c0fe7a86cddc912854f 100644 (file)
@@ -759,8 +759,9 @@ static struct sk_buff *be_insert_vlan_in_pkt(struct be_adapter *adapter,
 
        if (vlan_tx_tag_present(skb)) {
                vlan_tag = be_get_tx_vlan_tag(adapter, skb);
-               __vlan_put_tag(skb, vlan_tag);
-               skb->vlan_tci = 0;
+               skb = __vlan_put_tag(skb, vlan_tag);
+               if (skb)
+                       skb->vlan_tci = 0;
        }
 
        return skb;
index f292c3aa423fbdeabb83ebdafa3b1699e988b19a..73195f643c9c3b23e45a0fac4008caa919473a25 100644 (file)
@@ -1002,6 +1002,7 @@ static void fec_enet_adjust_link(struct net_device *ndev)
        } else {
                if (fep->link) {
                        fec_stop(ndev);
+                       fep->link = phy_dev->link;
                        status_change = 1;
                }
        }
index ec800b093e7eb22536b7247289d13c0450b9552f..d2bea3f07c73782504dffef8862d5a77944c7290 100644 (file)
@@ -870,7 +870,7 @@ err_unlock:
 }
 
 static int e100_exec_cb(struct nic *nic, struct sk_buff *skb,
-       void (*cb_prepare)(struct nic *, struct cb *, struct sk_buff *))
+       int (*cb_prepare)(struct nic *, struct cb *, struct sk_buff *))
 {
        struct cb *cb;
        unsigned long flags;
@@ -888,10 +888,13 @@ static int e100_exec_cb(struct nic *nic, struct sk_buff *skb,
        nic->cbs_avail--;
        cb->skb = skb;
 
+       err = cb_prepare(nic, cb, skb);
+       if (err)
+               goto err_unlock;
+
        if (unlikely(!nic->cbs_avail))
                err = -ENOSPC;
 
-       cb_prepare(nic, cb, skb);
 
        /* Order is important otherwise we'll be in a race with h/w:
         * set S-bit in current first, then clear S-bit in previous. */
@@ -1091,7 +1094,7 @@ static void e100_get_defaults(struct nic *nic)
        nic->mii.mdio_write = mdio_write;
 }
 
-static void e100_configure(struct nic *nic, struct cb *cb, struct sk_buff *skb)
+static int e100_configure(struct nic *nic, struct cb *cb, struct sk_buff *skb)
 {
        struct config *config = &cb->u.config;
        u8 *c = (u8 *)config;
@@ -1181,6 +1184,7 @@ static void e100_configure(struct nic *nic, struct cb *cb, struct sk_buff *skb)
        netif_printk(nic, hw, KERN_DEBUG, nic->netdev,
                     "[16-23]=%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
                     c[16], c[17], c[18], c[19], c[20], c[21], c[22], c[23]);
+       return 0;
 }
 
 /*************************************************************************
@@ -1331,7 +1335,7 @@ static const struct firmware *e100_request_firmware(struct nic *nic)
        return fw;
 }
 
-static void e100_setup_ucode(struct nic *nic, struct cb *cb,
+static int e100_setup_ucode(struct nic *nic, struct cb *cb,
                             struct sk_buff *skb)
 {
        const struct firmware *fw = (void *)skb;
@@ -1358,6 +1362,7 @@ static void e100_setup_ucode(struct nic *nic, struct cb *cb,
        cb->u.ucode[min_size] |= cpu_to_le32((BUNDLESMALL) ? 0xFFFF : 0xFF80);
 
        cb->command = cpu_to_le16(cb_ucode | cb_el);
+       return 0;
 }
 
 static inline int e100_load_ucode_wait(struct nic *nic)
@@ -1400,18 +1405,20 @@ static inline int e100_load_ucode_wait(struct nic *nic)
        return err;
 }
 
-static void e100_setup_iaaddr(struct nic *nic, struct cb *cb,
+static int e100_setup_iaaddr(struct nic *nic, struct cb *cb,
        struct sk_buff *skb)
 {
        cb->command = cpu_to_le16(cb_iaaddr);
        memcpy(cb->u.iaaddr, nic->netdev->dev_addr, ETH_ALEN);
+       return 0;
 }
 
-static void e100_dump(struct nic *nic, struct cb *cb, struct sk_buff *skb)
+static int e100_dump(struct nic *nic, struct cb *cb, struct sk_buff *skb)
 {
        cb->command = cpu_to_le16(cb_dump);
        cb->u.dump_buffer_addr = cpu_to_le32(nic->dma_addr +
                offsetof(struct mem, dump_buf));
+       return 0;
 }
 
 static int e100_phy_check_without_mii(struct nic *nic)
@@ -1581,7 +1588,7 @@ static int e100_hw_init(struct nic *nic)
        return 0;
 }
 
-static void e100_multi(struct nic *nic, struct cb *cb, struct sk_buff *skb)
+static int e100_multi(struct nic *nic, struct cb *cb, struct sk_buff *skb)
 {
        struct net_device *netdev = nic->netdev;
        struct netdev_hw_addr *ha;
@@ -1596,6 +1603,7 @@ static void e100_multi(struct nic *nic, struct cb *cb, struct sk_buff *skb)
                memcpy(&cb->u.multi.addr[i++ * ETH_ALEN], &ha->addr,
                        ETH_ALEN);
        }
+       return 0;
 }
 
 static void e100_set_multicast_list(struct net_device *netdev)
@@ -1756,11 +1764,18 @@ static void e100_watchdog(unsigned long data)
                  round_jiffies(jiffies + E100_WATCHDOG_PERIOD));
 }
 
-static void e100_xmit_prepare(struct nic *nic, struct cb *cb,
+static int e100_xmit_prepare(struct nic *nic, struct cb *cb,
        struct sk_buff *skb)
 {
+       dma_addr_t dma_addr;
        cb->command = nic->tx_command;
 
+       dma_addr = pci_map_single(nic->pdev,
+                                 skb->data, skb->len, PCI_DMA_TODEVICE);
+       /* If we can't map the skb, have the upper layer try later */
+       if (pci_dma_mapping_error(nic->pdev, dma_addr))
+               return -ENOMEM;
+
        /*
         * Use the last 4 bytes of the SKB payload packet as the CRC, used for
         * testing, ie sending frames with bad CRC.
@@ -1777,11 +1792,10 @@ static void e100_xmit_prepare(struct nic *nic, struct cb *cb,
        cb->u.tcb.tcb_byte_count = 0;
        cb->u.tcb.threshold = nic->tx_threshold;
        cb->u.tcb.tbd_count = 1;
-       cb->u.tcb.tbd.buf_addr = cpu_to_le32(pci_map_single(nic->pdev,
-               skb->data, skb->len, PCI_DMA_TODEVICE));
-       /* check for mapping failure? */
+       cb->u.tcb.tbd.buf_addr = cpu_to_le32(dma_addr);
        cb->u.tcb.tbd.size = cpu_to_le16(skb->len);
        skb_tx_timestamp(skb);
+       return 0;
 }
 
 static netdev_tx_t e100_xmit_frame(struct sk_buff *skb,
index 25151401c2abe54dcec7fe1fe6f48791e0660a64..ab577a763a20d96cb68c151b8f3ceb483af6f8bf 100644 (file)
@@ -284,18 +284,10 @@ struct igb_q_vector {
 enum e1000_ring_flags_t {
        IGB_RING_FLAG_RX_SCTP_CSUM,
        IGB_RING_FLAG_RX_LB_VLAN_BSWAP,
-       IGB_RING_FLAG_RX_BUILD_SKB_ENABLED,
        IGB_RING_FLAG_TX_CTX_IDX,
        IGB_RING_FLAG_TX_DETECT_HANG
 };
 
-#define ring_uses_build_skb(ring) \
-       test_bit(IGB_RING_FLAG_RX_BUILD_SKB_ENABLED, &(ring)->flags)
-#define set_ring_build_skb_enabled(ring) \
-       set_bit(IGB_RING_FLAG_RX_BUILD_SKB_ENABLED, &(ring)->flags)
-#define clear_ring_build_skb_enabled(ring) \
-       clear_bit(IGB_RING_FLAG_RX_BUILD_SKB_ENABLED, &(ring)->flags)
-
 #define IGB_TXD_DCMD (E1000_ADVTXD_DCMD_EOP | E1000_ADVTXD_DCMD_RS)
 
 #define IGB_RX_DESC(R, i)          \
index 8496adfc6a685580f6ec1c50b86f0fed62b2b121..64f75291e3a5ca5402dfbee6dccb7a68bf1f1dd0 100644 (file)
@@ -3350,20 +3350,6 @@ void igb_configure_rx_ring(struct igb_adapter *adapter,
        wr32(E1000_RXDCTL(reg_idx), rxdctl);
 }
 
-static void igb_set_rx_buffer_len(struct igb_adapter *adapter,
-                                 struct igb_ring *rx_ring)
-{
-#define IGB_MAX_BUILD_SKB_SIZE \
-       (SKB_WITH_OVERHEAD(IGB_RX_BUFSZ) - \
-        (NET_SKB_PAD + NET_IP_ALIGN + IGB_TS_HDR_LEN))
-
-       /* set build_skb flag */
-       if (adapter->max_frame_size <= IGB_MAX_BUILD_SKB_SIZE)
-               set_ring_build_skb_enabled(rx_ring);
-       else
-               clear_ring_build_skb_enabled(rx_ring);
-}
-
 /**
  * igb_configure_rx - Configure receive Unit after Reset
  * @adapter: board private structure
@@ -3383,11 +3369,8 @@ static void igb_configure_rx(struct igb_adapter *adapter)
 
        /* Setup the HW Rx Head and Tail Descriptor Pointers and
         * the Base and Length of the Rx Descriptor Ring */
-       for (i = 0; i < adapter->num_rx_queues; i++) {
-               struct igb_ring *rx_ring = adapter->rx_ring[i];
-               igb_set_rx_buffer_len(adapter, rx_ring);
-               igb_configure_rx_ring(adapter, rx_ring);
-       }
+       for (i = 0; i < adapter->num_rx_queues; i++)
+               igb_configure_rx_ring(adapter, adapter->rx_ring[i]);
 }
 
 /**
@@ -6203,78 +6186,6 @@ static bool igb_add_rx_frag(struct igb_ring *rx_ring,
        return igb_can_reuse_rx_page(rx_buffer, page, truesize);
 }
 
-static struct sk_buff *igb_build_rx_buffer(struct igb_ring *rx_ring,
-                                          union e1000_adv_rx_desc *rx_desc)
-{
-       struct igb_rx_buffer *rx_buffer;
-       struct sk_buff *skb;
-       struct page *page;
-       void *page_addr;
-       unsigned int size = le16_to_cpu(rx_desc->wb.upper.length);
-#if (PAGE_SIZE < 8192)
-       unsigned int truesize = IGB_RX_BUFSZ;
-#else
-       unsigned int truesize = SKB_DATA_ALIGN(sizeof(struct skb_shared_info)) +
-                               SKB_DATA_ALIGN(NET_SKB_PAD +
-                                              NET_IP_ALIGN +
-                                              size);
-#endif
-
-       /* If we spanned a buffer we have a huge mess so test for it */
-       BUG_ON(unlikely(!igb_test_staterr(rx_desc, E1000_RXD_STAT_EOP)));
-
-       rx_buffer = &rx_ring->rx_buffer_info[rx_ring->next_to_clean];
-       page = rx_buffer->page;
-       prefetchw(page);
-
-       page_addr = page_address(page) + rx_buffer->page_offset;
-
-       /* prefetch first cache line of first page */
-       prefetch(page_addr + NET_SKB_PAD + NET_IP_ALIGN);
-#if L1_CACHE_BYTES < 128
-       prefetch(page_addr + L1_CACHE_BYTES + NET_SKB_PAD + NET_IP_ALIGN);
-#endif
-
-       /* build an skb to around the page buffer */
-       skb = build_skb(page_addr, truesize);
-       if (unlikely(!skb)) {
-               rx_ring->rx_stats.alloc_failed++;
-               return NULL;
-       }
-
-       /* we are reusing so sync this buffer for CPU use */
-       dma_sync_single_range_for_cpu(rx_ring->dev,
-                                     rx_buffer->dma,
-                                     rx_buffer->page_offset,
-                                     IGB_RX_BUFSZ,
-                                     DMA_FROM_DEVICE);
-
-       /* update pointers within the skb to store the data */
-       skb_reserve(skb, NET_IP_ALIGN + NET_SKB_PAD);
-       __skb_put(skb, size);
-
-       /* pull timestamp out of packet data */
-       if (igb_test_staterr(rx_desc, E1000_RXDADV_STAT_TSIP)) {
-               igb_ptp_rx_pktstamp(rx_ring->q_vector, skb->data, skb);
-               __skb_pull(skb, IGB_TS_HDR_LEN);
-       }
-
-       if (igb_can_reuse_rx_page(rx_buffer, page, truesize)) {
-               /* hand second half of page back to the ring */
-               igb_reuse_rx_page(rx_ring, rx_buffer);
-       } else {
-               /* we are not reusing the buffer so unmap it */
-               dma_unmap_page(rx_ring->dev, rx_buffer->dma,
-                              PAGE_SIZE, DMA_FROM_DEVICE);
-       }
-
-       /* clear contents of buffer_info */
-       rx_buffer->dma = 0;
-       rx_buffer->page = NULL;
-
-       return skb;
-}
-
 static struct sk_buff *igb_fetch_rx_buffer(struct igb_ring *rx_ring,
                                           union e1000_adv_rx_desc *rx_desc,
                                           struct sk_buff *skb)
@@ -6690,10 +6601,7 @@ static bool igb_clean_rx_irq(struct igb_q_vector *q_vector, const int budget)
                rmb();
 
                /* retrieve a buffer from the ring */
-               if (ring_uses_build_skb(rx_ring))
-                       skb = igb_build_rx_buffer(rx_ring, rx_desc);
-               else
-                       skb = igb_fetch_rx_buffer(rx_ring, rx_desc, skb);
+               skb = igb_fetch_rx_buffer(rx_ring, rx_desc, skb);
 
                /* exit if we failed to retrieve a buffer */
                if (!skb)
@@ -6780,14 +6688,6 @@ static bool igb_alloc_mapped_page(struct igb_ring *rx_ring,
        return true;
 }
 
-static inline unsigned int igb_rx_offset(struct igb_ring *rx_ring)
-{
-       if (ring_uses_build_skb(rx_ring))
-               return NET_SKB_PAD + NET_IP_ALIGN;
-       else
-               return 0;
-}
-
 /**
  * igb_alloc_rx_buffers - Replace used receive buffers; packet split
  * @adapter: address of board private structure
@@ -6814,9 +6714,7 @@ void igb_alloc_rx_buffers(struct igb_ring *rx_ring, u16 cleaned_count)
                 * Refresh the desc even if buffer_addrs didn't change
                 * because each write-back erases this info.
                 */
-               rx_desc->read.pkt_addr = cpu_to_le64(bi->dma +
-                                                    bi->page_offset +
-                                                    igb_rx_offset(rx_ring));
+               rx_desc->read.pkt_addr = cpu_to_le64(bi->dma + bi->page_offset);
 
                rx_desc++;
                bi++;
index d44b4d21268ceafb33cd47c636db2809db2542f8..97e33669c0b9b4c6e4bc105ab5f125dffabd9ee0 100644 (file)
@@ -1049,6 +1049,12 @@ int ixgbe_ndo_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan, u8 qos)
        if ((vf >= adapter->num_vfs) || (vlan > 4095) || (qos > 7))
                return -EINVAL;
        if (vlan || qos) {
+               if (adapter->vfinfo[vf].pf_vlan)
+                       err = ixgbe_set_vf_vlan(adapter, false,
+                                               adapter->vfinfo[vf].pf_vlan,
+                                               vf);
+               if (err)
+                       goto out;
                err = ixgbe_set_vf_vlan(adapter, true, vlan, vf);
                if (err)
                        goto out;
index edfba9370922f54632f96440d394772a9da9054b..434e33c527df102adf5052854bc92d816588b4ba 100644 (file)
@@ -33,6 +33,7 @@ config MV643XX_ETH
 
 config MVMDIO
        tristate "Marvell MDIO interface support"
+       select PHYLIB
        ---help---
          This driver supports the MDIO interface found in the network
          interface units of the Marvell EBU SoCs (Kirkwood, Orion5x,
@@ -45,7 +46,6 @@ config MVMDIO
 config MVNETA
        tristate "Marvell Armada 370/XP network interface support"
        depends on MACH_ARMADA_370_XP
-       select PHYLIB
        select MVMDIO
        ---help---
          This driver supports the network interface units in the
index cd345b8969bcaa75643a34da5819af5d569a1523..a47a097c21e13b1373fb6fa896374d8d6ffcd04c 100644 (file)
@@ -374,7 +374,6 @@ static int rxq_number = 8;
 static int txq_number = 8;
 
 static int rxq_def;
-static int txq_def;
 
 #define MVNETA_DRIVER_NAME "mvneta"
 #define MVNETA_DRIVER_VERSION "1.0"
@@ -1475,7 +1474,8 @@ error:
 static int mvneta_tx(struct sk_buff *skb, struct net_device *dev)
 {
        struct mvneta_port *pp = netdev_priv(dev);
-       struct mvneta_tx_queue *txq = &pp->txqs[txq_def];
+       u16 txq_id = skb_get_queue_mapping(skb);
+       struct mvneta_tx_queue *txq = &pp->txqs[txq_id];
        struct mvneta_tx_desc *tx_desc;
        struct netdev_queue *nq;
        int frags = 0;
@@ -1485,7 +1485,7 @@ static int mvneta_tx(struct sk_buff *skb, struct net_device *dev)
                goto out;
 
        frags = skb_shinfo(skb)->nr_frags + 1;
-       nq    = netdev_get_tx_queue(dev, txq_def);
+       nq    = netdev_get_tx_queue(dev, txq_id);
 
        /* Get a descriptor for the first part of the packet */
        tx_desc = mvneta_txq_next_desc_get(txq);
@@ -2689,7 +2689,7 @@ static int mvneta_probe(struct platform_device *pdev)
                return -EINVAL;
        }
 
-       dev = alloc_etherdev_mq(sizeof(struct mvneta_port), 8);
+       dev = alloc_etherdev_mqs(sizeof(struct mvneta_port), txq_number, rxq_number);
        if (!dev)
                return -ENOMEM;
 
@@ -2771,16 +2771,17 @@ static int mvneta_probe(struct platform_device *pdev)
 
        netif_napi_add(dev, &pp->napi, mvneta_poll, pp->weight);
 
+       dev->features = NETIF_F_SG | NETIF_F_IP_CSUM;
+       dev->hw_features |= NETIF_F_SG | NETIF_F_IP_CSUM;
+       dev->vlan_features |= NETIF_F_SG | NETIF_F_IP_CSUM;
+       dev->priv_flags |= IFF_UNICAST_FLT;
+
        err = register_netdev(dev);
        if (err < 0) {
                dev_err(&pdev->dev, "failed to register\n");
                goto err_deinit;
        }
 
-       dev->features = NETIF_F_SG | NETIF_F_IP_CSUM;
-       dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM;
-       dev->priv_flags |= IFF_UNICAST_FLT;
-
        netdev_info(dev, "mac: %pM\n", dev->dev_addr);
 
        platform_set_drvdata(pdev, pp->dev);
@@ -2843,4 +2844,3 @@ module_param(rxq_number, int, S_IRUGO);
 module_param(txq_number, int, S_IRUGO);
 
 module_param(rxq_def, int, S_IRUGO);
-module_param(txq_def, int, S_IRUGO);
index cd5ae8813cb3967537bc047a475db69329993736..edd63f1230f3d0076f9bfbdcff146f62a6c2acaa 100644 (file)
@@ -1500,6 +1500,12 @@ int qlcnic_83xx_loopback_test(struct net_device *netdev, u8 mode)
                }
        } while ((adapter->ahw->linkup && ahw->has_link_events) != 1);
 
+       /* Make sure carrier is off and queue is stopped during loopback */
+       if (netif_running(netdev)) {
+               netif_carrier_off(netdev);
+               netif_stop_queue(netdev);
+       }
+
        ret = qlcnic_do_lb_test(adapter, mode);
 
        qlcnic_83xx_clear_lb_mode(adapter, mode);
@@ -2780,6 +2786,7 @@ static u64 *qlcnic_83xx_fill_stats(struct qlcnic_adapter *adapter,
 void qlcnic_83xx_get_stats(struct qlcnic_adapter *adapter, u64 *data)
 {
        struct qlcnic_cmd_args cmd;
+       struct net_device *netdev = adapter->netdev;
        int ret = 0;
 
        qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_STATISTICS);
@@ -2789,7 +2796,7 @@ void qlcnic_83xx_get_stats(struct qlcnic_adapter *adapter, u64 *data)
        data = qlcnic_83xx_fill_stats(adapter, &cmd, data,
                                      QLC_83XX_STAT_TX, &ret);
        if (ret) {
-               dev_info(&adapter->pdev->dev, "Error getting MAC stats\n");
+               netdev_err(netdev, "Error getting Tx stats\n");
                goto out;
        }
        /* Get MAC stats */
@@ -2799,8 +2806,7 @@ void qlcnic_83xx_get_stats(struct qlcnic_adapter *adapter, u64 *data)
        data = qlcnic_83xx_fill_stats(adapter, &cmd, data,
                                      QLC_83XX_STAT_MAC, &ret);
        if (ret) {
-               dev_info(&adapter->pdev->dev,
-                        "Error getting Rx stats\n");
+               netdev_err(netdev, "Error getting MAC stats\n");
                goto out;
        }
        /* Get Rx stats */
@@ -2810,8 +2816,7 @@ void qlcnic_83xx_get_stats(struct qlcnic_adapter *adapter, u64 *data)
        data = qlcnic_83xx_fill_stats(adapter, &cmd, data,
                                      QLC_83XX_STAT_RX, &ret);
        if (ret)
-               dev_info(&adapter->pdev->dev,
-                        "Error getting Tx stats\n");
+               netdev_err(netdev, "Error getting Rx stats\n");
 out:
        qlcnic_free_mbx_args(&cmd);
 }
index 0e630061bff31b41192d4b8fc7978e2be839e274..5fa847fe388a9df3b7f78b44b63f72bffaaeeced 100644 (file)
@@ -358,8 +358,7 @@ set_flags:
                memcpy(&first_desc->eth_addr, skb->data, ETH_ALEN);
        }
        opcode = TX_ETHER_PKT;
-       if ((adapter->netdev->features & (NETIF_F_TSO | NETIF_F_TSO6)) &&
-           skb_shinfo(skb)->gso_size > 0) {
+       if (skb_is_gso(skb)) {
                hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
                first_desc->mss = cpu_to_le16(skb_shinfo(skb)->gso_size);
                first_desc->total_hdr_length = hdr_len;
index 987fb6f8adc3b34a1089b9e44de928de5fba0119..5ef328af61d0ab9fcbc1c098b323f444fbd63854 100644 (file)
@@ -200,10 +200,10 @@ beacon_err:
        }
 
        err = qlcnic_config_led(adapter, b_state, b_rate);
-       if (!err)
+       if (!err) {
                err = len;
-       else
                ahw->beacon_state = b_state;
+       }
 
        if (test_and_clear_bit(__QLCNIC_DIAG_RES_ALLOC, &adapter->state))
                qlcnic_diag_free_res(adapter->netdev, max_sds_rings);
index a131d7b5d2fe00e1f96997bef8f8afa54186aaa5..7e8d68263963aa5928f5ef1f145ad27624c14ce2 100644 (file)
@@ -18,7 +18,7 @@
  */
 #define DRV_NAME       "qlge"
 #define DRV_STRING     "QLogic 10 Gigabit PCI-E Ethernet Driver "
-#define DRV_VERSION    "v1.00.00.31"
+#define DRV_VERSION    "v1.00.00.32"
 
 #define WQ_ADDR_ALIGN  0x3     /* 4 byte alignment */
 
index 6f316ab23257dc7343776d92db05cc471561d681..0780e039b2718d902805414daeb6844b7d2086e7 100644 (file)
@@ -379,13 +379,13 @@ static int ql_get_settings(struct net_device *ndev,
 
        ecmd->supported = SUPPORTED_10000baseT_Full;
        ecmd->advertising = ADVERTISED_10000baseT_Full;
-       ecmd->autoneg = AUTONEG_ENABLE;
        ecmd->transceiver = XCVR_EXTERNAL;
        if ((qdev->link_status & STS_LINK_TYPE_MASK) ==
                                STS_LINK_TYPE_10GBASET) {
                ecmd->supported |= (SUPPORTED_TP | SUPPORTED_Autoneg);
                ecmd->advertising |= (ADVERTISED_TP | ADVERTISED_Autoneg);
                ecmd->port = PORT_TP;
+               ecmd->autoneg = AUTONEG_ENABLE;
        } else {
                ecmd->supported |= SUPPORTED_FIBRE;
                ecmd->advertising |= ADVERTISED_FIBRE;
index b13ab544a7eb56760063474b598163227f27942f..8033555e53c2f6f524211b4d848dcc13a0e14f78 100644 (file)
@@ -1434,11 +1434,13 @@ map_error:
 }
 
 /* Categorizing receive firmware frame errors */
-static void ql_categorize_rx_err(struct ql_adapter *qdev, u8 rx_err)
+static void ql_categorize_rx_err(struct ql_adapter *qdev, u8 rx_err,
+                                struct rx_ring *rx_ring)
 {
        struct nic_stats *stats = &qdev->nic_stats;
 
        stats->rx_err_count++;
+       rx_ring->rx_errors++;
 
        switch (rx_err & IB_MAC_IOCB_RSP_ERR_MASK) {
        case IB_MAC_IOCB_RSP_ERR_CODE_ERR:
@@ -1474,6 +1476,12 @@ static void ql_process_mac_rx_gro_page(struct ql_adapter *qdev,
        struct bq_desc *lbq_desc = ql_get_curr_lchunk(qdev, rx_ring);
        struct napi_struct *napi = &rx_ring->napi;
 
+       /* Frame error, so drop the packet. */
+       if (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_ERR_MASK) {
+               ql_categorize_rx_err(qdev, ib_mac_rsp->flags2, rx_ring);
+               put_page(lbq_desc->p.pg_chunk.page);
+               return;
+       }
        napi->dev = qdev->ndev;
 
        skb = napi_get_frags(napi);
@@ -1529,6 +1537,12 @@ static void ql_process_mac_rx_page(struct ql_adapter *qdev,
        addr = lbq_desc->p.pg_chunk.va;
        prefetch(addr);
 
+       /* Frame error, so drop the packet. */
+       if (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_ERR_MASK) {
+               ql_categorize_rx_err(qdev, ib_mac_rsp->flags2, rx_ring);
+               goto err_out;
+       }
+
        /* The max framesize filter on this chip is set higher than
         * MTU since FCoE uses 2k frames.
         */
@@ -1614,6 +1628,13 @@ static void ql_process_mac_rx_skb(struct ql_adapter *qdev,
        memcpy(skb_put(new_skb, length), skb->data, length);
        skb = new_skb;
 
+       /* Frame error, so drop the packet. */
+       if (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_ERR_MASK) {
+               ql_categorize_rx_err(qdev, ib_mac_rsp->flags2, rx_ring);
+               dev_kfree_skb_any(skb);
+               return;
+       }
+
        /* loopback self test for ethtool */
        if (test_bit(QL_SELFTEST, &qdev->flags)) {
                ql_check_lb_frame(qdev, skb);
@@ -1919,6 +1940,13 @@ static void ql_process_mac_split_rx_intr(struct ql_adapter *qdev,
                return;
        }
 
+       /* Frame error, so drop the packet. */
+       if (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_ERR_MASK) {
+               ql_categorize_rx_err(qdev, ib_mac_rsp->flags2, rx_ring);
+               dev_kfree_skb_any(skb);
+               return;
+       }
+
        /* The max framesize filter on this chip is set higher than
         * MTU since FCoE uses 2k frames.
         */
@@ -2000,12 +2028,6 @@ static unsigned long ql_process_mac_rx_intr(struct ql_adapter *qdev,
 
        QL_DUMP_IB_MAC_RSP(ib_mac_rsp);
 
-       /* Frame error, so drop the packet. */
-       if (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_ERR_MASK) {
-               ql_categorize_rx_err(qdev, ib_mac_rsp->flags2);
-               return (unsigned long)length;
-       }
-
        if (ib_mac_rsp->flags4 & IB_MAC_IOCB_RSP_HV) {
                /* The data and headers are split into
                 * separate buffers.
index 0c74a702d4610597da59200be253306c7b4db534..50617c5a0bdb5e63fc930f7af277a1a9fb139af4 100644 (file)
@@ -149,6 +149,7 @@ void dwmac_mmc_intr_all_mask(void __iomem *ioaddr)
 {
        writel(MMC_DEFAULT_MASK, ioaddr + MMC_RX_INTR_MASK);
        writel(MMC_DEFAULT_MASK, ioaddr + MMC_TX_INTR_MASK);
+       writel(MMC_DEFAULT_MASK, ioaddr + MMC_RX_IPC_INTR_MASK);
 }
 
 /* This reads the MAC core counters (if actaully supported).
index 80cad06e5eb21337b111bc32af0376e6da2d7065..4781d3d8e18204ad7fc11d06d102fd2eb6829da4 100644 (file)
@@ -1380,7 +1380,7 @@ static int cpsw_probe_dt(struct cpsw_platform_data *data,
                        memcpy(slave_data->mac_addr, mac_addr, ETH_ALEN);
 
                if (data->dual_emac) {
-                       if (of_property_read_u32(node, "dual_emac_res_vlan",
+                       if (of_property_read_u32(slave_node, "dual_emac_res_vlan",
                                                 &prop)) {
                                pr_err("Missing dual_emac_res_vlan in DT.\n");
                                slave_data->dual_emac_res_vlan = i+1;
index 1cd77483da50114c2c309ab70a69dff134c3a919..f5f0f09e4cc5e2160a9fc40c8fad83b5ab295287 100644 (file)
@@ -470,8 +470,10 @@ static void netvsc_send_completion(struct hv_device *device,
                        packet->trans_id;
 
                /* Notify the layer above us */
-               nvsc_packet->completion.send.send_completion(
-                       nvsc_packet->completion.send.send_completion_ctx);
+               if (nvsc_packet)
+                       nvsc_packet->completion.send.send_completion(
+                               nvsc_packet->completion.send.
+                               send_completion_ctx);
 
                num_outstanding_sends =
                        atomic_dec_return(&net_device->num_outstanding_sends);
@@ -498,6 +500,7 @@ int netvsc_send(struct hv_device *device,
        int ret = 0;
        struct nvsp_message sendMessage;
        struct net_device *ndev;
+       u64 req_id;
 
        net_device = get_outbound_net_device(device);
        if (!net_device)
@@ -518,20 +521,24 @@ int netvsc_send(struct hv_device *device,
                0xFFFFFFFF;
        sendMessage.msg.v1_msg.send_rndis_pkt.send_buf_section_size = 0;
 
+       if (packet->completion.send.send_completion)
+               req_id = (u64)packet;
+       else
+               req_id = 0;
+
        if (packet->page_buf_cnt) {
                ret = vmbus_sendpacket_pagebuffer(device->channel,
                                                  packet->page_buf,
                                                  packet->page_buf_cnt,
                                                  &sendMessage,
                                                  sizeof(struct nvsp_message),
-                                                 (unsigned long)packet);
+                                                 req_id);
        } else {
                ret = vmbus_sendpacket(device->channel, &sendMessage,
                                sizeof(struct nvsp_message),
-                               (unsigned long)packet,
+                               req_id,
                                VM_PKT_DATA_INBAND,
                                VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
-
        }
 
        if (ret == 0) {
index 5f85205cd12b81284ba7f23dfc89aa7ef50d3c10..8341b62e552166a4f796f7977b6f31a2b945bcdd 100644 (file)
@@ -241,13 +241,11 @@ void netvsc_linkstatus_callback(struct hv_device *device_obj,
 
        if (status == 1) {
                netif_carrier_on(net);
-               netif_wake_queue(net);
                ndev_ctx = netdev_priv(net);
                schedule_delayed_work(&ndev_ctx->dwork, 0);
                schedule_delayed_work(&ndev_ctx->dwork, msecs_to_jiffies(20));
        } else {
                netif_carrier_off(net);
-               netif_tx_disable(net);
        }
 }
 
index 2b657d4d63a8cc86950db8f50c805c3f96e017d1..0775f0aefd1e67715ab77750ac898660d3ca6267 100644 (file)
@@ -61,9 +61,6 @@ struct rndis_request {
 
 static void rndis_filter_send_completion(void *ctx);
 
-static void rndis_filter_send_request_completion(void *ctx);
-
-
 
 static struct rndis_device *get_rndis_device(void)
 {
@@ -241,10 +238,7 @@ static int rndis_filter_send_request(struct rndis_device *dev,
                        packet->page_buf[0].len;
        }
 
-       packet->completion.send.send_completion_ctx = req;/* packet; */
-       packet->completion.send.send_completion =
-               rndis_filter_send_request_completion;
-       packet->completion.send.send_completion_tid = (unsigned long)dev;
+       packet->completion.send.send_completion = NULL;
 
        ret = netvsc_send(dev->net_dev->dev, packet);
        return ret;
@@ -999,9 +993,3 @@ static void rndis_filter_send_completion(void *ctx)
        /* Pass it back to the original handler */
        filter_pkt->completion(filter_pkt->completion_ctx);
 }
-
-
-static void rndis_filter_send_request_completion(void *ctx)
-{
-       /* Noop */
-}
index b7c457adc0dc7439cc2a842409ed3871207f079b..729ed533bb33834fac05825be4b344a755e0e859 100644 (file)
@@ -1594,7 +1594,7 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
 
                if (tun->flags & TUN_TAP_MQ &&
                    (tun->numqueues + tun->numdisabled > 1))
-                       return err;
+                       return -EBUSY;
        }
        else {
                char *name;
index 16c842997291483eb12306d9ccf0a638772f18f0..6bd91676d2cbb9a46b43108ae1fa994d4fca84f9 100644 (file)
@@ -134,7 +134,7 @@ static struct sk_buff *cdc_mbim_tx_fixup(struct usbnet *dev, struct sk_buff *skb
                goto error;
 
        if (skb) {
-               if (skb->len <= sizeof(ETH_HLEN))
+               if (skb->len <= ETH_HLEN)
                        goto error;
 
                /* mapping VLANs to MBIM sessions:
index 968d5d50751dc120b406f54fffca49b46eafa230..2a3579f679103da7864260f114f98419852eaecd 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/module.h>
 #include <linux/netdevice.h>
 #include <linux/ethtool.h>
+#include <linux/etherdevice.h>
 #include <linux/mii.h>
 #include <linux/usb.h>
 #include <linux/usb/cdc.h>
@@ -52,6 +53,96 @@ struct qmi_wwan_state {
        struct usb_interface *data;
 };
 
+/* default ethernet address used by the modem */
+static const u8 default_modem_addr[ETH_ALEN] = {0x02, 0x50, 0xf3};
+
+/* Make up an ethernet header if the packet doesn't have one.
+ *
+ * A firmware bug common among several devices cause them to send raw
+ * IP packets under some circumstances.  There is no way for the
+ * driver/host to know when this will happen.  And even when the bug
+ * hits, some packets will still arrive with an intact header.
+ *
+ * The supported devices are only capably of sending IPv4, IPv6 and
+ * ARP packets on a point-to-point link. Any packet with an ethernet
+ * header will have either our address or a broadcast/multicast
+ * address as destination.  ARP packets will always have a header.
+ *
+ * This means that this function will reliably add the appropriate
+ * header iff necessary, provided our hardware address does not start
+ * with 4 or 6.
+ *
+ * Another common firmware bug results in all packets being addressed
+ * to 00:a0:c6:00:00:00 despite the host address being different.
+ * This function will also fixup such packets.
+ */
+static int qmi_wwan_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
+{
+       __be16 proto;
+
+       /* usbnet rx_complete guarantees that skb->len is at least
+        * hard_header_len, so we can inspect the dest address without
+        * checking skb->len
+        */
+       switch (skb->data[0] & 0xf0) {
+       case 0x40:
+               proto = htons(ETH_P_IP);
+               break;
+       case 0x60:
+               proto = htons(ETH_P_IPV6);
+               break;
+       case 0x00:
+               if (is_multicast_ether_addr(skb->data))
+                       return 1;
+               /* possibly bogus destination - rewrite just in case */
+               skb_reset_mac_header(skb);
+               goto fix_dest;
+       default:
+               /* pass along other packets without modifications */
+               return 1;
+       }
+       if (skb_headroom(skb) < ETH_HLEN)
+               return 0;
+       skb_push(skb, ETH_HLEN);
+       skb_reset_mac_header(skb);
+       eth_hdr(skb)->h_proto = proto;
+       memset(eth_hdr(skb)->h_source, 0, ETH_ALEN);
+fix_dest:
+       memcpy(eth_hdr(skb)->h_dest, dev->net->dev_addr, ETH_ALEN);
+       return 1;
+}
+
+/* very simplistic detection of IPv4 or IPv6 headers */
+static bool possibly_iphdr(const char *data)
+{
+       return (data[0] & 0xd0) == 0x40;
+}
+
+/* disallow addresses which may be confused with IP headers */
+static int qmi_wwan_mac_addr(struct net_device *dev, void *p)
+{
+       int ret;
+       struct sockaddr *addr = p;
+
+       ret = eth_prepare_mac_addr_change(dev, p);
+       if (ret < 0)
+               return ret;
+       if (possibly_iphdr(addr->sa_data))
+               return -EADDRNOTAVAIL;
+       eth_commit_mac_addr_change(dev, p);
+       return 0;
+}
+
+static const struct net_device_ops qmi_wwan_netdev_ops = {
+       .ndo_open               = usbnet_open,
+       .ndo_stop               = usbnet_stop,
+       .ndo_start_xmit         = usbnet_start_xmit,
+       .ndo_tx_timeout         = usbnet_tx_timeout,
+       .ndo_change_mtu         = usbnet_change_mtu,
+       .ndo_set_mac_address    = qmi_wwan_mac_addr,
+       .ndo_validate_addr      = eth_validate_addr,
+};
+
 /* using a counter to merge subdriver requests with our own into a combined state */
 static int qmi_wwan_manage_power(struct usbnet *dev, int on)
 {
@@ -229,6 +320,18 @@ next_desc:
                usb_driver_release_interface(driver, info->data);
        }
 
+       /* Never use the same address on both ends of the link, even
+        * if the buggy firmware told us to.
+        */
+       if (!compare_ether_addr(dev->net->dev_addr, default_modem_addr))
+               eth_hw_addr_random(dev->net);
+
+       /* make MAC addr easily distinguishable from an IP header */
+       if (possibly_iphdr(dev->net->dev_addr)) {
+               dev->net->dev_addr[0] |= 0x02;  /* set local assignment bit */
+               dev->net->dev_addr[0] &= 0xbf;  /* clear "IP" bit */
+       }
+       dev->net->netdev_ops = &qmi_wwan_netdev_ops;
 err:
        return status;
 }
@@ -307,6 +410,7 @@ static const struct driver_info     qmi_wwan_info = {
        .bind           = qmi_wwan_bind,
        .unbind         = qmi_wwan_unbind,
        .manage_power   = qmi_wwan_manage_power,
+       .rx_fixup       = qmi_wwan_rx_fixup,
 };
 
 #define HUAWEI_VENDOR_ID       0x12D1
index 28fd99203f6447e4d3545b0fd12b920733ffc10c..bdee2ed67219b6e1c56a0f03a6a28391ba3283aa 100644 (file)
@@ -519,7 +519,7 @@ static const u32 ar9580_1p0_mac_core[][2] = {
        {0x00008258, 0x00000000},
        {0x0000825c, 0x40000000},
        {0x00008260, 0x00080922},
-       {0x00008264, 0x9bc00010},
+       {0x00008264, 0x9d400010},
        {0x00008268, 0xffffffff},
        {0x0000826c, 0x0000ffff},
        {0x00008270, 0x00000000},
index 467b60014b7b73720b25440c584ae9a49c968bcc..73fe8d6db566789ad2c6f34021d607c48a380855 100644 (file)
@@ -143,14 +143,14 @@ channel_detector_create(struct dfs_pattern_detector *dpd, u16 freq)
        u32 sz, i;
        struct channel_detector *cd;
 
-       cd = kmalloc(sizeof(*cd), GFP_KERNEL);
+       cd = kmalloc(sizeof(*cd), GFP_ATOMIC);
        if (cd == NULL)
                goto fail;
 
        INIT_LIST_HEAD(&cd->head);
        cd->freq = freq;
        sz = sizeof(cd->detectors) * dpd->num_radar_types;
-       cd->detectors = kzalloc(sz, GFP_KERNEL);
+       cd->detectors = kzalloc(sz, GFP_ATOMIC);
        if (cd->detectors == NULL)
                goto fail;
 
index 91b8dceeadb10ef6c9f84d20f4a5bba6cd1500dd..5e48c5515b8ccc0b59fac41844fd4a0a7c41883e 100644 (file)
@@ -218,7 +218,7 @@ static bool pulse_queue_enqueue(struct pri_detector *pde, u64 ts)
 {
        struct pulse_elem *p = pool_get_pulse_elem();
        if (p == NULL) {
-               p = kmalloc(sizeof(*p), GFP_KERNEL);
+               p = kmalloc(sizeof(*p), GFP_ATOMIC);
                if (p == NULL) {
                        DFS_POOL_STAT_INC(pulse_alloc_error);
                        return false;
@@ -299,7 +299,7 @@ static bool pseq_handler_create_sequences(struct pri_detector *pde,
                ps.deadline_ts = ps.first_ts + ps.dur;
                new_ps = pool_get_pseq_elem();
                if (new_ps == NULL) {
-                       new_ps = kmalloc(sizeof(*new_ps), GFP_KERNEL);
+                       new_ps = kmalloc(sizeof(*new_ps), GFP_ATOMIC);
                        if (new_ps == NULL) {
                                DFS_POOL_STAT_INC(pseq_alloc_error);
                                return false;
index 716058b675571b32c6693656dafeb567868b25cb..a47f5e05fc04835d6b747b8ba4553c91d6614178 100644 (file)
@@ -796,7 +796,7 @@ static int ath9k_init_firmware_version(struct ath9k_htc_priv *priv)
         * required version.
         */
        if (priv->fw_version_major != MAJOR_VERSION_REQ ||
-           priv->fw_version_minor != MINOR_VERSION_REQ) {
+           priv->fw_version_minor < MINOR_VERSION_REQ) {
                dev_err(priv->dev, "ath9k_htc: Please upgrade to FW version %d.%d\n",
                        MAJOR_VERSION_REQ, MINOR_VERSION_REQ);
                return -EINVAL;
index 6e66f9c6782b966ac249b4bd31ecc25e6a9456b2..988372d218a4dd24015a1b19d104839fab8f0080 100644 (file)
@@ -280,6 +280,10 @@ static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan)
        if (r) {
                ath_err(common,
                        "Unable to reset channel, reset status %d\n", r);
+
+               ath9k_hw_enable_interrupts(ah);
+               ath9k_queue_reset(sc, RESET_TYPE_BB_HANG);
+
                goto out;
        }
 
index e8486c1e091af2f2db2a23827dc612315398751b..b70f220bc4b378e626a59752fca5bce965456340 100644 (file)
@@ -5165,7 +5165,8 @@ static void b43_nphy_pmu_spur_avoid(struct b43_wldev *dev, bool avoid)
 #endif
 #ifdef CONFIG_B43_SSB
        case B43_BUS_SSB:
-               /* FIXME */
+               ssb_pmu_spuravoid_pllupdate(&dev->dev->sdev->bus->chipco,
+                                           avoid);
                break;
 #endif
        }
index 4469321c0eb3ea3924f68b02ff6863516ec9b333..35fc68be158d5b548e5c273ee85f7e3bf057a162 100644 (file)
@@ -3317,15 +3317,15 @@ static int _brcmf_sdbrcm_download_firmware(struct brcmf_sdio *bus)
                goto err;
        }
 
-       /* External image takes precedence if specified */
        if (brcmf_sdbrcm_download_code_file(bus)) {
                brcmf_err("dongle image file download failed\n");
                goto err;
        }
 
-       /* External nvram takes precedence if specified */
-       if (brcmf_sdbrcm_download_nvram(bus))
+       if (brcmf_sdbrcm_download_nvram(bus)) {
                brcmf_err("dongle nvram file download failed\n");
+               goto err;
+       }
 
        /* Take arm out of reset */
        if (brcmf_sdbrcm_download_state(bus, false)) {
index 2af9c0f0798d9e5cc2e484b0599a7d50aede68e5..78da3eff75e8a1c5c126a60aab7bc90d7663a314 100644 (file)
@@ -1891,8 +1891,10 @@ static s32
 brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev,
              u8 key_idx, const u8 *mac_addr, struct key_params *params)
 {
+       struct brcmf_if *ifp = netdev_priv(ndev);
        struct brcmf_wsec_key key;
        s32 err = 0;
+       u8 keybuf[8];
 
        memset(&key, 0, sizeof(key));
        key.index = (u32) key_idx;
@@ -1916,8 +1918,9 @@ brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev,
                brcmf_dbg(CONN, "Setting the key index %d\n", key.index);
                memcpy(key.data, params->key, key.len);
 
-               if (params->cipher == WLAN_CIPHER_SUITE_TKIP) {
-                       u8 keybuf[8];
+               if ((ifp->vif->mode != WL_MODE_AP) &&
+                   (params->cipher == WLAN_CIPHER_SUITE_TKIP)) {
+                       brcmf_dbg(CONN, "Swapping RX/TX MIC key\n");
                        memcpy(keybuf, &key.data[24], sizeof(keybuf));
                        memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
                        memcpy(&key.data[16], keybuf, sizeof(keybuf));
@@ -2013,7 +2016,7 @@ brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
                break;
        case WLAN_CIPHER_SUITE_TKIP:
                if (ifp->vif->mode != WL_MODE_AP) {
-                       brcmf_dbg(CONN, "Swapping key\n");
+                       brcmf_dbg(CONN, "Swapping RX/TX MIC key\n");
                        memcpy(keybuf, &key.data[24], sizeof(keybuf));
                        memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
                        memcpy(&key.data[16], keybuf, sizeof(keybuf));
@@ -2118,8 +2121,7 @@ brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
                err = -EAGAIN;
                goto done;
        }
-       switch (wsec & ~SES_OW_ENABLED) {
-       case WEP_ENABLED:
+       if (wsec & WEP_ENABLED) {
                sec = &profile->sec;
                if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) {
                        params.cipher = WLAN_CIPHER_SUITE_WEP40;
@@ -2128,16 +2130,13 @@ brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
                        params.cipher = WLAN_CIPHER_SUITE_WEP104;
                        brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
                }
-               break;
-       case TKIP_ENABLED:
+       } else if (wsec & TKIP_ENABLED) {
                params.cipher = WLAN_CIPHER_SUITE_TKIP;
                brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n");
-               break;
-       case AES_ENABLED:
+       } else if (wsec & AES_ENABLED) {
                params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
                brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n");
-               break;
-       default:
+       } else  {
                brcmf_err("Invalid algo (0x%x)\n", wsec);
                err = -EINVAL;
                goto done;
@@ -3824,8 +3823,9 @@ exit:
 static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
 {
        struct brcmf_if *ifp = netdev_priv(ndev);
-       s32 err = -EPERM;
+       s32 err;
        struct brcmf_fil_bss_enable_le bss_enable;
+       struct brcmf_join_params join_params;
 
        brcmf_dbg(TRACE, "Enter\n");
 
@@ -3833,16 +3833,21 @@ static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
                /* Due to most likely deauths outstanding we sleep */
                /* first to make sure they get processed by fw. */
                msleep(400);
-               err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 0);
-               if (err < 0) {
-                       brcmf_err("setting AP mode failed %d\n", err);
-                       goto exit;
-               }
+
+               memset(&join_params, 0, sizeof(join_params));
+               err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
+                                            &join_params, sizeof(join_params));
+               if (err < 0)
+                       brcmf_err("SET SSID error (%d)\n", err);
                err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 0);
-               if (err < 0) {
+               if (err < 0)
                        brcmf_err("BRCMF_C_UP error %d\n", err);
-                       goto exit;
-               }
+               err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 0);
+               if (err < 0)
+                       brcmf_err("setting AP mode failed %d\n", err);
+               err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, 0);
+               if (err < 0)
+                       brcmf_err("setting INFRA mode failed %d\n", err);
        } else {
                bss_enable.bsscfg_idx = cpu_to_le32(ifp->bssidx);
                bss_enable.enable = cpu_to_le32(0);
@@ -3855,7 +3860,6 @@ static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
        set_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state);
        clear_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
 
-exit:
        return err;
 }
 
@@ -4122,10 +4126,6 @@ static const struct ieee80211_iface_limit brcmf_iface_limits[] = {
                         BIT(NL80211_IFTYPE_ADHOC) |
                         BIT(NL80211_IFTYPE_AP)
        },
-       {
-               .max = 1,
-               .types = BIT(NL80211_IFTYPE_P2P_DEVICE)
-       },
        {
                .max = 1,
                .types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
@@ -4183,8 +4183,7 @@ static struct wiphy *brcmf_setup_wiphy(struct device *phydev)
                                 BIT(NL80211_IFTYPE_ADHOC) |
                                 BIT(NL80211_IFTYPE_AP) |
                                 BIT(NL80211_IFTYPE_P2P_CLIENT) |
-                                BIT(NL80211_IFTYPE_P2P_GO) |
-                                BIT(NL80211_IFTYPE_P2P_DEVICE);
+                                BIT(NL80211_IFTYPE_P2P_GO);
        wiphy->iface_combinations = brcmf_iface_combos;
        wiphy->n_iface_combinations = ARRAY_SIZE(brcmf_iface_combos);
        wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
index c6451c61407a8c4510c97056bde23ef1ee88c060..e2340b231aa163cfba03f8b8f90c0822003a385d 100644 (file)
@@ -274,6 +274,130 @@ static void brcms_set_basic_rate(struct brcm_rateset *rs, u16 rate, bool is_br)
        }
 }
 
+/**
+ * This function frees the WL per-device resources.
+ *
+ * This function frees resources owned by the WL device pointed to
+ * by the wl parameter.
+ *
+ * precondition: can both be called locked and unlocked
+ *
+ */
+static void brcms_free(struct brcms_info *wl)
+{
+       struct brcms_timer *t, *next;
+
+       /* free ucode data */
+       if (wl->fw.fw_cnt)
+               brcms_ucode_data_free(&wl->ucode);
+       if (wl->irq)
+               free_irq(wl->irq, wl);
+
+       /* kill dpc */
+       tasklet_kill(&wl->tasklet);
+
+       if (wl->pub) {
+               brcms_debugfs_detach(wl->pub);
+               brcms_c_module_unregister(wl->pub, "linux", wl);
+       }
+
+       /* free common resources */
+       if (wl->wlc) {
+               brcms_c_detach(wl->wlc);
+               wl->wlc = NULL;
+               wl->pub = NULL;
+       }
+
+       /* virtual interface deletion is deferred so we cannot spinwait */
+
+       /* wait for all pending callbacks to complete */
+       while (atomic_read(&wl->callbacks) > 0)
+               schedule();
+
+       /* free timers */
+       for (t = wl->timers; t; t = next) {
+               next = t->next;
+#ifdef DEBUG
+               kfree(t->name);
+#endif
+               kfree(t);
+       }
+}
+
+/*
+* called from both kernel as from this kernel module (error flow on attach)
+* precondition: perimeter lock is not acquired.
+*/
+static void brcms_remove(struct bcma_device *pdev)
+{
+       struct ieee80211_hw *hw = bcma_get_drvdata(pdev);
+       struct brcms_info *wl = hw->priv;
+
+       if (wl->wlc) {
+               wiphy_rfkill_set_hw_state(wl->pub->ieee_hw->wiphy, false);
+               wiphy_rfkill_stop_polling(wl->pub->ieee_hw->wiphy);
+               ieee80211_unregister_hw(hw);
+       }
+
+       brcms_free(wl);
+
+       bcma_set_drvdata(pdev, NULL);
+       ieee80211_free_hw(hw);
+}
+
+/*
+ * Precondition: Since this function is called in brcms_pci_probe() context,
+ * no locking is required.
+ */
+static void brcms_release_fw(struct brcms_info *wl)
+{
+       int i;
+       for (i = 0; i < MAX_FW_IMAGES; i++) {
+               release_firmware(wl->fw.fw_bin[i]);
+               release_firmware(wl->fw.fw_hdr[i]);
+       }
+}
+
+/*
+ * Precondition: Since this function is called in brcms_pci_probe() context,
+ * no locking is required.
+ */
+static int brcms_request_fw(struct brcms_info *wl, struct bcma_device *pdev)
+{
+       int status;
+       struct device *device = &pdev->dev;
+       char fw_name[100];
+       int i;
+
+       memset(&wl->fw, 0, sizeof(struct brcms_firmware));
+       for (i = 0; i < MAX_FW_IMAGES; i++) {
+               if (brcms_firmwares[i] == NULL)
+                       break;
+               sprintf(fw_name, "%s-%d.fw", brcms_firmwares[i],
+                       UCODE_LOADER_API_VER);
+               status = request_firmware(&wl->fw.fw_bin[i], fw_name, device);
+               if (status) {
+                       wiphy_err(wl->wiphy, "%s: fail to load firmware %s\n",
+                                 KBUILD_MODNAME, fw_name);
+                       return status;
+               }
+               sprintf(fw_name, "%s_hdr-%d.fw", brcms_firmwares[i],
+                       UCODE_LOADER_API_VER);
+               status = request_firmware(&wl->fw.fw_hdr[i], fw_name, device);
+               if (status) {
+                       wiphy_err(wl->wiphy, "%s: fail to load firmware %s\n",
+                                 KBUILD_MODNAME, fw_name);
+                       return status;
+               }
+               wl->fw.hdr_num_entries[i] =
+                   wl->fw.fw_hdr[i]->size / (sizeof(struct firmware_hdr));
+       }
+       wl->fw.fw_cnt = i;
+       status = brcms_ucode_data_init(wl, &wl->ucode);
+       brcms_release_fw(wl);
+       return status;
+}
+
 static void brcms_ops_tx(struct ieee80211_hw *hw,
                         struct ieee80211_tx_control *control,
                         struct sk_buff *skb)
@@ -306,6 +430,14 @@ static int brcms_ops_start(struct ieee80211_hw *hw)
        if (!blocked)
                wiphy_rfkill_stop_polling(wl->pub->ieee_hw->wiphy);
 
+       if (!wl->ucode.bcm43xx_bomminor) {
+               err = brcms_request_fw(wl, wl->wlc->hw->d11core);
+               if (err) {
+                       brcms_remove(wl->wlc->hw->d11core);
+                       return -ENOENT;
+               }
+       }
+
        spin_lock_bh(&wl->lock);
        /* avoid acknowledging frames before a non-monitor device is added */
        wl->mute_tx = true;
@@ -793,128 +925,6 @@ void brcms_dpc(unsigned long data)
        wake_up(&wl->tx_flush_wq);
 }
 
-/*
- * Precondition: Since this function is called in brcms_pci_probe() context,
- * no locking is required.
- */
-static int brcms_request_fw(struct brcms_info *wl, struct bcma_device *pdev)
-{
-       int status;
-       struct device *device = &pdev->dev;
-       char fw_name[100];
-       int i;
-
-       memset(&wl->fw, 0, sizeof(struct brcms_firmware));
-       for (i = 0; i < MAX_FW_IMAGES; i++) {
-               if (brcms_firmwares[i] == NULL)
-                       break;
-               sprintf(fw_name, "%s-%d.fw", brcms_firmwares[i],
-                       UCODE_LOADER_API_VER);
-               status = request_firmware(&wl->fw.fw_bin[i], fw_name, device);
-               if (status) {
-                       wiphy_err(wl->wiphy, "%s: fail to load firmware %s\n",
-                                 KBUILD_MODNAME, fw_name);
-                       return status;
-               }
-               sprintf(fw_name, "%s_hdr-%d.fw", brcms_firmwares[i],
-                       UCODE_LOADER_API_VER);
-               status = request_firmware(&wl->fw.fw_hdr[i], fw_name, device);
-               if (status) {
-                       wiphy_err(wl->wiphy, "%s: fail to load firmware %s\n",
-                                 KBUILD_MODNAME, fw_name);
-                       return status;
-               }
-               wl->fw.hdr_num_entries[i] =
-                   wl->fw.fw_hdr[i]->size / (sizeof(struct firmware_hdr));
-       }
-       wl->fw.fw_cnt = i;
-       return brcms_ucode_data_init(wl, &wl->ucode);
-}
-
-/*
- * Precondition: Since this function is called in brcms_pci_probe() context,
- * no locking is required.
- */
-static void brcms_release_fw(struct brcms_info *wl)
-{
-       int i;
-       for (i = 0; i < MAX_FW_IMAGES; i++) {
-               release_firmware(wl->fw.fw_bin[i]);
-               release_firmware(wl->fw.fw_hdr[i]);
-       }
-}
-
-/**
- * This function frees the WL per-device resources.
- *
- * This function frees resources owned by the WL device pointed to
- * by the wl parameter.
- *
- * precondition: can both be called locked and unlocked
- *
- */
-static void brcms_free(struct brcms_info *wl)
-{
-       struct brcms_timer *t, *next;
-
-       /* free ucode data */
-       if (wl->fw.fw_cnt)
-               brcms_ucode_data_free(&wl->ucode);
-       if (wl->irq)
-               free_irq(wl->irq, wl);
-
-       /* kill dpc */
-       tasklet_kill(&wl->tasklet);
-
-       if (wl->pub) {
-               brcms_debugfs_detach(wl->pub);
-               brcms_c_module_unregister(wl->pub, "linux", wl);
-       }
-
-       /* free common resources */
-       if (wl->wlc) {
-               brcms_c_detach(wl->wlc);
-               wl->wlc = NULL;
-               wl->pub = NULL;
-       }
-
-       /* virtual interface deletion is deferred so we cannot spinwait */
-
-       /* wait for all pending callbacks to complete */
-       while (atomic_read(&wl->callbacks) > 0)
-               schedule();
-
-       /* free timers */
-       for (t = wl->timers; t; t = next) {
-               next = t->next;
-#ifdef DEBUG
-               kfree(t->name);
-#endif
-               kfree(t);
-       }
-}
-
-/*
-* called from both kernel as from this kernel module (error flow on attach)
-* precondition: perimeter lock is not acquired.
-*/
-static void brcms_remove(struct bcma_device *pdev)
-{
-       struct ieee80211_hw *hw = bcma_get_drvdata(pdev);
-       struct brcms_info *wl = hw->priv;
-
-       if (wl->wlc) {
-               wiphy_rfkill_set_hw_state(wl->pub->ieee_hw->wiphy, false);
-               wiphy_rfkill_stop_polling(wl->pub->ieee_hw->wiphy);
-               ieee80211_unregister_hw(hw);
-       }
-
-       brcms_free(wl);
-
-       bcma_set_drvdata(pdev, NULL);
-       ieee80211_free_hw(hw);
-}
-
 static irqreturn_t brcms_isr(int irq, void *dev_id)
 {
        struct brcms_info *wl;
@@ -1047,18 +1057,8 @@ static struct brcms_info *brcms_attach(struct bcma_device *pdev)
        spin_lock_init(&wl->lock);
        spin_lock_init(&wl->isr_lock);
 
-       /* prepare ucode */
-       if (brcms_request_fw(wl, pdev) < 0) {
-               wiphy_err(wl->wiphy, "%s: Failed to find firmware usually in "
-                         "%s\n", KBUILD_MODNAME, "/lib/firmware/brcm");
-               brcms_release_fw(wl);
-               brcms_remove(pdev);
-               return NULL;
-       }
-
        /* common load-time initialization */
        wl->wlc = brcms_c_attach((void *)wl, pdev, unit, false, &err);
-       brcms_release_fw(wl);
        if (!wl->wlc) {
                wiphy_err(wl->wiphy, "%s: attach() failed with code %d\n",
                          KBUILD_MODNAME, err);
index d215b4d3c51b57db90eee2293f6c153059fe037b..e7f6deaf715e5020c56685c1b8daf4d55ac9b945 100644 (file)
@@ -1393,8 +1393,10 @@ int mwifiex_scan_networks(struct mwifiex_private *priv,
                        queue_work(adapter->workqueue, &adapter->main_work);
 
                        /* Perform internal scan synchronously */
-                       if (!priv->scan_request)
+                       if (!priv->scan_request) {
+                               dev_dbg(adapter->dev, "wait internal scan\n");
                                mwifiex_wait_queue_complete(adapter, cmd_node);
+                       }
                } else {
                        spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
                                               flags);
@@ -1793,7 +1795,12 @@ check_next_scan:
                /* Need to indicate IOCTL complete */
                if (adapter->curr_cmd->wait_q_enabled) {
                        adapter->cmd_wait_q.status = 0;
-                       mwifiex_complete_cmd(adapter, adapter->curr_cmd);
+                       if (!priv->scan_request) {
+                               dev_dbg(adapter->dev,
+                                       "complete internal scan\n");
+                               mwifiex_complete_cmd(adapter,
+                                                    adapter->curr_cmd);
+                       }
                }
                if (priv->report_scan_result)
                        priv->report_scan_result = false;
index 2bf4efa331867acaea139bb81dcca75a66532ef4..76cd47eb901e089bbf58669c8eb5fc7da6631a7a 100644 (file)
@@ -20,6 +20,7 @@ if RT2X00
 config RT2400PCI
        tristate "Ralink rt2400 (PCI/PCMCIA) support"
        depends on PCI
+       select RT2X00_LIB_MMIO
        select RT2X00_LIB_PCI
        select EEPROM_93CX6
        ---help---
@@ -31,6 +32,7 @@ config RT2400PCI
 config RT2500PCI
        tristate "Ralink rt2500 (PCI/PCMCIA) support"
        depends on PCI
+       select RT2X00_LIB_MMIO
        select RT2X00_LIB_PCI
        select EEPROM_93CX6
        ---help---
@@ -43,6 +45,7 @@ config RT61PCI
        tristate "Ralink rt2501/rt61 (PCI/PCMCIA) support"
        depends on PCI
        select RT2X00_LIB_PCI
+       select RT2X00_LIB_MMIO
        select RT2X00_LIB_FIRMWARE
        select RT2X00_LIB_CRYPTO
        select CRC_ITU_T
@@ -57,6 +60,7 @@ config RT2800PCI
        tristate "Ralink rt27xx/rt28xx/rt30xx (PCI/PCIe/PCMCIA) support"
        depends on PCI || SOC_RT288X || SOC_RT305X
        select RT2800_LIB
+       select RT2X00_LIB_MMIO
        select RT2X00_LIB_PCI if PCI
        select RT2X00_LIB_SOC if SOC_RT288X || SOC_RT305X
        select RT2X00_LIB_FIRMWARE
@@ -185,6 +189,9 @@ endif
 config RT2800_LIB
        tristate
 
+config RT2X00_LIB_MMIO
+       tristate
+
 config RT2X00_LIB_PCI
        tristate
        select RT2X00_LIB
index 349d5b8284a4f6c64faaa58d6b750864c3a8252e..f069d8bc5b678332151d7a6fe337f44e29205d82 100644 (file)
@@ -9,6 +9,7 @@ rt2x00lib-$(CONFIG_RT2X00_LIB_FIRMWARE) += rt2x00firmware.o
 rt2x00lib-$(CONFIG_RT2X00_LIB_LEDS)    += rt2x00leds.o
 
 obj-$(CONFIG_RT2X00_LIB)               += rt2x00lib.o
+obj-$(CONFIG_RT2X00_LIB_MMIO)          += rt2x00mmio.o
 obj-$(CONFIG_RT2X00_LIB_PCI)           += rt2x00pci.o
 obj-$(CONFIG_RT2X00_LIB_SOC)           += rt2x00soc.o
 obj-$(CONFIG_RT2X00_LIB_USB)           += rt2x00usb.o
index 221beaaa83f12c59554302569639ca87f83765b5..dcfb54e0c516beb21faa4ae0b4409592b8455756 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/slab.h>
 
 #include "rt2x00.h"
+#include "rt2x00mmio.h"
 #include "rt2x00pci.h"
 #include "rt2400pci.h"
 
index 39edc59e8d038613a07b4dce764e0033be2501cf..e1d2dc9ed28a6801c727b484a6e596e346d45175 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/slab.h>
 
 #include "rt2x00.h"
+#include "rt2x00mmio.h"
 #include "rt2x00pci.h"
 #include "rt2500pci.h"
 
index ded73da4de0b0d52cd6331d837c8c68e86b87749..ba5a05625aaa70b5dcba84081a4bbea5a5970a9d 100644 (file)
@@ -41,6 +41,7 @@
 #include <linux/eeprom_93cx6.h>
 
 #include "rt2x00.h"
+#include "rt2x00mmio.h"
 #include "rt2x00pci.h"
 #include "rt2x00soc.h"
 #include "rt2800lib.h"
diff --git a/drivers/net/wireless/rt2x00/rt2x00mmio.c b/drivers/net/wireless/rt2x00/rt2x00mmio.c
new file mode 100644 (file)
index 0000000..d84a680
--- /dev/null
@@ -0,0 +1,216 @@
+/*
+       Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com>
+       <http://rt2x00.serialmonkey.com>
+
+       This program is free software; you can redistribute it and/or modify
+       it under the terms of the GNU General Public License as published by
+       the Free Software Foundation; either version 2 of the License, or
+       (at your option) any later version.
+
+       This program is distributed in the hope that it will be useful,
+       but WITHOUT ANY WARRANTY; without even the implied warranty of
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+       GNU General Public License for more details.
+
+       You should have received a copy of the GNU General Public License
+       along with this program; if not, write to the
+       Free Software Foundation, Inc.,
+       59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/*
+       Module: rt2x00mmio
+       Abstract: rt2x00 generic mmio device routines.
+ */
+
+#include <linux/dma-mapping.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+
+#include "rt2x00.h"
+#include "rt2x00mmio.h"
+
+/*
+ * Register access.
+ */
+int rt2x00pci_regbusy_read(struct rt2x00_dev *rt2x00dev,
+                          const unsigned int offset,
+                          const struct rt2x00_field32 field,
+                          u32 *reg)
+{
+       unsigned int i;
+
+       if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
+               return 0;
+
+       for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
+               rt2x00pci_register_read(rt2x00dev, offset, reg);
+               if (!rt2x00_get_field32(*reg, field))
+                       return 1;
+               udelay(REGISTER_BUSY_DELAY);
+       }
+
+       printk_once(KERN_ERR "%s() Indirect register access failed: "
+             "offset=0x%.08x, value=0x%.08x\n", __func__, offset, *reg);
+       *reg = ~0;
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(rt2x00pci_regbusy_read);
+
+bool rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev)
+{
+       struct data_queue *queue = rt2x00dev->rx;
+       struct queue_entry *entry;
+       struct queue_entry_priv_pci *entry_priv;
+       struct skb_frame_desc *skbdesc;
+       int max_rx = 16;
+
+       while (--max_rx) {
+               entry = rt2x00queue_get_entry(queue, Q_INDEX);
+               entry_priv = entry->priv_data;
+
+               if (rt2x00dev->ops->lib->get_entry_state(entry))
+                       break;
+
+               /*
+                * Fill in desc fields of the skb descriptor
+                */
+               skbdesc = get_skb_frame_desc(entry->skb);
+               skbdesc->desc = entry_priv->desc;
+               skbdesc->desc_len = entry->queue->desc_size;
+
+               /*
+                * DMA is already done, notify rt2x00lib that
+                * it finished successfully.
+                */
+               rt2x00lib_dmastart(entry);
+               rt2x00lib_dmadone(entry);
+
+               /*
+                * Send the frame to rt2x00lib for further processing.
+                */
+               rt2x00lib_rxdone(entry, GFP_ATOMIC);
+       }
+
+       return !max_rx;
+}
+EXPORT_SYMBOL_GPL(rt2x00pci_rxdone);
+
+void rt2x00pci_flush_queue(struct data_queue *queue, bool drop)
+{
+       unsigned int i;
+
+       for (i = 0; !rt2x00queue_empty(queue) && i < 10; i++)
+               msleep(10);
+}
+EXPORT_SYMBOL_GPL(rt2x00pci_flush_queue);
+
+/*
+ * Device initialization handlers.
+ */
+static int rt2x00pci_alloc_queue_dma(struct rt2x00_dev *rt2x00dev,
+                                    struct data_queue *queue)
+{
+       struct queue_entry_priv_pci *entry_priv;
+       void *addr;
+       dma_addr_t dma;
+       unsigned int i;
+
+       /*
+        * Allocate DMA memory for descriptor and buffer.
+        */
+       addr = dma_alloc_coherent(rt2x00dev->dev,
+                                 queue->limit * queue->desc_size,
+                                 &dma, GFP_KERNEL);
+       if (!addr)
+               return -ENOMEM;
+
+       memset(addr, 0, queue->limit * queue->desc_size);
+
+       /*
+        * Initialize all queue entries to contain valid addresses.
+        */
+       for (i = 0; i < queue->limit; i++) {
+               entry_priv = queue->entries[i].priv_data;
+               entry_priv->desc = addr + i * queue->desc_size;
+               entry_priv->desc_dma = dma + i * queue->desc_size;
+       }
+
+       return 0;
+}
+
+static void rt2x00pci_free_queue_dma(struct rt2x00_dev *rt2x00dev,
+                                    struct data_queue *queue)
+{
+       struct queue_entry_priv_pci *entry_priv =
+           queue->entries[0].priv_data;
+
+       if (entry_priv->desc)
+               dma_free_coherent(rt2x00dev->dev,
+                                 queue->limit * queue->desc_size,
+                                 entry_priv->desc, entry_priv->desc_dma);
+       entry_priv->desc = NULL;
+}
+
+int rt2x00pci_initialize(struct rt2x00_dev *rt2x00dev)
+{
+       struct data_queue *queue;
+       int status;
+
+       /*
+        * Allocate DMA
+        */
+       queue_for_each(rt2x00dev, queue) {
+               status = rt2x00pci_alloc_queue_dma(rt2x00dev, queue);
+               if (status)
+                       goto exit;
+       }
+
+       /*
+        * Register interrupt handler.
+        */
+       status = request_irq(rt2x00dev->irq,
+                            rt2x00dev->ops->lib->irq_handler,
+                            IRQF_SHARED, rt2x00dev->name, rt2x00dev);
+       if (status) {
+               ERROR(rt2x00dev, "IRQ %d allocation failed (error %d).\n",
+                     rt2x00dev->irq, status);
+               goto exit;
+       }
+
+       return 0;
+
+exit:
+       queue_for_each(rt2x00dev, queue)
+               rt2x00pci_free_queue_dma(rt2x00dev, queue);
+
+       return status;
+}
+EXPORT_SYMBOL_GPL(rt2x00pci_initialize);
+
+void rt2x00pci_uninitialize(struct rt2x00_dev *rt2x00dev)
+{
+       struct data_queue *queue;
+
+       /*
+        * Free irq line.
+        */
+       free_irq(rt2x00dev->irq, rt2x00dev);
+
+       /*
+        * Free DMA
+        */
+       queue_for_each(rt2x00dev, queue)
+               rt2x00pci_free_queue_dma(rt2x00dev, queue);
+}
+EXPORT_SYMBOL_GPL(rt2x00pci_uninitialize);
+
+/*
+ * rt2x00mmio module information.
+ */
+MODULE_AUTHOR(DRV_PROJECT);
+MODULE_VERSION(DRV_VERSION);
+MODULE_DESCRIPTION("rt2x00 mmio library");
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/wireless/rt2x00/rt2x00mmio.h b/drivers/net/wireless/rt2x00/rt2x00mmio.h
new file mode 100644 (file)
index 0000000..4ecaf60
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+       Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com>
+       <http://rt2x00.serialmonkey.com>
+
+       This program is free software; you can redistribute it and/or modify
+       it under the terms of the GNU General Public License as published by
+       the Free Software Foundation; either version 2 of the License, or
+       (at your option) any later version.
+
+       This program is distributed in the hope that it will be useful,
+       but WITHOUT ANY WARRANTY; without even the implied warranty of
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+       GNU General Public License for more details.
+
+       You should have received a copy of the GNU General Public License
+       along with this program; if not, write to the
+       Free Software Foundation, Inc.,
+       59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/*
+       Module: rt2x00mmio
+       Abstract: Data structures for the rt2x00mmio module.
+ */
+
+#ifndef RT2X00MMIO_H
+#define RT2X00MMIO_H
+
+#include <linux/io.h>
+
+/*
+ * Register access.
+ */
+static inline void rt2x00pci_register_read(struct rt2x00_dev *rt2x00dev,
+                                          const unsigned int offset,
+                                          u32 *value)
+{
+       *value = readl(rt2x00dev->csr.base + offset);
+}
+
+static inline void rt2x00pci_register_multiread(struct rt2x00_dev *rt2x00dev,
+                                               const unsigned int offset,
+                                               void *value, const u32 length)
+{
+       memcpy_fromio(value, rt2x00dev->csr.base + offset, length);
+}
+
+static inline void rt2x00pci_register_write(struct rt2x00_dev *rt2x00dev,
+                                           const unsigned int offset,
+                                           u32 value)
+{
+       writel(value, rt2x00dev->csr.base + offset);
+}
+
+static inline void rt2x00pci_register_multiwrite(struct rt2x00_dev *rt2x00dev,
+                                                const unsigned int offset,
+                                                const void *value,
+                                                const u32 length)
+{
+       __iowrite32_copy(rt2x00dev->csr.base + offset, value, length >> 2);
+}
+
+/**
+ * rt2x00pci_regbusy_read - Read from register with busy check
+ * @rt2x00dev: Device pointer, see &struct rt2x00_dev.
+ * @offset: Register offset
+ * @field: Field to check if register is busy
+ * @reg: Pointer to where register contents should be stored
+ *
+ * This function will read the given register, and checks if the
+ * register is busy. If it is, it will sleep for a couple of
+ * microseconds before reading the register again. If the register
+ * is not read after a certain timeout, this function will return
+ * FALSE.
+ */
+int rt2x00pci_regbusy_read(struct rt2x00_dev *rt2x00dev,
+                          const unsigned int offset,
+                          const struct rt2x00_field32 field,
+                          u32 *reg);
+
+/**
+ * struct queue_entry_priv_pci: Per entry PCI specific information
+ *
+ * @desc: Pointer to device descriptor
+ * @desc_dma: DMA pointer to &desc.
+ * @data: Pointer to device's entry memory.
+ * @data_dma: DMA pointer to &data.
+ */
+struct queue_entry_priv_pci {
+       __le32 *desc;
+       dma_addr_t desc_dma;
+};
+
+/**
+ * rt2x00pci_rxdone - Handle RX done events
+ * @rt2x00dev: Device pointer, see &struct rt2x00_dev.
+ *
+ * Returns true if there are still rx frames pending and false if all
+ * pending rx frames were processed.
+ */
+bool rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev);
+
+/**
+ * rt2x00pci_flush_queue - Flush data queue
+ * @queue: Data queue to stop
+ * @drop: True to drop all pending frames.
+ *
+ * This will wait for a maximum of 100ms, waiting for the queues
+ * to become empty.
+ */
+void rt2x00pci_flush_queue(struct data_queue *queue, bool drop);
+
+/*
+ * Device initialization handlers.
+ */
+int rt2x00pci_initialize(struct rt2x00_dev *rt2x00dev);
+void rt2x00pci_uninitialize(struct rt2x00_dev *rt2x00dev);
+
+#endif /* RT2X00MMIO_H */
index a0c8caef3b0a8f3616a4dd4a71e6eebeb3b939ae..e87865e331139148c86a19b6efccf6efdaa329e2 100644 (file)
 #include "rt2x00.h"
 #include "rt2x00pci.h"
 
-/*
- * Register access.
- */
-int rt2x00pci_regbusy_read(struct rt2x00_dev *rt2x00dev,
-                          const unsigned int offset,
-                          const struct rt2x00_field32 field,
-                          u32 *reg)
-{
-       unsigned int i;
-
-       if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
-               return 0;
-
-       for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
-               rt2x00pci_register_read(rt2x00dev, offset, reg);
-               if (!rt2x00_get_field32(*reg, field))
-                       return 1;
-               udelay(REGISTER_BUSY_DELAY);
-       }
-
-       ERROR(rt2x00dev, "Indirect register access failed: "
-             "offset=0x%.08x, value=0x%.08x\n", offset, *reg);
-       *reg = ~0;
-
-       return 0;
-}
-EXPORT_SYMBOL_GPL(rt2x00pci_regbusy_read);
-
-bool rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev)
-{
-       struct data_queue *queue = rt2x00dev->rx;
-       struct queue_entry *entry;
-       struct queue_entry_priv_pci *entry_priv;
-       struct skb_frame_desc *skbdesc;
-       int max_rx = 16;
-
-       while (--max_rx) {
-               entry = rt2x00queue_get_entry(queue, Q_INDEX);
-               entry_priv = entry->priv_data;
-
-               if (rt2x00dev->ops->lib->get_entry_state(entry))
-                       break;
-
-               /*
-                * Fill in desc fields of the skb descriptor
-                */
-               skbdesc = get_skb_frame_desc(entry->skb);
-               skbdesc->desc = entry_priv->desc;
-               skbdesc->desc_len = entry->queue->desc_size;
-
-               /*
-                * DMA is already done, notify rt2x00lib that
-                * it finished successfully.
-                */
-               rt2x00lib_dmastart(entry);
-               rt2x00lib_dmadone(entry);
-
-               /*
-                * Send the frame to rt2x00lib for further processing.
-                */
-               rt2x00lib_rxdone(entry, GFP_ATOMIC);
-       }
-
-       return !max_rx;
-}
-EXPORT_SYMBOL_GPL(rt2x00pci_rxdone);
-
-void rt2x00pci_flush_queue(struct data_queue *queue, bool drop)
-{
-       unsigned int i;
-
-       for (i = 0; !rt2x00queue_empty(queue) && i < 10; i++)
-               msleep(10);
-}
-EXPORT_SYMBOL_GPL(rt2x00pci_flush_queue);
-
-/*
- * Device initialization handlers.
- */
-static int rt2x00pci_alloc_queue_dma(struct rt2x00_dev *rt2x00dev,
-                                    struct data_queue *queue)
-{
-       struct queue_entry_priv_pci *entry_priv;
-       void *addr;
-       dma_addr_t dma;
-       unsigned int i;
-
-       /*
-        * Allocate DMA memory for descriptor and buffer.
-        */
-       addr = dma_alloc_coherent(rt2x00dev->dev,
-                                 queue->limit * queue->desc_size,
-                                 &dma, GFP_KERNEL);
-       if (!addr)
-               return -ENOMEM;
-
-       memset(addr, 0, queue->limit * queue->desc_size);
-
-       /*
-        * Initialize all queue entries to contain valid addresses.
-        */
-       for (i = 0; i < queue->limit; i++) {
-               entry_priv = queue->entries[i].priv_data;
-               entry_priv->desc = addr + i * queue->desc_size;
-               entry_priv->desc_dma = dma + i * queue->desc_size;
-       }
-
-       return 0;
-}
-
-static void rt2x00pci_free_queue_dma(struct rt2x00_dev *rt2x00dev,
-                                    struct data_queue *queue)
-{
-       struct queue_entry_priv_pci *entry_priv =
-           queue->entries[0].priv_data;
-
-       if (entry_priv->desc)
-               dma_free_coherent(rt2x00dev->dev,
-                                 queue->limit * queue->desc_size,
-                                 entry_priv->desc, entry_priv->desc_dma);
-       entry_priv->desc = NULL;
-}
-
-int rt2x00pci_initialize(struct rt2x00_dev *rt2x00dev)
-{
-       struct data_queue *queue;
-       int status;
-
-       /*
-        * Allocate DMA
-        */
-       queue_for_each(rt2x00dev, queue) {
-               status = rt2x00pci_alloc_queue_dma(rt2x00dev, queue);
-               if (status)
-                       goto exit;
-       }
-
-       /*
-        * Register interrupt handler.
-        */
-       status = request_irq(rt2x00dev->irq,
-                            rt2x00dev->ops->lib->irq_handler,
-                            IRQF_SHARED, rt2x00dev->name, rt2x00dev);
-       if (status) {
-               ERROR(rt2x00dev, "IRQ %d allocation failed (error %d).\n",
-                     rt2x00dev->irq, status);
-               goto exit;
-       }
-
-       return 0;
-
-exit:
-       queue_for_each(rt2x00dev, queue)
-               rt2x00pci_free_queue_dma(rt2x00dev, queue);
-
-       return status;
-}
-EXPORT_SYMBOL_GPL(rt2x00pci_initialize);
-
-void rt2x00pci_uninitialize(struct rt2x00_dev *rt2x00dev)
-{
-       struct data_queue *queue;
-
-       /*
-        * Free irq line.
-        */
-       free_irq(rt2x00dev->irq, rt2x00dev);
-
-       /*
-        * Free DMA
-        */
-       queue_for_each(rt2x00dev, queue)
-               rt2x00pci_free_queue_dma(rt2x00dev, queue);
-}
-EXPORT_SYMBOL_GPL(rt2x00pci_uninitialize);
-
 /*
  * PCI driver handlers.
  */
index e2c99f2b9a1422f5e1dd1af1116f447f8b43c199..60d90b20f8b99216a8dd19b4926364be65725b28 100644 (file)
  */
 #define PCI_DEVICE_DATA(__ops) .driver_data = (kernel_ulong_t)(__ops)
 
-/*
- * Register access.
- */
-static inline void rt2x00pci_register_read(struct rt2x00_dev *rt2x00dev,
-                                          const unsigned int offset,
-                                          u32 *value)
-{
-       *value = readl(rt2x00dev->csr.base + offset);
-}
-
-static inline void rt2x00pci_register_multiread(struct rt2x00_dev *rt2x00dev,
-                                               const unsigned int offset,
-                                               void *value, const u32 length)
-{
-       memcpy_fromio(value, rt2x00dev->csr.base + offset, length);
-}
-
-static inline void rt2x00pci_register_write(struct rt2x00_dev *rt2x00dev,
-                                           const unsigned int offset,
-                                           u32 value)
-{
-       writel(value, rt2x00dev->csr.base + offset);
-}
-
-static inline void rt2x00pci_register_multiwrite(struct rt2x00_dev *rt2x00dev,
-                                                const unsigned int offset,
-                                                const void *value,
-                                                const u32 length)
-{
-       __iowrite32_copy(rt2x00dev->csr.base + offset, value, length >> 2);
-}
-
-/**
- * rt2x00pci_regbusy_read - Read from register with busy check
- * @rt2x00dev: Device pointer, see &struct rt2x00_dev.
- * @offset: Register offset
- * @field: Field to check if register is busy
- * @reg: Pointer to where register contents should be stored
- *
- * This function will read the given register, and checks if the
- * register is busy. If it is, it will sleep for a couple of
- * microseconds before reading the register again. If the register
- * is not read after a certain timeout, this function will return
- * FALSE.
- */
-int rt2x00pci_regbusy_read(struct rt2x00_dev *rt2x00dev,
-                          const unsigned int offset,
-                          const struct rt2x00_field32 field,
-                          u32 *reg);
-
-/**
- * struct queue_entry_priv_pci: Per entry PCI specific information
- *
- * @desc: Pointer to device descriptor
- * @desc_dma: DMA pointer to &desc.
- * @data: Pointer to device's entry memory.
- * @data_dma: DMA pointer to &data.
- */
-struct queue_entry_priv_pci {
-       __le32 *desc;
-       dma_addr_t desc_dma;
-};
-
-/**
- * rt2x00pci_rxdone - Handle RX done events
- * @rt2x00dev: Device pointer, see &struct rt2x00_dev.
- *
- * Returns true if there are still rx frames pending and false if all
- * pending rx frames were processed.
- */
-bool rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev);
-
-/**
- * rt2x00pci_flush_queue - Flush data queue
- * @queue: Data queue to stop
- * @drop: True to drop all pending frames.
- *
- * This will wait for a maximum of 100ms, waiting for the queues
- * to become empty.
- */
-void rt2x00pci_flush_queue(struct data_queue *queue, bool drop);
-
-/*
- * Device initialization handlers.
- */
-int rt2x00pci_initialize(struct rt2x00_dev *rt2x00dev);
-void rt2x00pci_uninitialize(struct rt2x00_dev *rt2x00dev);
-
 /*
  * PCI driver handlers.
  */
index f95792cfcf8922e17222fec2feddc34f5117c308..9e3c8ff53e3fd9e0b4f723e96671eba005d75d62 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/eeprom_93cx6.h>
 
 #include "rt2x00.h"
+#include "rt2x00mmio.h"
 #include "rt2x00pci.h"
 #include "rt61pci.h"
 
index 45cacf79f3a73b7dfd97fa8293458febc02b7da9..1a779bbfb87d2b8de61e964734981f4f9a6c891e 100644 (file)
@@ -134,7 +134,6 @@ static const struct key_entry hp_wmi_keymap[] = {
        { KE_KEY, 0x2142, { KEY_MEDIA } },
        { KE_KEY, 0x213b, { KEY_INFO } },
        { KE_KEY, 0x2169, { KEY_DIRECTION } },
-       { KE_KEY, 0x216a, { KEY_SETUP } },
        { KE_KEY, 0x231b, { KEY_HELP } },
        { KE_END, 0 }
 };
@@ -925,9 +924,6 @@ static int __init hp_wmi_init(void)
                err = hp_wmi_input_setup();
                if (err)
                        return err;
-               
-               //Enable magic for hotkeys that run on the SMBus
-               ec_write(0xe6,0x6e);
        }
 
        if (bios_capable) {
index 9a907567f41edf495f1c102d906ba63660de082e..edec135b1685d0525149bc21c724833398424cb1 100644 (file)
@@ -1964,9 +1964,6 @@ struct tp_nvram_state {
 /* kthread for the hotkey poller */
 static struct task_struct *tpacpi_hotkey_task;
 
-/* Acquired while the poller kthread is running, use to sync start/stop */
-static struct mutex hotkey_thread_mutex;
-
 /*
  * Acquire mutex to write poller control variables as an
  * atomic block.
@@ -2462,8 +2459,6 @@ static int hotkey_kthread(void *data)
        unsigned int poll_freq;
        bool was_frozen;
 
-       mutex_lock(&hotkey_thread_mutex);
-
        if (tpacpi_lifecycle == TPACPI_LIFE_EXITING)
                goto exit;
 
@@ -2523,7 +2518,6 @@ static int hotkey_kthread(void *data)
        }
 
 exit:
-       mutex_unlock(&hotkey_thread_mutex);
        return 0;
 }
 
@@ -2533,9 +2527,6 @@ static void hotkey_poll_stop_sync(void)
        if (tpacpi_hotkey_task) {
                kthread_stop(tpacpi_hotkey_task);
                tpacpi_hotkey_task = NULL;
-               mutex_lock(&hotkey_thread_mutex);
-               /* at this point, the thread did exit */
-               mutex_unlock(&hotkey_thread_mutex);
        }
 }
 
@@ -3234,7 +3225,6 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
        mutex_init(&hotkey_mutex);
 
 #ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL
-       mutex_init(&hotkey_thread_mutex);
        mutex_init(&hotkey_thread_data_mutex);
 #endif
 
index cc1f7bf53fd07c1c1788d0183b19e4ce41de8c1b..c6d77e20622c45f54e17e7063e3e498f781739c6 100644 (file)
@@ -4,7 +4,7 @@ menu "Remoteproc drivers"
 config REMOTEPROC
        tristate
        depends on HAS_DMA
-       select FW_CONFIG
+       select FW_LOADER
        select VIRTIO
 
 config OMAP_REMOTEPROC
index 29387df4bfc9aa40f73cb94a0dcc2b2d0044af68..8edb4aed5d368e551e968e9c841cfd9edb221b7a 100644 (file)
@@ -217,7 +217,7 @@ int rproc_alloc_vring(struct rproc_vdev *rvdev, int i)
         * TODO: support predefined notifyids (via resource table)
         */
        ret = idr_alloc(&rproc->notifyids, rvring, 0, 0, GFP_KERNEL);
-       if (ret) {
+       if (ret < 0) {
                dev_err(dev, "idr_alloc failed: %d\n", ret);
                dma_free_coherent(dev->parent, size, va, dma);
                return ret;
@@ -366,10 +366,12 @@ static int rproc_handle_vdev(struct rproc *rproc, struct fw_rsc_vdev *rsc,
        /* it is now safe to add the virtio device */
        ret = rproc_add_virtio_dev(rvdev, rsc->id);
        if (ret)
-               goto free_rvdev;
+               goto remove_rvdev;
 
        return 0;
 
+remove_rvdev:
+       list_del(&rvdev->node);
 free_rvdev:
        kfree(rvdev);
        return ret;
index a7743c069339d6b9d738054db0c9148a490d119b..fb95c4220052decb09117075d3a798dbbb6235b7 100644 (file)
@@ -240,6 +240,8 @@ static int sproc_drv_remove(struct platform_device *pdev)
 
        /* Unregister as remoteproc device */
        rproc_del(sproc->rproc);
+       dma_free_coherent(sproc->rproc->dev.parent, SPROC_FW_SIZE,
+                         sproc->fw_addr, sproc->fw_dma_addr);
        rproc_put(sproc->rproc);
 
        mdev->drv_data = NULL;
@@ -297,10 +299,13 @@ static int sproc_probe(struct platform_device *pdev)
        /* Register as a remoteproc device */
        err = rproc_add(rproc);
        if (err)
-               goto free_rproc;
+               goto free_mem;
 
        return 0;
 
+free_mem:
+       dma_free_coherent(rproc->dev.parent, SPROC_FW_SIZE,
+                         sproc->fw_addr, sproc->fw_dma_addr);
 free_rproc:
        /* Reset device data upon error */
        mdev->drv_data = NULL;
index 8c0622399fcd67bd7353b6274a3d370b3d9caaa4..6ccb7457746b29e4e6ac0f53731bba725709f6a8 100644 (file)
@@ -769,6 +769,7 @@ struct qeth_card {
        unsigned long thread_start_mask;
        unsigned long thread_allowed_mask;
        unsigned long thread_running_mask;
+       struct task_struct *recovery_task;
        spinlock_t ip_lock;
        struct list_head ip_list;
        struct list_head *ip_tbd_list;
@@ -862,6 +863,8 @@ extern struct qeth_card_list_struct qeth_core_card_list;
 extern struct kmem_cache *qeth_core_header_cache;
 extern struct qeth_dbf_info qeth_dbf[QETH_DBF_INFOS];
 
+void qeth_set_recovery_task(struct qeth_card *);
+void qeth_clear_recovery_task(struct qeth_card *);
 void qeth_set_allowed_threads(struct qeth_card *, unsigned long , int);
 int qeth_threads_running(struct qeth_card *, unsigned long);
 int qeth_wait_for_threads(struct qeth_card *, unsigned long);
index 0d73a999983d90ff632c0dcdcf6d54bedbd5a289..451f92020599e68add4a6b8a52888f672ad69084 100644 (file)
@@ -177,6 +177,23 @@ const char *qeth_get_cardname_short(struct qeth_card *card)
        return "n/a";
 }
 
+void qeth_set_recovery_task(struct qeth_card *card)
+{
+       card->recovery_task = current;
+}
+EXPORT_SYMBOL_GPL(qeth_set_recovery_task);
+
+void qeth_clear_recovery_task(struct qeth_card *card)
+{
+       card->recovery_task = NULL;
+}
+EXPORT_SYMBOL_GPL(qeth_clear_recovery_task);
+
+static bool qeth_is_recovery_task(const struct qeth_card *card)
+{
+       return card->recovery_task == current;
+}
+
 void qeth_set_allowed_threads(struct qeth_card *card, unsigned long threads,
                         int clear_start_mask)
 {
@@ -205,6 +222,8 @@ EXPORT_SYMBOL_GPL(qeth_threads_running);
 
 int qeth_wait_for_threads(struct qeth_card *card, unsigned long threads)
 {
+       if (qeth_is_recovery_task(card))
+               return 0;
        return wait_event_interruptible(card->wait_q,
                        qeth_threads_running(card, threads) == 0);
 }
index d690166efeaffbd4d47f1d39d3111af232876e66..155b101bd7309432d32ce9ed915c1a3a1b889a60 100644 (file)
@@ -1143,6 +1143,7 @@ static int qeth_l2_recover(void *ptr)
        QETH_CARD_TEXT(card, 2, "recover2");
        dev_warn(&card->gdev->dev,
                "A recovery process has been started for the device\n");
+       qeth_set_recovery_task(card);
        __qeth_l2_set_offline(card->gdev, 1);
        rc = __qeth_l2_set_online(card->gdev, 1);
        if (!rc)
@@ -1153,6 +1154,7 @@ static int qeth_l2_recover(void *ptr)
                dev_warn(&card->gdev->dev, "The qeth device driver "
                                "failed to recover an error on the device\n");
        }
+       qeth_clear_recovery_task(card);
        qeth_clear_thread_start_bit(card, QETH_RECOVER_THREAD);
        qeth_clear_thread_running_bit(card, QETH_RECOVER_THREAD);
        return 0;
index 8710337dab3eceb4e5fa692d6a39accd697ba508..1f7edf1b26c33bff2b6a9baa6b163311a79fad6f 100644 (file)
@@ -3515,6 +3515,7 @@ static int qeth_l3_recover(void *ptr)
        QETH_CARD_TEXT(card, 2, "recover2");
        dev_warn(&card->gdev->dev,
                "A recovery process has been started for the device\n");
+       qeth_set_recovery_task(card);
        __qeth_l3_set_offline(card->gdev, 1);
        rc = __qeth_l3_set_online(card->gdev, 1);
        if (!rc)
@@ -3525,6 +3526,7 @@ static int qeth_l3_recover(void *ptr)
                dev_warn(&card->gdev->dev, "The qeth device driver "
                                "failed to recover an error on the device\n");
        }
+       qeth_clear_recovery_task(card);
        qeth_clear_thread_start_bit(card, QETH_RECOVER_THREAD);
        qeth_clear_thread_running_bit(card, QETH_RECOVER_THREAD);
        return 0;
index 1a9d1e3ce64cc94aa36581fd29cefb6084f3502f..c1441ed282eb911ff67a6363ce5a78f6cbe45199 100644 (file)
@@ -282,7 +282,7 @@ static irqreturn_t bbc_i2c_interrupt(int irq, void *dev_id)
        return IRQ_HANDLED;
 }
 
-static void __init reset_one_i2c(struct bbc_i2c_bus *bp)
+static void reset_one_i2c(struct bbc_i2c_bus *bp)
 {
        writeb(I2C_PCF_PIN, bp->i2c_control_regs + 0x0);
        writeb(bp->own, bp->i2c_control_regs + 0x1);
@@ -291,7 +291,7 @@ static void __init reset_one_i2c(struct bbc_i2c_bus *bp)
        writeb(I2C_PCF_IDLE, bp->i2c_control_regs + 0x0);
 }
 
-static struct bbc_i2c_bus * __init attach_one_i2c(struct platform_device *op, int index)
+static struct bbc_i2c_bus * attach_one_i2c(struct platform_device *op, int index)
 {
        struct bbc_i2c_bus *bp;
        struct device_node *dp;
index a044f593e8b98437e208cc1b785ca58371483890..d0fa4b6c551fd677bfa14252525717cf4f32469d 100644 (file)
@@ -1899,8 +1899,8 @@ static int ibmvscsi_slave_configure(struct scsi_device *sdev)
                sdev->allow_restart = 1;
                blk_queue_rq_timeout(sdev->request_queue, 120 * HZ);
        }
-       scsi_adjust_queue_depth(sdev, 0, shost->cmd_per_lun);
        spin_unlock_irqrestore(shost->host_lock, lock_flags);
+       scsi_adjust_queue_depth(sdev, 0, shost->cmd_per_lun);
        return 0;
 }
 
index f328089a1060a95ac9872e6b480f5dfe3cb7e120..2197b57fb2251f541e0bfc0eab626ce670b66504 100644 (file)
@@ -5148,7 +5148,7 @@ static int ipr_cancel_op(struct scsi_cmnd *scsi_cmd)
                ipr_trace;
        }
 
-       list_add_tail(&ipr_cmd->queue, &hrrq->hrrq_free_q);
+       list_add_tail(&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_free_q);
        if (!ipr_is_naca_model(res))
                res->needs_sync_complete = 1;
 
@@ -9349,7 +9349,10 @@ static int ipr_test_msi(struct ipr_ioa_cfg *ioa_cfg, struct pci_dev *pdev)
        int_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg);
        spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
 
-       rc = request_irq(pdev->irq, ipr_test_intr, 0, IPR_NAME, ioa_cfg);
+       if (ioa_cfg->intr_flag == IPR_USE_MSIX)
+               rc = request_irq(ioa_cfg->vectors_info[0].vec, ipr_test_intr, 0, IPR_NAME, ioa_cfg);
+       else
+               rc = request_irq(pdev->irq, ipr_test_intr, 0, IPR_NAME, ioa_cfg);
        if (rc) {
                dev_err(&pdev->dev, "Can not assign irq %d\n", pdev->irq);
                return rc;
@@ -9371,7 +9374,10 @@ static int ipr_test_msi(struct ipr_ioa_cfg *ioa_cfg, struct pci_dev *pdev)
 
        spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
 
-       free_irq(pdev->irq, ioa_cfg);
+       if (ioa_cfg->intr_flag == IPR_USE_MSIX)
+               free_irq(ioa_cfg->vectors_info[0].vec, ioa_cfg);
+       else
+               free_irq(pdev->irq, ioa_cfg);
 
        LEAVE;
 
@@ -9722,6 +9728,7 @@ static void __ipr_remove(struct pci_dev *pdev)
        spin_unlock_irqrestore(ioa_cfg->host->host_lock, host_lock_flags);
        wait_event(ioa_cfg->reset_wait_q, !ioa_cfg->in_reset_reload);
        flush_work(&ioa_cfg->work_q);
+       INIT_LIST_HEAD(&ioa_cfg->used_res_q);
        spin_lock_irqsave(ioa_cfg->host->host_lock, host_lock_flags);
 
        spin_lock(&ipr_driver_lock);
index aec2e0da50164ca688cc9e2ea95355f0aeaf4669..55cbd018015997bba484bfe5ffdbacabcc7e43db 100644 (file)
@@ -235,6 +235,17 @@ static void sas_set_ex_phy(struct domain_device *dev, int phy_id, void *rsp)
        linkrate  = phy->linkrate;
        memcpy(sas_addr, phy->attached_sas_addr, SAS_ADDR_SIZE);
 
+       /* Handle vacant phy - rest of dr data is not valid so skip it */
+       if (phy->phy_state == PHY_VACANT) {
+               memset(phy->attached_sas_addr, 0, SAS_ADDR_SIZE);
+               phy->attached_dev_type = NO_DEVICE;
+               if (!test_bit(SAS_HA_ATA_EH_ACTIVE, &ha->state)) {
+                       phy->phy_id = phy_id;
+                       goto skip;
+               } else
+                       goto out;
+       }
+
        phy->attached_dev_type = to_dev_type(dr);
        if (test_bit(SAS_HA_ATA_EH_ACTIVE, &ha->state))
                goto out;
@@ -272,6 +283,7 @@ static void sas_set_ex_phy(struct domain_device *dev, int phy_id, void *rsp)
        phy->phy->maximum_linkrate = dr->pmax_linkrate;
        phy->phy->negotiated_linkrate = phy->linkrate;
 
+ skip:
        if (new_phy)
                if (sas_phy_add(phy->phy)) {
                        sas_phy_free(phy->phy);
@@ -388,7 +400,7 @@ int sas_ex_phy_discover(struct domain_device *dev, int single)
        if (!disc_req)
                return -ENOMEM;
 
-       disc_resp = alloc_smp_req(DISCOVER_RESP_SIZE);
+       disc_resp = alloc_smp_resp(DISCOVER_RESP_SIZE);
        if (!disc_resp) {
                kfree(disc_req);
                return -ENOMEM;
index 74b67d98e952b43fd980430b0fa0d9c37c55f741..d43faf34c1e29221ddc02b3aedcb2c566a0ed5e8 100644 (file)
@@ -438,11 +438,12 @@ lpfc_sli4_rq_put(struct lpfc_queue *hq, struct lpfc_queue *dq,
        struct lpfc_rqe *temp_hrqe;
        struct lpfc_rqe *temp_drqe;
        struct lpfc_register doorbell;
-       int put_index = hq->host_index;
+       int put_index;
 
        /* sanity check on queue memory */
        if (unlikely(!hq) || unlikely(!dq))
                return -ENOMEM;
+       put_index = hq->host_index;
        temp_hrqe = hq->qe[hq->host_index].rqe;
        temp_drqe = dq->qe[dq->host_index].rqe;
 
index 1d82eef4e1ebf33f2abc59b5b56a9c3b00f7f907..b3db9dcc261957c88d975246dbac839a1f017805 100644 (file)
@@ -1938,11 +1938,6 @@ qla24xx_vport_delete(struct fc_vport *fc_vport)
                    "Timer for the VP[%d] has stopped\n", vha->vp_idx);
        }
 
-       /* No pending activities shall be there on the vha now */
-       if (ql2xextended_error_logging & ql_dbg_user)
-               msleep(random32()%10);  /* Just to see if something falls on
-                                       * the net we have placed below */
-
        BUG_ON(atomic_read(&vha->vref_count));
 
        qla2x00_free_fcports(vha);
index 1626de52e32a764ae370c7c3bccd3bc65c4a7162..fbc305f1c87c5dafc34e95c9c6aa8004699f3820 100644 (file)
@@ -15,6 +15,7 @@
  * | Mailbox commands             |       0x115b       | 0x111a-0x111b  |
  * |                              |                    | 0x112c-0x112e  |
  * |                              |                    | 0x113a         |
+ * |                              |                    | 0x1155-0x1158  |
  * | Device Discovery             |       0x2087       | 0x2020-0x2022, |
  * |                              |                    | 0x2016         |
  * | Queue Command and IO tracing |       0x3031       | 0x3006-0x300b  |
@@ -401,7 +402,7 @@ qla2xxx_copy_atioqueues(struct qla_hw_data *ha, void *ptr,
                void *ring;
        } aq, *aqp;
 
-       if (!ha->tgt.atio_q_length)
+       if (!ha->tgt.atio_ring)
                return ptr;
 
        num_queues = 1;
index c6509911772b5569e9de368bca1a995897359b43..65c5ff75936b1a31c7d37529a74558482168d8af 100644 (file)
@@ -863,7 +863,6 @@ typedef struct {
 #define        MBX_1           BIT_1
 #define        MBX_0           BIT_0
 
-#define RNID_TYPE_SET_VERSION  0x9
 #define RNID_TYPE_ASIC_TEMP    0xC
 
 /*
index eb3ca21a7f17b3c36d08ced7bb6cf0344a85f81e..b310fa97b545c97b81119271a3938ad1ed0c3c4e 100644 (file)
@@ -357,9 +357,6 @@ qla2x00_enable_fce_trace(scsi_qla_host_t *, dma_addr_t, uint16_t , uint16_t *,
 extern int
 qla2x00_disable_fce_trace(scsi_qla_host_t *, uint64_t *, uint64_t *);
 
-extern int
-qla2x00_set_driver_version(scsi_qla_host_t *, char *);
-
 extern int
 qla2x00_read_sfp(scsi_qla_host_t *, dma_addr_t, uint8_t *,
        uint16_t, uint16_t, uint16_t, uint16_t);
index edf4d14a13356f788bd3bbdcf35c245b3bbc440c..b59203393cb22f0a991d299fcc2eac285f7cac9e 100644 (file)
@@ -619,8 +619,6 @@ qla2x00_initialize_adapter(scsi_qla_host_t *vha)
        if (IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha))
                qla24xx_read_fcp_prio_cfg(vha);
 
-       qla2x00_set_driver_version(vha, QLA2XXX_VERSION);
-
        return (rval);
 }
 
@@ -1399,7 +1397,7 @@ qla2x00_alloc_fw_dump(scsi_qla_host_t *vha)
                        mq_size += ha->max_rsp_queues *
                            (rsp->length * sizeof(response_t));
                }
-               if (ha->tgt.atio_q_length)
+               if (ha->tgt.atio_ring)
                        mq_size += ha->tgt.atio_q_length * sizeof(request_t);
                /* Allocate memory for Fibre Channel Event Buffer. */
                if (!IS_QLA25XX(ha) && !IS_QLA81XX(ha) && !IS_QLA83XX(ha))
index 186dd59ce4fa097d2cb051a38db5b49f507eb2b0..43345af56431d011850ad5568b5154179b4b3432 100644 (file)
@@ -3866,64 +3866,6 @@ qla81xx_restart_mpi_firmware(scsi_qla_host_t *vha)
        return rval;
 }
 
-int
-qla2x00_set_driver_version(scsi_qla_host_t *vha, char *version)
-{
-       int rval;
-       mbx_cmd_t mc;
-       mbx_cmd_t *mcp = &mc;
-       int len;
-       uint16_t dwlen;
-       uint8_t *str;
-       dma_addr_t str_dma;
-       struct qla_hw_data *ha = vha->hw;
-
-       if (!IS_FWI2_CAPABLE(ha) || IS_QLA82XX(ha))
-               return QLA_FUNCTION_FAILED;
-
-       ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1155,
-           "Entered %s.\n", __func__);
-
-       str = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &str_dma);
-       if (!str) {
-               ql_log(ql_log_warn, vha, 0x1156,
-                   "Failed to allocate driver version param.\n");
-               return QLA_MEMORY_ALLOC_FAILED;
-       }
-
-       memcpy(str, "\x7\x3\x11\x0", 4);
-       dwlen = str[0];
-       len = dwlen * sizeof(uint32_t) - 4;
-       memset(str + 4, 0, len);
-       if (len > strlen(version))
-               len = strlen(version);
-       memcpy(str + 4, version, len);
-
-       mcp->mb[0] = MBC_SET_RNID_PARAMS;
-       mcp->mb[1] = RNID_TYPE_SET_VERSION << 8 | dwlen;
-       mcp->mb[2] = MSW(LSD(str_dma));
-       mcp->mb[3] = LSW(LSD(str_dma));
-       mcp->mb[6] = MSW(MSD(str_dma));
-       mcp->mb[7] = LSW(MSD(str_dma));
-       mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
-       mcp->in_mb = MBX_0;
-       mcp->tov = MBX_TOV_SECONDS;
-       mcp->flags = 0;
-       rval = qla2x00_mailbox_command(vha, mcp);
-
-       if (rval != QLA_SUCCESS) {
-               ql_dbg(ql_dbg_mbx, vha, 0x1157,
-                   "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
-       } else {
-               ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1158,
-                   "Done %s.\n", __func__);
-       }
-
-       dma_pool_free(ha->s_dma_pool, str, str_dma);
-
-       return rval;
-}
-
 static int
 qla2x00_read_asic_temperature(scsi_qla_host_t *vha, uint16_t *temp)
 {
index 2b6e478d9e33769f881d77b659839b29ae409b64..ec54036d1e12061e4ceee6ee8124270cf97f03f7 100644 (file)
@@ -7,7 +7,7 @@
 /*
  * Driver version
  */
-#define QLA2XXX_VERSION      "8.04.00.08-k"
+#define QLA2XXX_VERSION      "8.04.00.13-k"
 
 #define QLA_DRIVER_MAJOR_VER   8
 #define QLA_DRIVER_MINOR_VER   4
index 86974471af68bf1a27f9f940243fcf044d599a08..2a32036a9404be10941a71ac0f23afe46ca449f9 100644 (file)
@@ -4112,6 +4112,10 @@ static int st_probe(struct device *dev)
        tpnt->disk = disk;
        disk->private_data = &tpnt->driver;
        disk->queue = SDp->request_queue;
+       /* SCSI tape doesn't register this gendisk via add_disk().  Manually
+        * take queue reference that release_disk() expects. */
+       if (!blk_get_queue(disk->queue))
+               goto out_put_disk;
        tpnt->driver = &st_template;
 
        tpnt->device = SDp;
@@ -4185,7 +4189,7 @@ static int st_probe(struct device *dev)
        idr_preload_end();
        if (error < 0) {
                pr_warn("st: idr allocation failed: %d\n", error);
-               goto out_put_disk;
+               goto out_put_queue;
        }
        tpnt->index = error;
        sprintf(disk->disk_name, "st%d", tpnt->index);
@@ -4211,6 +4215,8 @@ out_remove_devs:
        spin_lock(&st_index_lock);
        idr_remove(&st_index_idr, tpnt->index);
        spin_unlock(&st_index_lock);
+out_put_queue:
+       blk_put_queue(disk->queue);
 out_put_disk:
        put_disk(disk);
        kfree(tpnt);
index 4c0f6d883dd3bf689e1900d47285000f39734d5e..7b0bce9367626ad987eb900528a7b329a2f32261 100644 (file)
@@ -675,3 +675,32 @@ u32 ssb_pmu_get_controlclock(struct ssb_chipcommon *cc)
                return 0;
        }
 }
+
+void ssb_pmu_spuravoid_pllupdate(struct ssb_chipcommon *cc, int spuravoid)
+{
+       u32 pmu_ctl = 0;
+
+       switch (cc->dev->bus->chip_id) {
+       case 0x4322:
+               ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL0, 0x11100070);
+               ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL1, 0x1014140a);
+               ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL5, 0x88888854);
+               if (spuravoid == 1)
+                       ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL2, 0x05201828);
+               else
+                       ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL2, 0x05001828);
+               pmu_ctl = SSB_CHIPCO_PMU_CTL_PLL_UPD;
+               break;
+       case 43222:
+               /* TODO: BCM43222 requires updating PLLs too */
+               return;
+       default:
+               ssb_printk(KERN_ERR PFX
+                          "Unknown spuravoidance settings for chip 0x%04X, not changing PLL\n",
+                          cc->dev->bus->chip_id);
+               return;
+       }
+
+       chipco_set32(cc, SSB_CHIPCO_PMU_CTL, pmu_ctl);
+}
+EXPORT_SYMBOL_GPL(ssb_pmu_spuravoid_pllupdate);
index ff1c5ee352cb91107d61f09ae277a33acff9fa26..cbe48ab417459de02ec06660934ec8b3ff8804c0 100644 (file)
@@ -409,6 +409,7 @@ static inline int core_alua_state_standby(
        case REPORT_LUNS:
        case RECEIVE_DIAGNOSTIC:
        case SEND_DIAGNOSTIC:
+               return 0;
        case MAINTENANCE_IN:
                switch (cdb[1] & 0x1f) {
                case MI_REPORT_TARGET_PGS:
@@ -451,6 +452,7 @@ static inline int core_alua_state_unavailable(
        switch (cdb[0]) {
        case INQUIRY:
        case REPORT_LUNS:
+               return 0;
        case MAINTENANCE_IN:
                switch (cdb[1] & 0x1f) {
                case MI_REPORT_TARGET_PGS:
@@ -491,6 +493,7 @@ static inline int core_alua_state_transition(
        switch (cdb[0]) {
        case INQUIRY:
        case REPORT_LUNS:
+               return 0;
        case MAINTENANCE_IN:
                switch (cdb[1] & 0x1f) {
                case MI_REPORT_TARGET_PGS:
index 484b6a3c9b03714a3eae559e061f3767cdc3af72..302909ccf18383831e5f6091f167be354b4db989 100644 (file)
@@ -2643,9 +2643,9 @@ static int mxser_probe(struct pci_dev *pdev,
                                mxvar_sdriver, brd->idx + i, &pdev->dev);
                if (IS_ERR(tty_dev)) {
                        retval = PTR_ERR(tty_dev);
-                       for (i--; i >= 0; i--)
+                       for (; i > 0; i--)
                                tty_unregister_device(mxvar_sdriver,
-                                       brd->idx + i);
+                                       brd->idx + i - 1);
                        goto err_relbrd;
                }
        }
@@ -2751,9 +2751,9 @@ static int __init mxser_module_init(void)
                        tty_dev = tty_port_register_device(&brd->ports[i].port,
                                        mxvar_sdriver, brd->idx + i, NULL);
                        if (IS_ERR(tty_dev)) {
-                               for (i--; i >= 0; i--)
+                               for (; i > 0; i--)
                                        tty_unregister_device(mxvar_sdriver,
-                                               brd->idx + i);
+                                               brd->idx + i - 1);
                                for (i = 0; i < brd->info->nports; i++)
                                        tty_port_destroy(&brd->ports[i].port);
                                free_irq(brd->irq, brd);
index b3455a970a1da01c0afcf013d8c31a49e1004005..35d9ab95c5cbb51d6092f67540678f00e4ee52bd 100644 (file)
@@ -429,7 +429,6 @@ serial_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id)
 {
        struct uart_8250_port uart;
        int ret, line, flags = dev_id->driver_data;
-       struct resource *res = NULL;
 
        if (flags & UNKNOWN_DEV) {
                ret = serial_pnp_guess_board(dev);
@@ -440,12 +439,11 @@ serial_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id)
        memset(&uart, 0, sizeof(uart));
        if (pnp_irq_valid(dev, 0))
                uart.port.irq = pnp_irq(dev, 0);
-       if ((flags & CIR_PORT) && pnp_port_valid(dev, 2))
-               res = pnp_get_resource(dev, IORESOURCE_IO, 2);
-       else if (pnp_port_valid(dev, 0))
-               res = pnp_get_resource(dev, IORESOURCE_IO, 0);
-       if (pnp_resource_enabled(res)) {
-               uart.port.iobase = res->start;
+       if ((flags & CIR_PORT) && pnp_port_valid(dev, 2)) {
+               uart.port.iobase = pnp_port_start(dev, 2);
+               uart.port.iotype = UPIO_PORT;
+       } else if (pnp_port_valid(dev, 0)) {
+               uart.port.iobase = pnp_port_start(dev, 0);
                uart.port.iotype = UPIO_PORT;
        } else if (pnp_mem_valid(dev, 0)) {
                uart.port.mapbase = pnp_mem_start(dev, 0);
index 4dc41408ecb7f659c70ee4daedd96148bb96382d..30d4f7a783cd1f0bbfdf6ebaf491f2400153eaf0 100644 (file)
@@ -886,6 +886,17 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios,
        serial_out(up, UART_MCR, up->mcr | UART_MCR_TCRTLR);
        /* FIFO ENABLE, DMA MODE */
 
+       up->scr |= OMAP_UART_SCR_RX_TRIG_GRANU1_MASK;
+       /*
+        * NOTE: Setting OMAP_UART_SCR_RX_TRIG_GRANU1_MASK
+        * sets Enables the granularity of 1 for TRIGGER RX
+        * level. Along with setting RX FIFO trigger level
+        * to 1 (as noted below, 16 characters) and TLR[3:0]
+        * to zero this will result RX FIFO threshold level
+        * to 1 character, instead of 16 as noted in comment
+        * below.
+        */
+
        /* Set receive FIFO threshold to 16 characters and
         * transmit FIFO threshold to 16 spaces
         */
index 8189cb6a86af29f870cd975d19c4c6b40020c40e..7abc5c81af2ce2befb0067d3ee0b8565a703fcd2 100644 (file)
@@ -346,6 +346,7 @@ static long vfio_pci_ioctl(void *device_data,
 
                if (!(hdr.flags & VFIO_IRQ_SET_DATA_NONE)) {
                        size_t size;
+                       int max = vfio_pci_get_irq_count(vdev, hdr.index);
 
                        if (hdr.flags & VFIO_IRQ_SET_DATA_BOOL)
                                size = sizeof(uint8_t);
@@ -355,7 +356,7 @@ static long vfio_pci_ioctl(void *device_data,
                                return -EINVAL;
 
                        if (hdr.argsz - minsz < hdr.count * size ||
-                           hdr.count > vfio_pci_get_irq_count(vdev, hdr.index))
+                           hdr.start >= max || hdr.start + hdr.count > max)
                                return -EINVAL;
 
                        data = memdup_user((void __user *)(arg + minsz),
index 2968b4934659aab01dd626334a9ab7fc0e607383..957a0b98a5d90f689c68fb92ba76e60c72f89944 100644 (file)
@@ -74,9 +74,8 @@ enum {
 
 struct vhost_scsi {
        /* Protected by vhost_scsi->dev.mutex */
-       struct tcm_vhost_tpg *vs_tpg[VHOST_SCSI_MAX_TARGET];
+       struct tcm_vhost_tpg **vs_tpg;
        char vs_vhost_wwpn[TRANSPORT_IQN_LEN];
-       bool vs_endpoint;
 
        struct vhost_dev dev;
        struct vhost_virtqueue vqs[VHOST_SCSI_MAX_VQ];
@@ -579,9 +578,27 @@ static void tcm_vhost_submission_work(struct work_struct *work)
        }
 }
 
+static void vhost_scsi_send_bad_target(struct vhost_scsi *vs,
+       struct vhost_virtqueue *vq, int head, unsigned out)
+{
+       struct virtio_scsi_cmd_resp __user *resp;
+       struct virtio_scsi_cmd_resp rsp;
+       int ret;
+
+       memset(&rsp, 0, sizeof(rsp));
+       rsp.response = VIRTIO_SCSI_S_BAD_TARGET;
+       resp = vq->iov[out].iov_base;
+       ret = __copy_to_user(resp, &rsp, sizeof(rsp));
+       if (!ret)
+               vhost_add_used_and_signal(&vs->dev, vq, head, 0);
+       else
+               pr_err("Faulted on virtio_scsi_cmd_resp\n");
+}
+
 static void vhost_scsi_handle_vq(struct vhost_scsi *vs,
        struct vhost_virtqueue *vq)
 {
+       struct tcm_vhost_tpg **vs_tpg;
        struct virtio_scsi_cmd_req v_req;
        struct tcm_vhost_tpg *tv_tpg;
        struct tcm_vhost_cmd *tv_cmd;
@@ -590,8 +607,16 @@ static void vhost_scsi_handle_vq(struct vhost_scsi *vs,
        int head, ret;
        u8 target;
 
-       /* Must use ioctl VHOST_SCSI_SET_ENDPOINT */
-       if (unlikely(!vs->vs_endpoint))
+       /*
+        * We can handle the vq only after the endpoint is setup by calling the
+        * VHOST_SCSI_SET_ENDPOINT ioctl.
+        *
+        * TODO: Check that we are running from vhost_worker which acts
+        * as read-side critical section for vhost kind of RCU.
+        * See the comments in struct vhost_virtqueue in drivers/vhost/vhost.h
+        */
+       vs_tpg = rcu_dereference_check(vq->private_data, 1);
+       if (!vs_tpg)
                return;
 
        mutex_lock(&vq->mutex);
@@ -661,23 +686,11 @@ static void vhost_scsi_handle_vq(struct vhost_scsi *vs,
 
                /* Extract the tpgt */
                target = v_req.lun[1];
-               tv_tpg = vs->vs_tpg[target];
+               tv_tpg = ACCESS_ONCE(vs_tpg[target]);
 
                /* Target does not exist, fail the request */
                if (unlikely(!tv_tpg)) {
-                       struct virtio_scsi_cmd_resp __user *resp;
-                       struct virtio_scsi_cmd_resp rsp;
-
-                       memset(&rsp, 0, sizeof(rsp));
-                       rsp.response = VIRTIO_SCSI_S_BAD_TARGET;
-                       resp = vq->iov[out].iov_base;
-                       ret = __copy_to_user(resp, &rsp, sizeof(rsp));
-                       if (!ret)
-                               vhost_add_used_and_signal(&vs->dev,
-                                                         vq, head, 0);
-                       else
-                               pr_err("Faulted on virtio_scsi_cmd_resp\n");
-
+                       vhost_scsi_send_bad_target(vs, vq, head, out);
                        continue;
                }
 
@@ -690,22 +703,13 @@ static void vhost_scsi_handle_vq(struct vhost_scsi *vs,
                if (IS_ERR(tv_cmd)) {
                        vq_err(vq, "vhost_scsi_allocate_cmd failed %ld\n",
                                        PTR_ERR(tv_cmd));
-                       break;
+                       goto err_cmd;
                }
                pr_debug("Allocated tv_cmd: %p exp_data_len: %d, data_direction"
                        ": %d\n", tv_cmd, exp_data_len, data_direction);
 
                tv_cmd->tvc_vhost = vs;
                tv_cmd->tvc_vq = vq;
-
-               if (unlikely(vq->iov[out].iov_len !=
-                               sizeof(struct virtio_scsi_cmd_resp))) {
-                       vq_err(vq, "Expecting virtio_scsi_cmd_resp, got %zu"
-                               " bytes, out: %d, in: %d\n",
-                               vq->iov[out].iov_len, out, in);
-                       break;
-               }
-
                tv_cmd->tvc_resp = vq->iov[out].iov_base;
 
                /*
@@ -725,7 +729,7 @@ static void vhost_scsi_handle_vq(struct vhost_scsi *vs,
                                " exceeds SCSI_MAX_VARLEN_CDB_SIZE: %d\n",
                                scsi_command_size(tv_cmd->tvc_cdb),
                                TCM_VHOST_MAX_CDB_SIZE);
-                       break; /* TODO */
+                       goto err_free;
                }
                tv_cmd->tvc_lun = ((v_req.lun[2] << 8) | v_req.lun[3]) & 0x3FFF;
 
@@ -738,7 +742,7 @@ static void vhost_scsi_handle_vq(struct vhost_scsi *vs,
                                        data_direction == DMA_TO_DEVICE);
                        if (unlikely(ret)) {
                                vq_err(vq, "Failed to map iov to sgl\n");
-                               break; /* TODO */
+                               goto err_free;
                        }
                }
 
@@ -759,6 +763,13 @@ static void vhost_scsi_handle_vq(struct vhost_scsi *vs,
        }
 
        mutex_unlock(&vq->mutex);
+       return;
+
+err_free:
+       vhost_scsi_free_cmd(tv_cmd);
+err_cmd:
+       vhost_scsi_send_bad_target(vs, vq, head, out);
+       mutex_unlock(&vq->mutex);
 }
 
 static void vhost_scsi_ctl_handle_kick(struct vhost_work *work)
@@ -780,6 +791,20 @@ static void vhost_scsi_handle_kick(struct vhost_work *work)
        vhost_scsi_handle_vq(vs, vq);
 }
 
+static void vhost_scsi_flush_vq(struct vhost_scsi *vs, int index)
+{
+       vhost_poll_flush(&vs->dev.vqs[index].poll);
+}
+
+static void vhost_scsi_flush(struct vhost_scsi *vs)
+{
+       int i;
+
+       for (i = 0; i < VHOST_SCSI_MAX_VQ; i++)
+               vhost_scsi_flush_vq(vs, i);
+       vhost_work_flush(&vs->dev, &vs->vs_completion_work);
+}
+
 /*
  * Called from vhost_scsi_ioctl() context to walk the list of available
  * tcm_vhost_tpg with an active struct tcm_vhost_nexus
@@ -790,8 +815,10 @@ static int vhost_scsi_set_endpoint(
 {
        struct tcm_vhost_tport *tv_tport;
        struct tcm_vhost_tpg *tv_tpg;
+       struct tcm_vhost_tpg **vs_tpg;
+       struct vhost_virtqueue *vq;
+       int index, ret, i, len;
        bool match = false;
-       int index, ret;
 
        mutex_lock(&vs->dev.mutex);
        /* Verify that ring has been setup correctly. */
@@ -803,6 +830,15 @@ static int vhost_scsi_set_endpoint(
                }
        }
 
+       len = sizeof(vs_tpg[0]) * VHOST_SCSI_MAX_TARGET;
+       vs_tpg = kzalloc(len, GFP_KERNEL);
+       if (!vs_tpg) {
+               mutex_unlock(&vs->dev.mutex);
+               return -ENOMEM;
+       }
+       if (vs->vs_tpg)
+               memcpy(vs_tpg, vs->vs_tpg, len);
+
        mutex_lock(&tcm_vhost_mutex);
        list_for_each_entry(tv_tpg, &tcm_vhost_list, tv_tpg_list) {
                mutex_lock(&tv_tpg->tv_tpg_mutex);
@@ -817,14 +853,15 @@ static int vhost_scsi_set_endpoint(
                tv_tport = tv_tpg->tport;
 
                if (!strcmp(tv_tport->tport_name, t->vhost_wwpn)) {
-                       if (vs->vs_tpg[tv_tpg->tport_tpgt]) {
+                       if (vs->vs_tpg && vs->vs_tpg[tv_tpg->tport_tpgt]) {
                                mutex_unlock(&tv_tpg->tv_tpg_mutex);
                                mutex_unlock(&tcm_vhost_mutex);
                                mutex_unlock(&vs->dev.mutex);
+                               kfree(vs_tpg);
                                return -EEXIST;
                        }
                        tv_tpg->tv_tpg_vhost_count++;
-                       vs->vs_tpg[tv_tpg->tport_tpgt] = tv_tpg;
+                       vs_tpg[tv_tpg->tport_tpgt] = tv_tpg;
                        smp_mb__after_atomic_inc();
                        match = true;
                }
@@ -835,12 +872,27 @@ static int vhost_scsi_set_endpoint(
        if (match) {
                memcpy(vs->vs_vhost_wwpn, t->vhost_wwpn,
                       sizeof(vs->vs_vhost_wwpn));
-               vs->vs_endpoint = true;
+               for (i = 0; i < VHOST_SCSI_MAX_VQ; i++) {
+                       vq = &vs->vqs[i];
+                       /* Flushing the vhost_work acts as synchronize_rcu */
+                       mutex_lock(&vq->mutex);
+                       rcu_assign_pointer(vq->private_data, vs_tpg);
+                       vhost_init_used(vq);
+                       mutex_unlock(&vq->mutex);
+               }
                ret = 0;
        } else {
                ret = -EEXIST;
        }
 
+       /*
+        * Act as synchronize_rcu to make sure access to
+        * old vs->vs_tpg is finished.
+        */
+       vhost_scsi_flush(vs);
+       kfree(vs->vs_tpg);
+       vs->vs_tpg = vs_tpg;
+
        mutex_unlock(&vs->dev.mutex);
        return ret;
 }
@@ -851,6 +903,8 @@ static int vhost_scsi_clear_endpoint(
 {
        struct tcm_vhost_tport *tv_tport;
        struct tcm_vhost_tpg *tv_tpg;
+       struct vhost_virtqueue *vq;
+       bool match = false;
        int index, ret, i;
        u8 target;
 
@@ -862,9 +916,14 @@ static int vhost_scsi_clear_endpoint(
                        goto err_dev;
                }
        }
+
+       if (!vs->vs_tpg) {
+               mutex_unlock(&vs->dev.mutex);
+               return 0;
+       }
+
        for (i = 0; i < VHOST_SCSI_MAX_TARGET; i++) {
                target = i;
-
                tv_tpg = vs->vs_tpg[target];
                if (!tv_tpg)
                        continue;
@@ -886,10 +945,27 @@ static int vhost_scsi_clear_endpoint(
                }
                tv_tpg->tv_tpg_vhost_count--;
                vs->vs_tpg[target] = NULL;
-               vs->vs_endpoint = false;
+               match = true;
                mutex_unlock(&tv_tpg->tv_tpg_mutex);
        }
+       if (match) {
+               for (i = 0; i < VHOST_SCSI_MAX_VQ; i++) {
+                       vq = &vs->vqs[i];
+                       /* Flushing the vhost_work acts as synchronize_rcu */
+                       mutex_lock(&vq->mutex);
+                       rcu_assign_pointer(vq->private_data, NULL);
+                       mutex_unlock(&vq->mutex);
+               }
+       }
+       /*
+        * Act as synchronize_rcu to make sure access to
+        * old vs->vs_tpg is finished.
+        */
+       vhost_scsi_flush(vs);
+       kfree(vs->vs_tpg);
+       vs->vs_tpg = NULL;
        mutex_unlock(&vs->dev.mutex);
+
        return 0;
 
 err_tpg:
@@ -899,6 +975,24 @@ err_dev:
        return ret;
 }
 
+static int vhost_scsi_set_features(struct vhost_scsi *vs, u64 features)
+{
+       if (features & ~VHOST_SCSI_FEATURES)
+               return -EOPNOTSUPP;
+
+       mutex_lock(&vs->dev.mutex);
+       if ((features & (1 << VHOST_F_LOG_ALL)) &&
+           !vhost_log_access_ok(&vs->dev)) {
+               mutex_unlock(&vs->dev.mutex);
+               return -EFAULT;
+       }
+       vs->dev.acked_features = features;
+       smp_wmb();
+       vhost_scsi_flush(vs);
+       mutex_unlock(&vs->dev.mutex);
+       return 0;
+}
+
 static int vhost_scsi_open(struct inode *inode, struct file *f)
 {
        struct vhost_scsi *s;
@@ -939,38 +1033,6 @@ static int vhost_scsi_release(struct inode *inode, struct file *f)
        return 0;
 }
 
-static void vhost_scsi_flush_vq(struct vhost_scsi *vs, int index)
-{
-       vhost_poll_flush(&vs->dev.vqs[index].poll);
-}
-
-static void vhost_scsi_flush(struct vhost_scsi *vs)
-{
-       int i;
-
-       for (i = 0; i < VHOST_SCSI_MAX_VQ; i++)
-               vhost_scsi_flush_vq(vs, i);
-       vhost_work_flush(&vs->dev, &vs->vs_completion_work);
-}
-
-static int vhost_scsi_set_features(struct vhost_scsi *vs, u64 features)
-{
-       if (features & ~VHOST_SCSI_FEATURES)
-               return -EOPNOTSUPP;
-
-       mutex_lock(&vs->dev.mutex);
-       if ((features & (1 << VHOST_F_LOG_ALL)) &&
-           !vhost_log_access_ok(&vs->dev)) {
-               mutex_unlock(&vs->dev.mutex);
-               return -EFAULT;
-       }
-       vs->dev.acked_features = features;
-       smp_wmb();
-       vhost_scsi_flush(vs);
-       mutex_unlock(&vs->dev.mutex);
-       return 0;
-}
-
 static long vhost_scsi_ioctl(struct file *f, unsigned int ioctl,
                                unsigned long arg)
 {
index 7c254084b6a044da4658071a864e9dabbfdd16dc..86291dcd964a96088938b91fdaa79f6683104e8b 100644 (file)
@@ -1373,15 +1373,12 @@ fb_mmap(struct file *file, struct vm_area_struct * vma)
 {
        struct fb_info *info = file_fb_info(file);
        struct fb_ops *fb;
-       unsigned long off;
+       unsigned long mmio_pgoff;
        unsigned long start;
        u32 len;
 
        if (!info)
                return -ENODEV;
-       if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
-               return -EINVAL;
-       off = vma->vm_pgoff << PAGE_SHIFT;
        fb = info->fbops;
        if (!fb)
                return -ENODEV;
@@ -1393,32 +1390,24 @@ fb_mmap(struct file *file, struct vm_area_struct * vma)
                return res;
        }
 
-       /* frame buffer memory */
+       /*
+        * Ugh. This can be either the frame buffer mapping, or
+        * if pgoff points past it, the mmio mapping.
+        */
        start = info->fix.smem_start;
-       len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.smem_len);
-       if (off >= len) {
-               /* memory mapped io */
-               off -= len;
-               if (info->var.accel_flags) {
-                       mutex_unlock(&info->mm_lock);
-                       return -EINVAL;
-               }
+       len = info->fix.smem_len;
+       mmio_pgoff = PAGE_ALIGN((start & ~PAGE_MASK) + len) >> PAGE_SHIFT;
+       if (vma->vm_pgoff >= mmio_pgoff) {
+               vma->vm_pgoff -= mmio_pgoff;
                start = info->fix.mmio_start;
-               len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.mmio_len);
+               len = info->fix.mmio_len;
        }
        mutex_unlock(&info->mm_lock);
-       start &= PAGE_MASK;
-       if ((vma->vm_end - vma->vm_start + off) > len)
-               return -EINVAL;
-       off += start;
-       vma->vm_pgoff = off >> PAGE_SHIFT;
-       /* VM_IO | VM_DONTEXPAND | VM_DONTDUMP are set by io_remap_pfn_range()*/
+
        vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
-       fb_pgprotect(file, vma, off);
-       if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT,
-                            vma->vm_end - vma->vm_start, vma->vm_page_prot))
-               return -EAGAIN;
-       return 0;
+       fb_pgprotect(file, vma, start);
+
+       return vm_iomap_memory(vma, start, len);
 }
 
 static int
index 9ed83419038bbdd94da43f0d988732fcaefec188..84de2632857a335086b829597392e2a7e456cc54 100644 (file)
@@ -252,7 +252,5 @@ void mmp_unregister_path(struct mmp_path *path)
 
        kfree(path);
        mutex_unlock(&disp_lock);
-
-       dev_info(path->dev, "de-register %s\n", path->name);
 }
 EXPORT_SYMBOL_GPL(mmp_unregister_path);
index 9fcc70c11ceae14b78052dbab2b4eaafdee553db..e89fc313397233bf80a7d210d8b0db2a36492314 100644 (file)
@@ -117,7 +117,7 @@ config ARM_SP805_WATCHDOG
 
 config AT91RM9200_WATCHDOG
        tristate "AT91RM9200 watchdog"
-       depends on ARCH_AT91
+       depends on ARCH_AT91RM9200
        help
          Watchdog timer embedded into AT91RM9200 chips. This will reboot your
          system when the timeout is reached.
index aa85881d17b23f7ff6425be0140b6aed0c63c942..2647ad8e1f19c032eaa55a197dce9a5c215ddd8e 100644 (file)
@@ -1316,7 +1316,7 @@ static void __xen_evtchn_do_upcall(void)
 {
        int start_word_idx, start_bit_idx;
        int word_idx, bit_idx;
-       int i;
+       int i, irq;
        int cpu = get_cpu();
        struct shared_info *s = HYPERVISOR_shared_info;
        struct vcpu_info *vcpu_info = __this_cpu_read(xen_vcpu);
@@ -1324,6 +1324,8 @@ static void __xen_evtchn_do_upcall(void)
 
        do {
                xen_ulong_t pending_words;
+               xen_ulong_t pending_bits;
+               struct irq_desc *desc;
 
                vcpu_info->evtchn_upcall_pending = 0;
 
@@ -1335,6 +1337,17 @@ static void __xen_evtchn_do_upcall(void)
                 * selector flag. xchg_xen_ulong must contain an
                 * appropriate barrier.
                 */
+               if ((irq = per_cpu(virq_to_irq, cpu)[VIRQ_TIMER]) != -1) {
+                       int evtchn = evtchn_from_irq(irq);
+                       word_idx = evtchn / BITS_PER_LONG;
+                       pending_bits = evtchn % BITS_PER_LONG;
+                       if (active_evtchns(cpu, s, word_idx) & (1ULL << pending_bits)) {
+                               desc = irq_to_desc(irq);
+                               if (desc)
+                                       generic_handle_irq_desc(irq, desc);
+                       }
+               }
+
                pending_words = xchg_xen_ulong(&vcpu_info->evtchn_pending_sel, 0);
 
                start_word_idx = __this_cpu_read(current_word_idx);
@@ -1343,7 +1356,6 @@ static void __xen_evtchn_do_upcall(void)
                word_idx = start_word_idx;
 
                for (i = 0; pending_words != 0; i++) {
-                       xen_ulong_t pending_bits;
                        xen_ulong_t words;
 
                        words = MASK_LSBS(pending_words, word_idx);
@@ -1372,8 +1384,7 @@ static void __xen_evtchn_do_upcall(void)
 
                        do {
                                xen_ulong_t bits;
-                               int port, irq;
-                               struct irq_desc *desc;
+                               int port;
 
                                bits = MASK_LSBS(pending_bits, bit_idx);
 
index 3939829f6c5cc67e7d0ca1e9518f1df834be5088..86af964c2425d7077467bf54eaecde3d2d4c4911 100644 (file)
@@ -1137,6 +1137,7 @@ static unsigned long vma_dump_size(struct vm_area_struct *vma,
                        goto whole;
                if (!(vma->vm_flags & VM_SHARED) && FILTER(HUGETLB_PRIVATE))
                        goto whole;
+               return 0;
        }
 
        /* Do not dump I/O mapped devices or special mappings */
index bb5768f59b32e22fdcde250f0ae8b01eb6b69b48..b96fc6ce485595f0179bc909c807ae197258e671 100644 (file)
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -1428,8 +1428,6 @@ void bio_endio(struct bio *bio, int error)
        else if (!test_bit(BIO_UPTODATE, &bio->bi_flags))
                error = -EIO;
 
-       trace_block_bio_complete(bio, error);
-
        if (bio->bi_end_io)
                bio->bi_end_io(bio, error);
 }
index 451fad96ecd115393207e69433162b7328f74923..ef96381569a4a1229b95f6b3470f232b3ebe8b0e 100644 (file)
@@ -317,6 +317,7 @@ static noinline int overwrite_item(struct btrfs_trans_handle *trans,
        unsigned long src_ptr;
        unsigned long dst_ptr;
        int overwrite_root = 0;
+       bool inode_item = key->type == BTRFS_INODE_ITEM_KEY;
 
        if (root->root_key.objectid != BTRFS_TREE_LOG_OBJECTID)
                overwrite_root = 1;
@@ -326,6 +327,9 @@ static noinline int overwrite_item(struct btrfs_trans_handle *trans,
 
        /* look for the key in the destination tree */
        ret = btrfs_search_slot(NULL, root, key, path, 0, 0);
+       if (ret < 0)
+               return ret;
+
        if (ret == 0) {
                char *src_copy;
                char *dst_copy;
@@ -367,6 +371,30 @@ static noinline int overwrite_item(struct btrfs_trans_handle *trans,
                        return 0;
                }
 
+               /*
+                * We need to load the old nbytes into the inode so when we
+                * replay the extents we've logged we get the right nbytes.
+                */
+               if (inode_item) {
+                       struct btrfs_inode_item *item;
+                       u64 nbytes;
+
+                       item = btrfs_item_ptr(path->nodes[0], path->slots[0],
+                                             struct btrfs_inode_item);
+                       nbytes = btrfs_inode_nbytes(path->nodes[0], item);
+                       item = btrfs_item_ptr(eb, slot,
+                                             struct btrfs_inode_item);
+                       btrfs_set_inode_nbytes(eb, item, nbytes);
+               }
+       } else if (inode_item) {
+               struct btrfs_inode_item *item;
+
+               /*
+                * New inode, set nbytes to 0 so that the nbytes comes out
+                * properly when we replay the extents.
+                */
+               item = btrfs_item_ptr(eb, slot, struct btrfs_inode_item);
+               btrfs_set_inode_nbytes(eb, item, 0);
        }
 insert:
        btrfs_release_path(path);
@@ -486,7 +514,7 @@ static noinline int replay_one_extent(struct btrfs_trans_handle *trans,
        int found_type;
        u64 extent_end;
        u64 start = key->offset;
-       u64 saved_nbytes;
+       u64 nbytes = 0;
        struct btrfs_file_extent_item *item;
        struct inode *inode = NULL;
        unsigned long size;
@@ -496,10 +524,19 @@ static noinline int replay_one_extent(struct btrfs_trans_handle *trans,
        found_type = btrfs_file_extent_type(eb, item);
 
        if (found_type == BTRFS_FILE_EXTENT_REG ||
-           found_type == BTRFS_FILE_EXTENT_PREALLOC)
-               extent_end = start + btrfs_file_extent_num_bytes(eb, item);
-       else if (found_type == BTRFS_FILE_EXTENT_INLINE) {
+           found_type == BTRFS_FILE_EXTENT_PREALLOC) {
+               nbytes = btrfs_file_extent_num_bytes(eb, item);
+               extent_end = start + nbytes;
+
+               /*
+                * We don't add to the inodes nbytes if we are prealloc or a
+                * hole.
+                */
+               if (btrfs_file_extent_disk_bytenr(eb, item) == 0)
+                       nbytes = 0;
+       } else if (found_type == BTRFS_FILE_EXTENT_INLINE) {
                size = btrfs_file_extent_inline_len(eb, item);
+               nbytes = btrfs_file_extent_ram_bytes(eb, item);
                extent_end = ALIGN(start + size, root->sectorsize);
        } else {
                ret = 0;
@@ -548,7 +585,6 @@ static noinline int replay_one_extent(struct btrfs_trans_handle *trans,
        }
        btrfs_release_path(path);
 
-       saved_nbytes = inode_get_bytes(inode);
        /* drop any overlapping extents */
        ret = btrfs_drop_extents(trans, root, inode, start, extent_end, 1);
        BUG_ON(ret);
@@ -635,7 +671,7 @@ static noinline int replay_one_extent(struct btrfs_trans_handle *trans,
                BUG_ON(ret);
        }
 
-       inode_set_bytes(inode, saved_nbytes);
+       inode_add_bytes(inode, nbytes);
        ret = btrfs_update_inode(trans, root, inode);
 out:
        if (inode)
index 991c63c6bdd053189082c6208407a5df55b29053..21b3a291c327c1e3871d110725ed972ce8ab21ba 100644 (file)
@@ -1575,14 +1575,24 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
                        }
                        break;
                case Opt_blank_pass:
-                       vol->password = NULL;
-                       break;
-               case Opt_pass:
                        /* passwords have to be handled differently
                         * to allow the character used for deliminator
                         * to be passed within them
                         */
 
+                       /*
+                        * Check if this is a case where the  password
+                        * starts with a delimiter
+                        */
+                       tmp_end = strchr(data, '=');
+                       tmp_end++;
+                       if (!(tmp_end < end && tmp_end[1] == delim)) {
+                               /* No it is not. Set the password to NULL */
+                               vol->password = NULL;
+                               break;
+                       }
+                       /* Yes it is. Drop down to Opt_pass below.*/
+               case Opt_pass:
                        /* Obtain the value string */
                        value = strchr(data, '=');
                        value++;
index 412e6eda25f813e037f3d18936e7ed860793a443..e4141f2574953893377939f2362a673a62a609b9 100644 (file)
@@ -80,13 +80,6 @@ ecryptfs_miscdev_open(struct inode *inode, struct file *file)
        int rc;
 
        mutex_lock(&ecryptfs_daemon_hash_mux);
-       rc = try_module_get(THIS_MODULE);
-       if (rc == 0) {
-               rc = -EIO;
-               printk(KERN_ERR "%s: Error attempting to increment module use "
-                      "count; rc = [%d]\n", __func__, rc);
-               goto out_unlock_daemon_list;
-       }
        rc = ecryptfs_find_daemon_by_euid(&daemon);
        if (!rc) {
                rc = -EINVAL;
@@ -96,7 +89,7 @@ ecryptfs_miscdev_open(struct inode *inode, struct file *file)
        if (rc) {
                printk(KERN_ERR "%s: Error attempting to spawn daemon; "
                       "rc = [%d]\n", __func__, rc);
-               goto out_module_put_unlock_daemon_list;
+               goto out_unlock_daemon_list;
        }
        mutex_lock(&daemon->mux);
        if (daemon->flags & ECRYPTFS_DAEMON_MISCDEV_OPEN) {
@@ -108,9 +101,6 @@ ecryptfs_miscdev_open(struct inode *inode, struct file *file)
        atomic_inc(&ecryptfs_num_miscdev_opens);
 out_unlock_daemon:
        mutex_unlock(&daemon->mux);
-out_module_put_unlock_daemon_list:
-       if (rc)
-               module_put(THIS_MODULE);
 out_unlock_daemon_list:
        mutex_unlock(&ecryptfs_daemon_hash_mux);
        return rc;
@@ -147,7 +137,6 @@ ecryptfs_miscdev_release(struct inode *inode, struct file *file)
                       "bug.\n", __func__, rc);
                BUG();
        }
-       module_put(THIS_MODULE);
        return rc;
 }
 
@@ -471,6 +460,7 @@ out_free:
 
 
 static const struct file_operations ecryptfs_miscdev_fops = {
+       .owner   = THIS_MODULE,
        .open    = ecryptfs_miscdev_open,
        .poll    = ecryptfs_miscdev_poll,
        .read    = ecryptfs_miscdev_read,
index a94f0f779d5e3338281e3a1f5a0aaee6b16a01bc..fe0a76213d9eb6b39e291c415ccc4bf7af3a06e8 100644 (file)
@@ -533,7 +533,7 @@ void hfsplus_file_truncate(struct inode *inode)
                struct address_space *mapping = inode->i_mapping;
                struct page *page;
                void *fsdata;
-               u32 size = inode->i_size;
+               loff_t size = inode->i_size;
 
                res = pagecache_write_begin(NULL, mapping, size, 0,
                                                AOP_FLAG_UNINTERRUPTIBLE,
index 84e3d856e91d05c27aa182be0d28dead99128c93..523464e62849ccea755104d19e7ce39c2ca5fbfd 100644 (file)
@@ -110,7 +110,7 @@ static int hugetlbfs_file_mmap(struct file *file, struct vm_area_struct *vma)
         * way when do_mmap_pgoff unwinds (may be important on powerpc
         * and ia64).
         */
-       vma->vm_flags |= VM_HUGETLB | VM_DONTEXPAND | VM_DONTDUMP;
+       vma->vm_flags |= VM_HUGETLB | VM_DONTEXPAND;
        vma->vm_ops = &hugetlb_vm_ops;
 
        if (vma->vm_pgoff & (~huge_page_mask(h) >> PAGE_SHIFT))
index f5f7c06c36fb159f89a793510c62f3f9170c3e4d..a898b3d43ccf3990986d51be3305bdc3e6d665ef 100644 (file)
@@ -725,7 +725,7 @@ void prune_icache_sb(struct super_block *sb, int nr_to_scan)
                 * inode to the back of the list so we don't spin on it.
                 */
                if (!spin_trylock(&inode->i_lock)) {
-                       list_move_tail(&inode->i_lru, &sb->s_inode_lru);
+                       list_move(&inode->i_lru, &sb->s_inode_lru);
                        continue;
                }
 
index d581e45c0a9fd6ada94edd2bb6ea4fe4c7fc9e23..341d3f564082f2367a7f1538255e90bdfbfd8cd2 100644 (file)
@@ -1690,7 +1690,7 @@ static int do_loopback(struct path *path, const char *old_name,
 
        if (IS_ERR(mnt)) {
                err = PTR_ERR(mnt);
-               goto out;
+               goto out2;
        }
 
        err = graft_tree(mnt, path);
index ac4fc9a8fdbc6c6133b186ddd5de476db9f03930..66b6664dcd4c4c9cd209d9420eb9de895cd1e344 100644 (file)
@@ -300,7 +300,7 @@ int nfs40_walk_client_list(struct nfs_client *new,
                           struct rpc_cred *cred)
 {
        struct nfs_net *nn = net_generic(new->cl_net, nfs_net_id);
-       struct nfs_client *pos, *n, *prev = NULL;
+       struct nfs_client *pos, *prev = NULL;
        struct nfs4_setclientid_res clid = {
                .clientid       = new->cl_clientid,
                .confirm        = new->cl_confirm,
@@ -308,10 +308,23 @@ int nfs40_walk_client_list(struct nfs_client *new,
        int status = -NFS4ERR_STALE_CLIENTID;
 
        spin_lock(&nn->nfs_client_lock);
-       list_for_each_entry_safe(pos, n, &nn->nfs_client_list, cl_share_link) {
+       list_for_each_entry(pos, &nn->nfs_client_list, cl_share_link) {
                /* If "pos" isn't marked ready, we can't trust the
                 * remaining fields in "pos" */
-               if (pos->cl_cons_state < NFS_CS_READY)
+               if (pos->cl_cons_state > NFS_CS_READY) {
+                       atomic_inc(&pos->cl_count);
+                       spin_unlock(&nn->nfs_client_lock);
+
+                       if (prev)
+                               nfs_put_client(prev);
+                       prev = pos;
+
+                       status = nfs_wait_client_init_complete(pos);
+                       spin_lock(&nn->nfs_client_lock);
+                       if (status < 0)
+                               continue;
+               }
+               if (pos->cl_cons_state != NFS_CS_READY)
                        continue;
 
                if (pos->rpc_ops != new->rpc_ops)
@@ -423,16 +436,16 @@ int nfs41_walk_client_list(struct nfs_client *new,
                           struct rpc_cred *cred)
 {
        struct nfs_net *nn = net_generic(new->cl_net, nfs_net_id);
-       struct nfs_client *pos, *n, *prev = NULL;
+       struct nfs_client *pos, *prev = NULL;
        int status = -NFS4ERR_STALE_CLIENTID;
 
        spin_lock(&nn->nfs_client_lock);
-       list_for_each_entry_safe(pos, n, &nn->nfs_client_list, cl_share_link) {
+       list_for_each_entry(pos, &nn->nfs_client_list, cl_share_link) {
                /* If "pos" isn't marked ready, we can't trust the
                 * remaining fields in "pos", especially the client
                 * ID and serverowner fields.  Wait for CREATE_SESSION
                 * to finish. */
-               if (pos->cl_cons_state < NFS_CS_READY) {
+               if (pos->cl_cons_state > NFS_CS_READY) {
                        atomic_inc(&pos->cl_count);
                        spin_unlock(&nn->nfs_client_lock);
 
@@ -440,18 +453,17 @@ int nfs41_walk_client_list(struct nfs_client *new,
                                nfs_put_client(prev);
                        prev = pos;
 
-                       nfs4_schedule_lease_recovery(pos);
                        status = nfs_wait_client_init_complete(pos);
-                       if (status < 0) {
-                               nfs_put_client(pos);
-                               spin_lock(&nn->nfs_client_lock);
-                               continue;
+                       if (status == 0) {
+                               nfs4_schedule_lease_recovery(pos);
+                               status = nfs4_wait_clnt_recover(pos);
                        }
-                       status = pos->cl_cons_state;
                        spin_lock(&nn->nfs_client_lock);
                        if (status < 0)
                                continue;
                }
+               if (pos->cl_cons_state != NFS_CS_READY)
+                       continue;
 
                if (pos->rpc_ops != new->rpc_ops)
                        continue;
@@ -469,17 +481,18 @@ int nfs41_walk_client_list(struct nfs_client *new,
                        continue;
 
                atomic_inc(&pos->cl_count);
-               spin_unlock(&nn->nfs_client_lock);
+               *result = pos;
+               status = 0;
                dprintk("NFS: <-- %s using nfs_client = %p ({%d})\n",
                        __func__, pos, atomic_read(&pos->cl_count));
-
-               *result = pos;
-               return 0;
+               break;
        }
 
        /* No matching nfs_client found. */
        spin_unlock(&nn->nfs_client_lock);
        dprintk("NFS: <-- %s status = %d\n", __func__, status);
+       if (prev)
+               nfs_put_client(prev);
        return status;
 }
 #endif /* CONFIG_NFS_V4_1 */
index 26431cf62ddbc393fd5fe1e432742be37d06e12e..0ad025eb523bc6b651d82497c29a0d27ebdf3dac 100644 (file)
@@ -1046,6 +1046,7 @@ static struct nfs4_state *nfs4_try_open_cached(struct nfs4_opendata *opendata)
                /* Save the delegation */
                nfs4_stateid_copy(&stateid, &delegation->stateid);
                rcu_read_unlock();
+               nfs_release_seqid(opendata->o_arg.seqid);
                ret = nfs_may_open(state->inode, state->owner->so_cred, open_mode);
                if (ret != 0)
                        goto out;
index 6ace365c6334db844af0c2c3f221cd871ef3658c..d41a3518509fa5a0cf1dbbdcbed87f39fa3eff45 100644 (file)
@@ -1886,7 +1886,13 @@ again:
                        status = PTR_ERR(clnt);
                        break;
                }
-               clp->cl_rpcclient = clnt;
+               /* Note: this is safe because we haven't yet marked the
+                * client as ready, so we are the only user of
+                * clp->cl_rpcclient
+                */
+               clnt = xchg(&clp->cl_rpcclient, clnt);
+               rpc_shutdown_client(clnt);
+               clnt = clp->cl_rpcclient;
                goto again;
 
        case -NFS4ERR_MINOR_VERS_MISMATCH:
index f7ed9ee46eb9d3818d2210c100731e5eda6ee35e..cbd0f1b324b972b96f036139fcd96bf53a03fb01 100644 (file)
@@ -143,6 +143,7 @@ static const char * const task_state_array[] = {
        "x (dead)",             /*  64 */
        "K (wakekill)",         /* 128 */
        "W (waking)",           /* 256 */
+       "P (parked)",           /* 512 */
 };
 
 static inline const char *get_task_state(struct task_struct *tsk)
index 4b3b3ffb52f14e234aa3ec99abde281ca41e1817..21e1a8f1659d097f455e196d0b775771d3904b2b 100644 (file)
@@ -755,37 +755,8 @@ void pde_put(struct proc_dir_entry *pde)
                free_proc_entry(pde);
 }
 
-/*
- * Remove a /proc entry and free it if it's not currently in use.
- */
-void remove_proc_entry(const char *name, struct proc_dir_entry *parent)
+static void entry_rundown(struct proc_dir_entry *de)
 {
-       struct proc_dir_entry **p;
-       struct proc_dir_entry *de = NULL;
-       const char *fn = name;
-       unsigned int len;
-
-       spin_lock(&proc_subdir_lock);
-       if (__xlate_proc_name(name, &parent, &fn) != 0) {
-               spin_unlock(&proc_subdir_lock);
-               return;
-       }
-       len = strlen(fn);
-
-       for (p = &parent->subdir; *p; p=&(*p)->next ) {
-               if (proc_match(len, fn, *p)) {
-                       de = *p;
-                       *p = de->next;
-                       de->next = NULL;
-                       break;
-               }
-       }
-       spin_unlock(&proc_subdir_lock);
-       if (!de) {
-               WARN(1, "name '%s'\n", name);
-               return;
-       }
-
        spin_lock(&de->pde_unload_lock);
        /*
         * Stop accepting new callers into module. If you're
@@ -817,6 +788,40 @@ void remove_proc_entry(const char *name, struct proc_dir_entry *parent)
                spin_lock(&de->pde_unload_lock);
        }
        spin_unlock(&de->pde_unload_lock);
+}
+
+/*
+ * Remove a /proc entry and free it if it's not currently in use.
+ */
+void remove_proc_entry(const char *name, struct proc_dir_entry *parent)
+{
+       struct proc_dir_entry **p;
+       struct proc_dir_entry *de = NULL;
+       const char *fn = name;
+       unsigned int len;
+
+       spin_lock(&proc_subdir_lock);
+       if (__xlate_proc_name(name, &parent, &fn) != 0) {
+               spin_unlock(&proc_subdir_lock);
+               return;
+       }
+       len = strlen(fn);
+
+       for (p = &parent->subdir; *p; p=&(*p)->next ) {
+               if (proc_match(len, fn, *p)) {
+                       de = *p;
+                       *p = de->next;
+                       de->next = NULL;
+                       break;
+               }
+       }
+       spin_unlock(&proc_subdir_lock);
+       if (!de) {
+               WARN(1, "name '%s'\n", name);
+               return;
+       }
+
+       entry_rundown(de);
 
        if (S_ISDIR(de->mode))
                parent->nlink--;
@@ -827,3 +832,57 @@ void remove_proc_entry(const char *name, struct proc_dir_entry *parent)
        pde_put(de);
 }
 EXPORT_SYMBOL(remove_proc_entry);
+
+int remove_proc_subtree(const char *name, struct proc_dir_entry *parent)
+{
+       struct proc_dir_entry **p;
+       struct proc_dir_entry *root = NULL, *de, *next;
+       const char *fn = name;
+       unsigned int len;
+
+       spin_lock(&proc_subdir_lock);
+       if (__xlate_proc_name(name, &parent, &fn) != 0) {
+               spin_unlock(&proc_subdir_lock);
+               return -ENOENT;
+       }
+       len = strlen(fn);
+
+       for (p = &parent->subdir; *p; p=&(*p)->next ) {
+               if (proc_match(len, fn, *p)) {
+                       root = *p;
+                       *p = root->next;
+                       root->next = NULL;
+                       break;
+               }
+       }
+       if (!root) {
+               spin_unlock(&proc_subdir_lock);
+               return -ENOENT;
+       }
+       de = root;
+       while (1) {
+               next = de->subdir;
+               if (next) {
+                       de->subdir = next->next;
+                       next->next = NULL;
+                       de = next;
+                       continue;
+               }
+               spin_unlock(&proc_subdir_lock);
+
+               entry_rundown(de);
+               next = de->parent;
+               if (S_ISDIR(de->mode))
+                       next->nlink--;
+               de->nlink = 0;
+               if (de == root)
+                       break;
+               pde_put(de);
+
+               spin_lock(&proc_subdir_lock);
+               de = next;
+       }
+       pde_put(root);
+       return 0;
+}
+EXPORT_SYMBOL(remove_proc_subtree);
index 25f01d0bc149cc388ce5a8e66d556669809e2b34..b1b1fa6ffffecce461a44945524d60d9b46dd54c 100644 (file)
@@ -99,7 +99,12 @@ struct mmu_gather {
        unsigned int            need_flush : 1, /* Did free PTEs */
                                fast_mode  : 1; /* No batching   */
 
-       unsigned int            fullmm;
+       /* we are in the middle of an operation to clear
+        * a full mm and can make some optimizations */
+       unsigned int            fullmm : 1,
+       /* we have performed an operation which
+        * requires a complete flush of the tlb */
+                               need_flush_all : 1;
 
        struct mmu_gather_batch *active;
        struct mmu_gather_batch local;
index 8f7a3d68371a37314ab8263c078674fd79a8c5b5..ee0bd95240553576bf51672015c756aa0dea3b94 100644 (file)
@@ -954,7 +954,7 @@ static inline int atapi_cdb_len(const u16 *dev_id)
        }
 }
 
-static inline bool atapi_command_packet_set(const u16 *dev_id)
+static inline int atapi_command_packet_set(const u16 *dev_id)
 {
        return (dev_id[ATA_ID_CONFIG] >> 8) & 0x1f;
 }
index 0ea61e07a91c03053833faf3a4250e1f6023a10d..7c2e030e72f10542612ba34ce79b18f6b1b8ad06 100644 (file)
@@ -12,7 +12,6 @@
 
 struct blk_trace {
        int trace_state;
-       bool rq_based;
        struct rchan *rchan;
        unsigned long __percpu *sequence;
        unsigned char __percpu *msg_data;
index 98503b7923698e3b527dc278aa32d5db1da1dfe1..d9a4f7f40f329b22c81f86e31c72b259d4acb4bf 100644 (file)
@@ -35,6 +35,7 @@ struct cpu_vfs_cap_data {
 #define _KERNEL_CAP_T_SIZE     (sizeof(kernel_cap_t))
 
 
+struct file;
 struct inode;
 struct dentry;
 struct user_namespace;
@@ -211,6 +212,7 @@ extern bool capable(int cap);
 extern bool ns_capable(struct user_namespace *ns, int cap);
 extern bool nsown_capable(int cap);
 extern bool inode_capable(const struct inode *inode, int cap);
+extern bool file_ns_capable(const struct file *file, struct user_namespace *ns, int cap);
 
 /* audit system wants to get cap info from files as well */
 extern int get_vfs_caps_from_disk(const struct dentry *dentry, struct cpu_vfs_cap_data *cpu_caps);
index 9bf2f1fcae27789e54336f053fecabe4655b1fbd..3d7df3d32c662f20a2a7c1b661c9d89f5f4b9dd3 100644 (file)
@@ -333,6 +333,7 @@ typedef efi_status_t efi_query_capsule_caps_t(efi_capsule_header_t **capsules,
                                              unsigned long count,
                                              u64 *max_size,
                                              int *reset_type);
+typedef efi_status_t efi_query_variable_store_t(u32 attributes, unsigned long size);
 
 /*
  *  EFI Configuration Table and GUID definitions
@@ -575,9 +576,15 @@ extern void efi_enter_virtual_mode (void); /* switch EFI to virtual mode, if pos
 #ifdef CONFIG_X86
 extern void efi_late_init(void);
 extern void efi_free_boot_services(void);
+extern efi_status_t efi_query_variable_store(u32 attributes, unsigned long size);
 #else
 static inline void efi_late_init(void) {}
 static inline void efi_free_boot_services(void) {}
+
+static inline efi_status_t efi_query_variable_store(u32 attributes, unsigned long size)
+{
+       return EFI_SUCCESS;
+}
 #endif
 extern void __iomem *efi_lookup_mapped_addr(u64 phys_addr);
 extern u64 efi_get_iobase (void);
@@ -731,7 +738,7 @@ struct efivar_operations {
        efi_get_variable_t *get_variable;
        efi_get_next_variable_t *get_next_variable;
        efi_set_variable_t *set_variable;
-       efi_query_variable_info_t *query_variable_info;
+       efi_query_variable_store_t *query_variable_store;
 };
 
 struct efivars {
index e5ca8ef50e9bf674e46fa58d7fff5f0424ab5bad..52da2a250795f3aefc3d2acc927a229f8a662d59 100644 (file)
@@ -89,6 +89,7 @@ typedef void (*ftrace_func_t)(unsigned long ip, unsigned long parent_ip,
  *            that the call back has its own recursion protection. If it does
  *            not set this, then the ftrace infrastructure will add recursion
  *            protection for the caller.
+ * STUB   - The ftrace_ops is just a place holder.
  */
 enum {
        FTRACE_OPS_FL_ENABLED                   = 1 << 0,
@@ -98,6 +99,7 @@ enum {
        FTRACE_OPS_FL_SAVE_REGS                 = 1 << 4,
        FTRACE_OPS_FL_SAVE_REGS_IF_SUPPORTED    = 1 << 5,
        FTRACE_OPS_FL_RECURSION_SAFE            = 1 << 6,
+       FTRACE_OPS_FL_STUB                      = 1 << 7,
 };
 
 struct ftrace_ops {
@@ -394,7 +396,6 @@ ssize_t ftrace_filter_write(struct file *file, const char __user *ubuf,
                            size_t cnt, loff_t *ppos);
 ssize_t ftrace_notrace_write(struct file *file, const char __user *ubuf,
                             size_t cnt, loff_t *ppos);
-loff_t ftrace_regex_lseek(struct file *file, loff_t offset, int whence);
 int ftrace_regex_release(struct inode *inode, struct file *file);
 
 void __init
@@ -567,6 +568,8 @@ static inline int
 ftrace_regex_release(struct inode *inode, struct file *file) { return -ENODEV; }
 #endif /* CONFIG_DYNAMIC_FTRACE */
 
+loff_t ftrace_filter_lseek(struct file *file, loff_t offset, int whence);
+
 /* totally disable ftrace - can not re-enable after this */
 void ftrace_kill(void);
 
index d2e6927bbaae1eb65b5b1dd2575643a5562e329a..d78d28a733b15afdc25a620ca5925f6619f82a2c 100644 (file)
@@ -200,6 +200,8 @@ extern size_t vmcoreinfo_max_size;
 
 int __init parse_crashkernel(char *cmdline, unsigned long long system_ram,
                unsigned long long *crash_size, unsigned long long *crash_base);
+int parse_crashkernel_high(char *cmdline, unsigned long long system_ram,
+               unsigned long long *crash_size, unsigned long long *crash_base);
 int parse_crashkernel_low(char *cmdline, unsigned long long system_ram,
                unsigned long long *crash_size, unsigned long long *crash_base);
 int crash_shrink_memory(unsigned long new_size);
index 91c9d109e5f17bf39c88904cfaa635e132999c9e..eae7a053dc5141d062a80bb4055449520bac61cf 100644 (file)
@@ -398,6 +398,7 @@ enum {
        ATA_HORKAGE_NOSETXFER   = (1 << 14),    /* skip SETXFER, SATA only */
        ATA_HORKAGE_BROKEN_FPDMA_AA     = (1 << 15),    /* skip AA */
        ATA_HORKAGE_DUMP_ID     = (1 << 16),    /* dump IDENTIFY data */
+       ATA_HORKAGE_MAX_SEC_LBA48 = (1 << 17),  /* Set max sects to 65535 */
 
         /* DMA mask for user DMA control: User visible values; DO NOT
            renumber */
index e19ff30ad0a21453cece0df7524d0b336a69078f..e2091b88d24c972be51d80e1f110ad03c50d8902 100644 (file)
@@ -1611,6 +1611,8 @@ int vm_insert_pfn(struct vm_area_struct *vma, unsigned long addr,
                        unsigned long pfn);
 int vm_insert_mixed(struct vm_area_struct *vma, unsigned long addr,
                        unsigned long pfn);
+int vm_iomap_memory(struct vm_area_struct *vma, phys_addr_t start, unsigned long len);
+
 
 struct page *follow_page_mask(struct vm_area_struct *vma,
                              unsigned long address, unsigned int foll_flags,
index 01d25e6fc792472692f6e601de77a7b83fe69734..0214c4c146faab0dad0a339dcd098124245dbe37 100644 (file)
@@ -291,6 +291,7 @@ ip_set_hash_destroy(struct ip_set *set)
 #define type_pf_data_tlist     TOKEN(TYPE, PF, _data_tlist)
 #define type_pf_data_next      TOKEN(TYPE, PF, _data_next)
 #define type_pf_data_flags     TOKEN(TYPE, PF, _data_flags)
+#define type_pf_data_reset_flags TOKEN(TYPE, PF, _data_reset_flags)
 #ifdef IP_SET_HASH_WITH_NETS
 #define type_pf_data_match     TOKEN(TYPE, PF, _data_match)
 #else
@@ -385,9 +386,9 @@ type_pf_resize(struct ip_set *set, bool retried)
        struct ip_set_hash *h = set->data;
        struct htable *t, *orig = h->table;
        u8 htable_bits = orig->htable_bits;
-       const struct type_pf_elem *data;
+       struct type_pf_elem *data;
        struct hbucket *n, *m;
-       u32 i, j;
+       u32 i, j, flags = 0;
        int ret;
 
 retry:
@@ -412,9 +413,16 @@ retry:
                n = hbucket(orig, i);
                for (j = 0; j < n->pos; j++) {
                        data = ahash_data(n, j);
+#ifdef IP_SET_HASH_WITH_NETS
+                       flags = 0;
+                       type_pf_data_reset_flags(data, &flags);
+#endif
                        m = hbucket(t, HKEY(data, h->initval, htable_bits));
-                       ret = type_pf_elem_add(m, data, AHASH_MAX(h), 0);
+                       ret = type_pf_elem_add(m, data, AHASH_MAX(h), flags);
                        if (ret < 0) {
+#ifdef IP_SET_HASH_WITH_NETS
+                               type_pf_data_flags(data, flags);
+#endif
                                read_unlock_bh(&set->lock);
                                ahash_destroy(t);
                                if (ret == -EAGAIN)
@@ -836,9 +844,9 @@ type_pf_tresize(struct ip_set *set, bool retried)
        struct ip_set_hash *h = set->data;
        struct htable *t, *orig = h->table;
        u8 htable_bits = orig->htable_bits;
-       const struct type_pf_elem *data;
+       struct type_pf_elem *data;
        struct hbucket *n, *m;
-       u32 i, j;
+       u32 i, j, flags = 0;
        int ret;
 
        /* Try to cleanup once */
@@ -873,10 +881,17 @@ retry:
                n = hbucket(orig, i);
                for (j = 0; j < n->pos; j++) {
                        data = ahash_tdata(n, j);
+#ifdef IP_SET_HASH_WITH_NETS
+                       flags = 0;
+                       type_pf_data_reset_flags(data, &flags);
+#endif
                        m = hbucket(t, HKEY(data, h->initval, htable_bits));
-                       ret = type_pf_elem_tadd(m, data, AHASH_MAX(h), 0,
-                                               ip_set_timeout_get(type_pf_data_timeout(data)));
+                       ret = type_pf_elem_tadd(m, data, AHASH_MAX(h), flags,
+                               ip_set_timeout_get(type_pf_data_timeout(data)));
                        if (ret < 0) {
+#ifdef IP_SET_HASH_WITH_NETS
+                               type_pf_data_flags(data, flags);
+#endif
                                read_unlock_bh(&set->lock);
                                ahash_destroy(t);
                                if (ret == -EAGAIN)
@@ -1187,6 +1202,7 @@ type_pf_gc_init(struct ip_set *set)
 #undef type_pf_data_tlist
 #undef type_pf_data_next
 #undef type_pf_data_flags
+#undef type_pf_data_reset_flags
 #undef type_pf_data_match
 
 #undef type_pf_elem
index 5a710b9c578e2881478872d505e8b649e8bdb55f..87a03c746f177be0b4ddc0dee6a61860d596ff3d 100644 (file)
@@ -93,14 +93,20 @@ do { \
 
 #else /* !CONFIG_PREEMPT_COUNT */
 
-#define preempt_disable()              do { } while (0)
-#define sched_preempt_enable_no_resched()      do { } while (0)
-#define preempt_enable_no_resched()    do { } while (0)
-#define preempt_enable()               do { } while (0)
-
-#define preempt_disable_notrace()              do { } while (0)
-#define preempt_enable_no_resched_notrace()    do { } while (0)
-#define preempt_enable_notrace()               do { } while (0)
+/*
+ * Even if we don't have any preemption, we need preempt disable/enable
+ * to be barriers, so that we don't have things like get_user/put_user
+ * that can cause faults and scheduling migrate into our preempt-protected
+ * region.
+ */
+#define preempt_disable()              barrier()
+#define sched_preempt_enable_no_resched()      barrier()
+#define preempt_enable_no_resched()    barrier()
+#define preempt_enable()               barrier()
+
+#define preempt_disable_notrace()              barrier()
+#define preempt_enable_no_resched_notrace()    barrier()
+#define preempt_enable_notrace()               barrier()
 
 #endif /* CONFIG_PREEMPT_COUNT */
 
index 8307f2f94d860f46139b6a20d6795a9186704c19..94dfb2aa5533c3c6a2a661358a6da4c6555310d3 100644 (file)
@@ -117,6 +117,7 @@ struct proc_dir_entry *proc_create_data(const char *name, umode_t mode,
                                const struct file_operations *proc_fops,
                                void *data);
 extern void remove_proc_entry(const char *name, struct proc_dir_entry *parent);
+extern int remove_proc_subtree(const char *name, struct proc_dir_entry *parent);
 
 struct pid_namespace;
 
@@ -202,6 +203,7 @@ static inline struct proc_dir_entry *proc_create_data(const char *name,
        return NULL;
 }
 #define remove_proc_entry(name, parent) do {} while (0)
+#define remove_proc_subtree(name, parent) do {} while (0)
 
 static inline struct proc_dir_entry *proc_symlink(const char *name,
                struct proc_dir_entry *parent,const char *dest) {return NULL;}
index d35d2b6ddbfb69f098b1660fe280b4d2da8a5ffe..e692a022527bdaaace8b388268b0c280946fc5c2 100644 (file)
@@ -163,9 +163,10 @@ print_cfs_rq(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq)
 #define TASK_DEAD              64
 #define TASK_WAKEKILL          128
 #define TASK_WAKING            256
-#define TASK_STATE_MAX         512
+#define TASK_PARKED            512
+#define TASK_STATE_MAX         1024
 
-#define TASK_STATE_TO_CHAR_STR "RSDTtZXxKW"
+#define TASK_STATE_TO_CHAR_STR "RSDTtZXxKWP"
 
 extern char ___assert_task_state[1 - 2*!!(
                sizeof(TASK_STATE_TO_CHAR_STR)-1 != ilog2(TASK_STATE_MAX)+1)];
index eee7478cda701ddeabc00150f607f368a4239350..032c366ef1c62b203134e386ad1bc8a92a6c31fe 100644 (file)
@@ -1012,6 +1012,10 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
  *     This hook can be used by the module to update any security state
  *     associated with the TUN device's security structure.
  *     @security pointer to the TUN devices's security structure.
+ * @skb_owned_by:
+ *     This hook sets the packet's owning sock.
+ *     @skb is the packet.
+ *     @sk the sock which owns the packet.
  *
  * Security hooks for XFRM operations.
  *
@@ -1638,6 +1642,7 @@ struct security_operations {
        int (*tun_dev_attach_queue) (void *security);
        int (*tun_dev_attach) (struct sock *sk, void *security);
        int (*tun_dev_open) (void *security);
+       void (*skb_owned_by) (struct sk_buff *skb, struct sock *sk);
 #endif /* CONFIG_SECURITY_NETWORK */
 
 #ifdef CONFIG_SECURITY_NETWORK_XFRM
@@ -2588,6 +2593,8 @@ int security_tun_dev_attach_queue(void *security);
 int security_tun_dev_attach(struct sock *sk, void *security);
 int security_tun_dev_open(void *security);
 
+void security_skb_owned_by(struct sk_buff *skb, struct sock *sk);
+
 #else  /* CONFIG_SECURITY_NETWORK */
 static inline int security_unix_stream_connect(struct sock *sock,
                                               struct sock *other,
@@ -2779,6 +2786,11 @@ static inline int security_tun_dev_open(void *security)
 {
        return 0;
 }
+
+static inline void security_skb_owned_by(struct sk_buff *skb, struct sock *sk)
+{
+}
+
 #endif /* CONFIG_SECURITY_NETWORK */
 
 #ifdef CONFIG_SECURITY_NETWORK_XFRM
index a26e2fb604e6e5f004e93da22d4f5355bf9a7358..e2369c167dbd9e7300ecbf617cbc9d8f291c8dc0 100644 (file)
  * In the debug case, 1 means unlocked, 0 means locked. (the values
  * are inverted, to catch initialization bugs)
  *
- * No atomicity anywhere, we are on UP.
+ * No atomicity anywhere, we are on UP. However, we still need
+ * the compiler barriers, because we do not want the compiler to
+ * move potentially faulting instructions (notably user accesses)
+ * into the locked sequence, resulting in non-atomic execution.
  */
 
 #ifdef CONFIG_DEBUG_SPINLOCK
@@ -25,6 +28,7 @@
 static inline void arch_spin_lock(arch_spinlock_t *lock)
 {
        lock->slock = 0;
+       barrier();
 }
 
 static inline void
@@ -32,6 +36,7 @@ arch_spin_lock_flags(arch_spinlock_t *lock, unsigned long flags)
 {
        local_irq_save(flags);
        lock->slock = 0;
+       barrier();
 }
 
 static inline int arch_spin_trylock(arch_spinlock_t *lock)
@@ -39,32 +44,34 @@ static inline int arch_spin_trylock(arch_spinlock_t *lock)
        char oldval = lock->slock;
 
        lock->slock = 0;
+       barrier();
 
        return oldval > 0;
 }
 
 static inline void arch_spin_unlock(arch_spinlock_t *lock)
 {
+       barrier();
        lock->slock = 1;
 }
 
 /*
  * Read-write spinlocks. No debug version.
  */
-#define arch_read_lock(lock)           do { (void)(lock); } while (0)
-#define arch_write_lock(lock)          do { (void)(lock); } while (0)
-#define arch_read_trylock(lock)        ({ (void)(lock); 1; })
-#define arch_write_trylock(lock)       ({ (void)(lock); 1; })
-#define arch_read_unlock(lock)         do { (void)(lock); } while (0)
-#define arch_write_unlock(lock)        do { (void)(lock); } while (0)
+#define arch_read_lock(lock)           do { barrier(); (void)(lock); } while (0)
+#define arch_write_lock(lock)          do { barrier(); (void)(lock); } while (0)
+#define arch_read_trylock(lock)        ({ barrier(); (void)(lock); 1; })
+#define arch_write_trylock(lock)       ({ barrier(); (void)(lock); 1; })
+#define arch_read_unlock(lock)         do { barrier(); (void)(lock); } while (0)
+#define arch_write_unlock(lock)        do { barrier(); (void)(lock); } while (0)
 
 #else /* DEBUG_SPINLOCK */
 #define arch_spin_is_locked(lock)      ((void)(lock), 0)
 /* for sched.c and kernel_lock.c: */
-# define arch_spin_lock(lock)          do { (void)(lock); } while (0)
-# define arch_spin_lock_flags(lock, flags)     do { (void)(lock); } while (0)
-# define arch_spin_unlock(lock)        do { (void)(lock); } while (0)
-# define arch_spin_trylock(lock)       ({ (void)(lock); 1; })
+# define arch_spin_lock(lock)          do { barrier(); (void)(lock); } while (0)
+# define arch_spin_lock_flags(lock, flags)     do { barrier(); (void)(lock); } while (0)
+# define arch_spin_unlock(lock)        do { barrier(); (void)(lock); } while (0)
+# define arch_spin_trylock(lock)       ({ barrier(); (void)(lock); 1; })
 #endif /* DEBUG_SPINLOCK */
 
 #define arch_spin_is_contended(lock)   (((void)(lock), 0))
index 9e492be5244b40d8ead3340aa7ac475cb51e56ff..6fcfe99bd999d295e0eb8efb967d0b2892335afc 100644 (file)
 #define SSB_CHIPCO_PMU_CTL                     0x0600 /* PMU control */
 #define  SSB_CHIPCO_PMU_CTL_ILP_DIV            0xFFFF0000 /* ILP div mask */
 #define  SSB_CHIPCO_PMU_CTL_ILP_DIV_SHIFT      16
+#define  SSB_CHIPCO_PMU_CTL_PLL_UPD            0x00000400
 #define  SSB_CHIPCO_PMU_CTL_NOILPONW           0x00000200 /* No ILP on wait */
 #define  SSB_CHIPCO_PMU_CTL_HTREQEN            0x00000100 /* HT req enable */
 #define  SSB_CHIPCO_PMU_CTL_ALPREQEN           0x00000080 /* ALP req enable */
@@ -667,5 +668,6 @@ enum ssb_pmu_ldo_volt_id {
 void ssb_pmu_set_ldo_voltage(struct ssb_chipcommon *cc,
                             enum ssb_pmu_ldo_volt_id id, u32 voltage);
 void ssb_pmu_set_ldo_paref(struct ssb_chipcommon *cc, bool on);
+void ssb_pmu_spuravoid_pllupdate(struct ssb_chipcommon *cc, int spuravoid);
 
 #endif /* LINUX_SSB_CHIPCO_H_ */
index 2de42f9401d2599d4309028297c29a3bff9222c8..a5ffd32642fd6d46a8bad7e64eb2b791b9c4cdab 100644 (file)
@@ -25,6 +25,7 @@ extern int swiotlb_force;
 extern void swiotlb_init(int verbose);
 int swiotlb_init_with_tbl(char *tlb, unsigned long nslabs, int verbose);
 extern unsigned long swiotlb_nr_tbl(void);
+unsigned long swiotlb_size_or_default(void);
 extern int swiotlb_late_init_with_tbl(char *tlb, unsigned long nslabs);
 
 /*
diff --git a/include/linux/ucs2_string.h b/include/linux/ucs2_string.h
new file mode 100644 (file)
index 0000000..cbb20af
--- /dev/null
@@ -0,0 +1,14 @@
+#ifndef _LINUX_UCS2_STRING_H_
+#define _LINUX_UCS2_STRING_H_
+
+#include <linux/types.h>       /* for size_t */
+#include <linux/stddef.h>      /* for NULL */
+
+typedef u16 ucs2_char_t;
+
+unsigned long ucs2_strnlen(const ucs2_char_t *s, size_t maxlength);
+unsigned long ucs2_strlen(const ucs2_char_t *s);
+unsigned long ucs2_strsize(const ucs2_char_t *data, unsigned long maxlength);
+int ucs2_strncmp(const ucs2_char_t *a, const ucs2_char_t *b, size_t len);
+
+#endif /* _LINUX_UCS2_STRING_H_ */
index 40be2a0d8ae1bef7270b06a8a04cc9b9ab30b630..84a6440f1f19ee698dba94a7f899d77fc527e432 100644 (file)
@@ -199,6 +199,7 @@ extern bool ipv6_chk_acast_addr(struct net *net, struct net_device *dev,
 /* Device notifier */
 extern int register_inet6addr_notifier(struct notifier_block *nb);
 extern int unregister_inet6addr_notifier(struct notifier_block *nb);
+extern int inet6addr_notifier_call_chain(unsigned long val, void *v);
 
 extern void inet6_netconf_notify_devconf(struct net *net, int type, int ifindex,
                                         struct ipv6_devconf *devconf);
index f74109144d3fe544da2ff7ccf29f99884c22b32f..f132924cc9daec92b50427f705b88c3c350e70a3 100644 (file)
@@ -256,7 +256,8 @@ static inline __u32 irlmp_get_daddr(const struct lsap_cb *self)
        return (self && self->lap) ? self->lap->daddr : 0;
 }
 
-extern const char *irlmp_reasons[];
+const char *irlmp_reason_str(LM_REASON reason);
+
 extern int sysctl_discovery_timeout;
 extern int sysctl_discovery_slots;
 extern int sysctl_discovery;
index cc7c19732389dba327a92742de4cfeba96b5903e..714cc9a54a4c38575f15581cb379a20f6615b3e2 100644 (file)
@@ -130,6 +130,14 @@ struct iucv_sock {
                                               enum iucv_tx_notify n);
 };
 
+struct iucv_skb_cb {
+       u32     class;          /* target class of message */
+       u32     tag;            /* tag associated with message */
+       u32     offset;         /* offset for skb receival */
+};
+
+#define IUCV_SKB_CB(__skb)     ((struct iucv_skb_cb *)&((__skb)->cb[0]))
+
 /* iucv socket options (SOL_IUCV) */
 #define SO_IPRMDATA_MSG        0x0080          /* send/recv IPRM_DATA msgs */
 #define SO_MSGLIMIT    0x1000          /* get/set IUCV MSGLIMIT */
index 975cca01048bee3b7da9017725654053921250ae..b11708105681e04f5c24f7ed206f732e2c37dc02 100644 (file)
@@ -56,8 +56,8 @@ static __inline__ void scm_set_cred(struct scm_cookie *scm,
        scm->pid  = get_pid(pid);
        scm->cred = cred ? get_cred(cred) : NULL;
        scm->creds.pid = pid_vnr(pid);
-       scm->creds.uid = cred ? cred->euid : INVALID_UID;
-       scm->creds.gid = cred ? cred->egid : INVALID_GID;
+       scm->creds.uid = cred ? cred->uid : INVALID_UID;
+       scm->creds.gid = cred ? cred->gid : INVALID_GID;
 }
 
 static __inline__ void scm_destroy_cred(struct scm_cookie *scm)
index 9961726523d01251957b2f8c661422c31d1ac78c..9c1467357b03c616967cd193efab6506e3e5adff 100644 (file)
@@ -257,6 +257,7 @@ TRACE_EVENT(block_bio_bounce,
 
 /**
  * block_bio_complete - completed all work on the block operation
+ * @q: queue holding the block operation
  * @bio: block operation completed
  * @error: io error value
  *
@@ -265,9 +266,9 @@ TRACE_EVENT(block_bio_bounce,
  */
 TRACE_EVENT(block_bio_complete,
 
-       TP_PROTO(struct bio *bio, int error),
+       TP_PROTO(struct request_queue *q, struct bio *bio, int error),
 
-       TP_ARGS(bio, error),
+       TP_ARGS(q, bio, error),
 
        TP_STRUCT__entry(
                __field( dev_t,         dev             )
@@ -278,8 +279,7 @@ TRACE_EVENT(block_bio_complete,
        ),
 
        TP_fast_assign(
-               __entry->dev            = bio->bi_bdev ?
-                                         bio->bi_bdev->bd_dev : 0;
+               __entry->dev            = bio->bi_bdev->bd_dev;
                __entry->sector         = bio->bi_sector;
                __entry->nr_sector      = bio->bi_size >> 9;
                __entry->error          = error;
index 5a8671e8a67ff8fa8f715311300901181555d78e..e5586caff67a973c962a3ed6bf43d4cc01664083 100644 (file)
@@ -147,7 +147,7 @@ TRACE_EVENT(sched_switch,
                  __print_flags(__entry->prev_state & (TASK_STATE_MAX-1), "|",
                                { 1, "S"} , { 2, "D" }, { 4, "T" }, { 8, "t" },
                                { 16, "Z" }, { 32, "X" }, { 64, "x" },
-                               { 128, "W" }) : "R",
+                               { 128, "K" }, { 256, "W" }, { 512, "P" }) : "R",
                __entry->prev_state & TASK_STATE_MAX ? "+" : "",
                __entry->next_comm, __entry->next_pid, __entry->next_prio)
 );
index 4c43b44487922301a3c7949ee6c07020e50e248e..706d035fa7488df73b142b1812c2c3feaa8708d3 100644 (file)
 #ifndef _LINUX_FUSE_H
 #define _LINUX_FUSE_H
 
-#ifdef __linux__
+#ifdef __KERNEL__
 #include <linux/types.h>
 #else
 #include <stdint.h>
-#define __u64 uint64_t
-#define __s64 int64_t
-#define __u32 uint32_t
-#define __s32 int32_t
-#define __u16 uint16_t
 #endif
 
 /*
    userspace works under 64bit kernels */
 
 struct fuse_attr {
-       __u64   ino;
-       __u64   size;
-       __u64   blocks;
-       __u64   atime;
-       __u64   mtime;
-       __u64   ctime;
-       __u32   atimensec;
-       __u32   mtimensec;
-       __u32   ctimensec;
-       __u32   mode;
-       __u32   nlink;
-       __u32   uid;
-       __u32   gid;
-       __u32   rdev;
-       __u32   blksize;
-       __u32   padding;
+       uint64_t        ino;
+       uint64_t        size;
+       uint64_t        blocks;
+       uint64_t        atime;
+       uint64_t        mtime;
+       uint64_t        ctime;
+       uint32_t        atimensec;
+       uint32_t        mtimensec;
+       uint32_t        ctimensec;
+       uint32_t        mode;
+       uint32_t        nlink;
+       uint32_t        uid;
+       uint32_t        gid;
+       uint32_t        rdev;
+       uint32_t        blksize;
+       uint32_t        padding;
 };
 
 struct fuse_kstatfs {
-       __u64   blocks;
-       __u64   bfree;
-       __u64   bavail;
-       __u64   files;
-       __u64   ffree;
-       __u32   bsize;
-       __u32   namelen;
-       __u32   frsize;
-       __u32   padding;
-       __u32   spare[6];
+       uint64_t        blocks;
+       uint64_t        bfree;
+       uint64_t        bavail;
+       uint64_t        files;
+       uint64_t        ffree;
+       uint32_t        bsize;
+       uint32_t        namelen;
+       uint32_t        frsize;
+       uint32_t        padding;
+       uint32_t        spare[6];
 };
 
 struct fuse_file_lock {
-       __u64   start;
-       __u64   end;
-       __u32   type;
-       __u32   pid; /* tgid */
+       uint64_t        start;
+       uint64_t        end;
+       uint32_t        type;
+       uint32_t        pid; /* tgid */
 };
 
 /**
@@ -364,143 +359,143 @@ enum fuse_notify_code {
 #define FUSE_COMPAT_ENTRY_OUT_SIZE 120
 
 struct fuse_entry_out {
-       __u64   nodeid;         /* Inode ID */
-       __u64   generation;     /* Inode generation: nodeid:gen must
-                                  be unique for the fs's lifetime */
-       __u64   entry_valid;    /* Cache timeout for the name */
-       __u64   attr_valid;     /* Cache timeout for the attributes */
-       __u32   entry_valid_nsec;
-       __u32   attr_valid_nsec;
+       uint64_t        nodeid;         /* Inode ID */
+       uint64_t        generation;     /* Inode generation: nodeid:gen must
+                                          be unique for the fs's lifetime */
+       uint64_t        entry_valid;    /* Cache timeout for the name */
+       uint64_t        attr_valid;     /* Cache timeout for the attributes */
+       uint32_t        entry_valid_nsec;
+       uint32_t        attr_valid_nsec;
        struct fuse_attr attr;
 };
 
 struct fuse_forget_in {
-       __u64   nlookup;
+       uint64_t        nlookup;
 };
 
 struct fuse_forget_one {
-       __u64   nodeid;
-       __u64   nlookup;
+       uint64_t        nodeid;
+       uint64_t        nlookup;
 };
 
 struct fuse_batch_forget_in {
-       __u32   count;
-       __u32   dummy;
+       uint32_t        count;
+       uint32_t        dummy;
 };
 
 struct fuse_getattr_in {
-       __u32   getattr_flags;
-       __u32   dummy;
-       __u64   fh;
+       uint32_t        getattr_flags;
+       uint32_t        dummy;
+       uint64_t        fh;
 };
 
 #define FUSE_COMPAT_ATTR_OUT_SIZE 96
 
 struct fuse_attr_out {
-       __u64   attr_valid;     /* Cache timeout for the attributes */
-       __u32   attr_valid_nsec;
-       __u32   dummy;
+       uint64_t        attr_valid;     /* Cache timeout for the attributes */
+       uint32_t        attr_valid_nsec;
+       uint32_t        dummy;
        struct fuse_attr attr;
 };
 
 #define FUSE_COMPAT_MKNOD_IN_SIZE 8
 
 struct fuse_mknod_in {
-       __u32   mode;
-       __u32   rdev;
-       __u32   umask;
-       __u32   padding;
+       uint32_t        mode;
+       uint32_t        rdev;
+       uint32_t        umask;
+       uint32_t        padding;
 };
 
 struct fuse_mkdir_in {
-       __u32   mode;
-       __u32   umask;
+       uint32_t        mode;
+       uint32_t        umask;
 };
 
 struct fuse_rename_in {
-       __u64   newdir;
+       uint64_t        newdir;
 };
 
 struct fuse_link_in {
-       __u64   oldnodeid;
+       uint64_t        oldnodeid;
 };
 
 struct fuse_setattr_in {
-       __u32   valid;
-       __u32   padding;
-       __u64   fh;
-       __u64   size;
-       __u64   lock_owner;
-       __u64   atime;
-       __u64   mtime;
-       __u64   unused2;
-       __u32   atimensec;
-       __u32   mtimensec;
-       __u32   unused3;
-       __u32   mode;
-       __u32   unused4;
-       __u32   uid;
-       __u32   gid;
-       __u32   unused5;
+       uint32_t        valid;
+       uint32_t        padding;
+       uint64_t        fh;
+       uint64_t        size;
+       uint64_t        lock_owner;
+       uint64_t        atime;
+       uint64_t        mtime;
+       uint64_t        unused2;
+       uint32_t        atimensec;
+       uint32_t        mtimensec;
+       uint32_t        unused3;
+       uint32_t        mode;
+       uint32_t        unused4;
+       uint32_t        uid;
+       uint32_t        gid;
+       uint32_t        unused5;
 };
 
 struct fuse_open_in {
-       __u32   flags;
-       __u32   unused;
+       uint32_t        flags;
+       uint32_t        unused;
 };
 
 struct fuse_create_in {
-       __u32   flags;
-       __u32   mode;
-       __u32   umask;
-       __u32   padding;
+       uint32_t        flags;
+       uint32_t        mode;
+       uint32_t        umask;
+       uint32_t        padding;
 };
 
 struct fuse_open_out {
-       __u64   fh;
-       __u32   open_flags;
-       __u32   padding;
+       uint64_t        fh;
+       uint32_t        open_flags;
+       uint32_t        padding;
 };
 
 struct fuse_release_in {
-       __u64   fh;
-       __u32   flags;
-       __u32   release_flags;
-       __u64   lock_owner;
+       uint64_t        fh;
+       uint32_t        flags;
+       uint32_t        release_flags;
+       uint64_t        lock_owner;
 };
 
 struct fuse_flush_in {
-       __u64   fh;
-       __u32   unused;
-       __u32   padding;
-       __u64   lock_owner;
+       uint64_t        fh;
+       uint32_t        unused;
+       uint32_t        padding;
+       uint64_t        lock_owner;
 };
 
 struct fuse_read_in {
-       __u64   fh;
-       __u64   offset;
-       __u32   size;
-       __u32   read_flags;
-       __u64   lock_owner;
-       __u32   flags;
-       __u32   padding;
+       uint64_t        fh;
+       uint64_t        offset;
+       uint32_t        size;
+       uint32_t        read_flags;
+       uint64_t        lock_owner;
+       uint32_t        flags;
+       uint32_t        padding;
 };
 
 #define FUSE_COMPAT_WRITE_IN_SIZE 24
 
 struct fuse_write_in {
-       __u64   fh;
-       __u64   offset;
-       __u32   size;
-       __u32   write_flags;
-       __u64   lock_owner;
-       __u32   flags;
-       __u32   padding;
+       uint64_t        fh;
+       uint64_t        offset;
+       uint32_t        size;
+       uint32_t        write_flags;
+       uint64_t        lock_owner;
+       uint32_t        flags;
+       uint32_t        padding;
 };
 
 struct fuse_write_out {
-       __u32   size;
-       __u32   padding;
+       uint32_t        size;
+       uint32_t        padding;
 };
 
 #define FUSE_COMPAT_STATFS_SIZE 48
@@ -510,32 +505,32 @@ struct fuse_statfs_out {
 };
 
 struct fuse_fsync_in {
-       __u64   fh;
-       __u32   fsync_flags;
-       __u32   padding;
+       uint64_t        fh;
+       uint32_t        fsync_flags;
+       uint32_t        padding;
 };
 
 struct fuse_setxattr_in {
-       __u32   size;
-       __u32   flags;
+       uint32_t        size;
+       uint32_t        flags;
 };
 
 struct fuse_getxattr_in {
-       __u32   size;
-       __u32   padding;
+       uint32_t        size;
+       uint32_t        padding;
 };
 
 struct fuse_getxattr_out {
-       __u32   size;
-       __u32   padding;
+       uint32_t        size;
+       uint32_t        padding;
 };
 
 struct fuse_lk_in {
-       __u64   fh;
-       __u64   owner;
+       uint64_t        fh;
+       uint64_t        owner;
        struct fuse_file_lock lk;
-       __u32   lk_flags;
-       __u32   padding;
+       uint32_t        lk_flags;
+       uint32_t        padding;
 };
 
 struct fuse_lk_out {
@@ -543,134 +538,135 @@ struct fuse_lk_out {
 };
 
 struct fuse_access_in {
-       __u32   mask;
-       __u32   padding;
+       uint32_t        mask;
+       uint32_t        padding;
 };
 
 struct fuse_init_in {
-       __u32   major;
-       __u32   minor;
-       __u32   max_readahead;
-       __u32   flags;
+       uint32_t        major;
+       uint32_t        minor;
+       uint32_t        max_readahead;
+       uint32_t        flags;
 };
 
 struct fuse_init_out {
-       __u32   major;
-       __u32   minor;
-       __u32   max_readahead;
-       __u32   flags;
-       __u16   max_background;
-       __u16   congestion_threshold;
-       __u32   max_write;
+       uint32_t        major;
+       uint32_t        minor;
+       uint32_t        max_readahead;
+       uint32_t        flags;
+       uint16_t        max_background;
+       uint16_t        congestion_threshold;
+       uint32_t        max_write;
 };
 
 #define CUSE_INIT_INFO_MAX 4096
 
 struct cuse_init_in {
-       __u32   major;
-       __u32   minor;
-       __u32   unused;
-       __u32   flags;
+       uint32_t        major;
+       uint32_t        minor;
+       uint32_t        unused;
+       uint32_t        flags;
 };
 
 struct cuse_init_out {
-       __u32   major;
-       __u32   minor;
-       __u32   unused;
-       __u32   flags;
-       __u32   max_read;
-       __u32   max_write;
-       __u32   dev_major;              /* chardev major */
-       __u32   dev_minor;              /* chardev minor */
-       __u32   spare[10];
+       uint32_t        major;
+       uint32_t        minor;
+       uint32_t        unused;
+       uint32_t        flags;
+       uint32_t        max_read;
+       uint32_t        max_write;
+       uint32_t        dev_major;              /* chardev major */
+       uint32_t        dev_minor;              /* chardev minor */
+       uint32_t        spare[10];
 };
 
 struct fuse_interrupt_in {
-       __u64   unique;
+       uint64_t        unique;
 };
 
 struct fuse_bmap_in {
-       __u64   block;
-       __u32   blocksize;
-       __u32   padding;
+       uint64_t        block;
+       uint32_t        blocksize;
+       uint32_t        padding;
 };
 
 struct fuse_bmap_out {
-       __u64   block;
+       uint64_t        block;
 };
 
 struct fuse_ioctl_in {
-       __u64   fh;
-       __u32   flags;
-       __u32   cmd;
-       __u64   arg;
-       __u32   in_size;
-       __u32   out_size;
+       uint64_t        fh;
+       uint32_t        flags;
+       uint32_t        cmd;
+       uint64_t        arg;
+       uint32_t        in_size;
+       uint32_t        out_size;
 };
 
 struct fuse_ioctl_iovec {
-       __u64   base;
-       __u64   len;
+       uint64_t        base;
+       uint64_t        len;
 };
 
 struct fuse_ioctl_out {
-       __s32   result;
-       __u32   flags;
-       __u32   in_iovs;
-       __u32   out_iovs;
+       int32_t         result;
+       uint32_t        flags;
+       uint32_t        in_iovs;
+       uint32_t        out_iovs;
 };
 
 struct fuse_poll_in {
-       __u64   fh;
-       __u64   kh;
-       __u32   flags;
-       __u32   events;
+       uint64_t        fh;
+       uint64_t        kh;
+       uint32_t        flags;
+       uint32_t        events;
 };
 
 struct fuse_poll_out {
-       __u32   revents;
-       __u32   padding;
+       uint32_t        revents;
+       uint32_t        padding;
 };
 
 struct fuse_notify_poll_wakeup_out {
-       __u64   kh;
+       uint64_t        kh;
 };
 
 struct fuse_fallocate_in {
-       __u64   fh;
-       __u64   offset;
-       __u64   length;
-       __u32   mode;
-       __u32   padding;
+       uint64_t        fh;
+       uint64_t        offset;
+       uint64_t        length;
+       uint32_t        mode;
+       uint32_t        padding;
 };
 
 struct fuse_in_header {
-       __u32   len;
-       __u32   opcode;
-       __u64   unique;
-       __u64   nodeid;
-       __u32   uid;
-       __u32   gid;
-       __u32   pid;
-       __u32   padding;
+       uint32_t        len;
+       uint32_t        opcode;
+       uint64_t        unique;
+       uint64_t        nodeid;
+       uint32_t        uid;
+       uint32_t        gid;
+       uint32_t        pid;
+       uint32_t        padding;
 };
 
 struct fuse_out_header {
-       __u32   len;
-       __s32   error;
-       __u64   unique;
+       uint32_t        len;
+       int32_t         error;
+       uint64_t        unique;
 };
 
 struct fuse_dirent {
-       __u64   ino;
-       __u64   off;
-       __u32   namelen;
-       __u32   type;
+       uint64_t        ino;
+       uint64_t        off;
+       uint32_t        namelen;
+       uint32_t        type;
        char name[];
 };
 
 #define FUSE_NAME_OFFSET offsetof(struct fuse_dirent, name)
-#define FUSE_DIRENT_ALIGN(x) (((x) + sizeof(__u64) - 1) & ~(sizeof(__u64) - 1))
+#define FUSE_DIRENT_ALIGN(x) \
+       (((x) + sizeof(uint64_t) - 1) & ~(sizeof(uint64_t) - 1))
 #define FUSE_DIRENT_SIZE(d) \
        FUSE_DIRENT_ALIGN(FUSE_NAME_OFFSET + (d)->namelen)
 
@@ -685,47 +681,47 @@ struct fuse_direntplus {
        FUSE_DIRENT_ALIGN(FUSE_NAME_OFFSET_DIRENTPLUS + (d)->dirent.namelen)
 
 struct fuse_notify_inval_inode_out {
-       __u64   ino;
-       __s64   off;
-       __s64   len;
+       uint64_t        ino;
+       int64_t         off;
+       int64_t         len;
 };
 
 struct fuse_notify_inval_entry_out {
-       __u64   parent;
-       __u32   namelen;
-       __u32   padding;
+       uint64_t        parent;
+       uint32_t        namelen;
+       uint32_t        padding;
 };
 
 struct fuse_notify_delete_out {
-       __u64   parent;
-       __u64   child;
-       __u32   namelen;
-       __u32   padding;
+       uint64_t        parent;
+       uint64_t        child;
+       uint32_t        namelen;
+       uint32_t        padding;
 };
 
 struct fuse_notify_store_out {
-       __u64   nodeid;
-       __u64   offset;
-       __u32   size;
-       __u32   padding;
+       uint64_t        nodeid;
+       uint64_t        offset;
+       uint32_t        size;
+       uint32_t        padding;
 };
 
 struct fuse_notify_retrieve_out {
-       __u64   notify_unique;
-       __u64   nodeid;
-       __u64   offset;
-       __u32   size;
-       __u32   padding;
+       uint64_t        notify_unique;
+       uint64_t        nodeid;
+       uint64_t        offset;
+       uint32_t        size;
+       uint32_t        padding;
 };
 
 /* Matches the size of fuse_write_in */
 struct fuse_notify_retrieve_in {
-       __u64   dummy1;
-       __u64   offset;
-       __u32   size;
-       __u32   dummy2;
-       __u64   dummy3;
-       __u64   dummy4;
+       uint64_t        dummy1;
+       uint64_t        offset;
+       uint32_t        size;
+       uint32_t        dummy2;
+       uint64_t        dummy3;
+       uint64_t        dummy4;
 };
 
 #endif /* _LINUX_FUSE_H */
index 493d97259484cfef006c59b934be4fcf9663d1ac..f6c2ce5701e1c3c723d03e3d917c62f584c3a074 100644 (file)
@@ -392,6 +392,30 @@ bool ns_capable(struct user_namespace *ns, int cap)
 }
 EXPORT_SYMBOL(ns_capable);
 
+/**
+ * file_ns_capable - Determine if the file's opener had a capability in effect
+ * @file:  The file we want to check
+ * @ns:  The usernamespace we want the capability in
+ * @cap: The capability to be tested for
+ *
+ * Return true if task that opened the file had a capability in effect
+ * when the file was opened.
+ *
+ * This does not set PF_SUPERPRIV because the caller may not
+ * actually be privileged.
+ */
+bool file_ns_capable(const struct file *file, struct user_namespace *ns, int cap)
+{
+       if (WARN_ON_ONCE(!cap_valid(cap)))
+               return false;
+
+       if (security_capable(file->f_cred, ns, cap) == 0)
+               return true;
+
+       return false;
+}
+EXPORT_SYMBOL(file_ns_capable);
+
 /**
  * capable - Determine if the current task has a superior capability in effect
  * @cap: The capability to be tested for
index 59412d037eed2a81163483b89fb38d9feb30623a..4d3124b392774322ae1b33f167a10c1046d886d9 100644 (file)
@@ -4737,7 +4737,8 @@ static void perf_event_mmap_event(struct perf_mmap_event *mmap_event)
        } else {
                if (arch_vma_name(mmap_event->vma)) {
                        name = strncpy(tmp, arch_vma_name(mmap_event->vma),
-                                      sizeof(tmp));
+                                      sizeof(tmp) - 1);
+                       tmp[sizeof(tmp) - 1] = '\0';
                        goto got_name;
                }
 
@@ -5330,7 +5331,7 @@ static void sw_perf_event_destroy(struct perf_event *event)
 
 static int perf_swevent_init(struct perf_event *event)
 {
-       int event_id = event->attr.config;
+       u64 event_id = event->attr.config;
 
        if (event->attr.type != PERF_TYPE_SOFTWARE)
                return -ENOENT;
@@ -5986,6 +5987,7 @@ skip_type:
        if (pmu->pmu_cpu_context)
                goto got_cpu_context;
 
+       ret = -ENOMEM;
        pmu->pmu_cpu_context = alloc_percpu(struct perf_cpu_context);
        if (!pmu->pmu_cpu_context)
                goto free_dev;
index d56a64c99a8b1ccf07d3ee252d73048181dcdfd9..eb675c4d59dfd440b9f93d92226ee2dc5ffe8290 100644 (file)
@@ -16,7 +16,7 @@ struct ring_buffer {
        int                             page_order;     /* allocation order  */
 #endif
        int                             nr_pages;       /* nr of data pages  */
-       int                             writable;       /* are we writable   */
+       int                             overwrite;      /* can overwrite itself */
 
        atomic_t                        poll;           /* POLL_ for wakeups */
 
index 23cb34ff3973c2dc7e4ce9cf41f744f93a36f83a..97fddb09762b0dc815af7d1f674993d87cd45574 100644 (file)
 static bool perf_output_space(struct ring_buffer *rb, unsigned long tail,
                              unsigned long offset, unsigned long head)
 {
-       unsigned long mask;
+       unsigned long sz = perf_data_size(rb);
+       unsigned long mask = sz - 1;
 
-       if (!rb->writable)
+       /*
+        * check if user-writable
+        * overwrite : over-write its own tail
+        * !overwrite: buffer possibly drops events.
+        */
+       if (rb->overwrite)
                return true;
 
-       mask = perf_data_size(rb) - 1;
+       /*
+        * verify that payload is not bigger than buffer
+        * otherwise masking logic may fail to detect
+        * the "not enough space" condition
+        */
+       if ((head - offset) > sz)
+               return false;
 
        offset = (offset - tail) & mask;
        head   = (head   - tail) & mask;
@@ -212,7 +224,9 @@ ring_buffer_init(struct ring_buffer *rb, long watermark, int flags)
                rb->watermark = max_size / 2;
 
        if (flags & RING_BUFFER_WRITABLE)
-               rb->writable = 1;
+               rb->overwrite = 0;
+       else
+               rb->overwrite = 1;
 
        atomic_set(&rb->refcount, 1);
 
index cc47812d3feb0c86cbcf8f03e6ee81340ef7c57c..14be27feda491da1c3dc9990a5ae80ce649570aa 100644 (file)
@@ -63,6 +63,7 @@
 DEFINE_PER_CPU(struct hrtimer_cpu_base, hrtimer_bases) =
 {
 
+       .lock = __RAW_SPIN_LOCK_UNLOCKED(hrtimer_bases.lock),
        .clock_base =
        {
                {
@@ -1642,8 +1643,6 @@ static void __cpuinit init_hrtimers_cpu(int cpu)
        struct hrtimer_cpu_base *cpu_base = &per_cpu(hrtimer_bases, cpu);
        int i;
 
-       raw_spin_lock_init(&cpu_base->lock);
-
        for (i = 0; i < HRTIMER_MAX_CLOCK_BASES; i++) {
                cpu_base->clock_base[i].cpu_base = cpu_base;
                timerqueue_init_head(&cpu_base->clock_base[i].active);
index bddd3d7a74b688a1c9c2e68481b77363558124c7..ffd4e111fd67e7d7b29199b6206957f6c458a350 100644 (file)
@@ -55,7 +55,7 @@ struct resource crashk_res = {
        .flags = IORESOURCE_BUSY | IORESOURCE_MEM
 };
 struct resource crashk_low_res = {
-       .name  = "Crash kernel low",
+       .name  = "Crash kernel",
        .start = 0,
        .end   = 0,
        .flags = IORESOURCE_BUSY | IORESOURCE_MEM
@@ -1368,35 +1368,114 @@ static int __init parse_crashkernel_simple(char                *cmdline,
        return 0;
 }
 
+#define SUFFIX_HIGH 0
+#define SUFFIX_LOW  1
+#define SUFFIX_NULL 2
+static __initdata char *suffix_tbl[] = {
+       [SUFFIX_HIGH] = ",high",
+       [SUFFIX_LOW]  = ",low",
+       [SUFFIX_NULL] = NULL,
+};
+
 /*
- * That function is the entry point for command line parsing and should be
- * called from the arch-specific code.
+ * That function parses "suffix"  crashkernel command lines like
+ *
+ *     crashkernel=size,[high|low]
+ *
+ * It returns 0 on success and -EINVAL on failure.
  */
+static int __init parse_crashkernel_suffix(char *cmdline,
+                                          unsigned long long   *crash_size,
+                                          unsigned long long   *crash_base,
+                                          const char *suffix)
+{
+       char *cur = cmdline;
+
+       *crash_size = memparse(cmdline, &cur);
+       if (cmdline == cur) {
+               pr_warn("crashkernel: memory value expected\n");
+               return -EINVAL;
+       }
+
+       /* check with suffix */
+       if (strncmp(cur, suffix, strlen(suffix))) {
+               pr_warn("crashkernel: unrecognized char\n");
+               return -EINVAL;
+       }
+       cur += strlen(suffix);
+       if (*cur != ' ' && *cur != '\0') {
+               pr_warn("crashkernel: unrecognized char\n");
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static __init char *get_last_crashkernel(char *cmdline,
+                            const char *name,
+                            const char *suffix)
+{
+       char *p = cmdline, *ck_cmdline = NULL;
+
+       /* find crashkernel and use the last one if there are more */
+       p = strstr(p, name);
+       while (p) {
+               char *end_p = strchr(p, ' ');
+               char *q;
+
+               if (!end_p)
+                       end_p = p + strlen(p);
+
+               if (!suffix) {
+                       int i;
+
+                       /* skip the one with any known suffix */
+                       for (i = 0; suffix_tbl[i]; i++) {
+                               q = end_p - strlen(suffix_tbl[i]);
+                               if (!strncmp(q, suffix_tbl[i],
+                                            strlen(suffix_tbl[i])))
+                                       goto next;
+                       }
+                       ck_cmdline = p;
+               } else {
+                       q = end_p - strlen(suffix);
+                       if (!strncmp(q, suffix, strlen(suffix)))
+                               ck_cmdline = p;
+               }
+next:
+               p = strstr(p+1, name);
+       }
+
+       if (!ck_cmdline)
+               return NULL;
+
+       return ck_cmdline;
+}
+
 static int __init __parse_crashkernel(char *cmdline,
                             unsigned long long system_ram,
                             unsigned long long *crash_size,
                             unsigned long long *crash_base,
-                               const char *name)
+                            const char *name,
+                            const char *suffix)
 {
-       char    *p = cmdline, *ck_cmdline = NULL;
        char    *first_colon, *first_space;
+       char    *ck_cmdline;
 
        BUG_ON(!crash_size || !crash_base);
        *crash_size = 0;
        *crash_base = 0;
 
-       /* find crashkernel and use the last one if there are more */
-       p = strstr(p, name);
-       while (p) {
-               ck_cmdline = p;
-               p = strstr(p+1, name);
-       }
+       ck_cmdline = get_last_crashkernel(cmdline, name, suffix);
 
        if (!ck_cmdline)
                return -EINVAL;
 
        ck_cmdline += strlen(name);
 
+       if (suffix)
+               return parse_crashkernel_suffix(ck_cmdline, crash_size,
+                               crash_base, suffix);
        /*
         * if the commandline contains a ':', then that's the extended
         * syntax -- if not, it must be the classic syntax
@@ -1413,13 +1492,26 @@ static int __init __parse_crashkernel(char *cmdline,
        return 0;
 }
 
+/*
+ * That function is the entry point for command line parsing and should be
+ * called from the arch-specific code.
+ */
 int __init parse_crashkernel(char *cmdline,
                             unsigned long long system_ram,
                             unsigned long long *crash_size,
                             unsigned long long *crash_base)
 {
        return __parse_crashkernel(cmdline, system_ram, crash_size, crash_base,
-                                       "crashkernel=");
+                                       "crashkernel=", NULL);
+}
+
+int __init parse_crashkernel_high(char *cmdline,
+                            unsigned long long system_ram,
+                            unsigned long long *crash_size,
+                            unsigned long long *crash_base)
+{
+       return __parse_crashkernel(cmdline, system_ram, crash_size, crash_base,
+                               "crashkernel=", suffix_tbl[SUFFIX_HIGH]);
 }
 
 int __init parse_crashkernel_low(char *cmdline,
@@ -1428,7 +1520,7 @@ int __init parse_crashkernel_low(char *cmdline,
                             unsigned long long *crash_base)
 {
        return __parse_crashkernel(cmdline, system_ram, crash_size, crash_base,
-                                       "crashkernel_low=");
+                               "crashkernel=", suffix_tbl[SUFFIX_LOW]);
 }
 
 static void update_vmcoreinfo_note(void)
index e35be53f6613c4fd08c093b6865cd6f43e0b9a89..3fed7f0cbcdfe3d2149dd903e6912628ba58da95 100644 (file)
@@ -794,16 +794,16 @@ out:
 }
 
 #ifdef CONFIG_SYSCTL
-/* This should be called with kprobe_mutex locked */
 static void __kprobes optimize_all_kprobes(void)
 {
        struct hlist_head *head;
        struct kprobe *p;
        unsigned int i;
 
+       mutex_lock(&kprobe_mutex);
        /* If optimization is already allowed, just return */
        if (kprobes_allow_optimization)
-               return;
+               goto out;
 
        kprobes_allow_optimization = true;
        for (i = 0; i < KPROBE_TABLE_SIZE; i++) {
@@ -813,18 +813,22 @@ static void __kprobes optimize_all_kprobes(void)
                                optimize_kprobe(p);
        }
        printk(KERN_INFO "Kprobes globally optimized\n");
+out:
+       mutex_unlock(&kprobe_mutex);
 }
 
-/* This should be called with kprobe_mutex locked */
 static void __kprobes unoptimize_all_kprobes(void)
 {
        struct hlist_head *head;
        struct kprobe *p;
        unsigned int i;
 
+       mutex_lock(&kprobe_mutex);
        /* If optimization is already prohibited, just return */
-       if (!kprobes_allow_optimization)
+       if (!kprobes_allow_optimization) {
+               mutex_unlock(&kprobe_mutex);
                return;
+       }
 
        kprobes_allow_optimization = false;
        for (i = 0; i < KPROBE_TABLE_SIZE; i++) {
@@ -834,11 +838,14 @@ static void __kprobes unoptimize_all_kprobes(void)
                                unoptimize_kprobe(p, false);
                }
        }
+       mutex_unlock(&kprobe_mutex);
+
        /* Wait for unoptimizing completion */
        wait_for_kprobe_optimizer();
        printk(KERN_INFO "Kprobes globally unoptimized\n");
 }
 
+static DEFINE_MUTEX(kprobe_sysctl_mutex);
 int sysctl_kprobes_optimization;
 int proc_kprobes_optimization_handler(struct ctl_table *table, int write,
                                      void __user *buffer, size_t *length,
@@ -846,7 +853,7 @@ int proc_kprobes_optimization_handler(struct ctl_table *table, int write,
 {
        int ret;
 
-       mutex_lock(&kprobe_mutex);
+       mutex_lock(&kprobe_sysctl_mutex);
        sysctl_kprobes_optimization = kprobes_allow_optimization ? 1 : 0;
        ret = proc_dointvec_minmax(table, write, buffer, length, ppos);
 
@@ -854,7 +861,7 @@ int proc_kprobes_optimization_handler(struct ctl_table *table, int write,
                optimize_all_kprobes();
        else
                unoptimize_all_kprobes();
-       mutex_unlock(&kprobe_mutex);
+       mutex_unlock(&kprobe_sysctl_mutex);
 
        return ret;
 }
index 691dc2ef9baf241c121144799360a7e1237afcb5..9eb7fed0bbaa9895973a14e551c76de31fffe533 100644 (file)
@@ -124,12 +124,12 @@ void *kthread_data(struct task_struct *task)
 
 static void __kthread_parkme(struct kthread *self)
 {
-       __set_current_state(TASK_INTERRUPTIBLE);
+       __set_current_state(TASK_PARKED);
        while (test_bit(KTHREAD_SHOULD_PARK, &self->flags)) {
                if (!test_and_set_bit(KTHREAD_IS_PARKED, &self->flags))
                        complete(&self->parked);
                schedule();
-               __set_current_state(TASK_INTERRUPTIBLE);
+               __set_current_state(TASK_PARKED);
        }
        clear_bit(KTHREAD_IS_PARKED, &self->flags);
        __set_current_state(TASK_RUNNING);
@@ -256,8 +256,13 @@ struct task_struct *kthread_create_on_node(int (*threadfn)(void *data),
 }
 EXPORT_SYMBOL(kthread_create_on_node);
 
-static void __kthread_bind(struct task_struct *p, unsigned int cpu)
+static void __kthread_bind(struct task_struct *p, unsigned int cpu, long state)
 {
+       /* Must have done schedule() in kthread() before we set_task_cpu */
+       if (!wait_task_inactive(p, state)) {
+               WARN_ON(1);
+               return;
+       }
        /* It's safe because the task is inactive. */
        do_set_cpus_allowed(p, cpumask_of(cpu));
        p->flags |= PF_THREAD_BOUND;
@@ -274,12 +279,7 @@ static void __kthread_bind(struct task_struct *p, unsigned int cpu)
  */
 void kthread_bind(struct task_struct *p, unsigned int cpu)
 {
-       /* Must have done schedule() in kthread() before we set_task_cpu */
-       if (!wait_task_inactive(p, TASK_UNINTERRUPTIBLE)) {
-               WARN_ON(1);
-               return;
-       }
-       __kthread_bind(p, cpu);
+       __kthread_bind(p, cpu, TASK_UNINTERRUPTIBLE);
 }
 EXPORT_SYMBOL(kthread_bind);
 
@@ -324,6 +324,22 @@ static struct kthread *task_get_live_kthread(struct task_struct *k)
        return NULL;
 }
 
+static void __kthread_unpark(struct task_struct *k, struct kthread *kthread)
+{
+       clear_bit(KTHREAD_SHOULD_PARK, &kthread->flags);
+       /*
+        * We clear the IS_PARKED bit here as we don't wait
+        * until the task has left the park code. So if we'd
+        * park before that happens we'd see the IS_PARKED bit
+        * which might be about to be cleared.
+        */
+       if (test_and_clear_bit(KTHREAD_IS_PARKED, &kthread->flags)) {
+               if (test_bit(KTHREAD_IS_PER_CPU, &kthread->flags))
+                       __kthread_bind(k, kthread->cpu, TASK_PARKED);
+               wake_up_state(k, TASK_PARKED);
+       }
+}
+
 /**
  * kthread_unpark - unpark a thread created by kthread_create().
  * @k:         thread created by kthread_create().
@@ -336,20 +352,8 @@ void kthread_unpark(struct task_struct *k)
 {
        struct kthread *kthread = task_get_live_kthread(k);
 
-       if (kthread) {
-               clear_bit(KTHREAD_SHOULD_PARK, &kthread->flags);
-               /*
-                * We clear the IS_PARKED bit here as we don't wait
-                * until the task has left the park code. So if we'd
-                * park before that happens we'd see the IS_PARKED bit
-                * which might be about to be cleared.
-                */
-               if (test_and_clear_bit(KTHREAD_IS_PARKED, &kthread->flags)) {
-                       if (test_bit(KTHREAD_IS_PER_CPU, &kthread->flags))
-                               __kthread_bind(k, kthread->cpu);
-                       wake_up_process(k);
-               }
-       }
+       if (kthread)
+               __kthread_unpark(k, kthread);
        put_task_struct(k);
 }
 
@@ -407,7 +411,7 @@ int kthread_stop(struct task_struct *k)
        trace_sched_kthread_stop(k);
        if (kthread) {
                set_bit(KTHREAD_SHOULD_STOP, &kthread->flags);
-               clear_bit(KTHREAD_SHOULD_PARK, &kthread->flags);
+               __kthread_unpark(k, kthread);
                wake_up_process(k);
                wait_for_completion(&kthread->exited);
        }
index c685e31492dfcd38ff830ffbc0aecbd77e29ee83..c3ae1446461c0ffc22f41cc03a7504a84576b48b 100644 (file)
@@ -176,10 +176,36 @@ static u64 sched_clock_remote(struct sched_clock_data *scd)
        u64 this_clock, remote_clock;
        u64 *ptr, old_val, val;
 
+#if BITS_PER_LONG != 64
+again:
+       /*
+        * Careful here: The local and the remote clock values need to
+        * be read out atomic as we need to compare the values and
+        * then update either the local or the remote side. So the
+        * cmpxchg64 below only protects one readout.
+        *
+        * We must reread via sched_clock_local() in the retry case on
+        * 32bit as an NMI could use sched_clock_local() via the
+        * tracer and hit between the readout of
+        * the low32bit and the high 32bit portion.
+        */
+       this_clock = sched_clock_local(my_scd);
+       /*
+        * We must enforce atomic readout on 32bit, otherwise the
+        * update on the remote cpu can hit inbetween the readout of
+        * the low32bit and the high 32bit portion.
+        */
+       remote_clock = cmpxchg64(&scd->clock, 0, 0);
+#else
+       /*
+        * On 64bit the read of [my]scd->clock is atomic versus the
+        * update, so we can avoid the above 32bit dance.
+        */
        sched_clock_local(my_scd);
 again:
        this_clock = my_scd->clock;
        remote_clock = scd->clock;
+#endif
 
        /*
         * Use the opportunity that we have both locks
index 7f12624a393c3100506e5a3eaf588b5f463332ee..67d04651f44b294566422615b561310141f69b09 100644 (file)
@@ -1498,8 +1498,10 @@ static void try_to_wake_up_local(struct task_struct *p)
 {
        struct rq *rq = task_rq(p);
 
-       BUG_ON(rq != this_rq());
-       BUG_ON(p == current);
+       if (WARN_ON_ONCE(rq != this_rq()) ||
+           WARN_ON_ONCE(p == current))
+               return;
+
        lockdep_assert_held(&rq->lock);
 
        if (!raw_spin_trylock(&p->pi_lock)) {
@@ -4999,7 +5001,7 @@ static void sd_free_ctl_entry(struct ctl_table **tablep)
 }
 
 static int min_load_idx = 0;
-static int max_load_idx = CPU_LOAD_IDX_MAX;
+static int max_load_idx = CPU_LOAD_IDX_MAX-1;
 
 static void
 set_table_entry(struct ctl_table *entry,
index ed12cbb135f4b8ded0d3c7be26a67d1df8d2ffc2..e93cca92f38b77cce7ce1f49491a393fb79ee346 100644 (file)
@@ -310,7 +310,7 @@ void thread_group_cputime(struct task_struct *tsk, struct task_cputime *times)
 
        t = tsk;
        do {
-               task_cputime(tsk, &utime, &stime);
+               task_cputime(t, &utime, &stime);
                times->utime += utime;
                times->stime += stime;
                times->sum_exec_runtime += task_sched_runtime(t);
index dd72567767d963ccb8ac2f3cfa4a824fa5f81b4e..598dc06be4214c7a11fbf128baff984fa9c1c4b5 100644 (file)
@@ -2948,7 +2948,7 @@ do_send_specific(pid_t tgid, pid_t pid, int sig, struct siginfo *info)
 
 static int do_tkill(pid_t tgid, pid_t pid, int sig)
 {
-       struct siginfo info;
+       struct siginfo info = {};
 
        info.si_signo = sig;
        info.si_errno = 0;
index 8eaed9aa9cf0c1995520605af1de8ef3b9e95485..02fc5c9336735a834378dbbb6fff8e57b919b0fa 100644 (file)
@@ -185,8 +185,18 @@ __smpboot_create_thread(struct smp_hotplug_thread *ht, unsigned int cpu)
        }
        get_task_struct(tsk);
        *per_cpu_ptr(ht->store, cpu) = tsk;
-       if (ht->create)
-               ht->create(cpu);
+       if (ht->create) {
+               /*
+                * Make sure that the task has actually scheduled out
+                * into park position, before calling the create
+                * callback. At least the migration thread callback
+                * requires that the task is off the runqueue.
+                */
+               if (!wait_task_inactive(tsk, TASK_PARKED))
+                       WARN_ON(1);
+               else
+                       ht->create(cpu);
+       }
        return 0;
 }
 
index 39c9c4a2949f3166b114f11534957ff2f6060565..0da73cf73e60937ba8eb65a77f20febcb8264c45 100644 (file)
@@ -324,7 +324,6 @@ void kernel_restart_prepare(char *cmd)
        system_state = SYSTEM_RESTART;
        usermodehelper_disable();
        device_shutdown();
-       syscore_shutdown();
 }
 
 /**
@@ -370,6 +369,7 @@ void kernel_restart(char *cmd)
 {
        kernel_restart_prepare(cmd);
        disable_nonboot_cpus();
+       syscore_shutdown();
        if (!cmd)
                printk(KERN_EMERG "Restarting system.\n");
        else
@@ -395,6 +395,7 @@ static void kernel_shutdown_prepare(enum system_states state)
 void kernel_halt(void)
 {
        kernel_shutdown_prepare(SYSTEM_HALT);
+       disable_nonboot_cpus();
        syscore_shutdown();
        printk(KERN_EMERG "System halted.\n");
        kmsg_dump(KMSG_DUMP_HALT);
index 9e5b8c272eecc9121e8d3e064f30220c71c7e957..5a0f781cd729870892d105f24cc552a9d28b23e6 100644 (file)
@@ -739,12 +739,6 @@ static void blk_add_trace_rq_complete(void *ignore,
                                      struct request_queue *q,
                                      struct request *rq)
 {
-       struct blk_trace *bt = q->blk_trace;
-
-       /* if control ever passes through here, it's a request based driver */
-       if (unlikely(bt && !bt->rq_based))
-               bt->rq_based = true;
-
        blk_add_trace_rq(q, rq, BLK_TA_COMPLETE);
 }
 
@@ -780,24 +774,10 @@ static void blk_add_trace_bio_bounce(void *ignore,
        blk_add_trace_bio(q, bio, BLK_TA_BOUNCE, 0);
 }
 
-static void blk_add_trace_bio_complete(void *ignore, struct bio *bio, int error)
+static void blk_add_trace_bio_complete(void *ignore,
+                                      struct request_queue *q, struct bio *bio,
+                                      int error)
 {
-       struct request_queue *q;
-       struct blk_trace *bt;
-
-       if (!bio->bi_bdev)
-               return;
-
-       q = bdev_get_queue(bio->bi_bdev);
-       bt = q->blk_trace;
-
-       /*
-        * Request based drivers will generate both rq and bio completions.
-        * Ignore bio ones.
-        */
-       if (likely(!bt) || bt->rq_based)
-               return;
-
        blk_add_trace_bio(q, bio, BLK_TA_COMPLETE, error);
 }
 
index 6893d5a2bf086014f2919496ca7062c246935dad..b3fde6d7b7fc47683244a5a432ab35a543551499 100644 (file)
@@ -66,7 +66,7 @@
 
 static struct ftrace_ops ftrace_list_end __read_mostly = {
        .func           = ftrace_stub,
-       .flags          = FTRACE_OPS_FL_RECURSION_SAFE,
+       .flags          = FTRACE_OPS_FL_RECURSION_SAFE | FTRACE_OPS_FL_STUB,
 };
 
 /* ftrace_enabled is a method to turn ftrace on or off */
@@ -694,7 +694,6 @@ int ftrace_profile_pages_init(struct ftrace_profile_stat *stat)
                free_page(tmp);
        }
 
-       free_page((unsigned long)stat->pages);
        stat->pages = NULL;
        stat->start = NULL;
 
@@ -1053,6 +1052,19 @@ static __init void ftrace_profile_debugfs(struct dentry *d_tracer)
 
 static struct pid * const ftrace_swapper_pid = &init_struct_pid;
 
+loff_t
+ftrace_filter_lseek(struct file *file, loff_t offset, int whence)
+{
+       loff_t ret;
+
+       if (file->f_mode & FMODE_READ)
+               ret = seq_lseek(file, offset, whence);
+       else
+               file->f_pos = ret = 1;
+
+       return ret;
+}
+
 #ifdef CONFIG_DYNAMIC_FTRACE
 
 #ifndef CONFIG_FTRACE_MCOUNT_RECORD
@@ -2613,7 +2625,7 @@ static void ftrace_filter_reset(struct ftrace_hash *hash)
  * routine, you can use ftrace_filter_write() for the write
  * routine if @flag has FTRACE_ITER_FILTER set, or
  * ftrace_notrace_write() if @flag has FTRACE_ITER_NOTRACE set.
- * ftrace_regex_lseek() should be used as the lseek routine, and
+ * ftrace_filter_lseek() should be used as the lseek routine, and
  * release must call ftrace_regex_release().
  */
 int
@@ -2697,19 +2709,6 @@ ftrace_notrace_open(struct inode *inode, struct file *file)
                                 inode, file);
 }
 
-loff_t
-ftrace_regex_lseek(struct file *file, loff_t offset, int whence)
-{
-       loff_t ret;
-
-       if (file->f_mode & FMODE_READ)
-               ret = seq_lseek(file, offset, whence);
-       else
-               file->f_pos = ret = 1;
-
-       return ret;
-}
-
 static int ftrace_match(char *str, char *regex, int len, int type)
 {
        int matched = 0;
@@ -3441,14 +3440,14 @@ static char ftrace_filter_buf[FTRACE_FILTER_SIZE] __initdata;
 
 static int __init set_ftrace_notrace(char *str)
 {
-       strncpy(ftrace_notrace_buf, str, FTRACE_FILTER_SIZE);
+       strlcpy(ftrace_notrace_buf, str, FTRACE_FILTER_SIZE);
        return 1;
 }
 __setup("ftrace_notrace=", set_ftrace_notrace);
 
 static int __init set_ftrace_filter(char *str)
 {
-       strncpy(ftrace_filter_buf, str, FTRACE_FILTER_SIZE);
+       strlcpy(ftrace_filter_buf, str, FTRACE_FILTER_SIZE);
        return 1;
 }
 __setup("ftrace_filter=", set_ftrace_filter);
@@ -3571,7 +3570,7 @@ static const struct file_operations ftrace_filter_fops = {
        .open = ftrace_filter_open,
        .read = seq_read,
        .write = ftrace_filter_write,
-       .llseek = ftrace_regex_lseek,
+       .llseek = ftrace_filter_lseek,
        .release = ftrace_regex_release,
 };
 
@@ -3579,7 +3578,7 @@ static const struct file_operations ftrace_notrace_fops = {
        .open = ftrace_notrace_open,
        .read = seq_read,
        .write = ftrace_notrace_write,
-       .llseek = ftrace_regex_lseek,
+       .llseek = ftrace_filter_lseek,
        .release = ftrace_regex_release,
 };
 
@@ -3784,8 +3783,8 @@ static const struct file_operations ftrace_graph_fops = {
        .open           = ftrace_graph_open,
        .read           = seq_read,
        .write          = ftrace_graph_write,
+       .llseek         = ftrace_filter_lseek,
        .release        = ftrace_graph_release,
-       .llseek         = seq_lseek,
 };
 #endif /* CONFIG_FUNCTION_GRAPH_TRACER */
 
@@ -4131,7 +4130,8 @@ ftrace_ops_control_func(unsigned long ip, unsigned long parent_ip,
        preempt_disable_notrace();
        trace_recursion_set(TRACE_CONTROL_BIT);
        do_for_each_ftrace_op(op, ftrace_control_list) {
-               if (!ftrace_function_local_disabled(op) &&
+               if (!(op->flags & FTRACE_OPS_FL_STUB) &&
+                   !ftrace_function_local_disabled(op) &&
                    ftrace_ops_test(op, ip))
                        op->func(ip, parent_ip, op, regs);
        } while_for_each_ftrace_op(op);
@@ -4439,7 +4439,7 @@ static const struct file_operations ftrace_pid_fops = {
        .open           = ftrace_pid_open,
        .write          = ftrace_pid_write,
        .read           = seq_read,
-       .llseek         = seq_lseek,
+       .llseek         = ftrace_filter_lseek,
        .release        = ftrace_pid_release,
 };
 
@@ -4555,12 +4555,8 @@ ftrace_enable_sysctl(struct ctl_table *table, int write,
                ftrace_startup_sysctl();
 
                /* we are starting ftrace again */
-               if (ftrace_ops_list != &ftrace_list_end) {
-                       if (ftrace_ops_list->next == &ftrace_list_end)
-                               ftrace_trace_function = ftrace_ops_list->func;
-                       else
-                               ftrace_trace_function = ftrace_ops_list_func;
-               }
+               if (ftrace_ops_list != &ftrace_list_end)
+                       update_ftrace_function();
 
        } else {
                /* stopping ftrace calls (just send to ftrace_stub) */
index 4f1dade56981d6fe5d880e9f6caaf609ab1e9c02..66338c4f7f4bdb6142c2b21a99f14292c708d050 100644 (file)
@@ -132,7 +132,7 @@ static char *default_bootup_tracer;
 
 static int __init set_cmdline_ftrace(char *str)
 {
-       strncpy(bootup_tracer_buf, str, MAX_TRACER_SIZE);
+       strlcpy(bootup_tracer_buf, str, MAX_TRACER_SIZE);
        default_bootup_tracer = bootup_tracer_buf;
        /* We are using ftrace early, expand it */
        ring_buffer_expanded = 1;
@@ -162,7 +162,7 @@ static char *trace_boot_options __initdata;
 
 static int __init set_trace_boot_options(char *str)
 {
-       strncpy(trace_boot_options_buf, str, MAX_TRACER_SIZE);
+       strlcpy(trace_boot_options_buf, str, MAX_TRACER_SIZE);
        trace_boot_options = trace_boot_options_buf;
        return 0;
 }
@@ -744,8 +744,11 @@ update_max_tr_single(struct trace_array *tr, struct task_struct *tsk, int cpu)
                return;
 
        WARN_ON_ONCE(!irqs_disabled());
-       if (WARN_ON_ONCE(!current_trace->allocated_snapshot))
+       if (!current_trace->allocated_snapshot) {
+               /* Only the nop tracer should hit this when disabling */
+               WARN_ON_ONCE(current_trace != &nop_trace);
                return;
+       }
 
        arch_spin_lock(&ftrace_max_lock);
 
index 42ca822fc7019670d8bea7291caea4110477749b..83a8b5b7bd35fa01a5e0302d83bf3d33d81f9557 100644 (file)
@@ -322,7 +322,7 @@ static const struct file_operations stack_trace_filter_fops = {
        .open = stack_trace_filter_open,
        .read = seq_read,
        .write = ftrace_filter_write,
-       .llseek = ftrace_regex_lseek,
+       .llseek = ftrace_filter_lseek,
        .release = ftrace_regex_release,
 };
 
index a54f26f82eb250a60c7f24ecc651c6c1bbf8cc88..e134d8f365ddea425ac6a8df541875038928298d 100644 (file)
@@ -25,7 +25,8 @@
 
 static struct kmem_cache *user_ns_cachep __read_mostly;
 
-static bool new_idmap_permitted(struct user_namespace *ns, int cap_setid,
+static bool new_idmap_permitted(const struct file *file,
+                               struct user_namespace *ns, int cap_setid,
                                struct uid_gid_map *map);
 
 static void set_cred_user_ns(struct cred *cred, struct user_namespace *user_ns)
@@ -612,10 +613,10 @@ static ssize_t map_write(struct file *file, const char __user *buf,
        if (map->nr_extents != 0)
                goto out;
 
-       /* Require the appropriate privilege CAP_SETUID or CAP_SETGID
-        * over the user namespace in order to set the id mapping.
+       /*
+        * Adjusting namespace settings requires capabilities on the target.
         */
-       if (cap_valid(cap_setid) && !ns_capable(ns, cap_setid))
+       if (cap_valid(cap_setid) && !file_ns_capable(file, ns, CAP_SYS_ADMIN))
                goto out;
 
        /* Get a buffer */
@@ -700,7 +701,7 @@ static ssize_t map_write(struct file *file, const char __user *buf,
 
        ret = -EPERM;
        /* Validate the user is allowed to use user id's mapped to. */
-       if (!new_idmap_permitted(ns, cap_setid, &new_map))
+       if (!new_idmap_permitted(file, ns, cap_setid, &new_map))
                goto out;
 
        /* Map the lower ids from the parent user namespace to the
@@ -787,7 +788,8 @@ ssize_t proc_projid_map_write(struct file *file, const char __user *buf, size_t
                         &ns->projid_map, &ns->parent->projid_map);
 }
 
-static bool new_idmap_permitted(struct user_namespace *ns, int cap_setid,
+static bool new_idmap_permitted(const struct file *file, 
+                               struct user_namespace *ns, int cap_setid,
                                struct uid_gid_map *new_map)
 {
        /* Allow mapping to your own filesystem ids */
@@ -795,12 +797,12 @@ static bool new_idmap_permitted(struct user_namespace *ns, int cap_setid,
                u32 id = new_map->extent[0].lower_first;
                if (cap_setid == CAP_SETUID) {
                        kuid_t uid = make_kuid(ns->parent, id);
-                       if (uid_eq(uid, current_fsuid()))
+                       if (uid_eq(uid, file->f_cred->fsuid))
                                return true;
                }
                else if (cap_setid == CAP_SETGID) {
                        kgid_t gid = make_kgid(ns->parent, id);
-                       if (gid_eq(gid, current_fsgid()))
+                       if (gid_eq(gid, file->f_cred->fsgid))
                                return true;
                }
        }
@@ -811,8 +813,10 @@ static bool new_idmap_permitted(struct user_namespace *ns, int cap_setid,
 
        /* Allow the specified ids if we have the appropriate capability
         * (CAP_SETUID or CAP_SETGID) over the parent user namespace.
+        * And the opener of the id file also had the approprpiate capability.
         */
-       if (ns_capable(ns->parent, cap_setid))
+       if (ns_capable(ns->parent, cap_setid) &&
+           file_ns_capable(file, ns->parent, cap_setid))
                return true;
 
        return false;
index 3958dc4389f993cc204670706e834c42be80165b..fe01d418b09ae4d13a15b59039ef27602d1ad0f3 100644 (file)
@@ -404,4 +404,7 @@ config OID_REGISTRY
        help
          Enable fast lookup object identifier registry.
 
+config UCS2_STRING
+        tristate
+
 endmenu
index d7946ff75b2ea0f4baca2716aba3f41577f9b904..6e2cc561f761af79f2d555ca688bbcfe676de602 100644 (file)
@@ -174,3 +174,5 @@ quiet_cmd_build_OID_registry = GEN     $@
       cmd_build_OID_registry = perl $(srctree)/$(src)/build_OID_registry $< $@
 
 clean-files    += oid_registry_data.c
+
+obj-$(CONFIG_UCS2_STRING) += ucs2_string.o
index e07ee1fcd6f19da086439ffbeacd8376e4b3e533..a65486613d79775bf87918b390d8edd608d55cef 100644 (file)
@@ -529,6 +529,13 @@ struct kobject *kobject_get(struct kobject *kobj)
        return kobj;
 }
 
+static struct kobject *kobject_get_unless_zero(struct kobject *kobj)
+{
+       if (!kref_get_unless_zero(&kobj->kref))
+               kobj = NULL;
+       return kobj;
+}
+
 /*
  * kobject_cleanup - free kobject resources.
  * @kobj: object to cleanup
@@ -751,7 +758,7 @@ struct kobject *kset_find_obj(struct kset *kset, const char *name)
 
        list_for_each_entry(k, &kset->list, entry) {
                if (kobject_name(k) && !strcmp(kobject_name(k), name)) {
-                       ret = kobject_get(k);
+                       ret = kobject_get_unless_zero(k);
                        break;
                }
        }
index bfe02b8fc55b3d1c383832148e4e5aa44e0ef87c..d23762e6652c1e02bf87f070d3164afa93dc91a8 100644 (file)
@@ -105,9 +105,9 @@ setup_io_tlb_npages(char *str)
        if (!strcmp(str, "force"))
                swiotlb_force = 1;
 
-       return 1;
+       return 0;
 }
-__setup("swiotlb=", setup_io_tlb_npages);
+early_param("swiotlb", setup_io_tlb_npages);
 /* make io_tlb_overflow tunable too? */
 
 unsigned long swiotlb_nr_tbl(void)
@@ -115,6 +115,18 @@ unsigned long swiotlb_nr_tbl(void)
        return io_tlb_nslabs;
 }
 EXPORT_SYMBOL_GPL(swiotlb_nr_tbl);
+
+/* default to 64MB */
+#define IO_TLB_DEFAULT_SIZE (64UL<<20)
+unsigned long swiotlb_size_or_default(void)
+{
+       unsigned long size;
+
+       size = io_tlb_nslabs << IO_TLB_SHIFT;
+
+       return size ? size : (IO_TLB_DEFAULT_SIZE);
+}
+
 /* Note that this doesn't work with highmem page */
 static dma_addr_t swiotlb_virt_to_bus(struct device *hwdev,
                                      volatile void *address)
@@ -188,8 +200,7 @@ int __init swiotlb_init_with_tbl(char *tlb, unsigned long nslabs, int verbose)
 void  __init
 swiotlb_init(int verbose)
 {
-       /* default to 64MB */
-       size_t default_size = 64UL<<20;
+       size_t default_size = IO_TLB_DEFAULT_SIZE;
        unsigned char *vstart;
        unsigned long bytes;
 
diff --git a/lib/ucs2_string.c b/lib/ucs2_string.c
new file mode 100644 (file)
index 0000000..6f500ef
--- /dev/null
@@ -0,0 +1,51 @@
+#include <linux/ucs2_string.h>
+#include <linux/module.h>
+
+/* Return the number of unicode characters in data */
+unsigned long
+ucs2_strnlen(const ucs2_char_t *s, size_t maxlength)
+{
+        unsigned long length = 0;
+
+        while (*s++ != 0 && length < maxlength)
+                length++;
+        return length;
+}
+EXPORT_SYMBOL(ucs2_strnlen);
+
+unsigned long
+ucs2_strlen(const ucs2_char_t *s)
+{
+        return ucs2_strnlen(s, ~0UL);
+}
+EXPORT_SYMBOL(ucs2_strlen);
+
+/*
+ * Return the number of bytes is the length of this string
+ * Note: this is NOT the same as the number of unicode characters
+ */
+unsigned long
+ucs2_strsize(const ucs2_char_t *data, unsigned long maxlength)
+{
+        return ucs2_strnlen(data, maxlength/sizeof(ucs2_char_t)) * sizeof(ucs2_char_t);
+}
+EXPORT_SYMBOL(ucs2_strsize);
+
+int
+ucs2_strncmp(const ucs2_char_t *a, const ucs2_char_t *b, size_t len)
+{
+        while (1) {
+                if (len == 0)
+                        return 0;
+                if (*a < *b)
+                        return -1;
+                if (*a > *b)
+                        return 1;
+                if (*a == 0) /* implies *b == 0 */
+                        return 0;
+                a++;
+                b++;
+                len--;
+        }
+}
+EXPORT_SYMBOL(ucs2_strncmp);
index ca9a7c6d7e973c5db4bbecd7e72139d5c9529b72..1a12f5b9a0aba45396fccc46d14d2b6534c30263 100644 (file)
@@ -2961,7 +2961,17 @@ long follow_hugetlb_page(struct mm_struct *mm, struct vm_area_struct *vma,
                        break;
                }
 
-               if (absent ||
+               /*
+                * We need call hugetlb_fault for both hugepages under migration
+                * (in which case hugetlb_fault waits for the migration,) and
+                * hwpoisoned hugepages (in which case we need to prevent the
+                * caller from accessing to them.) In order to do this, we use
+                * here is_swap_pte instead of is_hugetlb_entry_migration and
+                * is_hugetlb_entry_hwpoisoned. This is because it simply covers
+                * both cases, and because we can't follow correct pages
+                * directly from any kind of swap entries.
+                */
+               if (absent || is_swap_pte(huge_ptep_get(pte)) ||
                    ((flags & FOLL_WRITE) && !pte_write(huge_ptep_get(pte)))) {
                        int ret;
 
index 494526ae024a3173fc200d47e36087f6252852c2..ba94dec5b25900e47093544e11f8c765bf243f9d 100644 (file)
@@ -216,6 +216,7 @@ void tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, bool fullmm)
        tlb->mm = mm;
 
        tlb->fullmm     = fullmm;
+       tlb->need_flush_all = 0;
        tlb->start      = -1UL;
        tlb->end        = 0;
        tlb->need_flush = 0;
@@ -2392,6 +2393,53 @@ int remap_pfn_range(struct vm_area_struct *vma, unsigned long addr,
 }
 EXPORT_SYMBOL(remap_pfn_range);
 
+/**
+ * vm_iomap_memory - remap memory to userspace
+ * @vma: user vma to map to
+ * @start: start of area
+ * @len: size of area
+ *
+ * This is a simplified io_remap_pfn_range() for common driver use. The
+ * driver just needs to give us the physical memory range to be mapped,
+ * we'll figure out the rest from the vma information.
+ *
+ * NOTE! Some drivers might want to tweak vma->vm_page_prot first to get
+ * whatever write-combining details or similar.
+ */
+int vm_iomap_memory(struct vm_area_struct *vma, phys_addr_t start, unsigned long len)
+{
+       unsigned long vm_len, pfn, pages;
+
+       /* Check that the physical memory area passed in looks valid */
+       if (start + len < start)
+               return -EINVAL;
+       /*
+        * You *really* shouldn't map things that aren't page-aligned,
+        * but we've historically allowed it because IO memory might
+        * just have smaller alignment.
+        */
+       len += start & ~PAGE_MASK;
+       pfn = start >> PAGE_SHIFT;
+       pages = (len + ~PAGE_MASK) >> PAGE_SHIFT;
+       if (pfn + pages < pfn)
+               return -EINVAL;
+
+       /* We start the mapping 'vm_pgoff' pages into the area */
+       if (vma->vm_pgoff > pages)
+               return -EINVAL;
+       pfn += vma->vm_pgoff;
+       pages -= vma->vm_pgoff;
+
+       /* Can we fit all of the mapping? */
+       vm_len = vma->vm_end - vma->vm_start;
+       if (vm_len >> PAGE_SHIFT > pages)
+               return -EINVAL;
+
+       /* Ok, let it rip */
+       return io_remap_pfn_range(vma, vma->vm_start, pfn, vm_len, vma->vm_page_prot);
+}
+EXPORT_SYMBOL(vm_iomap_memory);
+
 static int apply_to_pte_range(struct mm_struct *mm, pmd_t *pmd,
                                     unsigned long addr, unsigned long end,
                                     pte_fn_t fn, void *data)
index 88c5fed8b9a4bd9a54021810cf05710cff4fcbfc..669fba39be1aa41bb9adfd040c709e43b194cfe2 100644 (file)
@@ -3188,9 +3188,9 @@ int kswapd_run(int nid)
        if (IS_ERR(pgdat->kswapd)) {
                /* failure at boot is fatal */
                BUG_ON(system_state == SYSTEM_BOOTING);
-               pgdat->kswapd = NULL;
                pr_err("Failed to start kswapd on node %d\n", nid);
                ret = PTR_ERR(pgdat->kswapd);
+               pgdat->kswapd = NULL;
        }
        return ret;
 }
index a4cc3229952a17d387411cded9bc66d940b9929f..e085bcc754f602e4401e51c8c29442a1bd143de8 100644 (file)
@@ -870,8 +870,12 @@ void mrp_uninit_applicant(struct net_device *dev, struct mrp_application *appl)
         * all pending messages before the applicant is gone.
         */
        del_timer_sync(&app->join_timer);
+
+       spin_lock(&app->lock);
        mrp_mad_event(app, MRP_EVENT_TX);
        mrp_pdu_queue(app);
+       spin_unlock(&app->lock);
+
        mrp_queue_xmit(app);
 
        dev_mc_del(dev, appl->group_address);
index 7b491006eaf4000424282979b0c4709325102152..737bef59ce899adc0a3e0ba67ea3d56536e5b7e5 100644 (file)
@@ -531,6 +531,8 @@ int vcc_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
        struct sk_buff *skb;
        int copied, error = -EINVAL;
 
+       msg->msg_namelen = 0;
+
        if (sock->state != SS_CONNECTED)
                return -ENOTCONN;
 
index 7b11f8bc5071cba0de51054913fa5f3e8bb3f063..e277e38f736b93a133a6cd43cc7b264acfbad641 100644 (file)
@@ -1642,6 +1642,7 @@ static int ax25_recvmsg(struct kiocb *iocb, struct socket *sock,
                ax25_address src;
                const unsigned char *mac = skb_mac_header(skb);
 
+               memset(sax, 0, sizeof(struct full_sockaddr_ax25));
                ax25_addr_parse(mac + 1, skb->data - mac - 1, &src, NULL,
                                &digi, NULL, NULL);
                sax->sax25_family = AF_AX25;
index 0488d70c8c3512bef0311f1611d0a4a362b9057e..fa563e497c4861a3fd1656a91887eed47e81ec81 100644 (file)
@@ -169,7 +169,7 @@ void batadv_mesh_free(struct net_device *soft_iface)
        atomic_set(&bat_priv->mesh_state, BATADV_MESH_INACTIVE);
 }
 
-int batadv_is_my_mac(const uint8_t *addr)
+int batadv_is_my_mac(struct batadv_priv *bat_priv, const uint8_t *addr)
 {
        const struct batadv_hard_iface *hard_iface;
 
@@ -178,6 +178,9 @@ int batadv_is_my_mac(const uint8_t *addr)
                if (hard_iface->if_status != BATADV_IF_ACTIVE)
                        continue;
 
+               if (hard_iface->soft_iface != bat_priv->soft_iface)
+                       continue;
+
                if (batadv_compare_eth(hard_iface->net_dev->dev_addr, addr)) {
                        rcu_read_unlock();
                        return 1;
index ced08b936a9690a6f7d01af7f7eb8a31f3e1f29d..d40910dfc8ea5a20fbe2c839f59bd65018bf1c28 100644 (file)
@@ -162,7 +162,7 @@ extern struct workqueue_struct *batadv_event_workqueue;
 
 int batadv_mesh_init(struct net_device *soft_iface);
 void batadv_mesh_free(struct net_device *soft_iface);
-int batadv_is_my_mac(const uint8_t *addr);
+int batadv_is_my_mac(struct batadv_priv *bat_priv, const uint8_t *addr);
 struct batadv_hard_iface *
 batadv_seq_print_text_primary_if_get(struct seq_file *seq);
 int batadv_batman_skb_recv(struct sk_buff *skb, struct net_device *dev,
index 5ee21cebbbb0953fd7708b84761f379d8a1423e5..319f2906c71a2146328c1e6ad1c4e9cbedee1e53 100644 (file)
@@ -402,7 +402,7 @@ int batadv_recv_icmp_packet(struct sk_buff *skb,
                goto out;
 
        /* not for me */
-       if (!batadv_is_my_mac(ethhdr->h_dest))
+       if (!batadv_is_my_mac(bat_priv, ethhdr->h_dest))
                goto out;
 
        icmp_packet = (struct batadv_icmp_packet_rr *)skb->data;
@@ -416,7 +416,7 @@ int batadv_recv_icmp_packet(struct sk_buff *skb,
        }
 
        /* packet for me */
-       if (batadv_is_my_mac(icmp_packet->dst))
+       if (batadv_is_my_mac(bat_priv, icmp_packet->dst))
                return batadv_recv_my_icmp_packet(bat_priv, skb, hdr_size);
 
        /* TTL exceeded */
@@ -548,7 +548,8 @@ batadv_find_ifalter_router(struct batadv_orig_node *primary_orig,
        return router;
 }
 
-static int batadv_check_unicast_packet(struct sk_buff *skb, int hdr_size)
+static int batadv_check_unicast_packet(struct batadv_priv *bat_priv,
+                                      struct sk_buff *skb, int hdr_size)
 {
        struct ethhdr *ethhdr;
 
@@ -567,7 +568,7 @@ static int batadv_check_unicast_packet(struct sk_buff *skb, int hdr_size)
                return -1;
 
        /* not for me */
-       if (!batadv_is_my_mac(ethhdr->h_dest))
+       if (!batadv_is_my_mac(bat_priv, ethhdr->h_dest))
                return -1;
 
        return 0;
@@ -582,7 +583,7 @@ int batadv_recv_tt_query(struct sk_buff *skb, struct batadv_hard_iface *recv_if)
        char tt_flag;
        size_t packet_size;
 
-       if (batadv_check_unicast_packet(skb, hdr_size) < 0)
+       if (batadv_check_unicast_packet(bat_priv, skb, hdr_size) < 0)
                return NET_RX_DROP;
 
        /* I could need to modify it */
@@ -614,7 +615,7 @@ int batadv_recv_tt_query(struct sk_buff *skb, struct batadv_hard_iface *recv_if)
        case BATADV_TT_RESPONSE:
                batadv_inc_counter(bat_priv, BATADV_CNT_TT_RESPONSE_RX);
 
-               if (batadv_is_my_mac(tt_query->dst)) {
+               if (batadv_is_my_mac(bat_priv, tt_query->dst)) {
                        /* packet needs to be linearized to access the TT
                         * changes
                         */
@@ -657,14 +658,15 @@ int batadv_recv_roam_adv(struct sk_buff *skb, struct batadv_hard_iface *recv_if)
        struct batadv_roam_adv_packet *roam_adv_packet;
        struct batadv_orig_node *orig_node;
 
-       if (batadv_check_unicast_packet(skb, sizeof(*roam_adv_packet)) < 0)
+       if (batadv_check_unicast_packet(bat_priv, skb,
+                                       sizeof(*roam_adv_packet)) < 0)
                goto out;
 
        batadv_inc_counter(bat_priv, BATADV_CNT_TT_ROAM_ADV_RX);
 
        roam_adv_packet = (struct batadv_roam_adv_packet *)skb->data;
 
-       if (!batadv_is_my_mac(roam_adv_packet->dst))
+       if (!batadv_is_my_mac(bat_priv, roam_adv_packet->dst))
                return batadv_route_unicast_packet(skb, recv_if);
 
        /* check if it is a backbone gateway. we don't accept
@@ -967,7 +969,7 @@ static int batadv_check_unicast_ttvn(struct batadv_priv *bat_priv,
         * last time) the packet had an updated information or not
         */
        curr_ttvn = (uint8_t)atomic_read(&bat_priv->tt.vn);
-       if (!batadv_is_my_mac(unicast_packet->dest)) {
+       if (!batadv_is_my_mac(bat_priv, unicast_packet->dest)) {
                orig_node = batadv_orig_hash_find(bat_priv,
                                                  unicast_packet->dest);
                /* if it is not possible to find the orig_node representing the
@@ -1044,14 +1046,14 @@ int batadv_recv_unicast_packet(struct sk_buff *skb,
        if (is4addr)
                hdr_size = sizeof(*unicast_4addr_packet);
 
-       if (batadv_check_unicast_packet(skb, hdr_size) < 0)
+       if (batadv_check_unicast_packet(bat_priv, skb, hdr_size) < 0)
                return NET_RX_DROP;
 
        if (!batadv_check_unicast_ttvn(bat_priv, skb))
                return NET_RX_DROP;
 
        /* packet for me */
-       if (batadv_is_my_mac(unicast_packet->dest)) {
+       if (batadv_is_my_mac(bat_priv, unicast_packet->dest)) {
                if (is4addr) {
                        batadv_dat_inc_counter(bat_priv,
                                               unicast_4addr_packet->subtype);
@@ -1088,7 +1090,7 @@ int batadv_recv_ucast_frag_packet(struct sk_buff *skb,
        struct sk_buff *new_skb = NULL;
        int ret;
 
-       if (batadv_check_unicast_packet(skb, hdr_size) < 0)
+       if (batadv_check_unicast_packet(bat_priv, skb, hdr_size) < 0)
                return NET_RX_DROP;
 
        if (!batadv_check_unicast_ttvn(bat_priv, skb))
@@ -1097,7 +1099,7 @@ int batadv_recv_ucast_frag_packet(struct sk_buff *skb,
        unicast_packet = (struct batadv_unicast_frag_packet *)skb->data;
 
        /* packet for me */
-       if (batadv_is_my_mac(unicast_packet->dest)) {
+       if (batadv_is_my_mac(bat_priv, unicast_packet->dest)) {
                ret = batadv_frag_reassemble_skb(skb, bat_priv, &new_skb);
 
                if (ret == NET_RX_DROP)
@@ -1151,13 +1153,13 @@ int batadv_recv_bcast_packet(struct sk_buff *skb,
                goto out;
 
        /* ignore broadcasts sent by myself */
-       if (batadv_is_my_mac(ethhdr->h_source))
+       if (batadv_is_my_mac(bat_priv, ethhdr->h_source))
                goto out;
 
        bcast_packet = (struct batadv_bcast_packet *)skb->data;
 
        /* ignore broadcasts originated by myself */
-       if (batadv_is_my_mac(bcast_packet->orig))
+       if (batadv_is_my_mac(bat_priv, bcast_packet->orig))
                goto out;
 
        if (bcast_packet->header.ttl < 2)
@@ -1243,14 +1245,14 @@ int batadv_recv_vis_packet(struct sk_buff *skb,
        ethhdr = (struct ethhdr *)skb_mac_header(skb);
 
        /* not for me */
-       if (!batadv_is_my_mac(ethhdr->h_dest))
+       if (!batadv_is_my_mac(bat_priv, ethhdr->h_dest))
                return NET_RX_DROP;
 
        /* ignore own packets */
-       if (batadv_is_my_mac(vis_packet->vis_orig))
+       if (batadv_is_my_mac(bat_priv, vis_packet->vis_orig))
                return NET_RX_DROP;
 
-       if (batadv_is_my_mac(vis_packet->sender_orig))
+       if (batadv_is_my_mac(bat_priv, vis_packet->sender_orig))
                return NET_RX_DROP;
 
        switch (vis_packet->vis_type) {
index 98a66a021a602678d515df58199895bceef31a92..7abee19567e9e0f84ecb224e666f2e6c1094333c 100644 (file)
@@ -1953,7 +1953,7 @@ out:
 bool batadv_send_tt_response(struct batadv_priv *bat_priv,
                             struct batadv_tt_query_packet *tt_request)
 {
-       if (batadv_is_my_mac(tt_request->dst)) {
+       if (batadv_is_my_mac(bat_priv, tt_request->dst)) {
                /* don't answer backbone gws! */
                if (batadv_bla_is_backbone_gw_orig(bat_priv, tt_request->src))
                        return true;
index c053244b97bd38e03a588c1c629e6081d06b2154..6a1e646be96d45b21e21127a056a9aad3af91bb1 100644 (file)
@@ -477,7 +477,7 @@ void batadv_receive_client_update_packet(struct batadv_priv *bat_priv,
 
        /* Are we the target for this VIS packet? */
        if (vis_server == BATADV_VIS_TYPE_SERVER_SYNC   &&
-           batadv_is_my_mac(vis_packet->target_orig))
+           batadv_is_my_mac(bat_priv, vis_packet->target_orig))
                are_target = 1;
 
        spin_lock_bh(&bat_priv->vis.hash_lock);
@@ -496,7 +496,7 @@ void batadv_receive_client_update_packet(struct batadv_priv *bat_priv,
                batadv_send_list_add(bat_priv, info);
 
                /* ... we're not the recipient (and thus need to forward). */
-       } else if (!batadv_is_my_mac(packet->target_orig)) {
+       } else if (!batadv_is_my_mac(bat_priv, packet->target_orig)) {
                batadv_send_list_add(bat_priv, info);
        }
 
index d3ee69b35a78267f35b8ea4a9b32d367160eea21..0d1b08cc76e1d73acba966e4c22f64c0285cce05 100644 (file)
@@ -230,6 +230,8 @@ int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
        if (flags & (MSG_OOB))
                return -EOPNOTSUPP;
 
+       msg->msg_namelen = 0;
+
        skb = skb_recv_datagram(sk, flags, noblock, &err);
        if (!skb) {
                if (sk->sk_shutdown & RCV_SHUTDOWN)
@@ -237,8 +239,6 @@ int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
                return err;
        }
 
-       msg->msg_namelen = 0;
-
        copied = skb->len;
        if (len < copied) {
                msg->msg_flags |= MSG_TRUNC;
index c23bae86263b6e98a21a8f69ae45190b827b2376..7c9224bcce178c493ce0a19f3f8250b1828d39b8 100644 (file)
@@ -608,6 +608,7 @@ static int rfcomm_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
 
        if (test_and_clear_bit(RFCOMM_DEFER_SETUP, &d->flags)) {
                rfcomm_dlc_accept(d);
+               msg->msg_namelen = 0;
                return 0;
        }
 
index fad0302bdb325e5df700edf4fe323c6226216599..fb6192c9812e81bcac3d8dea31f60095aa40ffda 100644 (file)
@@ -665,6 +665,7 @@ static int sco_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
            test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
                hci_conn_accept(pi->conn->hcon, 0);
                sk->sk_state = BT_CONFIG;
+               msg->msg_namelen = 0;
 
                release_sock(sk);
                return 0;
index ef1b91431c6bb1e0627119f877eca0d2339a899c..459dab22b3f6009dc027c01e29fe587270291053 100644 (file)
@@ -67,7 +67,8 @@ void br_port_carrier_check(struct net_bridge_port *p)
        struct net_device *dev = p->dev;
        struct net_bridge *br = p->br;
 
-       if (netif_running(dev) && netif_oper_up(dev))
+       if (!(p->flags & BR_ADMIN_COST) &&
+           netif_running(dev) && netif_oper_up(dev))
                p->path_cost = port_cost(dev);
 
        if (!netif_running(br->dev))
index 3cbf5beb3d4be267fbea19a2fd81b7b09d3d6a0c..d2c043a857b6a0fd3bfd208f018179b96c42dacd 100644 (file)
@@ -156,6 +156,7 @@ struct net_bridge_port
 #define BR_BPDU_GUARD           0x00000002
 #define BR_ROOT_BLOCK          0x00000004
 #define BR_MULTICAST_FAST_LEAVE        0x00000008
+#define BR_ADMIN_COST          0x00000010
 
 #ifdef CONFIG_BRIDGE_IGMP_SNOOPING
        u32                             multicast_startup_queries_sent;
index 0bdb4ebd362b7818229bb50f13d25f7e1181dcad..d45e760141bb81a34909b98724b2d8f3fc876136 100644 (file)
@@ -288,6 +288,7 @@ int br_stp_set_path_cost(struct net_bridge_port *p, unsigned long path_cost)
            path_cost > BR_MAX_PATH_COST)
                return -ERANGE;
 
+       p->flags |= BR_ADMIN_COST;
        p->path_cost = path_cost;
        br_configuration_update(p->br);
        br_port_state_selection(p->br);
index 095259f839023a99a2127d1d4173bb29737471df..ff2ff3ce6965a73dcf74918cd5c5bcc1b4a7d51b 100644 (file)
@@ -286,6 +286,8 @@ static int caif_seqpkt_recvmsg(struct kiocb *iocb, struct socket *sock,
        if (m->msg_flags&MSG_OOB)
                goto read_error;
 
+       m->msg_namelen = 0;
+
        skb = skb_recv_datagram(sk, flags, 0 , &ret);
        if (!skb)
                goto read_error;
index 2d117dc5ebea0e027e34e844dc7685720a93c033..117814a7e73c720b20026289f4349528e8ed6f6a 100644 (file)
@@ -466,7 +466,7 @@ static int cgw_notifier(struct notifier_block *nb,
                        if (gwj->src.dev == dev || gwj->dst.dev == dev) {
                                hlist_del(&gwj->list);
                                cgw_unregister_filter(gwj);
-                               kfree(gwj);
+                               kmem_cache_free(cgw_cache, gwj);
                        }
                }
        }
@@ -864,7 +864,7 @@ static void cgw_remove_all_jobs(void)
        hlist_for_each_entry_safe(gwj, nx, &cgw_list, list) {
                hlist_del(&gwj->list);
                cgw_unregister_filter(gwj);
-               kfree(gwj);
+               kmem_cache_free(cgw_cache, gwj);
        }
 }
 
@@ -920,7 +920,7 @@ static int cgw_remove_job(struct sk_buff *skb,  struct nlmsghdr *nlh, void *arg)
 
                hlist_del(&gwj->list);
                cgw_unregister_filter(gwj);
-               kfree(gwj);
+               kmem_cache_free(cgw_cache, gwj);
                err = 0;
                break;
        }
index e7d68ed8aafe60f75233fcdc1ed68c39e755cda6..b24ab0e98eb4d8dd8cef2a20ef2a39b97d9ece92 100644 (file)
@@ -2148,6 +2148,9 @@ static void skb_warn_bad_offload(const struct sk_buff *skb)
        struct net_device *dev = skb->dev;
        const char *driver = "";
 
+       if (!net_ratelimit())
+               return;
+
        if (dev && dev->dev.parent)
                driver = dev_driver_string(dev->dev.parent);
 
index b65441da74abd85cc8deacc7650c583013e9dcfb..23854b51a259cb8b65c2bb1ee4be8e32e0ca0eb8 100644 (file)
@@ -1072,7 +1072,7 @@ static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
        rcu_read_lock();
        cb->seq = net->dev_base_seq;
 
-       if (nlmsg_parse(cb->nlh, sizeof(struct rtgenmsg), tb, IFLA_MAX,
+       if (nlmsg_parse(cb->nlh, sizeof(struct ifinfomsg), tb, IFLA_MAX,
                        ifla_policy) >= 0) {
 
                if (tb[IFLA_EXT_MASK])
@@ -1922,7 +1922,7 @@ static u16 rtnl_calcit(struct sk_buff *skb, struct nlmsghdr *nlh)
        u32 ext_filter_mask = 0;
        u16 min_ifinfo_dump_size = 0;
 
-       if (nlmsg_parse(nlh, sizeof(struct rtgenmsg), tb, IFLA_MAX,
+       if (nlmsg_parse(nlh, sizeof(struct ifinfomsg), tb, IFLA_MAX,
                        ifla_policy) >= 0) {
                if (tb[IFLA_EXT_MASK])
                        ext_filter_mask = nla_get_u32(tb[IFLA_EXT_MASK]);
index 96083b7a436bc9efddd0b8b3473caa78286e5f02..c6287cd978c2db7b40f3aa3fe06b5d43bced64d5 100644 (file)
@@ -587,13 +587,16 @@ static void check_lifetime(struct work_struct *work)
 {
        unsigned long now, next, next_sec, next_sched;
        struct in_ifaddr *ifa;
+       struct hlist_node *n;
        int i;
 
        now = jiffies;
        next = round_jiffies_up(now + ADDR_CHECK_FREQUENCY);
 
-       rcu_read_lock();
        for (i = 0; i < IN4_ADDR_HSIZE; i++) {
+               bool change_needed = false;
+
+               rcu_read_lock();
                hlist_for_each_entry_rcu(ifa, &inet_addr_lst[i], hash) {
                        unsigned long age;
 
@@ -606,16 +609,7 @@ static void check_lifetime(struct work_struct *work)
 
                        if (ifa->ifa_valid_lft != INFINITY_LIFE_TIME &&
                            age >= ifa->ifa_valid_lft) {
-                               struct in_ifaddr **ifap ;
-
-                               rtnl_lock();
-                               for (ifap = &ifa->ifa_dev->ifa_list;
-                                    *ifap != NULL; ifap = &ifa->ifa_next) {
-                                       if (*ifap == ifa)
-                                               inet_del_ifa(ifa->ifa_dev,
-                                                            ifap, 1);
-                               }
-                               rtnl_unlock();
+                               change_needed = true;
                        } else if (ifa->ifa_preferred_lft ==
                                   INFINITY_LIFE_TIME) {
                                continue;
@@ -625,10 +619,8 @@ static void check_lifetime(struct work_struct *work)
                                        next = ifa->ifa_tstamp +
                                               ifa->ifa_valid_lft * HZ;
 
-                               if (!(ifa->ifa_flags & IFA_F_DEPRECATED)) {
-                                       ifa->ifa_flags |= IFA_F_DEPRECATED;
-                                       rtmsg_ifa(RTM_NEWADDR, ifa, NULL, 0);
-                               }
+                               if (!(ifa->ifa_flags & IFA_F_DEPRECATED))
+                                       change_needed = true;
                        } else if (time_before(ifa->ifa_tstamp +
                                               ifa->ifa_preferred_lft * HZ,
                                               next)) {
@@ -636,8 +628,42 @@ static void check_lifetime(struct work_struct *work)
                                       ifa->ifa_preferred_lft * HZ;
                        }
                }
+               rcu_read_unlock();
+               if (!change_needed)
+                       continue;
+               rtnl_lock();
+               hlist_for_each_entry_safe(ifa, n, &inet_addr_lst[i], hash) {
+                       unsigned long age;
+
+                       if (ifa->ifa_flags & IFA_F_PERMANENT)
+                               continue;
+
+                       /* We try to batch several events at once. */
+                       age = (now - ifa->ifa_tstamp +
+                              ADDRCONF_TIMER_FUZZ_MINUS) / HZ;
+
+                       if (ifa->ifa_valid_lft != INFINITY_LIFE_TIME &&
+                           age >= ifa->ifa_valid_lft) {
+                               struct in_ifaddr **ifap;
+
+                               for (ifap = &ifa->ifa_dev->ifa_list;
+                                    *ifap != NULL; ifap = &(*ifap)->ifa_next) {
+                                       if (*ifap == ifa) {
+                                               inet_del_ifa(ifa->ifa_dev,
+                                                            ifap, 1);
+                                               break;
+                                       }
+                               }
+                       } else if (ifa->ifa_preferred_lft !=
+                                  INFINITY_LIFE_TIME &&
+                                  age >= ifa->ifa_preferred_lft &&
+                                  !(ifa->ifa_flags & IFA_F_DEPRECATED)) {
+                               ifa->ifa_flags |= IFA_F_DEPRECATED;
+                               rtmsg_ifa(RTM_NEWADDR, ifa, NULL, 0);
+                       }
+               }
+               rtnl_unlock();
        }
-       rcu_read_unlock();
 
        next_sec = round_jiffies_up(next);
        next_sched = next;
@@ -804,6 +830,8 @@ static int inet_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg
                        return -EEXIST;
                ifa = ifa_existing;
                set_ifa_lifetime(ifa, valid_lft, prefered_lft);
+               cancel_delayed_work(&check_lifetime_work);
+               schedule_delayed_work(&check_lifetime_work, 0);
                rtmsg_ifa(RTM_NEWADDR, ifa, nlh, NETLINK_CB(skb).portid);
                blocking_notifier_call_chain(&inetaddr_chain, NETDEV_UP, ifa);
        }
index 3b4f0cd2e63edbd136683577873b288712a4b92a..4cfe34d4cc967a94ed15f2deef3d249d2429e846 100644 (file)
@@ -139,8 +139,6 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb)
 
        /* skb is pure payload to encrypt */
 
-       err = -ENOMEM;
-
        esp = x->data;
        aead = esp->aead;
        alen = crypto_aead_authsize(aead);
@@ -176,8 +174,10 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb)
        }
 
        tmp = esp_alloc_tmp(aead, nfrags + sglists, seqhilen);
-       if (!tmp)
+       if (!tmp) {
+               err = -ENOMEM;
                goto error;
+       }
 
        seqhi = esp_tmp_seqhi(tmp);
        iv = esp_tmp_iv(aead, tmp, seqhilen);
index a6445b843ef40774f2bf5014e6800e1f4fd86b3e..52c273ea05c34c902e07c00609b4f881c392c37b 100644 (file)
@@ -248,8 +248,7 @@ static void ip_expire(unsigned long arg)
                if (!head->dev)
                        goto out_rcu_unlock;
 
-               /* skb dst is stale, drop it, and perform route lookup again */
-               skb_dst_drop(head);
+               /* skb has no dst, perform route lookup again */
                iph = ip_hdr(head);
                err = ip_route_input_noref(head, iph->daddr, iph->saddr,
                                           iph->tos, head->dev);
@@ -523,9 +522,16 @@ found:
                qp->q.max_size = skb->len + ihl;
 
        if (qp->q.last_in == (INET_FRAG_FIRST_IN | INET_FRAG_LAST_IN) &&
-           qp->q.meat == qp->q.len)
-               return ip_frag_reasm(qp, prev, dev);
+           qp->q.meat == qp->q.len) {
+               unsigned long orefdst = skb->_skb_refdst;
 
+               skb->_skb_refdst = 0UL;
+               err = ip_frag_reasm(qp, prev, dev);
+               skb->_skb_refdst = orefdst;
+               return err;
+       }
+
+       skb_dst_drop(skb);
        inet_frag_lru_move(&qp->q);
        return -EINPROGRESS;
 
index c30130062cd6515f31d7497eaa6a403d2b1d629d..c49dcd0284a06c6bb4b4e6787af5888289ba50f3 100644 (file)
@@ -66,6 +66,12 @@ static bool rpfilter_lookup_reverse(struct flowi4 *fl4,
        return dev_match;
 }
 
+static bool rpfilter_is_local(const struct sk_buff *skb)
+{
+       const struct rtable *rt = skb_rtable(skb);
+       return rt && (rt->rt_flags & RTCF_LOCAL);
+}
+
 static bool rpfilter_mt(const struct sk_buff *skb, struct xt_action_param *par)
 {
        const struct xt_rpfilter_info *info;
@@ -76,7 +82,7 @@ static bool rpfilter_mt(const struct sk_buff *skb, struct xt_action_param *par)
        info = par->matchinfo;
        invert = info->flags & XT_RPFILTER_INVERT;
 
-       if (par->in->flags & IFF_LOOPBACK)
+       if (rpfilter_is_local(skb))
                return true ^ invert;
 
        iph = ip_hdr(skb);
index ef54377fb11cbdd3f327fa29c45c623923b8cb2f..397e0f69435fd1b1b4b3775cadc409d67ea63332 100644 (file)
@@ -349,8 +349,8 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb,
         * hasn't changed since we received the original syn, but I see
         * no easy way to do this.
         */
-       flowi4_init_output(&fl4, 0, sk->sk_mark, RT_CONN_FLAGS(sk),
-                          RT_SCOPE_UNIVERSE, IPPROTO_TCP,
+       flowi4_init_output(&fl4, sk->sk_bound_dev_if, sk->sk_mark,
+                          RT_CONN_FLAGS(sk), RT_SCOPE_UNIVERSE, IPPROTO_TCP,
                           inet_sk_flowi_flags(sk),
                           (opt && opt->srr) ? opt->faddr : ireq->rmt_addr,
                           ireq->loc_addr, th->source, th->dest);
index 3bd55bad230ac7f822f4ea75eb280bc8ce0c07fc..13b9c08fc1582531aa34eef92a432dc96f2a1c52 100644 (file)
@@ -113,6 +113,7 @@ int sysctl_tcp_early_retrans __read_mostly = 2;
 #define FLAG_DSACKING_ACK      0x800 /* SACK blocks contained D-SACK info */
 #define FLAG_NONHEAD_RETRANS_ACKED     0x1000 /* Non-head rexmitted data was ACKed */
 #define FLAG_SACK_RENEGING     0x2000 /* snd_una advanced to a sacked seq */
+#define FLAG_UPDATE_TS_RECENT  0x4000 /* tcp_replace_ts_recent() */
 
 #define FLAG_ACKED             (FLAG_DATA_ACKED|FLAG_SYN_ACKED)
 #define FLAG_NOT_DUP           (FLAG_DATA|FLAG_WIN_UPDATE|FLAG_ACKED)
@@ -3564,6 +3565,27 @@ static void tcp_send_challenge_ack(struct sock *sk)
        }
 }
 
+static void tcp_store_ts_recent(struct tcp_sock *tp)
+{
+       tp->rx_opt.ts_recent = tp->rx_opt.rcv_tsval;
+       tp->rx_opt.ts_recent_stamp = get_seconds();
+}
+
+static void tcp_replace_ts_recent(struct tcp_sock *tp, u32 seq)
+{
+       if (tp->rx_opt.saw_tstamp && !after(seq, tp->rcv_wup)) {
+               /* PAWS bug workaround wrt. ACK frames, the PAWS discard
+                * extra check below makes sure this can only happen
+                * for pure ACK frames.  -DaveM
+                *
+                * Not only, also it occurs for expired timestamps.
+                */
+
+               if (tcp_paws_check(&tp->rx_opt, 0))
+                       tcp_store_ts_recent(tp);
+       }
+}
+
 /* This routine deals with incoming acks, but not outgoing ones. */
 static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag)
 {
@@ -3607,6 +3629,12 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag)
        prior_fackets = tp->fackets_out;
        prior_in_flight = tcp_packets_in_flight(tp);
 
+       /* ts_recent update must be made after we are sure that the packet
+        * is in window.
+        */
+       if (flag & FLAG_UPDATE_TS_RECENT)
+               tcp_replace_ts_recent(tp, TCP_SKB_CB(skb)->seq);
+
        if (!(flag & FLAG_SLOWPATH) && after(ack, prior_snd_una)) {
                /* Window is constant, pure forward advance.
                 * No more checks are required.
@@ -3927,27 +3955,6 @@ const u8 *tcp_parse_md5sig_option(const struct tcphdr *th)
 EXPORT_SYMBOL(tcp_parse_md5sig_option);
 #endif
 
-static inline void tcp_store_ts_recent(struct tcp_sock *tp)
-{
-       tp->rx_opt.ts_recent = tp->rx_opt.rcv_tsval;
-       tp->rx_opt.ts_recent_stamp = get_seconds();
-}
-
-static inline void tcp_replace_ts_recent(struct tcp_sock *tp, u32 seq)
-{
-       if (tp->rx_opt.saw_tstamp && !after(seq, tp->rcv_wup)) {
-               /* PAWS bug workaround wrt. ACK frames, the PAWS discard
-                * extra check below makes sure this can only happen
-                * for pure ACK frames.  -DaveM
-                *
-                * Not only, also it occurs for expired timestamps.
-                */
-
-               if (tcp_paws_check(&tp->rx_opt, 0))
-                       tcp_store_ts_recent(tp);
-       }
-}
-
 /* Sorry, PAWS as specified is broken wrt. pure-ACKs -DaveM
  *
  * It is not fatal. If this ACK does _not_ change critical state (seqs, window)
@@ -5543,14 +5550,9 @@ slow_path:
                return 0;
 
 step5:
-       if (tcp_ack(sk, skb, FLAG_SLOWPATH) < 0)
+       if (tcp_ack(sk, skb, FLAG_SLOWPATH | FLAG_UPDATE_TS_RECENT) < 0)
                goto discard;
 
-       /* ts_recent update must be made after we are sure that the packet
-        * is in window.
-        */
-       tcp_replace_ts_recent(tp, TCP_SKB_CB(skb)->seq);
-
        tcp_rcv_rtt_measure_ts(sk, skb);
 
        /* Process urgent data. */
@@ -5986,7 +5988,8 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
 
        /* step 5: check the ACK field */
        if (true) {
-               int acceptable = tcp_ack(sk, skb, FLAG_SLOWPATH) > 0;
+               int acceptable = tcp_ack(sk, skb, FLAG_SLOWPATH |
+                                                 FLAG_UPDATE_TS_RECENT) > 0;
 
                switch (sk->sk_state) {
                case TCP_SYN_RECV:
@@ -6137,11 +6140,6 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
                }
        }
 
-       /* ts_recent update must be made after we are sure that the packet
-        * is in window.
-        */
-       tcp_replace_ts_recent(tp, TCP_SKB_CB(skb)->seq);
-
        /* step 6: check the URG bit */
        tcp_urg(sk, skb, th);
 
index 5d0b4387cba6df401166a48f1e4cf3800d6ce6ff..509912a5ff98e73edfe9d60295de196ed16874a2 100644 (file)
@@ -2388,8 +2388,12 @@ int __tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb)
         */
        TCP_SKB_CB(skb)->when = tcp_time_stamp;
 
-       /* make sure skb->data is aligned on arches that require it */
-       if (unlikely(NET_IP_ALIGN && ((unsigned long)skb->data & 3))) {
+       /* make sure skb->data is aligned on arches that require it
+        * and check if ack-trimming & collapsing extended the headroom
+        * beyond what csum_start can cover.
+        */
+       if (unlikely((NET_IP_ALIGN && ((unsigned long)skb->data & 3)) ||
+                    skb_headroom(skb) >= 0xFFFF)) {
                struct sk_buff *nskb = __pskb_copy(skb, MAX_TCP_HEADER,
                                                   GFP_ATOMIC);
                return nskb ? tcp_transmit_skb(sk, nskb, 0, GFP_ATOMIC) :
@@ -2709,6 +2713,7 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst,
        skb_reserve(skb, MAX_TCP_HEADER);
 
        skb_dst_set(skb, dst);
+       security_skb_owned_by(skb, sk);
 
        mss = dst_metric_advmss(dst);
        if (tp->rx_opt.user_mss && tp->rx_opt.user_mss < mss)
index a459c4f5b76914e031798a4b90b3df1998f47a08..dae802c0af7c002df341d3dfe4ed94db6584118e 100644 (file)
@@ -168,8 +168,6 @@ static void inet6_prefix_notify(int event, struct inet6_dev *idev,
 static bool ipv6_chk_same_addr(struct net *net, const struct in6_addr *addr,
                               struct net_device *dev);
 
-static ATOMIC_NOTIFIER_HEAD(inet6addr_chain);
-
 static struct ipv6_devconf ipv6_devconf __read_mostly = {
        .forwarding             = 0,
        .hop_limit              = IPV6_DEFAULT_HOPLIMIT,
@@ -837,7 +835,7 @@ out2:
        rcu_read_unlock_bh();
 
        if (likely(err == 0))
-               atomic_notifier_call_chain(&inet6addr_chain, NETDEV_UP, ifa);
+               inet6addr_notifier_call_chain(NETDEV_UP, ifa);
        else {
                kfree(ifa);
                ifa = ERR_PTR(err);
@@ -927,7 +925,7 @@ static void ipv6_del_addr(struct inet6_ifaddr *ifp)
 
        ipv6_ifa_notify(RTM_DELADDR, ifp);
 
-       atomic_notifier_call_chain(&inet6addr_chain, NETDEV_DOWN, ifp);
+       inet6addr_notifier_call_chain(NETDEV_DOWN, ifp);
 
        /*
         * Purge or update corresponding prefix
@@ -2988,7 +2986,7 @@ static int addrconf_ifdown(struct net_device *dev, int how)
 
                if (state != INET6_IFADDR_STATE_DEAD) {
                        __ipv6_ifa_notify(RTM_DELADDR, ifa);
-                       atomic_notifier_call_chain(&inet6addr_chain, NETDEV_DOWN, ifa);
+                       inet6addr_notifier_call_chain(NETDEV_DOWN, ifa);
                }
                in6_ifa_put(ifa);
 
@@ -4869,22 +4867,6 @@ static struct pernet_operations addrconf_ops = {
        .exit = addrconf_exit_net,
 };
 
-/*
- *      Device notifier
- */
-
-int register_inet6addr_notifier(struct notifier_block *nb)
-{
-       return atomic_notifier_chain_register(&inet6addr_chain, nb);
-}
-EXPORT_SYMBOL(register_inet6addr_notifier);
-
-int unregister_inet6addr_notifier(struct notifier_block *nb)
-{
-       return atomic_notifier_chain_unregister(&inet6addr_chain, nb);
-}
-EXPORT_SYMBOL(unregister_inet6addr_notifier);
-
 static struct rtnl_af_ops inet6_ops = {
        .family           = AF_INET6,
        .fill_link_af     = inet6_fill_link_af,
index d051e5f4bf348092e8062b930b56881669974a95..72104562c86481311857359882669527359a7f6c 100644 (file)
@@ -78,3 +78,22 @@ int __ipv6_addr_type(const struct in6_addr *addr)
 }
 EXPORT_SYMBOL(__ipv6_addr_type);
 
+static ATOMIC_NOTIFIER_HEAD(inet6addr_chain);
+
+int register_inet6addr_notifier(struct notifier_block *nb)
+{
+       return atomic_notifier_chain_register(&inet6addr_chain, nb);
+}
+EXPORT_SYMBOL(register_inet6addr_notifier);
+
+int unregister_inet6addr_notifier(struct notifier_block *nb)
+{
+       return atomic_notifier_chain_unregister(&inet6addr_chain, nb);
+}
+EXPORT_SYMBOL(unregister_inet6addr_notifier);
+
+int inet6addr_notifier_call_chain(unsigned long val, void *v)
+{
+       return atomic_notifier_call_chain(&inet6addr_chain, val, v);
+}
+EXPORT_SYMBOL(inet6addr_notifier_call_chain);
index 5060d54199abbc180d7dc87ba072bace2bc167f7..e0983f3648a628410c6f6bfd9549ec339a325353 100644 (file)
@@ -71,6 +71,12 @@ static bool rpfilter_lookup_reverse6(const struct sk_buff *skb,
        return ret;
 }
 
+static bool rpfilter_is_local(const struct sk_buff *skb)
+{
+       const struct rt6_info *rt = (const void *) skb_dst(skb);
+       return rt && (rt->rt6i_flags & RTF_LOCAL);
+}
+
 static bool rpfilter_mt(const struct sk_buff *skb, struct xt_action_param *par)
 {
        const struct xt_rpfilter_info *info = par->matchinfo;
@@ -78,7 +84,7 @@ static bool rpfilter_mt(const struct sk_buff *skb, struct xt_action_param *par)
        struct ipv6hdr *iph;
        bool invert = info->flags & XT_RPFILTER_INVERT;
 
-       if (par->in->flags & IFF_LOOPBACK)
+       if (rpfilter_is_local(skb))
                return true ^ invert;
 
        iph = ipv6_hdr(skb);
index 196ab9347ad1df2bab5a9c98720a51e81773985c..0ba10e53a6298f07cb64193681ccbfb419d40f36 100644 (file)
@@ -330,9 +330,17 @@ found:
        }
 
        if (fq->q.last_in == (INET_FRAG_FIRST_IN | INET_FRAG_LAST_IN) &&
-           fq->q.meat == fq->q.len)
-               return ip6_frag_reasm(fq, prev, dev);
+           fq->q.meat == fq->q.len) {
+               int res;
+               unsigned long orefdst = skb->_skb_refdst;
+
+               skb->_skb_refdst = 0UL;
+               res = ip6_frag_reasm(fq, prev, dev);
+               skb->_skb_refdst = orefdst;
+               return res;
+       }
 
+       skb_dst_drop(skb);
        inet_frag_lru_move(&fq->q);
        return -1;
 
index f6d629fd6aee152aaff674a03db7a3dd0f194134..46a5be85be87ebed43ec8b01d6b63263df556279 100644 (file)
@@ -386,6 +386,7 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
 
                if (dst)
                        dst->ops->redirect(dst, sk, skb);
+               goto out;
        }
 
        if (type == ICMPV6_PKT_TOOBIG) {
index d28e7f014cc639779a4557203b4b2ba2f7e63927..e493b3397ae3337b4582d811febb932e0711a09e 100644 (file)
@@ -1386,6 +1386,8 @@ static int irda_recvmsg_dgram(struct kiocb *iocb, struct socket *sock,
 
        IRDA_DEBUG(4, "%s()\n", __func__);
 
+       msg->msg_namelen = 0;
+
        skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT,
                                flags & MSG_DONTWAIT, &err);
        if (!skb)
index 29340a9a6fb9937f9bc848ffda5c49c51cca47ee..e1b37f5a2691f7a79052f9b840aa0f9910182698 100644 (file)
@@ -303,7 +303,8 @@ static void iriap_disconnect_indication(void *instance, void *sap,
 {
        struct iriap_cb *self;
 
-       IRDA_DEBUG(4, "%s(), reason=%s\n", __func__, irlmp_reasons[reason]);
+       IRDA_DEBUG(4, "%s(), reason=%s [%d]\n", __func__,
+                  irlmp_reason_str(reason), reason);
 
        self = instance;
 
index 6115a44c0a24f9ba1cb3248de38b8579118e5dbf..1064621da6f6c297ee7deaa439e9569d9f37cf73 100644 (file)
@@ -66,8 +66,15 @@ const char *irlmp_reasons[] = {
        "LM_LAP_RESET",
        "LM_INIT_DISCONNECT",
        "ERROR, NOT USED",
+       "UNKNOWN",
 };
 
+const char *irlmp_reason_str(LM_REASON reason)
+{
+       reason = min_t(size_t, reason, ARRAY_SIZE(irlmp_reasons) - 1);
+       return irlmp_reasons[reason];
+}
+
 /*
  * Function irlmp_init (void)
  *
@@ -747,7 +754,8 @@ void irlmp_disconnect_indication(struct lsap_cb *self, LM_REASON reason,
 {
        struct lsap_cb *lsap;
 
-       IRDA_DEBUG(1, "%s(), reason=%s\n", __func__, irlmp_reasons[reason]);
+       IRDA_DEBUG(1, "%s(), reason=%s [%d]\n", __func__,
+                  irlmp_reason_str(reason), reason);
        IRDA_ASSERT(self != NULL, return;);
        IRDA_ASSERT(self->magic == LMP_LSAP_MAGIC, return;);
 
index a7d11ffe428428f25194702c5728562fd87a8e2b..206ce6db2c36a2ae44d694614f8be29317f5b74d 100644 (file)
@@ -49,12 +49,6 @@ static const u8 iprm_shutdown[8] =
 
 #define TRGCLS_SIZE    (sizeof(((struct iucv_message *)0)->class))
 
-/* macros to set/get socket control buffer at correct offset */
-#define CB_TAG(skb)    ((skb)->cb)             /* iucv message tag */
-#define CB_TAG_LEN     (sizeof(((struct iucv_message *) 0)->tag))
-#define CB_TRGCLS(skb) ((skb)->cb + CB_TAG_LEN) /* iucv msg target class */
-#define CB_TRGCLS_LEN  (TRGCLS_SIZE)
-
 #define __iucv_sock_wait(sk, condition, timeo, ret)                    \
 do {                                                                   \
        DEFINE_WAIT(__wait);                                            \
@@ -1141,7 +1135,7 @@ static int iucv_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
 
        /* increment and save iucv message tag for msg_completion cbk */
        txmsg.tag = iucv->send_tag++;
-       memcpy(CB_TAG(skb), &txmsg.tag, CB_TAG_LEN);
+       IUCV_SKB_CB(skb)->tag = txmsg.tag;
 
        if (iucv->transport == AF_IUCV_TRANS_HIPER) {
                atomic_inc(&iucv->msg_sent);
@@ -1224,7 +1218,7 @@ static int iucv_fragment_skb(struct sock *sk, struct sk_buff *skb, int len)
                        return -ENOMEM;
 
                /* copy target class to control buffer of new skb */
-               memcpy(CB_TRGCLS(nskb), CB_TRGCLS(skb), CB_TRGCLS_LEN);
+               IUCV_SKB_CB(nskb)->class = IUCV_SKB_CB(skb)->class;
 
                /* copy data fragment */
                memcpy(nskb->data, skb->data + copied, size);
@@ -1256,7 +1250,7 @@ static void iucv_process_message(struct sock *sk, struct sk_buff *skb,
 
        /* store msg target class in the second 4 bytes of skb ctrl buffer */
        /* Note: the first 4 bytes are reserved for msg tag */
-       memcpy(CB_TRGCLS(skb), &msg->class, CB_TRGCLS_LEN);
+       IUCV_SKB_CB(skb)->class = msg->class;
 
        /* check for special IPRM messages (e.g. iucv_sock_shutdown) */
        if ((msg->flags & IUCV_IPRMDATA) && len > 7) {
@@ -1292,6 +1286,7 @@ static void iucv_process_message(struct sock *sk, struct sk_buff *skb,
                }
        }
 
+       IUCV_SKB_CB(skb)->offset = 0;
        if (sock_queue_rcv_skb(sk, skb))
                skb_queue_head(&iucv_sk(sk)->backlog_skb_q, skb);
 }
@@ -1327,6 +1322,9 @@ static int iucv_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
        unsigned int copied, rlen;
        struct sk_buff *skb, *rskb, *cskb;
        int err = 0;
+       u32 offset;
+
+       msg->msg_namelen = 0;
 
        if ((sk->sk_state == IUCV_DISCONN) &&
            skb_queue_empty(&iucv->backlog_skb_q) &&
@@ -1346,13 +1344,14 @@ static int iucv_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
                return err;
        }
 
-       rlen   = skb->len;              /* real length of skb */
+       offset = IUCV_SKB_CB(skb)->offset;
+       rlen   = skb->len - offset;             /* real length of skb */
        copied = min_t(unsigned int, rlen, len);
        if (!rlen)
                sk->sk_shutdown = sk->sk_shutdown | RCV_SHUTDOWN;
 
        cskb = skb;
-       if (skb_copy_datagram_iovec(cskb, 0, msg->msg_iov, copied)) {
+       if (skb_copy_datagram_iovec(cskb, offset, msg->msg_iov, copied)) {
                if (!(flags & MSG_PEEK))
                        skb_queue_head(&sk->sk_receive_queue, skb);
                return -EFAULT;
@@ -1370,7 +1369,8 @@ static int iucv_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
         * get the trgcls from the control buffer of the skb due to
         * fragmentation of original iucv message. */
        err = put_cmsg(msg, SOL_IUCV, SCM_IUCV_TRGCLS,
-                       CB_TRGCLS_LEN, CB_TRGCLS(skb));
+                      sizeof(IUCV_SKB_CB(skb)->class),
+                      (void *)&IUCV_SKB_CB(skb)->class);
        if (err) {
                if (!(flags & MSG_PEEK))
                        skb_queue_head(&sk->sk_receive_queue, skb);
@@ -1382,9 +1382,8 @@ static int iucv_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
 
                /* SOCK_STREAM: re-queue skb if it contains unreceived data */
                if (sk->sk_type == SOCK_STREAM) {
-                       skb_pull(skb, copied);
-                       if (skb->len) {
-                               skb_queue_head(&sk->sk_receive_queue, skb);
+                       if (copied < rlen) {
+                               IUCV_SKB_CB(skb)->offset = offset + copied;
                                goto done;
                        }
                }
@@ -1403,6 +1402,7 @@ static int iucv_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
                spin_lock_bh(&iucv->message_q.lock);
                rskb = skb_dequeue(&iucv->backlog_skb_q);
                while (rskb) {
+                       IUCV_SKB_CB(rskb)->offset = 0;
                        if (sock_queue_rcv_skb(sk, rskb)) {
                                skb_queue_head(&iucv->backlog_skb_q,
                                                rskb);
@@ -1830,7 +1830,7 @@ static void iucv_callback_txdone(struct iucv_path *path,
                spin_lock_irqsave(&list->lock, flags);
 
                while (list_skb != (struct sk_buff *)list) {
-                       if (!memcmp(&msg->tag, CB_TAG(list_skb), CB_TAG_LEN)) {
+                       if (msg->tag != IUCV_SKB_CB(list_skb)->tag) {
                                this = list_skb;
                                break;
                        }
@@ -2091,6 +2091,7 @@ static int afiucv_hs_callback_rx(struct sock *sk, struct sk_buff *skb)
        skb_pull(skb, sizeof(struct af_iucv_trans_hdr));
        skb_reset_transport_header(skb);
        skb_reset_network_header(skb);
+       IUCV_SKB_CB(skb)->offset = 0;
        spin_lock(&iucv->message_q.lock);
        if (skb_queue_empty(&iucv->backlog_skb_q)) {
                if (sock_queue_rcv_skb(sk, skb)) {
@@ -2195,8 +2196,7 @@ static int afiucv_hs_rcv(struct sk_buff *skb, struct net_device *dev,
                /* fall through and receive zero length data */
        case 0:
                /* plain data frame */
-               memcpy(CB_TRGCLS(skb), &trans_hdr->iucv_hdr.class,
-                      CB_TRGCLS_LEN);
+               IUCV_SKB_CB(skb)->class = trans_hdr->iucv_hdr.class;
                err = afiucv_hs_callback_rx(sk, skb);
                break;
        default:
index c74f5a91ff6a3213209c23ff488f0b475a552857..b8a6039314e868781d3130f06fbb78ced6c4a678 100644 (file)
@@ -690,6 +690,7 @@ static int l2tp_ip6_recvmsg(struct kiocb *iocb, struct sock *sk,
                lsa->l2tp_addr = ipv6_hdr(skb)->saddr;
                lsa->l2tp_flowinfo = 0;
                lsa->l2tp_scope_id = 0;
+               lsa->l2tp_conn_id = 0;
                if (ipv6_addr_type(&lsa->l2tp_addr) & IPV6_ADDR_LINKLOCAL)
                        lsa->l2tp_scope_id = IP6CB(skb)->iif;
        }
index 88709882c4641f7d147fbeaa9f48323cfc8637eb..48aaa89253e037c9b7f2e07f3bc1d03d837266fd 100644 (file)
@@ -720,6 +720,8 @@ static int llc_ui_recvmsg(struct kiocb *iocb, struct socket *sock,
        int target;     /* Read at least this many bytes */
        long timeo;
 
+       msg->msg_namelen = 0;
+
        lock_sock(sk);
        copied = -ENOTCONN;
        if (unlikely(sk->sk_type == SOCK_STREAM && sk->sk_state == TCP_LISTEN))
index 58150f877ec3fe83f29adb2df4caf5bb617e3358..9ed49ad0380f151fc5ad5448e953f6497d800291 100644 (file)
@@ -78,7 +78,7 @@ void ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata)
                ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_TXPOWER);
 }
 
-u32 ieee80211_idle_off(struct ieee80211_local *local)
+static u32 __ieee80211_idle_off(struct ieee80211_local *local)
 {
        if (!(local->hw.conf.flags & IEEE80211_CONF_IDLE))
                return 0;
@@ -87,7 +87,7 @@ u32 ieee80211_idle_off(struct ieee80211_local *local)
        return IEEE80211_CONF_CHANGE_IDLE;
 }
 
-static u32 ieee80211_idle_on(struct ieee80211_local *local)
+static u32 __ieee80211_idle_on(struct ieee80211_local *local)
 {
        if (local->hw.conf.flags & IEEE80211_CONF_IDLE)
                return 0;
@@ -98,16 +98,18 @@ static u32 ieee80211_idle_on(struct ieee80211_local *local)
        return IEEE80211_CONF_CHANGE_IDLE;
 }
 
-void ieee80211_recalc_idle(struct ieee80211_local *local)
+static u32 __ieee80211_recalc_idle(struct ieee80211_local *local,
+                                  bool force_active)
 {
        bool working = false, scanning, active;
        unsigned int led_trig_start = 0, led_trig_stop = 0;
        struct ieee80211_roc_work *roc;
-       u32 change;
 
        lockdep_assert_held(&local->mtx);
 
-       active = !list_empty(&local->chanctx_list) || local->monitors;
+       active = force_active ||
+                !list_empty(&local->chanctx_list) ||
+                local->monitors;
 
        if (!local->ops->remain_on_channel) {
                list_for_each_entry(roc, &local->roc_list, list) {
@@ -132,9 +134,18 @@ void ieee80211_recalc_idle(struct ieee80211_local *local)
        ieee80211_mod_tpt_led_trig(local, led_trig_start, led_trig_stop);
 
        if (working || scanning || active)
-               change = ieee80211_idle_off(local);
-       else
-               change = ieee80211_idle_on(local);
+               return __ieee80211_idle_off(local);
+       return __ieee80211_idle_on(local);
+}
+
+u32 ieee80211_idle_off(struct ieee80211_local *local)
+{
+       return __ieee80211_recalc_idle(local, true);
+}
+
+void ieee80211_recalc_idle(struct ieee80211_local *local)
+{
+       u32 change = __ieee80211_recalc_idle(local, false);
        if (change)
                ieee80211_hw_config(local, change);
 }
index 82cc30318a86f66c4a8f23341ea6ed3f6b62d578..346ad4cfb01323cf471758dd5a6fcbdb12b338a6 100644 (file)
@@ -3964,8 +3964,16 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
        /* prep auth_data so we don't go into idle on disassoc */
        ifmgd->auth_data = auth_data;
 
-       if (ifmgd->associated)
-               ieee80211_set_disassoc(sdata, 0, 0, false, NULL);
+       if (ifmgd->associated) {
+               u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN];
+
+               ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH,
+                                      WLAN_REASON_UNSPECIFIED,
+                                      false, frame_buf);
+
+               __cfg80211_send_deauth(sdata->dev, frame_buf,
+                                      sizeof(frame_buf));
+       }
 
        sdata_info(sdata, "authenticate with %pM\n", req->bss->bssid);
 
@@ -4025,8 +4033,16 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
 
        mutex_lock(&ifmgd->mtx);
 
-       if (ifmgd->associated)
-               ieee80211_set_disassoc(sdata, 0, 0, false, NULL);
+       if (ifmgd->associated) {
+               u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN];
+
+               ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH,
+                                      WLAN_REASON_UNSPECIFIED,
+                                      false, frame_buf);
+
+               __cfg80211_send_deauth(sdata->dev, frame_buf,
+                                      sizeof(frame_buf));
+       }
 
        if (ifmgd->auth_data && !ifmgd->auth_data->done) {
                err = -EBUSY;
index 0f92dc24cb894bfa0674c2b3f6dca970d7615c64..d7df6ac2c6f10a1bf14be997a981f577e5364b98 100644 (file)
@@ -339,7 +339,11 @@ bitmap_ipmac_tlist(const struct ip_set *set,
 nla_put_failure:
        nla_nest_cancel(skb, nested);
        ipset_nest_end(skb, atd);
-       return -EMSGSIZE;
+       if (unlikely(id == first)) {
+               cb->args[2] = 0;
+               return -EMSGSIZE;
+       }
+       return 0;
 }
 
 static int
index f2627226a0870b22612fe17397c228ff7ef628b0..10a30b4fc7dba7af7ad858c566791e982475436a 100644 (file)
@@ -104,6 +104,15 @@ hash_ipportnet4_data_flags(struct hash_ipportnet4_elem *dst, u32 flags)
        dst->nomatch = !!(flags & IPSET_FLAG_NOMATCH);
 }
 
+static inline void
+hash_ipportnet4_data_reset_flags(struct hash_ipportnet4_elem *dst, u32 *flags)
+{
+       if (dst->nomatch) {
+               *flags = IPSET_FLAG_NOMATCH;
+               dst->nomatch = 0;
+       }
+}
+
 static inline int
 hash_ipportnet4_data_match(const struct hash_ipportnet4_elem *elem)
 {
@@ -414,6 +423,15 @@ hash_ipportnet6_data_flags(struct hash_ipportnet6_elem *dst, u32 flags)
        dst->nomatch = !!(flags & IPSET_FLAG_NOMATCH);
 }
 
+static inline void
+hash_ipportnet6_data_reset_flags(struct hash_ipportnet6_elem *dst, u32 *flags)
+{
+       if (dst->nomatch) {
+               *flags = IPSET_FLAG_NOMATCH;
+               dst->nomatch = 0;
+       }
+}
+
 static inline int
 hash_ipportnet6_data_match(const struct hash_ipportnet6_elem *elem)
 {
index 4b677cf6bf7d7899f7295fea5eeab54df84699c6..d6a59154d7104258d18335a39646fbf9e3b8f598 100644 (file)
@@ -87,7 +87,16 @@ hash_net4_data_copy(struct hash_net4_elem *dst,
 static inline void
 hash_net4_data_flags(struct hash_net4_elem *dst, u32 flags)
 {
-       dst->nomatch = flags & IPSET_FLAG_NOMATCH;
+       dst->nomatch = !!(flags & IPSET_FLAG_NOMATCH);
+}
+
+static inline void
+hash_net4_data_reset_flags(struct hash_net4_elem *dst, u32 *flags)
+{
+       if (dst->nomatch) {
+               *flags = IPSET_FLAG_NOMATCH;
+               dst->nomatch = 0;
+       }
 }
 
 static inline int
@@ -308,7 +317,16 @@ hash_net6_data_copy(struct hash_net6_elem *dst,
 static inline void
 hash_net6_data_flags(struct hash_net6_elem *dst, u32 flags)
 {
-       dst->nomatch = flags & IPSET_FLAG_NOMATCH;
+       dst->nomatch = !!(flags & IPSET_FLAG_NOMATCH);
+}
+
+static inline void
+hash_net6_data_reset_flags(struct hash_net6_elem *dst, u32 *flags)
+{
+       if (dst->nomatch) {
+               *flags = IPSET_FLAG_NOMATCH;
+               dst->nomatch = 0;
+       }
 }
 
 static inline int
index 6ba985f1c96ff5ef43bf0ad599e9792bd64f54ef..f2b0a3c30130ba66bc69fe24b39cb54cdbc0c77a 100644 (file)
@@ -198,7 +198,16 @@ hash_netiface4_data_copy(struct hash_netiface4_elem *dst,
 static inline void
 hash_netiface4_data_flags(struct hash_netiface4_elem *dst, u32 flags)
 {
-       dst->nomatch = flags & IPSET_FLAG_NOMATCH;
+       dst->nomatch = !!(flags & IPSET_FLAG_NOMATCH);
+}
+
+static inline void
+hash_netiface4_data_reset_flags(struct hash_netiface4_elem *dst, u32 *flags)
+{
+       if (dst->nomatch) {
+               *flags = IPSET_FLAG_NOMATCH;
+               dst->nomatch = 0;
+       }
 }
 
 static inline int
@@ -494,7 +503,7 @@ hash_netiface6_data_copy(struct hash_netiface6_elem *dst,
 static inline void
 hash_netiface6_data_flags(struct hash_netiface6_elem *dst, u32 flags)
 {
-       dst->nomatch = flags & IPSET_FLAG_NOMATCH;
+       dst->nomatch = !!(flags & IPSET_FLAG_NOMATCH);
 }
 
 static inline int
@@ -503,6 +512,15 @@ hash_netiface6_data_match(const struct hash_netiface6_elem *elem)
        return elem->nomatch ? -ENOTEMPTY : 1;
 }
 
+static inline void
+hash_netiface6_data_reset_flags(struct hash_netiface6_elem *dst, u32 *flags)
+{
+       if (dst->nomatch) {
+               *flags = IPSET_FLAG_NOMATCH;
+               dst->nomatch = 0;
+       }
+}
+
 static inline void
 hash_netiface6_data_zero_out(struct hash_netiface6_elem *elem)
 {
index af20c0c5ced2e9204df65ddaf37424a9b589be99..349deb672a2d4fd8303ab43bdb3f0207c9124e0d 100644 (file)
@@ -104,6 +104,15 @@ hash_netport4_data_flags(struct hash_netport4_elem *dst, u32 flags)
        dst->nomatch = !!(flags & IPSET_FLAG_NOMATCH);
 }
 
+static inline void
+hash_netport4_data_reset_flags(struct hash_netport4_elem *dst, u32 *flags)
+{
+       if (dst->nomatch) {
+               *flags = IPSET_FLAG_NOMATCH;
+               dst->nomatch = 0;
+       }
+}
+
 static inline int
 hash_netport4_data_match(const struct hash_netport4_elem *elem)
 {
@@ -375,6 +384,15 @@ hash_netport6_data_flags(struct hash_netport6_elem *dst, u32 flags)
        dst->nomatch = !!(flags & IPSET_FLAG_NOMATCH);
 }
 
+static inline void
+hash_netport6_data_reset_flags(struct hash_netport6_elem *dst, u32 *flags)
+{
+       if (dst->nomatch) {
+               *flags = IPSET_FLAG_NOMATCH;
+               dst->nomatch = 0;
+       }
+}
+
 static inline int
 hash_netport6_data_match(const struct hash_netport6_elem *elem)
 {
index 8371c2bac2e4240eb5c4b3f6abd0faa48f6212ce..09c744aa89829cb7f99878974ef2471364135f27 100644 (file)
@@ -174,9 +174,13 @@ list_set_add(struct list_set *map, u32 i, ip_set_id_t id,
 {
        const struct set_elem *e = list_set_elem(map, i);
 
-       if (i == map->size - 1 && e->id != IPSET_INVALID_ID)
-               /* Last element replaced: e.g. add new,before,last */
-               ip_set_put_byindex(e->id);
+       if (e->id != IPSET_INVALID_ID) {
+               const struct set_elem *x = list_set_elem(map, map->size - 1);
+
+               /* Last element replaced or pushed off */
+               if (x->id != IPSET_INVALID_ID)
+                       ip_set_put_byindex(x->id);
+       }
        if (with_timeout(map->timeout))
                list_elem_tadd(map, i, id, ip_set_timeout_set(timeout));
        else
index 0e7d423324c399b3c5012dc312fd75f470b78cb5..e0c4373b47478d4d72899d95166566db34a8bcfa 100644 (file)
@@ -1593,10 +1593,8 @@ static int sip_help_tcp(struct sk_buff *skb, unsigned int protoff,
                end += strlen("\r\n\r\n") + clen;
 
                msglen = origlen = end - dptr;
-               if (msglen > datalen) {
-                       nf_ct_helper_log(skb, ct, "incomplete/bad SIP message");
-                       return NF_DROP;
-               }
+               if (msglen > datalen)
+                       return NF_ACCEPT;
 
                ret = process_sip_msg(skb, ct, protoff, dataoff,
                                      &dptr, &msglen);
index 8d5769c6d16e505ed6239889faee03ab34d4c15d..ad24be070e53c0fe8c27e49a6e2cb93a39c32062 100644 (file)
@@ -467,33 +467,22 @@ EXPORT_SYMBOL_GPL(nf_nat_packet);
 struct nf_nat_proto_clean {
        u8      l3proto;
        u8      l4proto;
-       bool    hash;
 };
 
-/* Clear NAT section of all conntracks, in case we're loaded again. */
-static int nf_nat_proto_clean(struct nf_conn *i, void *data)
+/* kill conntracks with affected NAT section */
+static int nf_nat_proto_remove(struct nf_conn *i, void *data)
 {
        const struct nf_nat_proto_clean *clean = data;
        struct nf_conn_nat *nat = nfct_nat(i);
 
        if (!nat)
                return 0;
-       if (!(i->status & IPS_SRC_NAT_DONE))
-               return 0;
+
        if ((clean->l3proto && nf_ct_l3num(i) != clean->l3proto) ||
            (clean->l4proto && nf_ct_protonum(i) != clean->l4proto))
                return 0;
 
-       if (clean->hash) {
-               spin_lock_bh(&nf_nat_lock);
-               hlist_del_rcu(&nat->bysource);
-               spin_unlock_bh(&nf_nat_lock);
-       } else {
-               memset(nat, 0, sizeof(*nat));
-               i->status &= ~(IPS_NAT_MASK | IPS_NAT_DONE_MASK |
-                              IPS_SEQ_ADJUST);
-       }
-       return 0;
+       return i->status & IPS_NAT_MASK ? 1 : 0;
 }
 
 static void nf_nat_l4proto_clean(u8 l3proto, u8 l4proto)
@@ -505,16 +494,8 @@ static void nf_nat_l4proto_clean(u8 l3proto, u8 l4proto)
        struct net *net;
 
        rtnl_lock();
-       /* Step 1 - remove from bysource hash */
-       clean.hash = true;
        for_each_net(net)
-               nf_ct_iterate_cleanup(net, nf_nat_proto_clean, &clean);
-       synchronize_rcu();
-
-       /* Step 2 - clean NAT section */
-       clean.hash = false;
-       for_each_net(net)
-               nf_ct_iterate_cleanup(net, nf_nat_proto_clean, &clean);
+               nf_ct_iterate_cleanup(net, nf_nat_proto_remove, &clean);
        rtnl_unlock();
 }
 
@@ -526,16 +507,9 @@ static void nf_nat_l3proto_clean(u8 l3proto)
        struct net *net;
 
        rtnl_lock();
-       /* Step 1 - remove from bysource hash */
-       clean.hash = true;
-       for_each_net(net)
-               nf_ct_iterate_cleanup(net, nf_nat_proto_clean, &clean);
-       synchronize_rcu();
 
-       /* Step 2 - clean NAT section */
-       clean.hash = false;
        for_each_net(net)
-               nf_ct_iterate_cleanup(net, nf_nat_proto_clean, &clean);
+               nf_ct_iterate_cleanup(net, nf_nat_proto_remove, &clean);
        rtnl_unlock();
 }
 
@@ -773,7 +747,7 @@ static void __net_exit nf_nat_net_exit(struct net *net)
 {
        struct nf_nat_proto_clean clean = {};
 
-       nf_ct_iterate_cleanup(net, &nf_nat_proto_clean, &clean);
+       nf_ct_iterate_cleanup(net, &nf_nat_proto_remove, &clean);
        synchronize_rcu();
        nf_ct_free_hashtable(net->ct.nat_bysource, net->ct.nat_htable_size);
 }
index d1fa1d9ffd2e82450d1a6c73fbfb55419cebe0c5..103bd704b5fc39e24d07714dd6831ca2d3bf036a 100644 (file)
@@ -1173,6 +1173,7 @@ static int nr_recvmsg(struct kiocb *iocb, struct socket *sock,
        }
 
        if (sax != NULL) {
+               memset(sax, 0, sizeof(*sax));
                sax->sax25_family = AF_NETROM;
                skb_copy_from_linear_data_offset(skb, 7, sax->sax25_call.ax25_call,
                              AX25_ADDR_LEN);
index 8f025746f3370b4296c8064c603e06085adcb42e..6c94447ec414c87479581b45fbcced1071f782cb 100644 (file)
@@ -646,6 +646,8 @@ static int llcp_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
 
        pr_debug("%p %zu\n", sk, len);
 
+       msg->msg_namelen = 0;
+
        lock_sock(sk);
 
        if (sk->sk_state == LLCP_CLOSED &&
@@ -691,6 +693,7 @@ static int llcp_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
 
                pr_debug("Datagram socket %d %d\n", ui_cb->dsap, ui_cb->ssap);
 
+               memset(sockaddr, 0, sizeof(*sockaddr));
                sockaddr->sa_family = AF_NFC;
                sockaddr->nfc_protocol = NFC_PROTO_NFC_DEP;
                sockaddr->dsap = ui_cb->dsap;
index a4b724708a1ab0b7d4aedffc07606b8fbfdac0a9..6980c3e6f0667b0ed22098098b66da7cf929a47e 100644 (file)
@@ -1593,10 +1593,8 @@ struct sk_buff *ovs_vport_cmd_build_info(struct vport *vport, u32 portid,
                return ERR_PTR(-ENOMEM);
 
        retval = ovs_vport_cmd_fill_info(vport, skb, portid, seq, 0, cmd);
-       if (retval < 0) {
-               kfree_skb(skb);
-               return ERR_PTR(retval);
-       }
+       BUG_ON(retval < 0);
+
        return skb;
 }
 
@@ -1726,24 +1724,32 @@ static int ovs_vport_cmd_set(struct sk_buff *skb, struct genl_info *info)
            nla_get_u32(a[OVS_VPORT_ATTR_TYPE]) != vport->ops->type)
                err = -EINVAL;
 
+       reply = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
+       if (!reply) {
+               err = -ENOMEM;
+               goto exit_unlock;
+       }
+
        if (!err && a[OVS_VPORT_ATTR_OPTIONS])
                err = ovs_vport_set_options(vport, a[OVS_VPORT_ATTR_OPTIONS]);
        if (err)
-               goto exit_unlock;
+               goto exit_free;
+
        if (a[OVS_VPORT_ATTR_UPCALL_PID])
                vport->upcall_portid = nla_get_u32(a[OVS_VPORT_ATTR_UPCALL_PID]);
 
-       reply = ovs_vport_cmd_build_info(vport, info->snd_portid, info->snd_seq,
-                                        OVS_VPORT_CMD_NEW);
-       if (IS_ERR(reply)) {
-               netlink_set_err(sock_net(skb->sk)->genl_sock, 0,
-                               ovs_dp_vport_multicast_group.id, PTR_ERR(reply));
-               goto exit_unlock;
-       }
+       err = ovs_vport_cmd_fill_info(vport, reply, info->snd_portid,
+                                     info->snd_seq, 0, OVS_VPORT_CMD_NEW);
+       BUG_ON(err < 0);
 
        genl_notify(reply, genl_info_net(info), info->snd_portid,
                    ovs_dp_vport_multicast_group.id, info->nlhdr, GFP_KERNEL);
 
+       rtnl_unlock();
+       return 0;
+
+exit_free:
+       kfree_skb(reply);
 exit_unlock:
        rtnl_unlock();
        return err;
index fe0e4215c73d6045469ba006722ef223d43ebd66..67a2b783fe70257cb6c33542806d3f3ca17f3d76 100644 (file)
@@ -795,9 +795,9 @@ void ovs_flow_tbl_insert(struct flow_table *table, struct sw_flow *flow)
 
 void ovs_flow_tbl_remove(struct flow_table *table, struct sw_flow *flow)
 {
+       BUG_ON(table->count == 0);
        hlist_del_rcu(&flow->hash_node[table->node_ver]);
        table->count--;
-       BUG_ON(table->count < 0);
 }
 
 /* The size of the argument for each %OVS_KEY_ATTR_* Netlink attribute.  */
index cf68e6e4054a6735694b1ce5bbee30fefbb02899..9c834745159786e5e1d4338f51860be00943a0fd 100644 (file)
@@ -1253,6 +1253,7 @@ static int rose_recvmsg(struct kiocb *iocb, struct socket *sock,
        skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
 
        if (srose != NULL) {
+               memset(srose, 0, msg->msg_namelen);
                srose->srose_family = AF_ROSE;
                srose->srose_addr   = rose->dest_addr;
                srose->srose_call   = rose->dest_call;
index 1135d8227f9bf1811a2c45c211b80e6b9a69706f..9b97172db84a7c72c31c2b6bd36141149859eb1c 100644 (file)
@@ -204,7 +204,6 @@ fw_change_attrs(struct net *net, struct tcf_proto *tp, struct fw_filter *f,
        if (err < 0)
                return err;
 
-       err = -EINVAL;
        if (tb[TCA_FW_CLASSID]) {
                f->res.classid = nla_get_u32(tb[TCA_FW_CLASSID]);
                tcf_bind_filter(tp, &f->res, base);
@@ -218,6 +217,7 @@ fw_change_attrs(struct net *net, struct tcf_proto *tp, struct fw_filter *f,
        }
 #endif /* CONFIG_NET_CLS_IND */
 
+       err = -EINVAL;
        if (tb[TCA_FW_MASK]) {
                mask = nla_get_u32(tb[TCA_FW_MASK]);
                if (mask != head->mask)
index dcc446e7fbf6b6c0d639e2889438bc5f2aa65df2..d5f35f15af983e7a6955c576460a092ec70c0bcb 100644 (file)
@@ -304,10 +304,8 @@ static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, stru
        err = rpciod_up();
        if (err)
                goto out_no_rpciod;
-       err = -EINVAL;
-       if (!xprt)
-               goto out_no_xprt;
 
+       err = -EINVAL;
        if (args->version >= program->nrvers)
                goto out_err;
        version = program->version[args->version];
@@ -382,10 +380,9 @@ out_no_principal:
 out_no_stats:
        kfree(clnt);
 out_err:
-       xprt_put(xprt);
-out_no_xprt:
        rpciod_down();
 out_no_rpciod:
+       xprt_put(xprt);
        return ERR_PTR(err);
 }
 
@@ -512,7 +509,7 @@ static struct rpc_clnt *__rpc_clone_client(struct rpc_create_args *args,
        new = rpc_new_client(args, xprt);
        if (IS_ERR(new)) {
                err = PTR_ERR(new);
-               goto out_put;
+               goto out_err;
        }
 
        atomic_inc(&clnt->cl_count);
@@ -525,8 +522,6 @@ static struct rpc_clnt *__rpc_clone_client(struct rpc_create_args *args,
        new->cl_chatty = clnt->cl_chatty;
        return new;
 
-out_put:
-       xprt_put(xprt);
 out_err:
        dprintk("RPC:       %s: returned error %d\n", __func__, err);
        return ERR_PTR(err);
index a9622b6cd91689ae17ae92b9226c3705067a1a8a..515ce38e4f4c7286023f32f4c8c692af2787ec80 100644 (file)
@@ -790,6 +790,7 @@ static void set_orig_addr(struct msghdr *m, struct tipc_msg *msg)
        if (addr) {
                addr->family = AF_TIPC;
                addr->addrtype = TIPC_ADDR_ID;
+               memset(&addr->addr, 0, sizeof(addr->addr));
                addr->addr.id.ref = msg_origport(msg);
                addr->addr.id.node = msg_orignode(msg);
                addr->addr.name.domain = 0;     /* could leave uninitialized */
@@ -904,6 +905,9 @@ static int recv_msg(struct kiocb *iocb, struct socket *sock,
                goto exit;
        }
 
+       /* will be updated in set_orig_addr() if needed */
+       m->msg_namelen = 0;
+
        timeout = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
 restart:
 
@@ -1013,6 +1017,9 @@ static int recv_stream(struct kiocb *iocb, struct socket *sock,
                goto exit;
        }
 
+       /* will be updated in set_orig_addr() if needed */
+       m->msg_namelen = 0;
+
        target = sock_rcvlowat(sk, flags & MSG_WAITALL, buf_len);
        timeout = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
 
index d8079daf1bdeaed0f341aaac673c8b9e1da7d96b..7f93e2a42d7a57f0cbdbe2305c942cce7b544d1b 100644 (file)
@@ -1670,6 +1670,8 @@ vsock_stream_recvmsg(struct kiocb *kiocb,
        vsk = vsock_sk(sk);
        err = 0;
 
+       msg->msg_namelen = 0;
+
        lock_sock(sk);
 
        if (sk->sk_state != SS_CONNECTED) {
index 1f6508e249ae5934ce9257ebe5cc3e5941300ffa..5e04d3d96285daaa01ff8d35e58081ce4807f093 100644 (file)
@@ -1736,6 +1736,8 @@ static int vmci_transport_dgram_dequeue(struct kiocb *kiocb,
        if (flags & MSG_OOB || flags & MSG_ERRQUEUE)
                return -EOPNOTSUPP;
 
+       msg->msg_namelen = 0;
+
        /* Retrieve the head sk_buff from the socket's receive queue. */
        err = 0;
        skb = skb_recv_datagram(&vsk->sk, flags, noblock, &err);
@@ -1768,7 +1770,6 @@ static int vmci_transport_dgram_dequeue(struct kiocb *kiocb,
        if (err)
                goto out;
 
-       msg->msg_namelen = 0;
        if (msg->msg_name) {
                struct sockaddr_vm *vm_addr;
 
index 09d994d192ffa1c78b963933daad73e4240dfe4b..482c70e7012727fe66e400872379e115b7a7caad 100644 (file)
@@ -224,6 +224,7 @@ void cfg80211_conn_work(struct work_struct *work)
        rtnl_lock();
        cfg80211_lock_rdev(rdev);
        mutex_lock(&rdev->devlist_mtx);
+       mutex_lock(&rdev->sched_scan_mtx);
 
        list_for_each_entry(wdev, &rdev->wdev_list, list) {
                wdev_lock(wdev);
@@ -248,6 +249,7 @@ void cfg80211_conn_work(struct work_struct *work)
                wdev_unlock(wdev);
        }
 
+       mutex_unlock(&rdev->sched_scan_mtx);
        mutex_unlock(&rdev->devlist_mtx);
        cfg80211_unlock_rdev(rdev);
        rtnl_unlock();
index b28cc384a5bcf30952f66d7da5b349978e39b49a..4de4bc48493bca4947182bc10483bc272f459331 100755 (executable)
@@ -3016,6 +3016,7 @@ sub process {
                            $dstat !~ /^'X'$/ &&                                        # character constants
                            $dstat !~ /$exceptions/ &&
                            $dstat !~ /^\.$Ident\s*=/ &&                                # .foo =
+                           $dstat !~ /^(?:\#\s*$Ident|\#\s*$Constant)\s*$/ &&          # stringification #foo
                            $dstat !~ /^do\s*$Constant\s*while\s*$Constant;?$/ &&       # do {...} while (...); // do {...} while (...)
                            $dstat !~ /^for\s*$Constant$/ &&                            # for (...)
                            $dstat !~ /^for\s*$Constant\s+(?:$Ident|-?$Constant)$/ &&   # for (...) bar()
index 579775088967fdb11a044beb75c70de48d572ad6..6783c3e6c88e24fa5e2dacd07fd64ea5b61ac636 100644 (file)
@@ -737,6 +737,11 @@ static int cap_tun_dev_open(void *security)
 {
        return 0;
 }
+
+static void cap_skb_owned_by(struct sk_buff *skb, struct sock *sk)
+{
+}
+
 #endif /* CONFIG_SECURITY_NETWORK */
 
 #ifdef CONFIG_SECURITY_NETWORK_XFRM
@@ -1071,6 +1076,7 @@ void __init security_fixup_ops(struct security_operations *ops)
        set_to_cap_if_null(ops, tun_dev_open);
        set_to_cap_if_null(ops, tun_dev_attach_queue);
        set_to_cap_if_null(ops, tun_dev_attach);
+       set_to_cap_if_null(ops, skb_owned_by);
 #endif /* CONFIG_SECURITY_NETWORK */
 #ifdef CONFIG_SECURITY_NETWORK_XFRM
        set_to_cap_if_null(ops, xfrm_policy_alloc_security);
index 7b88c6aeaed43e5f37b449fd8ec87610b3b69a93..03f248b84e9fd964a8c2ba706916ce3a4a9a3f34 100644 (file)
@@ -1290,6 +1290,11 @@ int security_tun_dev_open(void *security)
 }
 EXPORT_SYMBOL(security_tun_dev_open);
 
+void security_skb_owned_by(struct sk_buff *skb, struct sock *sk)
+{
+       security_ops->skb_owned_by(skb, sk);
+}
+
 #endif /* CONFIG_SECURITY_NETWORK */
 
 #ifdef CONFIG_SECURITY_NETWORK_XFRM
index 2fa28c88900c1cb4ad7a1cc57e7b28421f4c1587..7171a957b9335694c1bbd1c5c9a41e2ec13bbda9 100644 (file)
@@ -51,6 +51,7 @@
 #include <linux/tty.h>
 #include <net/icmp.h>
 #include <net/ip.h>            /* for local_port_range[] */
+#include <net/sock.h>
 #include <net/tcp.h>           /* struct or_callable used in sock_rcv_skb */
 #include <net/net_namespace.h>
 #include <net/netlabel.h>
@@ -4363,6 +4364,11 @@ static void selinux_inet_conn_established(struct sock *sk, struct sk_buff *skb)
        selinux_skb_peerlbl_sid(skb, family, &sksec->peer_sid);
 }
 
+static void selinux_skb_owned_by(struct sk_buff *skb, struct sock *sk)
+{
+       skb_set_owner_w(skb, sk);
+}
+
 static int selinux_secmark_relabel_packet(u32 sid)
 {
        const struct task_security_struct *__tsec;
@@ -5664,6 +5670,7 @@ static struct security_operations selinux_ops = {
        .tun_dev_attach_queue =         selinux_tun_dev_attach_queue,
        .tun_dev_attach =               selinux_tun_dev_attach,
        .tun_dev_open =                 selinux_tun_dev_open,
+       .skb_owned_by =                 selinux_skb_owned_by,
 
 #ifdef CONFIG_SECURITY_NETWORK_XFRM
        .xfrm_policy_alloc_security =   selinux_xfrm_policy_alloc,
index 71ae86ca64ac3b696121c66cbc7b334bc03cb3f3..eb560fa32321eff55002830cf78f2764d7a09518 100644 (file)
@@ -3222,18 +3222,10 @@ EXPORT_SYMBOL_GPL(snd_pcm_lib_default_mmap);
 int snd_pcm_lib_mmap_iomem(struct snd_pcm_substream *substream,
                           struct vm_area_struct *area)
 {
-       long size;
-       unsigned long offset;
+       struct snd_pcm_runtime *runtime = substream->runtime;;
 
        area->vm_page_prot = pgprot_noncached(area->vm_page_prot);
-       area->vm_flags |= VM_IO;
-       size = area->vm_end - area->vm_start;
-       offset = area->vm_pgoff << PAGE_SHIFT;
-       if (io_remap_pfn_range(area, area->vm_start,
-                               (substream->runtime->dma_addr + offset) >> PAGE_SHIFT,
-                               size, area->vm_page_prot))
-               return -EAGAIN;
-       return 0;
+       return vm_iomap_memory(area, runtime->dma_addr, runtime->dma_bytes);
 }
 
 EXPORT_SYMBOL(snd_pcm_lib_mmap_iomem);
index fe4541df498cbd85eb4a10275a658ee15cdbab9b..4b3be6c3c91e28b170a7dcebd998559f9292f0ec 100644 (file)
@@ -90,8 +90,33 @@ static struct snd_soc_platform_driver dummy_platform = {
 };
 
 static struct snd_soc_codec_driver dummy_codec;
+
+#define STUB_RATES     SNDRV_PCM_RATE_8000_192000
+#define STUB_FORMATS   (SNDRV_PCM_FMTBIT_S8 | \
+                       SNDRV_PCM_FMTBIT_U8 | \
+                       SNDRV_PCM_FMTBIT_S16_LE | \
+                       SNDRV_PCM_FMTBIT_U16_LE | \
+                       SNDRV_PCM_FMTBIT_S24_LE | \
+                       SNDRV_PCM_FMTBIT_U24_LE | \
+                       SNDRV_PCM_FMTBIT_S32_LE | \
+                       SNDRV_PCM_FMTBIT_U32_LE | \
+                       SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE)
 static struct snd_soc_dai_driver dummy_dai = {
        .name = "snd-soc-dummy-dai",
+       .playback = {
+               .stream_name    = "Playback",
+               .channels_min   = 1,
+               .channels_max   = 384,
+               .rates          = STUB_RATES,
+               .formats        = STUB_FORMATS,
+       },
+       .capture = {
+               .stream_name    = "Capture",
+               .channels_min   = 1,
+               .channels_max   = 384,
+               .rates = STUB_RATES,
+               .formats = STUB_FORMATS,
+        },
 };
 
 static int snd_soc_dummy_probe(struct platform_device *pdev)
index 497d2741d1192f7b5b8eea43d9347023faa220f2..ebe91440a068a8f500901652892d5a3575b68e63 100644 (file)
@@ -509,7 +509,7 @@ static int snd_nativeinstruments_control_get(struct snd_kcontrol *kcontrol,
        else
                ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), bRequest,
                                  USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
-                                 0, cpu_to_le16(wIndex),
+                                 0, wIndex,
                                  &tmp, sizeof(tmp), 1000);
        up_read(&mixer->chip->shutdown_rwsem);
 
@@ -540,7 +540,7 @@ static int snd_nativeinstruments_control_put(struct snd_kcontrol *kcontrol,
        else
                ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), bRequest,
                                  USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
-                                 cpu_to_le16(wValue), cpu_to_le16(wIndex),
+                                 wValue, wIndex,
                                  NULL, 0, 1000);
        up_read(&mixer->chip->shutdown_rwsem);
 
index 5325a3869bb7fbbb714bbb7d6bc894062e00b2b7..9c5ab22358b159f919612fd20779dc81bb19b7d2 100644 (file)
@@ -486,7 +486,7 @@ static int snd_usb_nativeinstruments_boot_quirk(struct usb_device *dev)
 {
        int ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
                                  0xaf, USB_TYPE_VENDOR | USB_RECIP_DEVICE,
-                                 cpu_to_le16(1), 0, NULL, 0, 1000);
+                                 1, 0, NULL, 0, 1000);
 
        if (ret < 0)
                return ret;
index 6f3214ed4444ecb14c33cc29c3119057bf812cf5..321e066a07533bcf7a18e72c471e01cc1bef9527 100644 (file)
@@ -1421,6 +1421,7 @@ int has_nehalem_turbo_ratio_limit(unsigned int family, unsigned int model)
        case 0x3C:      /* HSW */
        case 0x3F:      /* HSW */
        case 0x45:      /* HSW */
+       case 0x46:      /* HSW */
                return 1;
        case 0x2E:      /* Nehalem-EX Xeon - Beckton */
        case 0x2F:      /* Westmere-EX Xeon - Eagleton */
@@ -1515,6 +1516,7 @@ void rapl_probe(unsigned int family, unsigned int model)
        case 0x3C:      /* HSW */
        case 0x3F:      /* HSW */
        case 0x45:      /* HSW */
+       case 0x46:      /* HSW */
                do_rapl = RAPL_PKG | RAPL_CORES | RAPL_GFX;
                break;
        case 0x2D:
@@ -1754,6 +1756,7 @@ int is_snb(unsigned int family, unsigned int model)
        case 0x3C:      /* HSW */
        case 0x3F:      /* HSW */
        case 0x45:      /* HSW */
+       case 0x46:      /* HSW */
                return 1;
        }
        return 0;
@@ -2276,7 +2279,7 @@ int main(int argc, char **argv)
        cmdline(argc, argv);
 
        if (verbose)
-               fprintf(stderr, "turbostat v3.2 February 11, 2013"
+               fprintf(stderr, "turbostat v3.3 March 15, 2013"
                        " - Len Brown <lenb@kernel.org>\n");
 
        turbostat_init();