Merge tag 'regmap-v3.10-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie...
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 10 Jun 2013 20:26:41 +0000 (13:26 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 10 Jun 2013 20:26:41 +0000 (13:26 -0700)
Pull regmap fixes from Mark Brown:
 "The biggest fix here is Lars-Peter's fix for custom locking callbacks
  which is pretty localised but important for those devices that use the
  feature.  Otherwise we've got a couple of fairly small cleanups which
  would have been sent sooner were it not for letting Lars-Peter's patch
  soak for a while"

* tag 'regmap-v3.10-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap:
  regmap: rbtree: Fixed node range check on sync
  regmap: regcache: Fixup locking for custom lock callbacks
  regmap: debugfs: Check return value of regmap_write()

310 files changed:
Documentation/dmatest.txt
Documentation/filesystems/xfs.txt
MAINTAINERS
Makefile
arch/arm/boot/compressed/Makefile
arch/arm/boot/compressed/debug.S
arch/arm/boot/compressed/head-sa1100.S
arch/arm/boot/compressed/head-shark.S
arch/arm/boot/compressed/head.S
arch/arm/boot/dts/bcm2835.dtsi
arch/arm/boot/dts/imx25.dtsi
arch/arm/boot/dts/imx27.dtsi
arch/arm/boot/dts/imx51.dtsi
arch/arm/boot/dts/imx53.dtsi
arch/arm/include/asm/percpu.h
arch/arm/include/asm/tlb.h
arch/arm/kernel/topology.c
arch/arm/kvm/arm.c
arch/arm/kvm/mmu.c
arch/arm/mach-exynos/common.c
arch/arm/mach-imx/clk-imx6q.c
arch/arm/mach-kirkwood/board-ts219.c
arch/arm/mach-mvebu/coherency_ll.S
arch/arm/mach-shmobile/setup-sh73a0.c
arch/arm/mach-ux500/board-mop500-regulators.c
arch/arm/mach-ux500/cpuidle.c
arch/arm/plat-samsung/include/plat/uncompress.h
arch/ia64/include/asm/tlb.h
arch/m68k/include/asm/gpio.h
arch/m68k/kernel/head.S
arch/microblaze/include/asm/cacheflush.h
arch/microblaze/include/asm/uaccess.h
arch/mips/cavium-octeon/setup.c
arch/mips/include/asm/kvm_host.h
arch/mips/include/asm/ptrace.h
arch/mips/include/uapi/asm/kvm.h
arch/mips/include/uapi/asm/ptrace.h
arch/mips/kernel/binfmt_elfn32.c
arch/mips/kernel/binfmt_elfo32.c
arch/mips/kernel/rtlx.c
arch/mips/kernel/traps.c
arch/mips/kvm/kvm_mips.c
arch/mips/kvm/kvm_trap_emul.c
arch/mips/mm/tlbex.c
arch/mips/ralink/of.c
arch/powerpc/include/asm/cputable.h
arch/powerpc/kernel/cputable.c
arch/powerpc/kernel/entry_64.S
arch/powerpc/kernel/exceptions-64s.S
arch/powerpc/kernel/pci-common.c
arch/powerpc/kernel/process.c
arch/powerpc/perf/core-book3s.c
arch/powerpc/platforms/pseries/eeh_pseries.c
arch/s390/appldata/appldata_base.c
arch/s390/include/asm/dma-mapping.h
arch/s390/include/asm/io.h
arch/s390/include/asm/pgtable.h
arch/s390/kernel/smp.c
arch/s390/mm/pgtable.c
arch/x86/kvm/emulate.c
arch/x86/kvm/lapic.c
arch/x86/pci/common.c
crypto/Kconfig
drivers/acpi/apei/ghes.c
drivers/acpi/device_pm.c
drivers/acpi/video.c
drivers/ata/acard-ahci.c
drivers/ata/ahci.c
drivers/ata/ahci.h
drivers/ata/ata_piix.c
drivers/ata/libahci.c
drivers/ata/libata-core.c
drivers/ata/libata-eh.c
drivers/ata/libata-scsi.c
drivers/ata/libata-sff.c
drivers/ata/pdc_adma.c
drivers/ata/sata_promise.c
drivers/ata/sata_rcar.c
drivers/ata/sata_sil.c
drivers/ata/sata_sx4.c
drivers/ata/sata_via.c
drivers/cpufreq/acpi-cpufreq.c
drivers/cpufreq/cpufreq-cpu0.c
drivers/cpufreq/cpufreq_governor.c
drivers/crypto/sahara.c
drivers/dma/dmatest.c
drivers/dma/ste_dma40.c
drivers/gpu/drm/drm_irq.c
drivers/gpu/drm/i915/i915_gem.c
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_lvds.c
drivers/gpu/drm/i915/intel_sdvo.c
drivers/gpu/drm/mgag200/mgag200_mode.c
drivers/gpu/drm/nouveau/core/engine/disp/dacnv50.c
drivers/gpu/drm/nouveau/core/engine/disp/hdminv84.c
drivers/gpu/drm/nouveau/core/engine/fifo/nv50.c
drivers/gpu/drm/nouveau/core/include/core/class.h
drivers/gpu/drm/nouveau/nv50_display.c
drivers/gpu/drm/radeon/atombios_encoders.c
drivers/gpu/drm/radeon/evergreen.c
drivers/gpu/drm/radeon/ni.c
drivers/gpu/drm/radeon/r100.c
drivers/gpu/drm/radeon/r300.c
drivers/gpu/drm/radeon/r420.c
drivers/gpu/drm/radeon/r520.c
drivers/gpu/drm/radeon/r600.c
drivers/gpu/drm/radeon/r600d.h
drivers/gpu/drm/radeon/radeon_asic.c
drivers/gpu/drm/radeon/radeon_asic.h
drivers/gpu/drm/radeon/rs400.c
drivers/gpu/drm/radeon/rs600.c
drivers/gpu/drm/radeon/rs690.c
drivers/gpu/drm/radeon/rv515.c
drivers/gpu/drm/radeon/rv770.c
drivers/gpu/drm/radeon/si.c
drivers/gpu/drm/tilcdc/Kconfig
drivers/hwmon/adm1021.c
drivers/iio/buffer_cb.c
drivers/iio/frequency/adf4350.c
drivers/iio/inkern.c
drivers/infiniband/hw/qib/qib_keys.c
drivers/infiniband/ulp/iser/iscsi_iser.c
drivers/infiniband/ulp/iser/iscsi_iser.h
drivers/infiniband/ulp/iser/iser_initiator.c
drivers/infiniband/ulp/iser/iser_memory.c
drivers/infiniband/ulp/iser/iser_verbs.c
drivers/input/mouse/synaptics.c
drivers/input/tablet/wacom_wac.c
drivers/irqchip/irq-mxs.c
drivers/irqchip/irq-versatile-fpga.c
drivers/irqchip/irq-vic.c
drivers/mmc/host/atmel-mci.c
drivers/mmc/host/omap_hsmmc.c
drivers/mmc/host/sdhci-acpi.c
drivers/mmc/host/sdhci-esdhc-imx.c
drivers/mmc/host/sdhci-pci.c
drivers/net/can/usb/esd_usb2.c
drivers/net/can/usb/kvaser_usb.c
drivers/net/can/usb/peak_usb/pcan_usb_pro.c
drivers/net/can/usb/peak_usb/pcan_usb_pro.h
drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
drivers/net/ethernet/broadcom/tg3.c
drivers/net/ethernet/broadcom/tg3.h
drivers/net/ethernet/emulex/benet/be.h
drivers/net/ethernet/emulex/benet/be_cmds.c
drivers/net/ethernet/emulex/benet/be_hw.h
drivers/net/ethernet/emulex/benet/be_main.c
drivers/net/ethernet/freescale/fec_main.c
drivers/net/ethernet/mellanox/mlx4/cmd.c
drivers/net/ethernet/mellanox/mlx4/en_netdev.c
drivers/net/ethernet/mellanox/mlx4/fw.c
drivers/net/ethernet/mellanox/mlx4/main.c
drivers/net/ethernet/qlogic/qlge/qlge_main.c
drivers/net/ethernet/xilinx/xilinx_emaclite.c
drivers/net/hyperv/netvsc_drv.c
drivers/net/phy/phy.c
drivers/net/team/team.c
drivers/net/tun.c
drivers/net/wireless/ath/ath9k/ar9003_eeprom.h
drivers/net/wireless/ath/ath9k/ar9003_phy.c
drivers/net/wireless/ath/ath9k/ath9k.h
drivers/net/wireless/ath/ath9k/hw.c
drivers/net/wireless/ath/ath9k/mac.c
drivers/net/wireless/ath/ath9k/main.c
drivers/net/wireless/ath/ath9k/rc.c
drivers/net/wireless/ath/ath9k/reg.h
drivers/net/wireless/ath/ath9k/xmit.c
drivers/net/wireless/atmel.c
drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
drivers/net/wireless/brcm80211/brcmfmac/fweh.c
drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h
drivers/net/wireless/brcm80211/brcmfmac/p2p.c
drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h
drivers/net/wireless/iwlwifi/dvm/sta.c
drivers/nfc/Kconfig
drivers/nfc/mei_phy.c
drivers/nfc/microread/mei.c
drivers/nfc/pn544/mei.c
drivers/pinctrl/sh-pfc/pfc-r8a7779.c
drivers/platform/x86/hp-wmi.c
drivers/ptp/ptp_pch.c
drivers/regulator/core.c
drivers/regulator/dbx500-prcmu.c
drivers/regulator/palmas-regulator.c
drivers/s390/block/dasd.c
drivers/staging/android/alarm-dev.c
drivers/staging/dwc2/hcd.c
drivers/staging/zcache/ramster.h
drivers/staging/zcache/ramster/debug.c
drivers/staging/zcache/ramster/ramster.c
drivers/tty/serial/8250/8250_core.c
drivers/tty/serial/imx.c
drivers/tty/serial/samsung.c
drivers/usb/core/devio.c
drivers/usb/dwc3/dwc3-exynos.c
drivers/usb/dwc3/dwc3-pci.c
drivers/usb/dwc3/gadget.c
drivers/usb/host/ehci-sched.c
drivers/usb/host/xhci-mem.c
drivers/usb/host/xhci-pci.c
drivers/usb/host/xhci.c
drivers/usb/host/xhci.h
drivers/usb/musb/musb_host.c
drivers/usb/musb/musb_host.h
drivers/usb/serial/ark3116.c
drivers/usb/serial/cypress_m8.c
drivers/usb/serial/cypress_m8.h
drivers/usb/serial/iuu_phoenix.c
drivers/usb/serial/keyspan.c
drivers/usb/serial/mos7720.c
drivers/usb/serial/mos7840.c
drivers/usb/serial/option.c
drivers/usb/serial/qcserial.c
drivers/usb/serial/usb-serial.c
drivers/usb/serial/visor.c
drivers/usb/serial/whiteheat.c
drivers/usb/serial/zte_ev.c
drivers/vfio/vfio.c
fs/cifs/connect.c
fs/ecryptfs/file.c
fs/fuse/dir.c
fs/fuse/file.c
fs/fuse/inode.c
fs/gfs2/bmap.c
fs/gfs2/dir.c
fs/gfs2/file.c
fs/gfs2/inode.c
fs/gfs2/lops.c
fs/gfs2/rgrp.c
fs/gfs2/super.c
fs/hpfs/file.c
fs/jfs/jfs_logmgr.c
fs/jfs/super.c
fs/proc/base.c
fs/xfs/xfs_acl.c
fs/xfs/xfs_acl.h
fs/xfs/xfs_attr_leaf.c
fs/xfs/xfs_dquot.c
fs/xfs/xfs_inode.c
fs/xfs/xfs_log_recover.c
fs/xfs/xfs_qm.c
fs/xfs/xfs_quota.h
fs/xfs/xfs_super.c
include/asm-generic/io.h
include/asm-generic/tlb.h
include/linux/cgroup.h
include/linux/list.h
include/linux/netfilter_ipv6.h
include/linux/rculist.h
include/linux/rculist_nulls.h
include/linux/rcupdate.h
include/linux/skbuff.h
include/linux/socket.h
include/net/addrconf.h
include/net/sch_generic.h
include/net/xfrm.h
kernel/cgroup.c
kernel/irq/irqdomain.c
kernel/time/ntp.c
kernel/time/tick-broadcast.c
kernel/time/timekeeping.c
kernel/trace/ftrace.c
kernel/trace/trace.c
kernel/trace/trace_selftest.c
mm/memory.c
net/compat.c
net/core/dev_addr_lists.c
net/core/skbuff.c
net/core/sock.c
net/ipv4/ip_tunnel.c
net/ipv4/netfilter/ipt_ULOG.c
net/ipv4/route.c
net/ipv6/addrconf.c
net/ipv6/netfilter.c
net/ipv6/proc.c
net/ipv6/udp_offload.c
net/key/af_key.c
net/mac80211/iface.c
net/mac80211/mlme.c
net/netfilter/core.c
net/netfilter/ipvs/ip_vs_core.c
net/netfilter/ipvs/ip_vs_sh.c
net/netfilter/xt_LOG.c
net/netfilter/xt_addrtype.c
net/netlink/af_netlink.c
net/nfc/Makefile
net/sched/act_police.c
net/sched/sch_generic.c
net/sched/sch_htb.c
net/sched/sch_tbf.c
net/socket.c
net/wireless/nl80211.c
net/wireless/sme.c
net/xfrm/xfrm_policy.c
net/xfrm/xfrm_user.c
scripts/Makefile.lib
scripts/config
scripts/kconfig/lxdialog/menubox.c
scripts/kconfig/mconf.c
scripts/kconfig/menu.c
security/selinux/xfrm.c
sound/pci/hda/hda_generic.c
sound/pci/hda/hda_generic.h
sound/pci/hda/patch_realtek.c
sound/pci/hda/patch_via.c
sound/pci/sis7019.c
sound/usb/mixer.c
sound/usb/quirks-table.h

index 279ac0a..132a094 100644 (file)
@@ -34,7 +34,7 @@ command:
 After a while you will start to get messages about current status or error like
 in the original code.
 
-Note that running a new test will stop any in progress test.
+Note that running a new test will not stop any in progress test.
 
 The following command should return actual state of the test.
        % cat /sys/kernel/debug/dmatest/run
@@ -52,8 +52,8 @@ To wait for test done the user may perform a busy loop that checks the state.
 
 The module parameters that is supplied to the kernel command line will be used
 for the first performed test. After user gets a control, the test could be
-interrupted or re-run with same or different parameters. For the details see
-the above section "Part 2 - When dmatest is built as a module..."
+re-run with the same or different parameters. For the details see the above
+section "Part 2 - When dmatest is built as a module..."
 
 In both cases the module parameters are used as initial values for the test case.
 You always could check them at run-time by running
index 3e4b3dd..83577f0 100644 (file)
@@ -33,6 +33,9 @@ When mounting an XFS filesystem, the following options are accepted.
        removing extended attributes) the on-disk superblock feature
        bit field will be updated to reflect this format being in use.
 
+       CRC enabled filesystems always use the attr2 format, and so
+       will reject the noattr2 mount option if it is set.
+
   barrier
        Enables the use of block layer write barriers for writes into
        the journal and unwritten extent conversion.  This allows for
index f35a259..250dc97 100644 (file)
@@ -2890,8 +2890,8 @@ F:        drivers/media/dvb-frontends/ec100*
 
 ECRYPT FILE SYSTEM
 M:     Tyler Hicks <tyhicks@canonical.com>
-M:     Dustin Kirkland <dustin.kirkland@gazzang.com>
 L:     ecryptfs@vger.kernel.org
+W:     http://ecryptfs.org
 W:     https://launchpad.net/ecryptfs
 S:     Supported
 F:     Documentation/filesystems/ecryptfs.txt
@@ -4448,6 +4448,16 @@ S:       Maintained
 F:     drivers/scsi/*iscsi*
 F:     include/scsi/*iscsi*
 
+ISCSI EXTENSIONS FOR RDMA (ISER) INITIATOR
+M:     Or Gerlitz <ogerlitz@mellanox.com>
+M:     Roi Dayan <roid@mellanox.com>
+L:     linux-rdma@vger.kernel.org
+S:     Supported
+W:     http://www.openfabrics.org
+W:     www.open-iscsi.org
+Q:     http://patchwork.kernel.org/project/linux-rdma/list/
+F:     drivers/infiniband/ulp/iser
+
 ISDN SUBSYSTEM
 M:     Karsten Keil <isdn@linux-pingi.de>
 L:     isdn4linux@listserv.isdn4linux.de (subscribers-only)
index 49aa84b..9040016 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 3
 PATCHLEVEL = 10
 SUBLEVEL = 0
-EXTRAVERSION = -rc4
+EXTRAVERSION = -rc5
 NAME = Unicycling Gorilla
 
 # *DOCUMENTATION*
index 3580d57..79e9bdb 100644 (file)
@@ -124,7 +124,7 @@ KBUILD_CFLAGS = $(subst -pg, , $(ORIG_CFLAGS))
 endif
 
 ccflags-y := -fpic -mno-single-pic-base -fno-builtin -I$(obj)
-asflags-y := -Wa,-march=all -DZIMAGE
+asflags-y := -DZIMAGE
 
 # Supply kernel BSS size to the decompressor via a linker symbol.
 KBSS_SZ = $(shell $(CROSS_COMPILE)size $(obj)/../../../../vmlinux | \
index 6e8382d..5392ee6 100644 (file)
@@ -1,6 +1,8 @@
 #include <linux/linkage.h>
 #include <asm/assembler.h>
 
+#ifndef CONFIG_DEBUG_SEMIHOSTING
+
 #include CONFIG_DEBUG_LL_INCLUDE
 
 ENTRY(putc)
@@ -10,3 +12,29 @@ ENTRY(putc)
        busyuart r3, r1
        mov      pc, lr
 ENDPROC(putc)
+
+#else
+
+ENTRY(putc)
+       adr     r1, 1f
+       ldmia   r1, {r2, r3}
+       add     r2, r2, r1
+       ldr     r1, [r2, r3]
+       strb    r0, [r1]
+       mov     r0, #0x03               @ SYS_WRITEC
+   ARM(        svc     #0x123456       )
+ THUMB(        svc     #0xab           )
+       mov     pc, lr
+       .align  2
+1:     .word   _GLOBAL_OFFSET_TABLE_ - .
+       .word   semi_writec_buf(GOT)
+ENDPROC(putc)
+
+       .bss
+       .global semi_writec_buf
+       .type   semi_writec_buf, %object
+semi_writec_buf:
+       .space  4
+       .size   semi_writec_buf, 4
+
+#endif
index 6179d94..3115e31 100644 (file)
@@ -11,6 +11,7 @@
 #include <asm/mach-types.h>
 
                .section        ".start", "ax"
+               .arch   armv4
 
 __SA1100_start:
 
index 089c560..92b5689 100644 (file)
@@ -18,6 +18,7 @@
        
                .section        ".start", "ax"
 
+               .arch armv4
                b       __beginning
        
 __ofw_data:    .long   0                               @ the number of memory blocks
index fe4d9c3..032a8d9 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/linkage.h>
 #include <asm/assembler.h>
 
+       .arch   armv7-a
 /*
  * Debugging stuff
  *
@@ -805,8 +806,8 @@ call_cache_fn:      adr     r12, proc_types
                .align  2
                .type   proc_types,#object
 proc_types:
-               .word   0x00000000              @ old ARM ID
-               .word   0x0000f000
+               .word   0x41000000              @ old ARM ID
+               .word   0xff00f000
                mov     pc, lr
  THUMB(                nop                             )
                mov     pc, lr
index f0052dc..1e12aef 100644 (file)
@@ -44,6 +44,7 @@
                        reg = <0x7e201000 0x1000>;
                        interrupts = <2 25>;
                        clock-frequency = <3000000>;
+                       arm,primecell-periphid = <0x00241011>;
                };
 
                gpio: gpio {
index d2550e0..7011539 100644 (file)
                                #size-cells = <0>;
                                compatible = "fsl,imx25-cspi", "fsl,imx35-cspi";
                                reg = <0x43fa4000 0x4000>;
-                               clocks = <&clks 62>;
-                               clock-names = "ipg";
+                               clocks = <&clks 62>, <&clks 62>;
+                               clock-names = "ipg", "per";
                                interrupts = <14>;
                                status = "disabled";
                        };
                                compatible = "fsl,imx25-cspi", "fsl,imx35-cspi";
                                reg = <0x50004000 0x4000>;
                                interrupts = <0>;
-                               clocks = <&clks 80>;
-                               clock-names = "ipg";
+                               clocks = <&clks 80>, <&clks 80>;
+                               clock-names = "ipg", "per";
                                status = "disabled";
                        };
 
                                #size-cells = <0>;
                                compatible = "fsl,imx25-cspi", "fsl,imx35-cspi";
                                reg = <0x50010000 0x4000>;
-                               clocks = <&clks 79>;
-                               clock-names = "ipg";
+                               clocks = <&clks 79>, <&clks 79>;
+                               clock-names = "ipg", "per";
                                interrupts = <13>;
                                status = "disabled";
                        };
index ff4bd48..75bd113 100644 (file)
                                compatible = "fsl,imx27-cspi";
                                reg = <0x1000e000 0x1000>;
                                interrupts = <16>;
-                               clocks = <&clks 53>, <&clks 0>;
+                               clocks = <&clks 53>, <&clks 53>;
                                clock-names = "ipg", "per";
                                status = "disabled";
                        };
                                compatible = "fsl,imx27-cspi";
                                reg = <0x1000f000 0x1000>;
                                interrupts = <15>;
-                               clocks = <&clks 52>, <&clks 0>;
+                               clocks = <&clks 52>, <&clks 52>;
                                clock-names = "ipg", "per";
                                status = "disabled";
                        };
                                compatible = "fsl,imx27-cspi";
                                reg = <0x10017000 0x1000>;
                                interrupts = <6>;
-                               clocks = <&clks 51>, <&clks 0>;
+                               clocks = <&clks 51>, <&clks 51>;
                                clock-names = "ipg", "per";
                                status = "disabled";
                        };
index 21bb786..53fdde6 100644 (file)
                                compatible = "fsl,imx51-cspi", "fsl,imx35-cspi";
                                reg = <0x83fc0000 0x4000>;
                                interrupts = <38>;
-                               clocks = <&clks 55>, <&clks 0>;
+                               clocks = <&clks 55>, <&clks 55>;
                                clock-names = "ipg", "per";
                                status = "disabled";
                        };
index 845982e..eb83aa0 100644 (file)
                                compatible = "fsl,imx53-cspi", "fsl,imx35-cspi";
                                reg = <0x63fc0000 0x4000>;
                                interrupts = <38>;
-                               clocks = <&clks 55>, <&clks 0>;
+                               clocks = <&clks 55>, <&clks 55>;
                                clock-names = "ipg", "per";
                                status = "disabled";
                        };
index 968c0a1..209e650 100644 (file)
@@ -30,8 +30,15 @@ static inline void set_my_cpu_offset(unsigned long off)
 static inline unsigned long __my_cpu_offset(void)
 {
        unsigned long off;
-       /* Read TPIDRPRW */
-       asm("mrc p15, 0, %0, c13, c0, 4" : "=r" (off) : : "memory");
+       register unsigned long *sp asm ("sp");
+
+       /*
+        * Read TPIDRPRW.
+        * We want to allow caching the value, so avoid using volatile and
+        * instead use a fake stack read to hazard against barrier().
+        */
+       asm("mrc p15, 0, %0, c13, c0, 4" : "=r" (off) : "Q" (*sp));
+
        return off;
 }
 #define __my_cpu_offset __my_cpu_offset()
index 99a1951..bdf2b84 100644 (file)
 #include <asm/pgalloc.h>
 #include <asm/tlbflush.h>
 
-/*
- * We need to delay page freeing for SMP as other CPUs can access pages
- * which have been removed but not yet had their TLB entries invalidated.
- * Also, as ARMv7 speculative prefetch can drag new entries into the TLB,
- * we need to apply this same delaying tactic to ensure correct operation.
- */
-#if defined(CONFIG_SMP) || defined(CONFIG_CPU_32v7)
-#define tlb_fast_mode(tlb)     0
-#else
-#define tlb_fast_mode(tlb)     1
-#endif
-
 #define MMU_GATHER_BUNDLE      8
 
 /*
@@ -112,12 +100,10 @@ static inline void __tlb_alloc_page(struct mmu_gather *tlb)
 static inline void tlb_flush_mmu(struct mmu_gather *tlb)
 {
        tlb_flush(tlb);
-       if (!tlb_fast_mode(tlb)) {
-               free_pages_and_swap_cache(tlb->pages, tlb->nr);
-               tlb->nr = 0;
-               if (tlb->pages == tlb->local)
-                       __tlb_alloc_page(tlb);
-       }
+       free_pages_and_swap_cache(tlb->pages, tlb->nr);
+       tlb->nr = 0;
+       if (tlb->pages == tlb->local)
+               __tlb_alloc_page(tlb);
 }
 
 static inline void
@@ -178,11 +164,6 @@ tlb_end_vma(struct mmu_gather *tlb, struct vm_area_struct *vma)
 
 static inline int __tlb_remove_page(struct mmu_gather *tlb, struct page *page)
 {
-       if (tlb_fast_mode(tlb)) {
-               free_page_and_swap_cache(page);
-               return 1; /* avoid calling tlb_flush_mmu */
-       }
-
        tlb->pages[tlb->nr++] = page;
        VM_BUG_ON(tlb->nr > tlb->max);
        return tlb->max - tlb->nr;
index f10316b..c5a5954 100644 (file)
@@ -13,6 +13,7 @@
 
 #include <linux/cpu.h>
 #include <linux/cpumask.h>
+#include <linux/export.h>
 #include <linux/init.h>
 #include <linux/percpu.h>
 #include <linux/node.h>
@@ -200,6 +201,7 @@ static inline void update_cpu_power(unsigned int cpuid, unsigned int mpidr) {}
  * cpu topology table
  */
 struct cputopo_arm cpu_topology[NR_CPUS];
+EXPORT_SYMBOL_GPL(cpu_topology);
 
 const struct cpumask *cpu_coregroup_mask(int cpu)
 {
index 37d216d..ef1703b 100644 (file)
@@ -492,6 +492,11 @@ static void vcpu_pause(struct kvm_vcpu *vcpu)
        wait_event_interruptible(*wq, !vcpu->arch.pause);
 }
 
+static int kvm_vcpu_initialized(struct kvm_vcpu *vcpu)
+{
+       return vcpu->arch.target >= 0;
+}
+
 /**
  * kvm_arch_vcpu_ioctl_run - the main VCPU run function to execute guest code
  * @vcpu:      The VCPU pointer
@@ -508,8 +513,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
        int ret;
        sigset_t sigsaved;
 
-       /* Make sure they initialize the vcpu with KVM_ARM_VCPU_INIT */
-       if (unlikely(vcpu->arch.target < 0))
+       if (unlikely(!kvm_vcpu_initialized(vcpu)))
                return -ENOEXEC;
 
        ret = kvm_vcpu_first_run_init(vcpu);
@@ -710,6 +714,10 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
        case KVM_SET_ONE_REG:
        case KVM_GET_ONE_REG: {
                struct kvm_one_reg reg;
+
+               if (unlikely(!kvm_vcpu_initialized(vcpu)))
+                       return -ENOEXEC;
+
                if (copy_from_user(&reg, argp, sizeof(reg)))
                        return -EFAULT;
                if (ioctl == KVM_SET_ONE_REG)
@@ -722,6 +730,9 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
                struct kvm_reg_list reg_list;
                unsigned n;
 
+               if (unlikely(!kvm_vcpu_initialized(vcpu)))
+                       return -ENOEXEC;
+
                if (copy_from_user(&reg_list, user_list, sizeof(reg_list)))
                        return -EFAULT;
                n = reg_list.n;
index 9657065..84ba67b 100644 (file)
@@ -43,7 +43,14 @@ static phys_addr_t hyp_idmap_vector;
 
 static void kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa)
 {
-       kvm_call_hyp(__kvm_tlb_flush_vmid_ipa, kvm, ipa);
+       /*
+        * This function also gets called when dealing with HYP page
+        * tables. As HYP doesn't have an associated struct kvm (and
+        * the HYP page tables are fairly static), we don't do
+        * anything there.
+        */
+       if (kvm)
+               kvm_call_hyp(__kvm_tlb_flush_vmid_ipa, kvm, ipa);
 }
 
 static int mmu_topup_memory_cache(struct kvm_mmu_memory_cache *cache,
@@ -78,18 +85,20 @@ static void *mmu_memory_cache_alloc(struct kvm_mmu_memory_cache *mc)
        return p;
 }
 
-static void clear_pud_entry(pud_t *pud)
+static void clear_pud_entry(struct kvm *kvm, pud_t *pud, phys_addr_t addr)
 {
        pmd_t *pmd_table = pmd_offset(pud, 0);
        pud_clear(pud);
+       kvm_tlb_flush_vmid_ipa(kvm, addr);
        pmd_free(NULL, pmd_table);
        put_page(virt_to_page(pud));
 }
 
-static void clear_pmd_entry(pmd_t *pmd)
+static void clear_pmd_entry(struct kvm *kvm, pmd_t *pmd, phys_addr_t addr)
 {
        pte_t *pte_table = pte_offset_kernel(pmd, 0);
        pmd_clear(pmd);
+       kvm_tlb_flush_vmid_ipa(kvm, addr);
        pte_free_kernel(NULL, pte_table);
        put_page(virt_to_page(pmd));
 }
@@ -100,11 +109,12 @@ static bool pmd_empty(pmd_t *pmd)
        return page_count(pmd_page) == 1;
 }
 
-static void clear_pte_entry(pte_t *pte)
+static void clear_pte_entry(struct kvm *kvm, pte_t *pte, phys_addr_t addr)
 {
        if (pte_present(*pte)) {
                kvm_set_pte(pte, __pte(0));
                put_page(virt_to_page(pte));
+               kvm_tlb_flush_vmid_ipa(kvm, addr);
        }
 }
 
@@ -114,7 +124,8 @@ static bool pte_empty(pte_t *pte)
        return page_count(pte_page) == 1;
 }
 
-static void unmap_range(pgd_t *pgdp, unsigned long long start, u64 size)
+static void unmap_range(struct kvm *kvm, pgd_t *pgdp,
+                       unsigned long long start, u64 size)
 {
        pgd_t *pgd;
        pud_t *pud;
@@ -138,15 +149,15 @@ static void unmap_range(pgd_t *pgdp, unsigned long long start, u64 size)
                }
 
                pte = pte_offset_kernel(pmd, addr);
-               clear_pte_entry(pte);
+               clear_pte_entry(kvm, pte, addr);
                range = PAGE_SIZE;
 
                /* If we emptied the pte, walk back up the ladder */
                if (pte_empty(pte)) {
-                       clear_pmd_entry(pmd);
+                       clear_pmd_entry(kvm, pmd, addr);
                        range = PMD_SIZE;
                        if (pmd_empty(pmd)) {
-                               clear_pud_entry(pud);
+                               clear_pud_entry(kvm, pud, addr);
                                range = PUD_SIZE;
                        }
                }
@@ -165,14 +176,14 @@ void free_boot_hyp_pgd(void)
        mutex_lock(&kvm_hyp_pgd_mutex);
 
        if (boot_hyp_pgd) {
-               unmap_range(boot_hyp_pgd, hyp_idmap_start, PAGE_SIZE);
-               unmap_range(boot_hyp_pgd, TRAMPOLINE_VA, PAGE_SIZE);
+               unmap_range(NULL, boot_hyp_pgd, hyp_idmap_start, PAGE_SIZE);
+               unmap_range(NULL, boot_hyp_pgd, TRAMPOLINE_VA, PAGE_SIZE);
                kfree(boot_hyp_pgd);
                boot_hyp_pgd = NULL;
        }
 
        if (hyp_pgd)
-               unmap_range(hyp_pgd, TRAMPOLINE_VA, PAGE_SIZE);
+               unmap_range(NULL, hyp_pgd, TRAMPOLINE_VA, PAGE_SIZE);
 
        kfree(init_bounce_page);
        init_bounce_page = NULL;
@@ -200,9 +211,10 @@ void free_hyp_pgds(void)
 
        if (hyp_pgd) {
                for (addr = PAGE_OFFSET; virt_addr_valid(addr); addr += PGDIR_SIZE)
-                       unmap_range(hyp_pgd, KERN_TO_HYP(addr), PGDIR_SIZE);
+                       unmap_range(NULL, hyp_pgd, KERN_TO_HYP(addr), PGDIR_SIZE);
                for (addr = VMALLOC_START; is_vmalloc_addr((void*)addr); addr += PGDIR_SIZE)
-                       unmap_range(hyp_pgd, KERN_TO_HYP(addr), PGDIR_SIZE);
+                       unmap_range(NULL, hyp_pgd, KERN_TO_HYP(addr), PGDIR_SIZE);
+
                kfree(hyp_pgd);
                hyp_pgd = NULL;
        }
@@ -393,7 +405,7 @@ int kvm_alloc_stage2_pgd(struct kvm *kvm)
  */
 static void unmap_stage2_range(struct kvm *kvm, phys_addr_t start, u64 size)
 {
-       unmap_range(kvm->arch.pgd, start, size);
+       unmap_range(kvm, kvm->arch.pgd, start, size);
 }
 
 /**
@@ -675,7 +687,6 @@ static void handle_hva_to_gpa(struct kvm *kvm,
 static void kvm_unmap_hva_handler(struct kvm *kvm, gpa_t gpa, void *data)
 {
        unmap_stage2_range(kvm, gpa, PAGE_SIZE);
-       kvm_tlb_flush_vmid_ipa(kvm, gpa);
 }
 
 int kvm_unmap_hva(struct kvm *kvm, unsigned long hva)
index 027c9e7..f7e504b 100644 (file)
@@ -386,6 +386,8 @@ int __init exynos_fdt_map_chipid(unsigned long node, const char *uname,
 
 void __init exynos_init_io(struct map_desc *mach_desc, int size)
 {
+       debug_ll_io_init();
+
 #ifdef CONFIG_OF
        if (initial_boot_params)
                of_scan_flat_dt(exynos_fdt_map_chipid, NULL);
index dda9a2b..4e3148c 100644 (file)
@@ -181,14 +181,14 @@ static const char *periph_clk2_sels[]     = { "pll3_usb_otg", "osc", "osc", "dummy",
 static const char *periph2_clk2_sels[] = { "pll3_usb_otg", "pll2_bus", };
 static const char *periph_sels[]       = { "periph_pre", "periph_clk2", };
 static const char *periph2_sels[]      = { "periph2_pre", "periph2_clk2", };
-static const char *axi_sels[]          = { "periph", "pll2_pfd2_396m", "pll3_pfd1_540m", };
+static const char *axi_sels[]          = { "periph", "pll2_pfd2_396m", "periph", "pll3_pfd1_540m", };
 static const char *audio_sels[]        = { "pll4_post_div", "pll3_pfd2_508m", "pll3_pfd3_454m", "pll3_usb_otg", };
 static const char *gpu_axi_sels[]      = { "axi", "ahb", };
 static const char *gpu2d_core_sels[]   = { "axi", "pll3_usb_otg", "pll2_pfd0_352m", "pll2_pfd2_396m", };
 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", "pll3_pfd0_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_usb_otg", };
+static const char *ldb_di_sels[]       = { "pll5_video_div", "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_div", "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", };
index acb0187..4695d5f 100644 (file)
@@ -41,13 +41,3 @@ void __init qnap_dt_ts219_init(void)
 
        pm_power_off = qnap_tsx1x_power_off;
 }
-
-/* FIXME: Will not work with DT. Maybe use MPP40_GPIO? */
-static int __init ts219_pci_init(void)
-{
-       if (machine_is_ts219())
-               kirkwood_pcie_init(KW_PCIE0);
-
-       return 0;
-}
-subsys_initcall(ts219_pci_init);
index 53e8391..5476669 100644 (file)
@@ -32,15 +32,21 @@ ENTRY(ll_set_cpu_coherent)
 
        /* Add CPU to SMP group - Atomic */
        add     r3, r0, #ARMADA_XP_CFB_CTL_REG_OFFSET
-       ldr     r2, [r3]
+1:
+       ldrex   r2, [r3]
        orr     r2, r2, r1
-       str     r2, [r3]
+       strex   r0, r2, [r3]
+       cmp     r0, #0
+       bne 1b
 
        /* Enable coherency on CPU - Atomic */
-       add     r3, r0, #ARMADA_XP_CFB_CFG_REG_OFFSET
-       ldr     r2, [r3]
+       add     r3, r3, #ARMADA_XP_CFB_CFG_REG_OFFSET
+1:
+       ldrex   r2, [r3]
        orr     r2, r2, r1
-       str     r2, [r3]
+       strex   r0, r2, [r3]
+       cmp     r0, #0
+       bne 1b
 
        dsb
 
index fdf3894..9696f36 100644 (file)
@@ -252,7 +252,7 @@ static struct sh_timer_config cmt10_platform_data = {
        .name = "CMT10",
        .channel_offset = 0x10,
        .timer_bit = 0,
-       .clockevent_rating = 125,
+       .clockevent_rating = 80,
        .clocksource_rating = 125,
 };
 
index 33c353b..d6b7c85 100644 (file)
@@ -374,6 +374,7 @@ static struct ab8500_regulator_reg_init ab8500_reg_init[] = {
 static struct regulator_init_data ab8500_regulators[AB8500_NUM_REGULATORS] = {
        /* supplies to the display/camera */
        [AB8500_LDO_AUX1] = {
+               .supply_regulator = "ab8500-ext-supply3",
                .constraints = {
                        .name = "V-DISPLAY",
                        .min_uV = 2800000,
@@ -387,6 +388,7 @@ static struct regulator_init_data ab8500_regulators[AB8500_NUM_REGULATORS] = {
        },
        /* supplies to the on-board eMMC */
        [AB8500_LDO_AUX2] = {
+               .supply_regulator = "ab8500-ext-supply3",
                .constraints = {
                        .name = "V-eMMC1",
                        .min_uV = 1100000,
@@ -402,6 +404,7 @@ static struct regulator_init_data ab8500_regulators[AB8500_NUM_REGULATORS] = {
        },
        /* supply for VAUX3, supplies to SDcard slots */
        [AB8500_LDO_AUX3] = {
+               .supply_regulator = "ab8500-ext-supply3",
                .constraints = {
                        .name = "V-MMC-SD",
                        .min_uV = 1100000,
index 317a2be..a45dd09 100644 (file)
@@ -21,6 +21,7 @@
 #include <asm/proc-fns.h>
 
 #include "db8500-regs.h"
+#include "id.h"
 
 static atomic_t master = ATOMIC_INIT(0);
 static DEFINE_SPINLOCK(master_lock);
@@ -114,6 +115,9 @@ static struct cpuidle_driver ux500_idle_driver = {
 
 int __init ux500_idle_init(void)
 {
+       if (!(cpu_is_u8500_family() || cpu_is_ux540_family()))
+               return -ENODEV;
+
        /* Configure wake up reasons */
        prcmu_enable_wakeups(PRCMU_WAKEUP(ARM) | PRCMU_WAKEUP(RTC) |
                             PRCMU_WAKEUP(ABB));
index 438b248..02b66d7 100644 (file)
@@ -66,6 +66,9 @@ uart_rd(unsigned int reg)
 
 static void putc(int ch)
 {
+       if (!config_enabled(CONFIG_DEBUG_LL))
+               return;
+
        if (uart_rd(S3C2410_UFCON) & S3C2410_UFCON_FIFOMODE) {
                int level;
 
@@ -118,7 +121,12 @@ static void arch_decomp_error(const char *x)
 #ifdef CONFIG_S3C_BOOT_UART_FORCE_FIFO
 static inline void arch_enable_uart_fifo(void)
 {
-       u32 fifocon = uart_rd(S3C2410_UFCON);
+       u32 fifocon;
+
+       if (!config_enabled(CONFIG_DEBUG_LL))
+               return;
+
+       fifocon = uart_rd(S3C2410_UFCON);
 
        if (!(fifocon & S3C2410_UFCON_FIFOMODE)) {
                fifocon |= S3C2410_UFCON_RESETBOTH;
index c3ffe3e..ef3a9de 100644 (file)
 #include <asm/tlbflush.h>
 #include <asm/machvec.h>
 
-#ifdef CONFIG_SMP
-# define tlb_fast_mode(tlb)    ((tlb)->nr == ~0U)
-#else
-# define tlb_fast_mode(tlb)    (1)
-#endif
-
 /*
  * If we can't allocate a page to make a big batch of page pointers
  * to work on, then just handle a few from the on-stack structure.
@@ -60,7 +54,7 @@
 
 struct mmu_gather {
        struct mm_struct        *mm;
-       unsigned int            nr;             /* == ~0U => fast mode */
+       unsigned int            nr;
        unsigned int            max;
        unsigned char           fullmm;         /* non-zero means full mm flush */
        unsigned char           need_flush;     /* really unmapped some PTEs? */
@@ -103,6 +97,7 @@ extern struct ia64_tr_entry *ia64_idtrs[NR_CPUS];
 static inline void
 ia64_tlb_flush_mmu (struct mmu_gather *tlb, unsigned long start, unsigned long end)
 {
+       unsigned long i;
        unsigned int nr;
 
        if (!tlb->need_flush)
@@ -141,13 +136,11 @@ ia64_tlb_flush_mmu (struct mmu_gather *tlb, unsigned long start, unsigned long e
 
        /* lastly, release the freed pages */
        nr = tlb->nr;
-       if (!tlb_fast_mode(tlb)) {
-               unsigned long i;
-               tlb->nr = 0;
-               tlb->start_addr = ~0UL;
-               for (i = 0; i < nr; ++i)
-                       free_page_and_swap_cache(tlb->pages[i]);
-       }
+
+       tlb->nr = 0;
+       tlb->start_addr = ~0UL;
+       for (i = 0; i < nr; ++i)
+               free_page_and_swap_cache(tlb->pages[i]);
 }
 
 static inline void __tlb_alloc_page(struct mmu_gather *tlb)
@@ -167,20 +160,7 @@ tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned int full_m
        tlb->mm = mm;
        tlb->max = ARRAY_SIZE(tlb->local);
        tlb->pages = tlb->local;
-       /*
-        * Use fast mode if only 1 CPU is online.
-        *
-        * It would be tempting to turn on fast-mode for full_mm_flush as well.  But this
-        * doesn't work because of speculative accesses and software prefetching: the page
-        * table of "mm" may (and usually is) the currently active page table and even
-        * though the kernel won't do any user-space accesses during the TLB shoot down, a
-        * compiler might use speculation or lfetch.fault on what happens to be a valid
-        * user-space address.  This in turn could trigger a TLB miss fault (or a VHPT
-        * walk) and re-insert a TLB entry we just removed.  Slow mode avoids such
-        * problems.  (We could make fast-mode work by switching the current task to a
-        * different "mm" during the shootdown.) --davidm 08/02/2002
-        */
-       tlb->nr = (num_online_cpus() == 1) ? ~0U : 0;
+       tlb->nr = 0;
        tlb->fullmm = full_mm_flush;
        tlb->start_addr = ~0UL;
 }
@@ -214,11 +194,6 @@ static inline int __tlb_remove_page(struct mmu_gather *tlb, struct page *page)
 {
        tlb->need_flush = 1;
 
-       if (tlb_fast_mode(tlb)) {
-               free_page_and_swap_cache(page);
-               return 1; /* avoid calling tlb_flush_mmu */
-       }
-
        if (!tlb->nr && tlb->pages == tlb->local)
                __tlb_alloc_page(tlb);
 
index 8cc8343..2f6eec1 100644 (file)
@@ -86,6 +86,7 @@ static inline int gpio_cansleep(unsigned gpio)
        return gpio < MCFGPIO_PIN_MAX ? 0 : __gpio_cansleep(gpio);
 }
 
+#ifndef CONFIG_GPIOLIB
 static inline int gpio_request_one(unsigned gpio, unsigned long flags, const char *label)
 {
        int err;
@@ -105,5 +106,5 @@ static inline int gpio_request_one(unsigned gpio, unsigned long flags, const cha
 
        return err;
 }
-
+#endif /* !CONFIG_GPIOLIB */
 #endif
index d197e7f..ac85f16 100644 (file)
@@ -2752,11 +2752,9 @@ func_return      get_new_page
 #ifdef CONFIG_MAC
 
 L(scc_initable_mac):
-       .byte   9,12            /* Reset */
        .byte   4,0x44          /* x16, 1 stopbit, no parity */
        .byte   3,0xc0          /* receiver: 8 bpc */
        .byte   5,0xe2          /* transmitter: 8 bpc, assert dtr/rts */
-       .byte   9,0             /* no interrupts */
        .byte   10,0            /* NRZ */
        .byte   11,0x50         /* use baud rate generator */
        .byte   12,1,13,0       /* 38400 baud */
@@ -2899,6 +2897,7 @@ func_start        serial_init,%d0/%d1/%a0/%a1
        is_not_mac(L(serial_init_not_mac))
 
 #ifdef SERIAL_DEBUG
+
 /* You may define either or both of these. */
 #define MAC_USE_SCC_A /* Modem port */
 #define MAC_USE_SCC_B /* Printer port */
@@ -2908,9 +2907,21 @@ func_start       serial_init,%d0/%d1/%a0/%a1
 #define mac_scc_cha_b_data_offset      0x4
 #define mac_scc_cha_a_data_offset      0x6
 
+#if defined(MAC_USE_SCC_A) || defined(MAC_USE_SCC_B)
+       movel   %pc@(L(mac_sccbase)),%a0
+       /* Reset SCC device */
+       moveb   #9,%a0@(mac_scc_cha_a_ctrl_offset)
+       moveb   #0xc0,%a0@(mac_scc_cha_a_ctrl_offset)
+       /* Wait for 5 PCLK cycles, which is about 68 CPU cycles */
+       /* 5 / 3.6864 MHz = approx. 1.36 us = 68 / 50 MHz */
+       movel   #35,%d0
+5:
+       subq    #1,%d0
+       jne     5b
+#endif
+
 #ifdef MAC_USE_SCC_A
        /* Initialize channel A */
-       movel   %pc@(L(mac_sccbase)),%a0
        lea     %pc@(L(scc_initable_mac)),%a1
 5:     moveb   %a1@+,%d0
        jmi     6f
@@ -2922,9 +2933,6 @@ func_start        serial_init,%d0/%d1/%a0/%a1
 
 #ifdef MAC_USE_SCC_B
        /* Initialize channel B */
-#ifndef MAC_USE_SCC_A  /* Load mac_sccbase only if needed */
-       movel   %pc@(L(mac_sccbase)),%a0
-#endif /* MAC_USE_SCC_A */
        lea     %pc@(L(scc_initable_mac)),%a1
 7:     moveb   %a1@+,%d0
        jmi     8f
@@ -2933,6 +2941,7 @@ func_start        serial_init,%d0/%d1/%a0/%a1
        jra     7b
 8:
 #endif /* MAC_USE_SCC_B */
+
 #endif /* SERIAL_DEBUG */
 
        jra     L(serial_init_done)
@@ -3006,17 +3015,17 @@ func_start      serial_putc,%d0/%d1/%a0/%a1
 
 #ifdef SERIAL_DEBUG
 
-#ifdef MAC_USE_SCC_A
+#if defined(MAC_USE_SCC_A) || defined(MAC_USE_SCC_B)
        movel   %pc@(L(mac_sccbase)),%a1
+#endif
+
+#ifdef MAC_USE_SCC_A
 3:     btst    #2,%a1@(mac_scc_cha_a_ctrl_offset)
        jeq     3b
        moveb   %d0,%a1@(mac_scc_cha_a_data_offset)
 #endif /* MAC_USE_SCC_A */
 
 #ifdef MAC_USE_SCC_B
-#ifndef MAC_USE_SCC_A  /* Load mac_sccbase only if needed */
-       movel   %pc@(L(mac_sccbase)),%a1
-#endif /* MAC_USE_SCC_A */
 4:     btst    #2,%a1@(mac_scc_cha_b_ctrl_offset)
        jeq     4b
        moveb   %d0,%a1@(mac_scc_cha_b_data_offset)
index 0f553bc..ffea82a 100644 (file)
@@ -102,21 +102,23 @@ do { \
 
 #define flush_cache_range(vma, start, len) do { } while (0)
 
-#define copy_to_user_page(vma, page, vaddr, dst, src, len)             \
-do {                                                                   \
-       u32 addr = virt_to_phys(dst);                                   \
-       memcpy((dst), (src), (len));                                    \
-       if (vma->vm_flags & VM_EXEC) {                                  \
-               invalidate_icache_range((unsigned) (addr),              \
-                                       (unsigned) (addr) + PAGE_SIZE); \
-               flush_dcache_range((unsigned) (addr),                   \
-                                       (unsigned) (addr) + PAGE_SIZE); \
-       }                                                               \
-} while (0)
-
-#define copy_from_user_page(vma, page, vaddr, dst, src, len)           \
-do {                                                                   \
-       memcpy((dst), (src), (len));                                    \
-} while (0)
+static inline void copy_to_user_page(struct vm_area_struct *vma,
+                                    struct page *page, unsigned long vaddr,
+                                    void *dst, void *src, int len)
+{
+       u32 addr = virt_to_phys(dst);
+       memcpy(dst, src, len);
+       if (vma->vm_flags & VM_EXEC) {
+               invalidate_icache_range(addr, addr + PAGE_SIZE);
+               flush_dcache_range(addr, addr + PAGE_SIZE);
+       }
+}
+
+static inline void copy_from_user_page(struct vm_area_struct *vma,
+                                      struct page *page, unsigned long vaddr,
+                                      void *dst, void *src, int len)
+{
+       memcpy(dst, src, len);
+}
 
 #endif /* _ASM_MICROBLAZE_CACHEFLUSH_H */
index efe59d8..04e4955 100644 (file)
@@ -99,13 +99,13 @@ static inline int access_ok(int type, const void __user *addr,
        if ((get_fs().seg < ((unsigned long)addr)) ||
                        (get_fs().seg < ((unsigned long)addr + size - 1))) {
                pr_debug("ACCESS fail: %s at 0x%08x (size 0x%x), seg 0x%08x\n",
-                       type ? "WRITE" : "READ ", (u32)addr, (u32)size,
+                       type ? "WRITE" : "READ ", (__force u32)addr, (u32)size,
                        (u32)get_fs().seg);
                return 0;
        }
 ok:
        pr_debug("ACCESS OK: %s at 0x%08x (size 0x%x), seg 0x%08x\n",
-                       type ? "WRITE" : "READ ", (u32)addr, (u32)size,
+                       type ? "WRITE" : "READ ", (__force u32)addr, (u32)size,
                        (u32)get_fs().seg);
        return 1;
 }
index b0baa29..01b1b3f 100644 (file)
@@ -428,13 +428,16 @@ static void octeon_restart(char *command)
  */
 static void octeon_kill_core(void *arg)
 {
-       mb();
-       if (octeon_is_simulation()) {
-               /* The simulator needs the watchdog to stop for dead cores */
-               cvmx_write_csr(CVMX_CIU_WDOGX(cvmx_get_core_num()), 0);
+       if (octeon_is_simulation())
                /* A break instruction causes the simulator stop a core */
-               asm volatile ("sync\nbreak");
-       }
+               asm volatile ("break" ::: "memory");
+
+       local_irq_disable();
+       /* Disable watchdog on this core. */
+       cvmx_write_csr(CVMX_CIU_WDOGX(cvmx_get_core_num()), 0);
+       /* Spin in a low power mode. */
+       while (true)
+               asm volatile ("wait" ::: "memory");
 }
 
 
index 143875c..4d6fa0b 100644 (file)
@@ -496,10 +496,6 @@ struct kvm_mips_callbacks {
                            uint32_t cause);
        int (*irq_clear) (struct kvm_vcpu *vcpu, unsigned int priority,
                          uint32_t cause);
-       int (*vcpu_ioctl_get_regs) (struct kvm_vcpu *vcpu,
-                                   struct kvm_regs *regs);
-       int (*vcpu_ioctl_set_regs) (struct kvm_vcpu *vcpu,
-                                   struct kvm_regs *regs);
 };
 extern struct kvm_mips_callbacks *kvm_mips_callbacks;
 int kvm_mips_emulation_init(struct kvm_mips_callbacks **install_callbacks);
index a3186f2..5e6cd09 100644 (file)
 #include <asm/isadep.h>
 #include <uapi/asm/ptrace.h>
 
+/*
+ * This struct defines the way the registers are stored on the stack during a
+ * system call/exception. As usual the registers k0/k1 aren't being saved.
+ */
+struct pt_regs {
+#ifdef CONFIG_32BIT
+       /* Pad bytes for argument save space on the stack. */
+       unsigned long pad0[6];
+#endif
+
+       /* Saved main processor registers. */
+       unsigned long regs[32];
+
+       /* Saved special registers. */
+       unsigned long cp0_status;
+       unsigned long hi;
+       unsigned long lo;
+#ifdef CONFIG_CPU_HAS_SMARTMIPS
+       unsigned long acx;
+#endif
+       unsigned long cp0_badvaddr;
+       unsigned long cp0_cause;
+       unsigned long cp0_epc;
+#ifdef CONFIG_MIPS_MT_SMTC
+       unsigned long cp0_tcstatus;
+#endif /* CONFIG_MIPS_MT_SMTC */
+#ifdef CONFIG_CPU_CAVIUM_OCTEON
+       unsigned long long mpl[3];        /* MTM{0,1,2} */
+       unsigned long long mtp[3];        /* MTP{0,1,2} */
+#endif
+} __aligned(8);
+
 struct task_struct;
 
 extern int ptrace_getregs(struct task_struct *child, __s64 __user *data);
index 85789ea..3f424f5 100644 (file)
 /*
-* This file is subject to the terms and conditions of the GNU General Public
-* License.  See the file "COPYING" in the main directory of this archive
-* for more details.
-*
-* Copyright (C) 2012  MIPS Technologies, Inc.  All rights reserved.
-* Authors: Sanjay Lal <sanjayl@kymasys.com>
-*/
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2012  MIPS Technologies, Inc.  All rights reserved.
+ * Copyright (C) 2013 Cavium, Inc.
+ * Authors: Sanjay Lal <sanjayl@kymasys.com>
+ */
 
 #ifndef __LINUX_KVM_MIPS_H
 #define __LINUX_KVM_MIPS_H
 
 #include <linux/types.h>
 
-#define __KVM_MIPS
-
-#define N_MIPS_COPROC_REGS      32
-#define N_MIPS_COPROC_SEL      8
+/*
+ * KVM MIPS specific structures and definitions.
+ *
+ * Some parts derived from the x86 version of this file.
+ */
 
-/* for KVM_GET_REGS and KVM_SET_REGS */
+/*
+ * for KVM_GET_REGS and KVM_SET_REGS
+ *
+ * If Config[AT] is zero (32-bit CPU), the register contents are
+ * stored in the lower 32-bits of the struct kvm_regs fields and sign
+ * extended to 64-bits.
+ */
 struct kvm_regs {
-       __u32 gprs[32];
-       __u32 hi;
-       __u32 lo;
-       __u32 pc;
-
-       __u32 cp0reg[N_MIPS_COPROC_REGS][N_MIPS_COPROC_SEL];
-};
-
-/* for KVM_GET_SREGS and KVM_SET_SREGS */
-struct kvm_sregs {
+       /* out (KVM_GET_REGS) / in (KVM_SET_REGS) */
+       __u64 gpr[32];
+       __u64 hi;
+       __u64 lo;
+       __u64 pc;
 };
 
-/* for KVM_GET_FPU and KVM_SET_FPU */
+/*
+ * for KVM_GET_FPU and KVM_SET_FPU
+ *
+ * If Status[FR] is zero (32-bit FPU), the upper 32-bits of the FPRs
+ * are zero filled.
+ */
 struct kvm_fpu {
+       __u64 fpr[32];
+       __u32 fir;
+       __u32 fccr;
+       __u32 fexr;
+       __u32 fenr;
+       __u32 fcsr;
+       __u32 pad;
 };
 
+
+/*
+ * For MIPS, we use KVM_SET_ONE_REG and KVM_GET_ONE_REG to access CP0
+ * registers.  The id field is broken down as follows:
+ *
+ *  bits[2..0]   - Register 'sel' index.
+ *  bits[7..3]   - Register 'rd'  index.
+ *  bits[15..8]  - Must be zero.
+ *  bits[63..16] - 1 -> CP0 registers.
+ *
+ * Other sets registers may be added in the future.  Each set would
+ * have its own identifier in bits[63..16].
+ *
+ * The addr field of struct kvm_one_reg must point to an aligned
+ * 64-bit wide location.  For registers that are narrower than
+ * 64-bits, the value is stored in the low order bits of the location,
+ * and sign extended to 64-bits.
+ *
+ * The registers defined in struct kvm_regs are also accessible, the
+ * id values for these are below.
+ */
+
+#define KVM_REG_MIPS_R0 0
+#define KVM_REG_MIPS_R1 1
+#define KVM_REG_MIPS_R2 2
+#define KVM_REG_MIPS_R3 3
+#define KVM_REG_MIPS_R4 4
+#define KVM_REG_MIPS_R5 5
+#define KVM_REG_MIPS_R6 6
+#define KVM_REG_MIPS_R7 7
+#define KVM_REG_MIPS_R8 8
+#define KVM_REG_MIPS_R9 9
+#define KVM_REG_MIPS_R10 10
+#define KVM_REG_MIPS_R11 11
+#define KVM_REG_MIPS_R12 12
+#define KVM_REG_MIPS_R13 13
+#define KVM_REG_MIPS_R14 14
+#define KVM_REG_MIPS_R15 15
+#define KVM_REG_MIPS_R16 16
+#define KVM_REG_MIPS_R17 17
+#define KVM_REG_MIPS_R18 18
+#define KVM_REG_MIPS_R19 19
+#define KVM_REG_MIPS_R20 20
+#define KVM_REG_MIPS_R21 21
+#define KVM_REG_MIPS_R22 22
+#define KVM_REG_MIPS_R23 23
+#define KVM_REG_MIPS_R24 24
+#define KVM_REG_MIPS_R25 25
+#define KVM_REG_MIPS_R26 26
+#define KVM_REG_MIPS_R27 27
+#define KVM_REG_MIPS_R28 28
+#define KVM_REG_MIPS_R29 29
+#define KVM_REG_MIPS_R30 30
+#define KVM_REG_MIPS_R31 31
+
+#define KVM_REG_MIPS_HI 32
+#define KVM_REG_MIPS_LO 33
+#define KVM_REG_MIPS_PC 34
+
+/*
+ * KVM MIPS specific structures and definitions
+ *
+ */
 struct kvm_debug_exit_arch {
+       __u64 epc;
 };
 
 /* for KVM_SET_GUEST_DEBUG */
 struct kvm_guest_debug_arch {
 };
 
+/* definition of registers in kvm_run */
+struct kvm_sync_regs {
+};
+
+/* dummy definition */
+struct kvm_sregs {
+};
+
 struct kvm_mips_interrupt {
        /* in */
        __u32 cpu;
        __u32 irq;
 };
 
-/* definition of registers in kvm_run */
-struct kvm_sync_regs {
-};
-
 #endif /* __LINUX_KVM_MIPS_H */
index 4d58d84..b26f7e3 100644 (file)
 #define DSP_CONTROL    77
 #define ACX            78
 
+#ifndef __KERNEL__
 /*
  * This struct defines the way the registers are stored on the stack during a
  * system call/exception. As usual the registers k0/k1 aren't being saved.
  */
 struct pt_regs {
-#ifdef CONFIG_32BIT
-       /* Pad bytes for argument save space on the stack. */
-       unsigned long pad0[6];
-#endif
-
        /* Saved main processor registers. */
        unsigned long regs[32];
 
@@ -39,20 +35,11 @@ struct pt_regs {
        unsigned long cp0_status;
        unsigned long hi;
        unsigned long lo;
-#ifdef CONFIG_CPU_HAS_SMARTMIPS
-       unsigned long acx;
-#endif
        unsigned long cp0_badvaddr;
        unsigned long cp0_cause;
        unsigned long cp0_epc;
-#ifdef CONFIG_MIPS_MT_SMTC
-       unsigned long cp0_tcstatus;
-#endif /* CONFIG_MIPS_MT_SMTC */
-#ifdef CONFIG_CPU_CAVIUM_OCTEON
-       unsigned long long mpl[3];        /* MTM{0,1,2} */
-       unsigned long long mtp[3];        /* MTP{0,1,2} */
-#endif
 } __attribute__ ((aligned (8)));
+#endif /* __KERNEL__ */
 
 /* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */
 #define PTRACE_GETREGS         12
index e06f777..1188e00 100644 (file)
@@ -119,4 +119,15 @@ MODULE_AUTHOR("Ralf Baechle (ralf@linux-mips.org)");
 #undef TASK_SIZE
 #define TASK_SIZE TASK_SIZE32
 
+#undef cputime_to_timeval
+#define cputime_to_timeval cputime_to_compat_timeval
+static __inline__ void
+cputime_to_compat_timeval(const cputime_t cputime, struct compat_timeval *value)
+{
+       unsigned long jiffies = cputime_to_jiffies(cputime);
+
+       value->tv_usec = (jiffies % HZ) * (1000000L / HZ);
+       value->tv_sec = jiffies / HZ;
+}
+
 #include "../../../fs/binfmt_elf.c"
index 97c5a16..202e581 100644 (file)
@@ -162,4 +162,15 @@ MODULE_AUTHOR("Ralf Baechle (ralf@linux-mips.org)");
 #undef TASK_SIZE
 #define TASK_SIZE TASK_SIZE32
 
+#undef cputime_to_timeval
+#define cputime_to_timeval cputime_to_compat_timeval
+static __inline__ void
+cputime_to_compat_timeval(const cputime_t cputime, struct compat_timeval *value)
+{
+       unsigned long jiffies = cputime_to_jiffies(cputime);
+
+       value->tv_usec = (jiffies % HZ) * (1000000L / HZ);
+       value->tv_sec = jiffies / HZ;
+}
+
 #include "../../../fs/binfmt_elf.c"
index 93c070b..6fa198d 100644 (file)
@@ -40,6 +40,7 @@
 #include <asm/processor.h>
 #include <asm/vpe.h>
 #include <asm/rtlx.h>
+#include <asm/setup.h>
 
 static struct rtlx_info *rtlx;
 static int major;
index e3be670..a75ae40 100644 (file)
@@ -897,22 +897,24 @@ out_sigsegv:
 
 asmlinkage void do_tr(struct pt_regs *regs)
 {
-       unsigned int opcode, tcode = 0;
+       u32 opcode, tcode = 0;
        u16 instr[2];
-       unsigned long epc = exception_epc(regs);
+       unsigned long epc = msk_isa16_mode(exception_epc(regs));
 
-       if ((__get_user(instr[0], (u16 __user *)msk_isa16_mode(epc))) ||
-               (__get_user(instr[1], (u16 __user *)msk_isa16_mode(epc + 2))))
+       if (get_isa16_mode(regs->cp0_epc)) {
+               if (__get_user(instr[0], (u16 __user *)(epc + 0)) ||
+                   __get_user(instr[1], (u16 __user *)(epc + 2)))
                        goto out_sigsegv;
-       opcode = (instr[0] << 16) | instr[1];
-
-       /* Immediate versions don't provide a code.  */
-       if (!(opcode & OPCODE)) {
-               if (get_isa16_mode(regs->cp0_epc))
-                       /* microMIPS */
-                       tcode = (opcode >> 12) & 0x1f;
-               else
-                       tcode = ((opcode >> 6) & ((1 << 10) - 1));
+               opcode = (instr[0] << 16) | instr[1];
+               /* Immediate versions don't provide a code.  */
+               if (!(opcode & OPCODE))
+                       tcode = (opcode >> 12) & ((1 << 4) - 1);
+       } else {
+               if (__get_user(opcode, (u32 __user *)epc))
+                       goto out_sigsegv;
+               /* Immediate versions don't provide a code.  */
+               if (!(opcode & OPCODE))
+                       tcode = (opcode >> 6) & ((1 << 10) - 1);
        }
 
        do_trap_or_bp(regs, tcode, "Trap");
index e0dad02..d934b01 100644 (file)
@@ -195,7 +195,7 @@ void kvm_arch_destroy_vm(struct kvm *kvm)
 long
 kvm_arch_dev_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg)
 {
-       return -EINVAL;
+       return -ENOIOCTLCMD;
 }
 
 void kvm_arch_free_memslot(struct kvm_memory_slot *free,
@@ -401,7 +401,7 @@ int
 kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
                                    struct kvm_guest_debug *dbg)
 {
-       return -EINVAL;
+       return -ENOIOCTLCMD;
 }
 
 int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
@@ -475,14 +475,223 @@ int
 kvm_arch_vcpu_ioctl_get_mpstate(struct kvm_vcpu *vcpu,
                                struct kvm_mp_state *mp_state)
 {
-       return -EINVAL;
+       return -ENOIOCTLCMD;
 }
 
 int
 kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu,
                                struct kvm_mp_state *mp_state)
 {
-       return -EINVAL;
+       return -ENOIOCTLCMD;
+}
+
+#define KVM_REG_MIPS_CP0_INDEX (0x10000 + 8 * 0 + 0)
+#define KVM_REG_MIPS_CP0_ENTRYLO0 (0x10000 + 8 * 2 + 0)
+#define KVM_REG_MIPS_CP0_ENTRYLO1 (0x10000 + 8 * 3 + 0)
+#define KVM_REG_MIPS_CP0_CONTEXT (0x10000 + 8 * 4 + 0)
+#define KVM_REG_MIPS_CP0_USERLOCAL (0x10000 + 8 * 4 + 2)
+#define KVM_REG_MIPS_CP0_PAGEMASK (0x10000 + 8 * 5 + 0)
+#define KVM_REG_MIPS_CP0_PAGEGRAIN (0x10000 + 8 * 5 + 1)
+#define KVM_REG_MIPS_CP0_WIRED (0x10000 + 8 * 6 + 0)
+#define KVM_REG_MIPS_CP0_HWRENA (0x10000 + 8 * 7 + 0)
+#define KVM_REG_MIPS_CP0_BADVADDR (0x10000 + 8 * 8 + 0)
+#define KVM_REG_MIPS_CP0_COUNT (0x10000 + 8 * 9 + 0)
+#define KVM_REG_MIPS_CP0_ENTRYHI (0x10000 + 8 * 10 + 0)
+#define KVM_REG_MIPS_CP0_COMPARE (0x10000 + 8 * 11 + 0)
+#define KVM_REG_MIPS_CP0_STATUS (0x10000 + 8 * 12 + 0)
+#define KVM_REG_MIPS_CP0_CAUSE (0x10000 + 8 * 13 + 0)
+#define KVM_REG_MIPS_CP0_EBASE (0x10000 + 8 * 15 + 1)
+#define KVM_REG_MIPS_CP0_CONFIG (0x10000 + 8 * 16 + 0)
+#define KVM_REG_MIPS_CP0_CONFIG1 (0x10000 + 8 * 16 + 1)
+#define KVM_REG_MIPS_CP0_CONFIG2 (0x10000 + 8 * 16 + 2)
+#define KVM_REG_MIPS_CP0_CONFIG3 (0x10000 + 8 * 16 + 3)
+#define KVM_REG_MIPS_CP0_CONFIG7 (0x10000 + 8 * 16 + 7)
+#define KVM_REG_MIPS_CP0_XCONTEXT (0x10000 + 8 * 20 + 0)
+#define KVM_REG_MIPS_CP0_ERROREPC (0x10000 + 8 * 30 + 0)
+
+static u64 kvm_mips_get_one_regs[] = {
+       KVM_REG_MIPS_R0,
+       KVM_REG_MIPS_R1,
+       KVM_REG_MIPS_R2,
+       KVM_REG_MIPS_R3,
+       KVM_REG_MIPS_R4,
+       KVM_REG_MIPS_R5,
+       KVM_REG_MIPS_R6,
+       KVM_REG_MIPS_R7,
+       KVM_REG_MIPS_R8,
+       KVM_REG_MIPS_R9,
+       KVM_REG_MIPS_R10,
+       KVM_REG_MIPS_R11,
+       KVM_REG_MIPS_R12,
+       KVM_REG_MIPS_R13,
+       KVM_REG_MIPS_R14,
+       KVM_REG_MIPS_R15,
+       KVM_REG_MIPS_R16,
+       KVM_REG_MIPS_R17,
+       KVM_REG_MIPS_R18,
+       KVM_REG_MIPS_R19,
+       KVM_REG_MIPS_R20,
+       KVM_REG_MIPS_R21,
+       KVM_REG_MIPS_R22,
+       KVM_REG_MIPS_R23,
+       KVM_REG_MIPS_R24,
+       KVM_REG_MIPS_R25,
+       KVM_REG_MIPS_R26,
+       KVM_REG_MIPS_R27,
+       KVM_REG_MIPS_R28,
+       KVM_REG_MIPS_R29,
+       KVM_REG_MIPS_R30,
+       KVM_REG_MIPS_R31,
+
+       KVM_REG_MIPS_HI,
+       KVM_REG_MIPS_LO,
+       KVM_REG_MIPS_PC,
+
+       KVM_REG_MIPS_CP0_INDEX,
+       KVM_REG_MIPS_CP0_CONTEXT,
+       KVM_REG_MIPS_CP0_PAGEMASK,
+       KVM_REG_MIPS_CP0_WIRED,
+       KVM_REG_MIPS_CP0_BADVADDR,
+       KVM_REG_MIPS_CP0_ENTRYHI,
+       KVM_REG_MIPS_CP0_STATUS,
+       KVM_REG_MIPS_CP0_CAUSE,
+       /* EPC set via kvm_regs, et al. */
+       KVM_REG_MIPS_CP0_CONFIG,
+       KVM_REG_MIPS_CP0_CONFIG1,
+       KVM_REG_MIPS_CP0_CONFIG2,
+       KVM_REG_MIPS_CP0_CONFIG3,
+       KVM_REG_MIPS_CP0_CONFIG7,
+       KVM_REG_MIPS_CP0_ERROREPC
+};
+
+static int kvm_mips_get_reg(struct kvm_vcpu *vcpu,
+                           const struct kvm_one_reg *reg)
+{
+       u64 __user *uaddr = (u64 __user *)(long)reg->addr;
+
+       struct mips_coproc *cop0 = vcpu->arch.cop0;
+       s64 v;
+
+       switch (reg->id) {
+       case KVM_REG_MIPS_R0 ... KVM_REG_MIPS_R31:
+               v = (long)vcpu->arch.gprs[reg->id - KVM_REG_MIPS_R0];
+               break;
+       case KVM_REG_MIPS_HI:
+               v = (long)vcpu->arch.hi;
+               break;
+       case KVM_REG_MIPS_LO:
+               v = (long)vcpu->arch.lo;
+               break;
+       case KVM_REG_MIPS_PC:
+               v = (long)vcpu->arch.pc;
+               break;
+
+       case KVM_REG_MIPS_CP0_INDEX:
+               v = (long)kvm_read_c0_guest_index(cop0);
+               break;
+       case KVM_REG_MIPS_CP0_CONTEXT:
+               v = (long)kvm_read_c0_guest_context(cop0);
+               break;
+       case KVM_REG_MIPS_CP0_PAGEMASK:
+               v = (long)kvm_read_c0_guest_pagemask(cop0);
+               break;
+       case KVM_REG_MIPS_CP0_WIRED:
+               v = (long)kvm_read_c0_guest_wired(cop0);
+               break;
+       case KVM_REG_MIPS_CP0_BADVADDR:
+               v = (long)kvm_read_c0_guest_badvaddr(cop0);
+               break;
+       case KVM_REG_MIPS_CP0_ENTRYHI:
+               v = (long)kvm_read_c0_guest_entryhi(cop0);
+               break;
+       case KVM_REG_MIPS_CP0_STATUS:
+               v = (long)kvm_read_c0_guest_status(cop0);
+               break;
+       case KVM_REG_MIPS_CP0_CAUSE:
+               v = (long)kvm_read_c0_guest_cause(cop0);
+               break;
+       case KVM_REG_MIPS_CP0_ERROREPC:
+               v = (long)kvm_read_c0_guest_errorepc(cop0);
+               break;
+       case KVM_REG_MIPS_CP0_CONFIG:
+               v = (long)kvm_read_c0_guest_config(cop0);
+               break;
+       case KVM_REG_MIPS_CP0_CONFIG1:
+               v = (long)kvm_read_c0_guest_config1(cop0);
+               break;
+       case KVM_REG_MIPS_CP0_CONFIG2:
+               v = (long)kvm_read_c0_guest_config2(cop0);
+               break;
+       case KVM_REG_MIPS_CP0_CONFIG3:
+               v = (long)kvm_read_c0_guest_config3(cop0);
+               break;
+       case KVM_REG_MIPS_CP0_CONFIG7:
+               v = (long)kvm_read_c0_guest_config7(cop0);
+               break;
+       default:
+               return -EINVAL;
+       }
+       return put_user(v, uaddr);
+}
+
+static int kvm_mips_set_reg(struct kvm_vcpu *vcpu,
+                           const struct kvm_one_reg *reg)
+{
+       u64 __user *uaddr = (u64 __user *)(long)reg->addr;
+       struct mips_coproc *cop0 = vcpu->arch.cop0;
+       u64 v;
+
+       if (get_user(v, uaddr) != 0)
+               return -EFAULT;
+
+       switch (reg->id) {
+       case KVM_REG_MIPS_R0:
+               /* Silently ignore requests to set $0 */
+               break;
+       case KVM_REG_MIPS_R1 ... KVM_REG_MIPS_R31:
+               vcpu->arch.gprs[reg->id - KVM_REG_MIPS_R0] = v;
+               break;
+       case KVM_REG_MIPS_HI:
+               vcpu->arch.hi = v;
+               break;
+       case KVM_REG_MIPS_LO:
+               vcpu->arch.lo = v;
+               break;
+       case KVM_REG_MIPS_PC:
+               vcpu->arch.pc = v;
+               break;
+
+       case KVM_REG_MIPS_CP0_INDEX:
+               kvm_write_c0_guest_index(cop0, v);
+               break;
+       case KVM_REG_MIPS_CP0_CONTEXT:
+               kvm_write_c0_guest_context(cop0, v);
+               break;
+       case KVM_REG_MIPS_CP0_PAGEMASK:
+               kvm_write_c0_guest_pagemask(cop0, v);
+               break;
+       case KVM_REG_MIPS_CP0_WIRED:
+               kvm_write_c0_guest_wired(cop0, v);
+               break;
+       case KVM_REG_MIPS_CP0_BADVADDR:
+               kvm_write_c0_guest_badvaddr(cop0, v);
+               break;
+       case KVM_REG_MIPS_CP0_ENTRYHI:
+               kvm_write_c0_guest_entryhi(cop0, v);
+               break;
+       case KVM_REG_MIPS_CP0_STATUS:
+               kvm_write_c0_guest_status(cop0, v);
+               break;
+       case KVM_REG_MIPS_CP0_CAUSE:
+               kvm_write_c0_guest_cause(cop0, v);
+               break;
+       case KVM_REG_MIPS_CP0_ERROREPC:
+               kvm_write_c0_guest_errorepc(cop0, v);
+               break;
+       default:
+               return -EINVAL;
+       }
+       return 0;
 }
 
 long
@@ -491,9 +700,38 @@ kvm_arch_vcpu_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg)
        struct kvm_vcpu *vcpu = filp->private_data;
        void __user *argp = (void __user *)arg;
        long r;
-       int intr;
 
        switch (ioctl) {
+       case KVM_SET_ONE_REG:
+       case KVM_GET_ONE_REG: {
+               struct kvm_one_reg reg;
+               if (copy_from_user(&reg, argp, sizeof(reg)))
+                       return -EFAULT;
+               if (ioctl == KVM_SET_ONE_REG)
+                       return kvm_mips_set_reg(vcpu, &reg);
+               else
+                       return kvm_mips_get_reg(vcpu, &reg);
+       }
+       case KVM_GET_REG_LIST: {
+               struct kvm_reg_list __user *user_list = argp;
+               u64 __user *reg_dest;
+               struct kvm_reg_list reg_list;
+               unsigned n;
+
+               if (copy_from_user(&reg_list, user_list, sizeof(reg_list)))
+                       return -EFAULT;
+               n = reg_list.n;
+               reg_list.n = ARRAY_SIZE(kvm_mips_get_one_regs);
+               if (copy_to_user(user_list, &reg_list, sizeof(reg_list)))
+                       return -EFAULT;
+               if (n < reg_list.n)
+                       return -E2BIG;
+               reg_dest = user_list->reg;
+               if (copy_to_user(reg_dest, kvm_mips_get_one_regs,
+                                sizeof(kvm_mips_get_one_regs)))
+                       return -EFAULT;
+               return 0;
+       }
        case KVM_NMI:
                /* Treat the NMI as a CPU reset */
                r = kvm_mips_reset_vcpu(vcpu);
@@ -505,8 +743,6 @@ kvm_arch_vcpu_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg)
                        if (copy_from_user(&irq, argp, sizeof(irq)))
                                goto out;
 
-                       intr = (int)irq.irq;
-
                        kvm_debug("[%d] %s: irq: %d\n", vcpu->vcpu_id, __func__,
                                  irq.irq);
 
@@ -514,7 +750,7 @@ kvm_arch_vcpu_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg)
                        break;
                }
        default:
-               r = -EINVAL;
+               r = -ENOIOCTLCMD;
        }
 
 out:
@@ -565,7 +801,7 @@ long kvm_arch_vm_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg)
 
        switch (ioctl) {
        default:
-               r = -EINVAL;
+               r = -ENOIOCTLCMD;
        }
 
        return r;
@@ -593,13 +829,13 @@ void kvm_arch_exit(void)
 int
 kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
 {
-       return -ENOTSUPP;
+       return -ENOIOCTLCMD;
 }
 
 int
 kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
 {
-       return -ENOTSUPP;
+       return -ENOIOCTLCMD;
 }
 
 int kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu)
@@ -609,12 +845,12 @@ int kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu)
 
 int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
 {
-       return -ENOTSUPP;
+       return -ENOIOCTLCMD;
 }
 
 int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
 {
-       return -ENOTSUPP;
+       return -ENOIOCTLCMD;
 }
 
 int kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf)
@@ -627,6 +863,9 @@ int kvm_dev_ioctl_check_extension(long ext)
        int r;
 
        switch (ext) {
+       case KVM_CAP_ONE_REG:
+               r = 1;
+               break;
        case KVM_CAP_COALESCED_MMIO:
                r = KVM_COALESCED_MMIO_PAGE_OFFSET;
                break;
@@ -635,7 +874,6 @@ int kvm_dev_ioctl_check_extension(long ext)
                break;
        }
        return r;
-
 }
 
 int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu)
@@ -677,28 +915,28 @@ int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
 {
        int i;
 
-       for (i = 0; i < 32; i++)
-               vcpu->arch.gprs[i] = regs->gprs[i];
-
+       for (i = 1; i < ARRAY_SIZE(vcpu->arch.gprs); i++)
+               vcpu->arch.gprs[i] = regs->gpr[i];
+       vcpu->arch.gprs[0] = 0; /* zero is special, and cannot be set. */
        vcpu->arch.hi = regs->hi;
        vcpu->arch.lo = regs->lo;
        vcpu->arch.pc = regs->pc;
 
-       return kvm_mips_callbacks->vcpu_ioctl_set_regs(vcpu, regs);
+       return 0;
 }
 
 int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
 {
        int i;
 
-       for (i = 0; i < 32; i++)
-               regs->gprs[i] = vcpu->arch.gprs[i];
+       for (i = 0; i < ARRAY_SIZE(vcpu->arch.gprs); i++)
+               regs->gpr[i] = vcpu->arch.gprs[i];
 
        regs->hi = vcpu->arch.hi;
        regs->lo = vcpu->arch.lo;
        regs->pc = vcpu->arch.pc;
 
-       return kvm_mips_callbacks->vcpu_ioctl_get_regs(vcpu, regs);
+       return 0;
 }
 
 void kvm_mips_comparecount_func(unsigned long data)
index 466aeef..30d7253 100644 (file)
@@ -345,54 +345,6 @@ static int kvm_trap_emul_handle_break(struct kvm_vcpu *vcpu)
        return ret;
 }
 
-static int
-kvm_trap_emul_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
-{
-       struct mips_coproc *cop0 = vcpu->arch.cop0;
-
-       kvm_write_c0_guest_index(cop0, regs->cp0reg[MIPS_CP0_TLB_INDEX][0]);
-       kvm_write_c0_guest_context(cop0, regs->cp0reg[MIPS_CP0_TLB_CONTEXT][0]);
-       kvm_write_c0_guest_badvaddr(cop0, regs->cp0reg[MIPS_CP0_BAD_VADDR][0]);
-       kvm_write_c0_guest_entryhi(cop0, regs->cp0reg[MIPS_CP0_TLB_HI][0]);
-       kvm_write_c0_guest_epc(cop0, regs->cp0reg[MIPS_CP0_EXC_PC][0]);
-
-       kvm_write_c0_guest_status(cop0, regs->cp0reg[MIPS_CP0_STATUS][0]);
-       kvm_write_c0_guest_cause(cop0, regs->cp0reg[MIPS_CP0_CAUSE][0]);
-       kvm_write_c0_guest_pagemask(cop0,
-                                   regs->cp0reg[MIPS_CP0_TLB_PG_MASK][0]);
-       kvm_write_c0_guest_wired(cop0, regs->cp0reg[MIPS_CP0_TLB_WIRED][0]);
-       kvm_write_c0_guest_errorepc(cop0, regs->cp0reg[MIPS_CP0_ERROR_PC][0]);
-
-       return 0;
-}
-
-static int
-kvm_trap_emul_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
-{
-       struct mips_coproc *cop0 = vcpu->arch.cop0;
-
-       regs->cp0reg[MIPS_CP0_TLB_INDEX][0] = kvm_read_c0_guest_index(cop0);
-       regs->cp0reg[MIPS_CP0_TLB_CONTEXT][0] = kvm_read_c0_guest_context(cop0);
-       regs->cp0reg[MIPS_CP0_BAD_VADDR][0] = kvm_read_c0_guest_badvaddr(cop0);
-       regs->cp0reg[MIPS_CP0_TLB_HI][0] = kvm_read_c0_guest_entryhi(cop0);
-       regs->cp0reg[MIPS_CP0_EXC_PC][0] = kvm_read_c0_guest_epc(cop0);
-
-       regs->cp0reg[MIPS_CP0_STATUS][0] = kvm_read_c0_guest_status(cop0);
-       regs->cp0reg[MIPS_CP0_CAUSE][0] = kvm_read_c0_guest_cause(cop0);
-       regs->cp0reg[MIPS_CP0_TLB_PG_MASK][0] =
-           kvm_read_c0_guest_pagemask(cop0);
-       regs->cp0reg[MIPS_CP0_TLB_WIRED][0] = kvm_read_c0_guest_wired(cop0);
-       regs->cp0reg[MIPS_CP0_ERROR_PC][0] = kvm_read_c0_guest_errorepc(cop0);
-
-       regs->cp0reg[MIPS_CP0_CONFIG][0] = kvm_read_c0_guest_config(cop0);
-       regs->cp0reg[MIPS_CP0_CONFIG][1] = kvm_read_c0_guest_config1(cop0);
-       regs->cp0reg[MIPS_CP0_CONFIG][2] = kvm_read_c0_guest_config2(cop0);
-       regs->cp0reg[MIPS_CP0_CONFIG][3] = kvm_read_c0_guest_config3(cop0);
-       regs->cp0reg[MIPS_CP0_CONFIG][7] = kvm_read_c0_guest_config7(cop0);
-
-       return 0;
-}
-
 static int kvm_trap_emul_vm_init(struct kvm *kvm)
 {
        return 0;
@@ -471,8 +423,6 @@ static struct kvm_mips_callbacks kvm_trap_emul_callbacks = {
        .dequeue_io_int = kvm_mips_dequeue_io_int_cb,
        .irq_deliver = kvm_mips_irq_deliver_cb,
        .irq_clear = kvm_mips_irq_clear_cb,
-       .vcpu_ioctl_get_regs = kvm_trap_emul_ioctl_get_regs,
-       .vcpu_ioctl_set_regs = kvm_trap_emul_ioctl_set_regs,
 };
 
 int kvm_mips_emulation_init(struct kvm_mips_callbacks **install_callbacks)
index ce9818e..afeef93 100644 (file)
@@ -301,10 +301,6 @@ static u32 tlb_handler[128] __cpuinitdata;
 static struct uasm_label labels[128] __cpuinitdata;
 static struct uasm_reloc relocs[128] __cpuinitdata;
 
-#ifdef CONFIG_64BIT
-static int check_for_high_segbits __cpuinitdata;
-#endif
-
 static int check_for_high_segbits __cpuinitdata;
 
 static unsigned int kscratch_used_mask __cpuinitdata;
index fb15695..6b5f340 100644 (file)
@@ -88,7 +88,7 @@ void __init plat_mem_setup(void)
        __dt_setup_arch(&__dtb_start);
 
        if (soc_info.mem_size)
-               add_memory_region(soc_info.mem_base, soc_info.mem_size,
+               add_memory_region(soc_info.mem_base, soc_info.mem_size * SZ_1M,
                                  BOOT_MEM_RAM);
        else
                detect_memory_region(soc_info.mem_base,
index 26807e5..6f3887d 100644 (file)
@@ -176,6 +176,7 @@ extern const char *powerpc_base_platform;
 #define CPU_FTR_CFAR                   LONG_ASM_CONST(0x0100000000000000)
 #define        CPU_FTR_HAS_PPR                 LONG_ASM_CONST(0x0200000000000000)
 #define CPU_FTR_DAWR                   LONG_ASM_CONST(0x0400000000000000)
+#define CPU_FTR_DABRX                  LONG_ASM_CONST(0x0800000000000000)
 
 #ifndef __ASSEMBLY__
 
@@ -394,19 +395,20 @@ extern const char *powerpc_base_platform;
            CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | CPU_FTR_ARCH_201 | \
            CPU_FTR_ALTIVEC_COMP | CPU_FTR_CAN_NAP | CPU_FTR_MMCRA | \
            CPU_FTR_CP_USE_DCBTZ | CPU_FTR_STCX_CHECKS_ADDRESS | \
-           CPU_FTR_HVMODE)
+           CPU_FTR_HVMODE | CPU_FTR_DABRX)
 #define CPU_FTRS_POWER5        (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
            CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
            CPU_FTR_MMCRA | CPU_FTR_SMT | \
            CPU_FTR_COHERENT_ICACHE | CPU_FTR_PURR | \
-           CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB)
+           CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_DABRX)
 #define CPU_FTRS_POWER6 (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
            CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
            CPU_FTR_MMCRA | CPU_FTR_SMT | \
            CPU_FTR_COHERENT_ICACHE | \
            CPU_FTR_PURR | CPU_FTR_SPURR | CPU_FTR_REAL_LE | \
            CPU_FTR_DSCR | CPU_FTR_UNALIGNED_LD_STD | \
-           CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_CFAR)
+           CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_CFAR | \
+           CPU_FTR_DABRX)
 #define CPU_FTRS_POWER7 (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
            CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | CPU_FTR_ARCH_206 |\
            CPU_FTR_MMCRA | CPU_FTR_SMT | \
@@ -415,7 +417,7 @@ extern const char *powerpc_base_platform;
            CPU_FTR_DSCR | CPU_FTR_SAO  | CPU_FTR_ASYM_SMT | \
            CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \
            CPU_FTR_ICSWX | CPU_FTR_CFAR | CPU_FTR_HVMODE | \
-           CPU_FTR_VMX_COPY | CPU_FTR_HAS_PPR)
+           CPU_FTR_VMX_COPY | CPU_FTR_HAS_PPR | CPU_FTR_DABRX)
 #define CPU_FTRS_POWER8 (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
            CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | CPU_FTR_ARCH_206 |\
            CPU_FTR_MMCRA | CPU_FTR_SMT | \
@@ -430,14 +432,15 @@ extern const char *powerpc_base_platform;
            CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
            CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \
            CPU_FTR_PAUSE_ZERO  | CPU_FTR_CELL_TB_BUG | CPU_FTR_CP_USE_DCBTZ | \
-           CPU_FTR_UNALIGNED_LD_STD)
+           CPU_FTR_UNALIGNED_LD_STD | CPU_FTR_DABRX)
 #define CPU_FTRS_PA6T (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
            CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_ALTIVEC_COMP | \
-           CPU_FTR_PURR | CPU_FTR_REAL_LE)
+           CPU_FTR_PURR | CPU_FTR_REAL_LE | CPU_FTR_DABRX)
 #define CPU_FTRS_COMPATIBLE    (CPU_FTR_USE_TB | CPU_FTR_PPCAS_ARCH_V2)
 
 #define CPU_FTRS_A2 (CPU_FTR_USE_TB | CPU_FTR_SMT | CPU_FTR_DBELL | \
-                    CPU_FTR_NOEXECUTE | CPU_FTR_NODSISRALIGN | CPU_FTR_ICSWX)
+                    CPU_FTR_NOEXECUTE | CPU_FTR_NODSISRALIGN | \
+                    CPU_FTR_ICSWX | CPU_FTR_DABRX )
 
 #ifdef __powerpc64__
 #ifdef CONFIG_PPC_BOOK3E
index 1f0937d..2a45d0f 100644 (file)
@@ -452,8 +452,8 @@ static struct cpu_spec __initdata cpu_specs[] = {
                .mmu_features           = MMU_FTRS_POWER8,
                .icache_bsize           = 128,
                .dcache_bsize           = 128,
-               .oprofile_type          = PPC_OPROFILE_POWER4,
-               .oprofile_cpu_type      = 0,
+               .oprofile_type          = PPC_OPROFILE_INVALID,
+               .oprofile_cpu_type      = "ppc64/ibm-compat-v1",
                .cpu_setup              = __setup_cpu_power8,
                .cpu_restore            = __restore_cpu_power8,
                .platform               = "power8",
@@ -506,8 +506,8 @@ static struct cpu_spec __initdata cpu_specs[] = {
                .dcache_bsize           = 128,
                .num_pmcs               = 6,
                .pmc_type               = PPC_PMC_IBM,
-               .oprofile_cpu_type      = 0,
-               .oprofile_type          = PPC_OPROFILE_POWER4,
+               .oprofile_cpu_type      = "ppc64/power8",
+               .oprofile_type          = PPC_OPROFILE_INVALID,
                .cpu_setup              = __setup_cpu_power8,
                .cpu_restore            = __restore_cpu_power8,
                .platform               = "power8",
index 246b11c..8741c85 100644 (file)
@@ -465,20 +465,6 @@ BEGIN_FTR_SECTION
        std     r0, THREAD_EBBHR(r3)
        mfspr   r0, SPRN_EBBRR
        std     r0, THREAD_EBBRR(r3)
-
-       /* PMU registers made user read/(write) by EBB */
-       mfspr   r0, SPRN_SIAR
-       std     r0, THREAD_SIAR(r3)
-       mfspr   r0, SPRN_SDAR
-       std     r0, THREAD_SDAR(r3)
-       mfspr   r0, SPRN_SIER
-       std     r0, THREAD_SIER(r3)
-       mfspr   r0, SPRN_MMCR0
-       std     r0, THREAD_MMCR0(r3)
-       mfspr   r0, SPRN_MMCR2
-       std     r0, THREAD_MMCR2(r3)
-       mfspr   r0, SPRN_MMCRA
-       std     r0, THREAD_MMCRA(r3)
 END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
 #endif
 
@@ -581,20 +567,6 @@ BEGIN_FTR_SECTION
        ld      r0, THREAD_EBBRR(r4)
        mtspr   SPRN_EBBRR, r0
 
-       /* PMU registers made user read/(write) by EBB */
-       ld      r0, THREAD_SIAR(r4)
-       mtspr   SPRN_SIAR, r0
-       ld      r0, THREAD_SDAR(r4)
-       mtspr   SPRN_SDAR, r0
-       ld      r0, THREAD_SIER(r4)
-       mtspr   SPRN_SIER, r0
-       ld      r0, THREAD_MMCR0(r4)
-       mtspr   SPRN_MMCR0, r0
-       ld      r0, THREAD_MMCR2(r4)
-       mtspr   SPRN_MMCR2, r0
-       ld      r0, THREAD_MMCRA(r4)
-       mtspr   SPRN_MMCRA, r0
-
        ld      r0,THREAD_TAR(r4)
        mtspr   SPRN_TAR,r0
 END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
index e6eba1b..e783453 100644 (file)
@@ -454,38 +454,14 @@ BEGIN_FTR_SECTION
        xori    r10,r10,(MSR_FE0|MSR_FE1)
        mtmsrd  r10
        sync
-       fmr     0,0
-       fmr     1,1
-       fmr     2,2
-       fmr     3,3
-       fmr     4,4
-       fmr     5,5
-       fmr     6,6
-       fmr     7,7
-       fmr     8,8
-       fmr     9,9
-       fmr     10,10
-       fmr     11,11
-       fmr     12,12
-       fmr     13,13
-       fmr     14,14
-       fmr     15,15
-       fmr     16,16
-       fmr     17,17
-       fmr     18,18
-       fmr     19,19
-       fmr     20,20
-       fmr     21,21
-       fmr     22,22
-       fmr     23,23
-       fmr     24,24
-       fmr     25,25
-       fmr     26,26
-       fmr     27,27
-       fmr     28,28
-       fmr     29,29
-       fmr     30,30
-       fmr     31,31
+
+#define FMR2(n)  fmr (n), (n) ; fmr n+1, n+1
+#define FMR4(n)  FMR2(n) ; FMR2(n+2)
+#define FMR8(n)  FMR4(n) ; FMR4(n+4)
+#define FMR16(n) FMR8(n) ; FMR8(n+8)
+#define FMR32(n) FMR16(n) ; FMR16(n+16)
+       FMR32(0)
+
 FTR_SECTION_ELSE
 /*
  * To denormalise we need to move a copy of the register to itself.
@@ -495,39 +471,25 @@ FTR_SECTION_ELSE
        oris    r10,r10,MSR_VSX@h
        mtmsrd  r10
        sync
-       XVCPSGNDP(0,0,0)
-       XVCPSGNDP(1,1,1)
-       XVCPSGNDP(2,2,2)
-       XVCPSGNDP(3,3,3)
-       XVCPSGNDP(4,4,4)
-       XVCPSGNDP(5,5,5)
-       XVCPSGNDP(6,6,6)
-       XVCPSGNDP(7,7,7)
-       XVCPSGNDP(8,8,8)
-       XVCPSGNDP(9,9,9)
-       XVCPSGNDP(10,10,10)
-       XVCPSGNDP(11,11,11)
-       XVCPSGNDP(12,12,12)
-       XVCPSGNDP(13,13,13)
-       XVCPSGNDP(14,14,14)
-       XVCPSGNDP(15,15,15)
-       XVCPSGNDP(16,16,16)
-       XVCPSGNDP(17,17,17)
-       XVCPSGNDP(18,18,18)
-       XVCPSGNDP(19,19,19)
-       XVCPSGNDP(20,20,20)
-       XVCPSGNDP(21,21,21)
-       XVCPSGNDP(22,22,22)
-       XVCPSGNDP(23,23,23)
-       XVCPSGNDP(24,24,24)
-       XVCPSGNDP(25,25,25)
-       XVCPSGNDP(26,26,26)
-       XVCPSGNDP(27,27,27)
-       XVCPSGNDP(28,28,28)
-       XVCPSGNDP(29,29,29)
-       XVCPSGNDP(30,30,30)
-       XVCPSGNDP(31,31,31)
+
+#define XVCPSGNDP2(n) XVCPSGNDP(n,n,n) ; XVCPSGNDP(n+1,n+1,n+1)
+#define XVCPSGNDP4(n) XVCPSGNDP2(n) ; XVCPSGNDP2(n+2)
+#define XVCPSGNDP8(n) XVCPSGNDP4(n) ; XVCPSGNDP4(n+4)
+#define XVCPSGNDP16(n) XVCPSGNDP8(n) ; XVCPSGNDP8(n+8)
+#define XVCPSGNDP32(n) XVCPSGNDP16(n) ; XVCPSGNDP16(n+16)
+       XVCPSGNDP32(0)
+
 ALT_FTR_SECTION_END_IFCLR(CPU_FTR_ARCH_206)
+
+BEGIN_FTR_SECTION
+       b       denorm_done
+END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_207S)
+/*
+ * To denormalise we need to move a copy of the register to itself.
+ * For POWER8 we need to do that for all 64 VSX registers
+ */
+       XVCPSGNDP32(32)
+denorm_done:
        mtspr   SPRN_HSRR0,r11
        mtcrf   0x80,r9
        ld      r9,PACA_EXGEN+EX_R9(r13)
index 7f2273c..eabeec9 100644 (file)
@@ -827,6 +827,7 @@ static void pcibios_fixup_resources(struct pci_dev *dev)
        }
        for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
                struct resource *res = dev->resource + i;
+               struct pci_bus_region reg;
                if (!res->flags)
                        continue;
 
@@ -835,8 +836,9 @@ static void pcibios_fixup_resources(struct pci_dev *dev)
                 * at 0 as unset as well, except if PCI_PROBE_ONLY is also set
                 * since in that case, we don't want to re-assign anything
                 */
+               pcibios_resource_to_bus(dev, &reg, res);
                if (pci_has_flag(PCI_REASSIGN_ALL_RSRC) ||
-                   (res->start == 0 && !pci_has_flag(PCI_PROBE_ONLY))) {
+                   (reg.start == 0 && !pci_has_flag(PCI_PROBE_ONLY))) {
                        /* Only print message if not re-assigning */
                        if (!pci_has_flag(PCI_REASSIGN_ALL_RSRC))
                                pr_debug("PCI:%s Resource %d %016llx-%016llx [%x] "
index a902723..b0f3e3f 100644 (file)
@@ -399,7 +399,8 @@ static inline int __set_dabr(unsigned long dabr, unsigned long dabrx)
 static inline int __set_dabr(unsigned long dabr, unsigned long dabrx)
 {
        mtspr(SPRN_DABR, dabr);
-       mtspr(SPRN_DABRX, dabrx);
+       if (cpu_has_feature(CPU_FTR_DABRX))
+               mtspr(SPRN_DABRX, dabrx);
        return 0;
 }
 #else
index 845c867..29c6482 100644 (file)
@@ -1758,7 +1758,7 @@ static void perf_event_interrupt(struct pt_regs *regs)
                        }
                }
        }
-       if ((!found) && printk_ratelimit())
+       if (!found && !nmi && printk_ratelimit())
                printk(KERN_WARNING "Can't find PMC that caused IRQ\n");
 
        /*
index 19506f9..b456b15 100644 (file)
@@ -83,7 +83,11 @@ static int pseries_eeh_init(void)
        ibm_configure_pe                = rtas_token("ibm,configure-pe");
        ibm_configure_bridge            = rtas_token("ibm,configure-bridge");
 
-       /* necessary sanity check */
+       /*
+        * Necessary sanity check. We needn't check "get-config-addr-info"
+        * and its variant since the old firmware probably support address
+        * of domain/bus/slot/function for EEH RTAS operations.
+        */
        if (ibm_set_eeh_option == RTAS_UNKNOWN_SERVICE) {
                pr_warning("%s: RTAS service <ibm,set-eeh-option> invalid\n",
                        __func__);
@@ -102,12 +106,6 @@ static int pseries_eeh_init(void)
                pr_warning("%s: RTAS service <ibm,slot-error-detail> invalid\n",
                        __func__);
                return -EINVAL;
-       } else if (ibm_get_config_addr_info2 == RTAS_UNKNOWN_SERVICE &&
-                  ibm_get_config_addr_info == RTAS_UNKNOWN_SERVICE) {
-               pr_warning("%s: RTAS service <ibm,get-config-addr-info2> and "
-                       "<ibm,get-config-addr-info> invalid\n",
-                       __func__);
-               return -EINVAL;
        } else if (ibm_configure_pe == RTAS_UNKNOWN_SERVICE &&
                   ibm_configure_bridge == RTAS_UNKNOWN_SERVICE) {
                pr_warning("%s: RTAS service <ibm,configure-pe> and "
index bae0f40..87a2209 100644 (file)
@@ -212,7 +212,9 @@ appldata_timer_handler(ctl_table *ctl, int write,
                return 0;
        }
        if (!write) {
-               len = sprintf(buf, appldata_timer_active ? "1\n" : "0\n");
+               strncpy(buf, appldata_timer_active ? "1\n" : "0\n",
+                       ARRAY_SIZE(buf));
+               len = strnlen(buf, ARRAY_SIZE(buf));
                if (len > *lenp)
                        len = *lenp;
                if (copy_to_user(buffer, buf, len))
@@ -317,7 +319,8 @@ appldata_generic_handler(ctl_table *ctl, int write,
                return 0;
        }
        if (!write) {
-               len = sprintf(buf, ops->active ? "1\n" : "0\n");
+               strncpy(buf, ops->active ? "1\n" : "0\n", ARRAY_SIZE(buf));
+               len = strnlen(buf, ARRAY_SIZE(buf));
                if (len > *lenp)
                        len = *lenp;
                if (copy_to_user(buffer, buf, len)) {
index 9411db6..886ac7d 100644 (file)
@@ -71,8 +71,8 @@ static inline void dma_free_coherent(struct device *dev, size_t size,
 {
        struct dma_map_ops *dma_ops = get_dma_ops(dev);
 
-       dma_ops->free(dev, size, cpu_addr, dma_handle, NULL);
        debug_dma_free_coherent(dev, size, cpu_addr, dma_handle);
+       dma_ops->free(dev, size, cpu_addr, dma_handle, NULL);
 }
 
 #endif /* _ASM_S390_DMA_MAPPING_H */
index 379d96e..fd9be01 100644 (file)
@@ -36,6 +36,7 @@ static inline void * phys_to_virt(unsigned long address)
 }
 
 void *xlate_dev_mem_ptr(unsigned long phys);
+#define xlate_dev_mem_ptr xlate_dev_mem_ptr
 void unxlate_dev_mem_ptr(unsigned long phys, void *addr);
 
 /*
index 0f0de30..ac01463 100644 (file)
@@ -646,7 +646,7 @@ static inline pgste_t pgste_update_all(pte_t *ptep, pgste_t pgste)
        unsigned long address, bits;
        unsigned char skey;
 
-       if (!pte_present(*ptep))
+       if (pte_val(*ptep) & _PAGE_INVALID)
                return pgste;
        address = pte_val(*ptep) & PAGE_MASK;
        skey = page_get_storage_key(address);
@@ -680,7 +680,7 @@ static inline pgste_t pgste_update_young(pte_t *ptep, pgste_t pgste)
 #ifdef CONFIG_PGSTE
        int young;
 
-       if (!pte_present(*ptep))
+       if (pte_val(*ptep) & _PAGE_INVALID)
                return pgste;
        /* Get referenced bit from storage key */
        young = page_reset_referenced(pte_val(*ptep) & PAGE_MASK);
@@ -706,7 +706,7 @@ static inline void pgste_set_key(pte_t *ptep, pgste_t pgste, pte_t entry)
        unsigned long address;
        unsigned long okey, nkey;
 
-       if (!pte_present(entry))
+       if (pte_val(entry) & _PAGE_INVALID)
                return;
        address = pte_val(entry) & PAGE_MASK;
        okey = nkey = page_get_storage_key(address);
@@ -1098,6 +1098,9 @@ static inline pte_t ptep_modify_prot_start(struct mm_struct *mm,
        pte = *ptep;
        if (!mm_exclusive(mm))
                __ptep_ipte(address, ptep);
+
+       if (mm_has_pgste(mm))
+               pgste = pgste_update_all(&pte, pgste);
        return pte;
 }
 
@@ -1105,9 +1108,13 @@ static inline void ptep_modify_prot_commit(struct mm_struct *mm,
                                           unsigned long address,
                                           pte_t *ptep, pte_t pte)
 {
+       pgste_t pgste;
+
        if (mm_has_pgste(mm)) {
+               pgste = *(pgste_t *)(ptep + PTRS_PER_PTE);
+               pgste_set_key(ptep, pgste, pte);
                pgste_set_pte(ptep, pte);
-               pgste_set_unlock(ptep, *(pgste_t *)(ptep + PTRS_PER_PTE));
+               pgste_set_unlock(ptep, pgste);
        } else
                *ptep = pte;
 }
index 05674b6..4f977d0 100644 (file)
@@ -428,34 +428,27 @@ void smp_stop_cpu(void)
  * This is the main routine where commands issued by other
  * cpus are handled.
  */
-static void do_ext_call_interrupt(struct ext_code ext_code,
-                                 unsigned int param32, unsigned long param64)
+static void smp_handle_ext_call(void)
 {
        unsigned long bits;
-       int cpu;
-
-       cpu = smp_processor_id();
-       if (ext_code.code == 0x1202)
-               inc_irq_stat(IRQEXT_EXC);
-       else
-               inc_irq_stat(IRQEXT_EMS);
-       /*
-        * handle bit signal external calls
-        */
-       bits = xchg(&pcpu_devices[cpu].ec_mask, 0);
 
+       /* handle bit signal external calls */
+       bits = xchg(&pcpu_devices[smp_processor_id()].ec_mask, 0);
        if (test_bit(ec_stop_cpu, &bits))
                smp_stop_cpu();
-
        if (test_bit(ec_schedule, &bits))
                scheduler_ipi();
-
        if (test_bit(ec_call_function, &bits))
                generic_smp_call_function_interrupt();
-
        if (test_bit(ec_call_function_single, &bits))
                generic_smp_call_function_single_interrupt();
+}
 
+static void do_ext_call_interrupt(struct ext_code ext_code,
+                                 unsigned int param32, unsigned long param64)
+{
+       inc_irq_stat(ext_code.code == 0x1202 ? IRQEXT_EXC : IRQEXT_EMS);
+       smp_handle_ext_call();
 }
 
 void arch_send_call_function_ipi_mask(const struct cpumask *mask)
@@ -760,6 +753,8 @@ int __cpu_disable(void)
 {
        unsigned long cregs[16];
 
+       /* Handle possible pending IPIs */
+       smp_handle_ext_call();
        set_cpu_online(smp_processor_id(), false);
        /* Disable pseudo page faults on this cpu. */
        pfault_fini();
index 18dc417..a938b54 100644 (file)
@@ -492,7 +492,7 @@ static int gmap_connect_pgtable(unsigned long address, unsigned long segment,
        mp = (struct gmap_pgtable *) page->index;
        rmap->gmap = gmap;
        rmap->entry = segment_ptr;
-       rmap->vmaddr = address;
+       rmap->vmaddr = address & PMD_MASK;
        spin_lock(&mm->page_table_lock);
        if (*segment_ptr == segment) {
                list_add(&rmap->list, &mp->mapper);
index 8db0010..5953dce 100644 (file)
@@ -1240,9 +1240,12 @@ static int decode_modrm(struct x86_emulate_ctxt *ctxt,
        ctxt->modrm_seg = VCPU_SREG_DS;
 
        if (ctxt->modrm_mod == 3) {
+               int highbyte_regs = ctxt->rex_prefix == 0;
+
                op->type = OP_REG;
                op->bytes = (ctxt->d & ByteOp) ? 1 : ctxt->op_bytes;
-               op->addr.reg = decode_register(ctxt, ctxt->modrm_rm, ctxt->d & ByteOp);
+               op->addr.reg = decode_register(ctxt, ctxt->modrm_rm,
+                                              highbyte_regs && (ctxt->d & ByteOp));
                if (ctxt->d & Sse) {
                        op->type = OP_XMM;
                        op->bytes = 16;
@@ -3997,7 +4000,8 @@ static const struct opcode twobyte_table[256] = {
        DI(ImplicitOps | Priv, invd), DI(ImplicitOps | Priv, wbinvd), N, N,
        N, D(ImplicitOps | ModRM), N, N,
        /* 0x10 - 0x1F */
-       N, N, N, N, N, N, N, N, D(ImplicitOps | ModRM), N, N, N, N, N, N, N,
+       N, N, N, N, N, N, N, N,
+       D(ImplicitOps | ModRM), N, N, N, N, N, N, D(ImplicitOps | ModRM),
        /* 0x20 - 0x2F */
        DIP(ModRM | DstMem | Priv | Op3264, cr_read, check_cr_read),
        DIP(ModRM | DstMem | Priv | Op3264, dr_read, check_dr_read),
@@ -4836,6 +4840,7 @@ twobyte_insn:
        case 0x08:              /* invd */
        case 0x0d:              /* GrpP (prefetch) */
        case 0x18:              /* Grp16 (prefetch/nop) */
+       case 0x1f:              /* nop */
                break;
        case 0x20: /* mov cr, reg */
                ctxt->dst.val = ops->get_cr(ctxt, ctxt->modrm_reg);
index e1adbb4..0eee2c8 100644 (file)
@@ -1861,11 +1861,14 @@ void kvm_apic_accept_events(struct kvm_vcpu *vcpu)
 {
        struct kvm_lapic *apic = vcpu->arch.apic;
        unsigned int sipi_vector;
+       unsigned long pe;
 
-       if (!kvm_vcpu_has_lapic(vcpu))
+       if (!kvm_vcpu_has_lapic(vcpu) || !apic->pending_events)
                return;
 
-       if (test_and_clear_bit(KVM_APIC_INIT, &apic->pending_events)) {
+       pe = xchg(&apic->pending_events, 0);
+
+       if (test_bit(KVM_APIC_INIT, &pe)) {
                kvm_lapic_reset(vcpu);
                kvm_vcpu_reset(vcpu);
                if (kvm_vcpu_is_bsp(apic->vcpu))
@@ -1873,7 +1876,7 @@ void kvm_apic_accept_events(struct kvm_vcpu *vcpu)
                else
                        vcpu->arch.mp_state = KVM_MP_STATE_INIT_RECEIVED;
        }
-       if (test_and_clear_bit(KVM_APIC_SIPI, &apic->pending_events) &&
+       if (test_bit(KVM_APIC_SIPI, &pe) &&
            vcpu->arch.mp_state == KVM_MP_STATE_INIT_RECEIVED) {
                /* evaluate pending_events before reading the vector */
                smp_rmb();
index 305c68b..981c2db 100644 (file)
@@ -628,7 +628,9 @@ int pcibios_add_device(struct pci_dev *dev)
 
        pa_data = boot_params.hdr.setup_data;
        while (pa_data) {
-               data = phys_to_virt(pa_data);
+               data = ioremap(pa_data, sizeof(*rom));
+               if (!data)
+                       return -ENOMEM;
 
                if (data->type == SETUP_PCI) {
                        rom = (struct pci_setup_rom *)data;
@@ -645,6 +647,7 @@ int pcibios_add_device(struct pci_dev *dev)
                        }
                }
                pa_data = data->next;
+               iounmap(data);
        }
        return 0;
 }
index 622d8a4..bf8148e 100644 (file)
@@ -823,6 +823,7 @@ config CRYPTO_BLOWFISH_X86_64
 config CRYPTO_BLOWFISH_AVX2_X86_64
        tristate "Blowfish cipher algorithm (x86_64/AVX2)"
        depends on X86 && 64BIT
+       depends on BROKEN
        select CRYPTO_ALGAPI
        select CRYPTO_CRYPTD
        select CRYPTO_ABLK_HELPER_X86
@@ -1299,6 +1300,7 @@ config CRYPTO_TWOFISH_AVX_X86_64
 config CRYPTO_TWOFISH_AVX2_X86_64
        tristate "Twofish cipher algorithm (x86_64/AVX2)"
        depends on X86 && 64BIT
+       depends on BROKEN
        select CRYPTO_ALGAPI
        select CRYPTO_CRYPTD
        select CRYPTO_ABLK_HELPER_X86
index 403baf4..fcd7d91 100644 (file)
@@ -919,13 +919,14 @@ static int ghes_probe(struct platform_device *ghes_dev)
                break;
        case ACPI_HEST_NOTIFY_EXTERNAL:
                /* External interrupt vector is GSI */
-               if (acpi_gsi_to_irq(generic->notify.vector, &ghes->irq)) {
+               rc = acpi_gsi_to_irq(generic->notify.vector, &ghes->irq);
+               if (rc) {
                        pr_err(GHES_PFX "Failed to map GSI to IRQ for generic hardware error source: %d\n",
                               generic->header.source_id);
                        goto err_edac_unreg;
                }
-               if (request_irq(ghes->irq, ghes_irq_func,
-                               0, "GHES IRQ", ghes)) {
+               rc = request_irq(ghes->irq, ghes_irq_func, 0, "GHES IRQ", ghes);
+               if (rc) {
                        pr_err(GHES_PFX "Failed to register IRQ for generic hardware error source: %d\n",
                               generic->header.source_id);
                        goto err_edac_unreg;
index bc493aa..318fa32 100644 (file)
@@ -278,11 +278,13 @@ int acpi_bus_init_power(struct acpi_device *device)
                if (result)
                        return result;
        } else if (state == ACPI_STATE_UNKNOWN) {
-               /* No power resources and missing _PSC? Try to force D0. */
+               /*
+                * No power resources and missing _PSC?  Cross fingers and make
+                * it D0 in hope that this is what the BIOS put the device into.
+                * [We tried to force D0 here by executing _PS0, but that broke
+                * Toshiba P870-303 in a nasty way.]
+                */
                state = ACPI_STATE_D0;
-               result = acpi_dev_pm_explicit_set(device, state);
-               if (result)
-                       return result;
        }
        device->power.state = state;
        return 0;
index 5b32e15..5d7075d 100644 (file)
@@ -456,6 +456,14 @@ static struct dmi_system_id video_dmi_table[] __initdata = {
                DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dm4 Notebook PC"),
                },
        },
+       {
+        .callback = video_ignore_initial_backlight,
+        .ident = "HP Pavilion g6 Notebook PC",
+        .matches = {
+                DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"),
+                DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion g6 Notebook PC"),
+               },
+       },
        {
         .callback = video_ignore_initial_backlight,
         .ident = "HP 1000 Notebook PC",
@@ -464,6 +472,14 @@ static struct dmi_system_id video_dmi_table[] __initdata = {
                DMI_MATCH(DMI_PRODUCT_NAME, "HP 1000 Notebook PC"),
                },
        },
+       {
+        .callback = video_ignore_initial_backlight,
+        .ident = "HP Pavilion m4",
+        .matches = {
+               DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"),
+               DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion m4 Notebook PC"),
+               },
+       },
        {}
 };
 
index 4e94ba2..9d0cf01 100644 (file)
@@ -2,7 +2,7 @@
 /*
  *  acard-ahci.c - ACard AHCI SATA support
  *
- *  Maintained by:  Jeff Garzik <jgarzik@pobox.com>
+ *  Maintained by:  Tejun Heo <tj@kernel.org>
  *                 Please ALWAYS copy linux-ide@vger.kernel.org
  *                 on emails.
  *
index 251e57d..2b50dfd 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  ahci.c - AHCI SATA support
  *
- *  Maintained by:  Jeff Garzik <jgarzik@pobox.com>
+ *  Maintained by:  Tejun Heo <tj@kernel.org>
  *                 Please ALWAYS copy linux-ide@vger.kernel.org
  *                 on emails.
  *
@@ -423,6 +423,8 @@ static const struct pci_device_id ahci_pci_tbl[] = {
          .driver_data = board_ahci_yes_fbs },                  /* 88se9125 */
        { PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x917a),
          .driver_data = board_ahci_yes_fbs },                  /* 88se9172 */
+       { PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x9172),
+         .driver_data = board_ahci_yes_fbs },                  /* 88se9172 */
        { PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x9192),
          .driver_data = board_ahci_yes_fbs },                  /* 88se9172 on some Gigabyte */
        { PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x91a3),
index b830e6c..10b14d4 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  ahci.h - Common AHCI SATA definitions and declarations
  *
- *  Maintained by:  Jeff Garzik <jgarzik@pobox.com>
+ *  Maintained by:  Tejun Heo <tj@kernel.org>
  *                 Please ALWAYS copy linux-ide@vger.kernel.org
  *                 on emails.
  *
index 2f48123..9a8a674 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *    ata_piix.c - Intel PATA/SATA controllers
  *
- *    Maintained by:  Jeff Garzik <jgarzik@pobox.com>
+ *    Maintained by:  Tejun Heo <tj@kernel.org>
  *                 Please ALWAYS copy linux-ide@vger.kernel.org
  *                 on emails.
  *
@@ -151,6 +151,7 @@ enum piix_controller_ids {
        piix_pata_vmw,                  /* PIIX4 for VMware, spurious DMA_ERR */
        ich8_sata_snb,
        ich8_2port_sata_snb,
+       ich8_2port_sata_byt,
 };
 
 struct piix_map_db {
@@ -334,6 +335,9 @@ static const struct pci_device_id piix_pci_tbl[] = {
        { 0x8086, 0x8d60, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_snb },
        /* SATA Controller IDE (Wellsburg) */
        { 0x8086, 0x8d68, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
+       /* SATA Controller IDE (BayTrail) */
+       { 0x8086, 0x0F20, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata_byt },
+       { 0x8086, 0x0F21, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata_byt },
 
        { }     /* terminate list */
 };
@@ -441,6 +445,7 @@ static const struct piix_map_db *piix_map_db_table[] = {
        [tolapai_sata]          = &tolapai_map_db,
        [ich8_sata_snb]         = &ich8_map_db,
        [ich8_2port_sata_snb]   = &ich8_2port_map_db,
+       [ich8_2port_sata_byt]   = &ich8_2port_map_db,
 };
 
 static struct pci_bits piix_enable_bits[] = {
@@ -1254,6 +1259,16 @@ static struct ata_port_info piix_port_info[] = {
                .udma_mask      = ATA_UDMA6,
                .port_ops       = &piix_sata_ops,
        },
+
+       [ich8_2port_sata_byt] =
+       {
+               .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 34c8216..a70ff15 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  libahci.c - Common AHCI SATA low-level routines
  *
- *  Maintained by:  Jeff Garzik <jgarzik@pobox.com>
+ *  Maintained by:  Tejun Heo <tj@kernel.org>
  *                 Please ALWAYS copy linux-ide@vger.kernel.org
  *                 on emails.
  *
index 63c743b..f218427 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  libata-core.c - helper library for ATA
  *
- *  Maintained by:  Jeff Garzik <jgarzik@pobox.com>
+ *  Maintained by:  Tejun Heo <tj@kernel.org>
  *                 Please ALWAYS copy linux-ide@vger.kernel.org
  *                 on emails.
  *
@@ -1602,6 +1602,12 @@ unsigned ata_exec_internal_sg(struct ata_device *dev,
        qc->tf = *tf;
        if (cdb)
                memcpy(qc->cdb, cdb, ATAPI_CDB_LEN);
+
+       /* some SATA bridges need us to indicate data xfer direction */
+       if (tf->protocol == ATAPI_PROT_DMA && (dev->flags & ATA_DFLAG_DMADIR) &&
+           dma_dir == DMA_FROM_DEVICE)
+               qc->tf.feature |= ATAPI_DMADIR;
+
        qc->flags |= ATA_QCFLAG_RESULT_TF;
        qc->dma_dir = dma_dir;
        if (dma_dir != DMA_NONE) {
index f9476fb..c69fcce 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  libata-eh.c - libata error handling
  *
- *  Maintained by:  Jeff Garzik <jgarzik@pobox.com>
+ *  Maintained by:  Tejun Heo <tj@kernel.org>
  *                 Please ALWAYS copy linux-ide@vger.kernel.org
  *                 on emails.
  *
index dd310b2..0101af5 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  libata-scsi.c - helper library for ATA
  *
- *  Maintained by:  Jeff Garzik <jgarzik@pobox.com>
+ *  Maintained by:  Tejun Heo <tj@kernel.org>
  *                 Please ALWAYS copy linux-ide@vger.kernel.org
  *                 on emails.
  *
index d8af325..b603720 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  libata-sff.c - helper library for PCI IDE BMDMA
  *
- *  Maintained by:  Jeff Garzik <jgarzik@pobox.com>
+ *  Maintained by:  Tejun Heo <tj@kernel.org>
  *                 Please ALWAYS copy linux-ide@vger.kernel.org
  *                 on emails.
  *
index 5053333..8ea6e6a 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  pdc_adma.c - Pacific Digital Corporation ADMA
  *
- *  Maintained by:  Mark Lord <mlord@pobox.com>
+ *  Maintained by:  Tejun Heo <tj@kernel.org>
  *
  *  Copyright 2005 Mark Lord
  *
index fb0dd87..958ba2a 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  sata_promise.c - Promise SATA
  *
- *  Maintained by:  Jeff Garzik <jgarzik@pobox.com>
+ *  Maintained by:  Tejun Heo <tj@kernel.org>
  *                 Mikael Pettersson <mikpe@it.uu.se>
  *                 Please ALWAYS copy linux-ide@vger.kernel.org
  *                 on emails.
index 4799868..249c8a2 100644 (file)
@@ -549,6 +549,7 @@ static void sata_rcar_bmdma_start(struct ata_queued_cmd *qc)
 
        /* start host DMA transaction */
        dmactl = ioread32(priv->base + ATAPI_CONTROL1_REG);
+       dmactl &= ~ATAPI_CONTROL1_STOP;
        dmactl |= ATAPI_CONTROL1_START;
        iowrite32(dmactl, priv->base + ATAPI_CONTROL1_REG);
 }
@@ -618,17 +619,16 @@ static struct ata_port_operations sata_rcar_port_ops = {
        .bmdma_status           = sata_rcar_bmdma_status,
 };
 
-static int sata_rcar_serr_interrupt(struct ata_port *ap)
+static void sata_rcar_serr_interrupt(struct ata_port *ap)
 {
        struct sata_rcar_priv *priv = ap->host->private_data;
        struct ata_eh_info *ehi = &ap->link.eh_info;
        int freeze = 0;
-       int handled = 0;
        u32 serror;
 
        serror = ioread32(priv->base + SCRSERR_REG);
        if (!serror)
-               return 0;
+               return;
 
        DPRINTK("SError @host_intr: 0x%x\n", serror);
 
@@ -641,7 +641,6 @@ static int sata_rcar_serr_interrupt(struct ata_port *ap)
                ata_ehi_push_desc(ehi, "%s", "hotplug");
 
                freeze = serror & SERR_COMM_WAKE ? 0 : 1;
-               handled = 1;
        }
 
        /* freeze or abort */
@@ -649,11 +648,9 @@ static int sata_rcar_serr_interrupt(struct ata_port *ap)
                ata_port_freeze(ap);
        else
                ata_port_abort(ap);
-
-       return handled;
 }
 
-static int sata_rcar_ata_interrupt(struct ata_port *ap)
+static void sata_rcar_ata_interrupt(struct ata_port *ap)
 {
        struct ata_queued_cmd *qc;
        int handled = 0;
@@ -662,7 +659,9 @@ static int sata_rcar_ata_interrupt(struct ata_port *ap)
        if (qc)
                handled |= ata_bmdma_port_intr(ap, qc);
 
-       return handled;
+       /* be sure to clear ATA interrupt */
+       if (!handled)
+               sata_rcar_check_status(ap);
 }
 
 static irqreturn_t sata_rcar_interrupt(int irq, void *dev_instance)
@@ -677,20 +676,21 @@ static irqreturn_t sata_rcar_interrupt(int irq, void *dev_instance)
        spin_lock_irqsave(&host->lock, flags);
 
        sataintstat = ioread32(priv->base + SATAINTSTAT_REG);
+       sataintstat &= SATA_RCAR_INT_MASK;
        if (!sataintstat)
                goto done;
        /* ack */
-       iowrite32(sataintstat & ~SATA_RCAR_INT_MASK,
-                priv->base + SATAINTSTAT_REG);
+       iowrite32(~sataintstat & 0x7ff, priv->base + SATAINTSTAT_REG);
 
        ap = host->ports[0];
 
        if (sataintstat & SATAINTSTAT_ATA)
-               handled |= sata_rcar_ata_interrupt(ap);
+               sata_rcar_ata_interrupt(ap);
 
        if (sataintstat & SATAINTSTAT_SERR)
-               handled |= sata_rcar_serr_interrupt(ap);
+               sata_rcar_serr_interrupt(ap);
 
+       handled = 1;
 done:
        spin_unlock_irqrestore(&host->lock, flags);
 
index a7b3167..0ae3ca4 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  sata_sil.c - Silicon Image SATA
  *
- *  Maintained by:  Jeff Garzik <jgarzik@pobox.com>
+ *  Maintained by:  Tejun Heo <tj@kernel.org>
  *                 Please ALWAYS copy linux-ide@vger.kernel.org
  *                 on emails.
  *
index 7b7127a..9947010 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  sata_sx4.c - Promise SATA
  *
- *  Maintained by:  Jeff Garzik <jgarzik@pobox.com>
+ *  Maintained by:  Tejun Heo <tj@kernel.org>
  *                 Please ALWAYS copy linux-ide@vger.kernel.org
  *                 on emails.
  *
index 5913ea9..87f056e 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  sata_via.c - VIA Serial ATA controllers
  *
- *  Maintained by:  Jeff Garzik <jgarzik@pobox.com>
+ *  Maintained by:  Tejun Heo <tj@kernel.org>
  *                Please ALWAYS copy linux-ide@vger.kernel.org
  *                on emails.
  *
index 11b8b4b..edc089e 100644 (file)
@@ -347,11 +347,11 @@ static u32 get_cur_val(const struct cpumask *mask)
        switch (per_cpu(acfreq_data, cpumask_first(mask))->cpu_feature) {
        case SYSTEM_INTEL_MSR_CAPABLE:
                cmd.type = SYSTEM_INTEL_MSR_CAPABLE;
-               cmd.addr.msr.reg = MSR_IA32_PERF_STATUS;
+               cmd.addr.msr.reg = MSR_IA32_PERF_CTL;
                break;
        case SYSTEM_AMD_MSR_CAPABLE:
                cmd.type = SYSTEM_AMD_MSR_CAPABLE;
-               cmd.addr.msr.reg = MSR_AMD_PERF_STATUS;
+               cmd.addr.msr.reg = MSR_AMD_PERF_CTL;
                break;
        case SYSTEM_IO_CAPABLE:
                cmd.type = SYSTEM_IO_CAPABLE;
index a64eb8b..ad1fde2 100644 (file)
@@ -45,7 +45,7 @@ static int cpu0_set_target(struct cpufreq_policy *policy,
        struct cpufreq_freqs freqs;
        struct opp *opp;
        unsigned long volt = 0, volt_old = 0, tol = 0;
-       long freq_Hz;
+       long freq_Hz, freq_exact;
        unsigned int index;
        int ret;
 
@@ -60,6 +60,7 @@ static int cpu0_set_target(struct cpufreq_policy *policy,
        freq_Hz = clk_round_rate(cpu_clk, freq_table[index].frequency * 1000);
        if (freq_Hz < 0)
                freq_Hz = freq_table[index].frequency * 1000;
+       freq_exact = freq_Hz;
        freqs.new = freq_Hz / 1000;
        freqs.old = clk_get_rate(cpu_clk) / 1000;
 
@@ -98,7 +99,7 @@ static int cpu0_set_target(struct cpufreq_policy *policy,
                }
        }
 
-       ret = clk_set_rate(cpu_clk, freqs.new * 1000);
+       ret = clk_set_rate(cpu_clk, freq_exact);
        if (ret) {
                pr_err("failed to set clock rate: %d\n", ret);
                if (cpu_reg)
index 5af40ad..dc9b72e 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/tick.h>
 #include <linux/types.h>
 #include <linux/workqueue.h>
+#include <linux/cpu.h>
 
 #include "cpufreq_governor.h"
 
@@ -180,8 +181,10 @@ void gov_queue_work(struct dbs_data *dbs_data, struct cpufreq_policy *policy,
        if (!all_cpus) {
                __gov_queue_work(smp_processor_id(), dbs_data, delay);
        } else {
+               get_online_cpus();
                for_each_cpu(i, policy->cpus)
                        __gov_queue_work(i, dbs_data, delay);
+               put_online_cpus();
        }
 }
 EXPORT_SYMBOL_GPL(gov_queue_work);
index a97bb6c..c3dc1c0 100644 (file)
@@ -863,7 +863,7 @@ static struct of_device_id sahara_dt_ids[] = {
        { .compatible = "fsl,imx27-sahara" },
        { /* sentinel */ }
 };
-MODULE_DEVICE_TABLE(platform, sahara_dt_ids);
+MODULE_DEVICE_TABLE(of, sahara_dt_ids);
 
 static int sahara_probe(struct platform_device *pdev)
 {
index d8ce4ec..e88ded2 100644 (file)
@@ -716,8 +716,7 @@ static int dmatest_func(void *data)
                }
                dma_async_issue_pending(chan);
 
-               wait_event_freezable_timeout(done_wait,
-                                            done.done || kthread_should_stop(),
+               wait_event_freezable_timeout(done_wait, done.done,
                                             msecs_to_jiffies(params->timeout));
 
                status = dma_async_is_tx_complete(chan, cookie, NULL, NULL);
@@ -997,7 +996,6 @@ static void stop_threaded_test(struct dmatest_info *info)
 static int __restart_threaded_test(struct dmatest_info *info, bool run)
 {
        struct dmatest_params *params = &info->params;
-       int ret;
 
        /* Stop any running test first */
        __stop_threaded_test(info);
@@ -1012,13 +1010,23 @@ static int __restart_threaded_test(struct dmatest_info *info, bool run)
        memcpy(params, &info->dbgfs_params, sizeof(*params));
 
        /* Run test with new parameters */
-       ret = __run_threaded_test(info);
-       if (ret) {
-               __stop_threaded_test(info);
-               pr_err("dmatest: Can't run test\n");
+       return __run_threaded_test(info);
+}
+
+static bool __is_threaded_test_run(struct dmatest_info *info)
+{
+       struct dmatest_chan *dtc;
+
+       list_for_each_entry(dtc, &info->channels, node) {
+               struct dmatest_thread *thread;
+
+               list_for_each_entry(thread, &dtc->threads, node) {
+                       if (!thread->done)
+                               return true;
+               }
        }
 
-       return ret;
+       return false;
 }
 
 static ssize_t dtf_write_string(void *to, size_t available, loff_t *ppos,
@@ -1091,22 +1099,10 @@ static ssize_t dtf_read_run(struct file *file, char __user *user_buf,
 {
        struct dmatest_info *info = file->private_data;
        char buf[3];
-       struct dmatest_chan *dtc;
-       bool alive = false;
 
        mutex_lock(&info->lock);
-       list_for_each_entry(dtc, &info->channels, node) {
-               struct dmatest_thread *thread;
-
-               list_for_each_entry(thread, &dtc->threads, node) {
-                       if (!thread->done) {
-                               alive = true;
-                               break;
-                       }
-               }
-       }
 
-       if (alive) {
+       if (__is_threaded_test_run(info)) {
                buf[0] = 'Y';
        } else {
                __stop_threaded_test(info);
@@ -1132,7 +1128,12 @@ static ssize_t dtf_write_run(struct file *file, const char __user *user_buf,
 
        if (strtobool(buf, &bv) == 0) {
                mutex_lock(&info->lock);
-               ret = __restart_threaded_test(info, bv);
+
+               if (__is_threaded_test_run(info))
+                       ret = -EBUSY;
+               else
+                       ret = __restart_threaded_test(info, bv);
+
                mutex_unlock(&info->lock);
        }
 
index 1734fee..71bf4ec 100644 (file)
@@ -1566,10 +1566,12 @@ static void dma_tc_handle(struct d40_chan *d40c)
                        return;
                }
 
-               if (d40_queue_start(d40c) == NULL)
+               if (d40_queue_start(d40c) == NULL) {
                        d40c->busy = false;
-               pm_runtime_mark_last_busy(d40c->base->dev);
-               pm_runtime_put_autosuspend(d40c->base->dev);
+
+                       pm_runtime_mark_last_busy(d40c->base->dev);
+                       pm_runtime_put_autosuspend(d40c->base->dev);
+               }
 
                d40_desc_remove(d40d);
                d40_desc_done(d40c, d40d);
index a6a8643..8bcce78 100644 (file)
@@ -1054,7 +1054,7 @@ EXPORT_SYMBOL(drm_vblank_off);
  */
 void drm_vblank_pre_modeset(struct drm_device *dev, int crtc)
 {
-       /* vblank is not initialized (IRQ not installed ?) */
+       /* vblank is not initialized (IRQ not installed ?), or has been freed */
        if (!dev->num_crtcs)
                return;
        /*
@@ -1076,6 +1076,10 @@ void drm_vblank_post_modeset(struct drm_device *dev, int crtc)
 {
        unsigned long irqflags;
 
+       /* vblank is not initialized (IRQ not installed ?), or has been freed */
+       if (!dev->num_crtcs)
+               return;
+
        if (dev->vblank_inmodeset[crtc]) {
                spin_lock_irqsave(&dev->vbl_lock, irqflags);
                dev->vblank_disable_allowed = 1;
index a6cf8e8..970ad17 100644 (file)
@@ -91,14 +91,11 @@ i915_gem_wait_for_error(struct i915_gpu_error *error)
 {
        int ret;
 
-#define EXIT_COND (!i915_reset_in_progress(error))
+#define EXIT_COND (!i915_reset_in_progress(error) || \
+                  i915_terminally_wedged(error))
        if (EXIT_COND)
                return 0;
 
-       /* GPU is already declared terminally dead, give up. */
-       if (i915_terminally_wedged(error))
-               return -EIO;
-
        /*
         * Only wait 10 seconds for the gpu reset to complete to avoid hanging
         * userspace. If it takes that long something really bad is going on and
index ad1117b..56746dc 100644 (file)
@@ -7937,6 +7937,11 @@ intel_modeset_check_state(struct drm_device *dev)
                memset(&pipe_config, 0, sizeof(pipe_config));
                active = dev_priv->display.get_pipe_config(crtc,
                                                           &pipe_config);
+
+               /* hw state is inconsistent with the pipe A quirk */
+               if (crtc->pipe == PIPE_A && dev_priv->quirks & QUIRK_PIPEA_FORCE)
+                       active = crtc->active;
+
                WARN(crtc->active != active,
                     "crtc active state doesn't match with hw state "
                     "(expected %i, found %i)\n", crtc->active, active);
index f36f1ba..29412cc 100644 (file)
@@ -815,10 +815,10 @@ static const struct dmi_system_id intel_no_lvds[] = {
        },
        {
                .callback = intel_no_lvds_dmi_callback,
-               .ident = "Hewlett-Packard HP t5740e Thin Client",
+               .ident = "Hewlett-Packard HP t5740",
                .matches = {
                        DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "HP t5740e Thin Client"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, " t5740"),
                },
        },
        {
index d154284..4c47b44 100644 (file)
@@ -1776,7 +1776,7 @@ static void intel_sdvo_get_lvds_modes(struct drm_connector *connector)
         * Assume that the preferred modes are
         * arranged in priority order.
         */
-       intel_ddc_get_modes(connector, intel_sdvo->i2c);
+       intel_ddc_get_modes(connector, &intel_sdvo->ddc);
        if (list_empty(&connector->probed_modes) == false)
                goto end;
 
index 77b8a45..ee66bad 100644 (file)
@@ -1034,13 +1034,14 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc,
                        else
                                hi_pri_lvl = 5;
 
-                       WREG8(0x1fde, 0x06);
-                       WREG8(0x1fdf, hi_pri_lvl);
+                       WREG8(MGAREG_CRTCEXT_INDEX, 0x06);
+                       WREG8(MGAREG_CRTCEXT_DATA, hi_pri_lvl);
                } else {
+                       WREG8(MGAREG_CRTCEXT_INDEX, 0x06);
                        if (mdev->reg_1e24 >= 0x01)
-                               WREG8(0x1fdf, 0x03);
+                               WREG8(MGAREG_CRTCEXT_DATA, 0x03);
                        else
-                               WREG8(0x1fdf, 0x04);
+                               WREG8(MGAREG_CRTCEXT_DATA, 0x04);
                }
        }
        return 0;
index d0817d9..f02fd9f 100644 (file)
@@ -50,11 +50,16 @@ nv50_dac_sense(struct nv50_disp_priv *priv, int or, u32 loadval)
 {
        const u32 doff = (or * 0x800);
        int load = -EINVAL;
+       nv_mask(priv, 0x61a004 + doff, 0x807f0000, 0x80150000);
+       nv_wait(priv, 0x61a004 + doff, 0x80000000, 0x00000000);
        nv_wr32(priv, 0x61a00c + doff, 0x00100000 | loadval);
-       udelay(9500);
+       mdelay(9);
+       udelay(500);
        nv_wr32(priv, 0x61a00c + doff, 0x80000000);
        load = (nv_rd32(priv, 0x61a00c + doff) & 0x38000000) >> 27;
        nv_wr32(priv, 0x61a00c + doff, 0x00000000);
+       nv_mask(priv, 0x61a004 + doff, 0x807f0000, 0x80550000);
+       nv_wait(priv, 0x61a004 + doff, 0x80000000, 0x00000000);
        return load;
 }
 
index 0d36bdc..7fdade6 100644 (file)
@@ -55,6 +55,10 @@ nv84_hdmi_ctrl(struct nv50_disp_priv *priv, int head, int or, u32 data)
        nv_wr32(priv, 0x616510 + hoff, 0x00000000);
        nv_mask(priv, 0x616500 + hoff, 0x00000001, 0x00000001);
 
+       nv_mask(priv, 0x6165d0 + hoff, 0x00070001, 0x00010001); /* SPARE, HW_CTS */
+       nv_mask(priv, 0x616568 + hoff, 0x00010101, 0x00000000); /* ACR_CTRL, ?? */
+       nv_mask(priv, 0x616578 + hoff, 0x80000000, 0x80000000); /* ACR_0441_ENABLE */
+
        /* ??? */
        nv_mask(priv, 0x61733c, 0x00100000, 0x00100000); /* RESETF */
        nv_mask(priv, 0x61733c, 0x10000000, 0x10000000); /* LOOKUP_EN */
index 89bf459..e9b8217 100644 (file)
  * FIFO channel objects
  ******************************************************************************/
 
-void
-nv50_fifo_playlist_update(struct nv50_fifo_priv *priv)
+static void
+nv50_fifo_playlist_update_locked(struct nv50_fifo_priv *priv)
 {
        struct nouveau_bar *bar = nouveau_bar(priv);
        struct nouveau_gpuobj *cur;
        int i, p;
 
-       mutex_lock(&nv_subdev(priv)->mutex);
        cur = priv->playlist[priv->cur_playlist];
        priv->cur_playlist = !priv->cur_playlist;
 
@@ -61,6 +60,13 @@ nv50_fifo_playlist_update(struct nv50_fifo_priv *priv)
        nv_wr32(priv, 0x0032f4, cur->addr >> 12);
        nv_wr32(priv, 0x0032ec, p);
        nv_wr32(priv, 0x002500, 0x00000101);
+}
+
+void
+nv50_fifo_playlist_update(struct nv50_fifo_priv *priv)
+{
+       mutex_lock(&nv_subdev(priv)->mutex);
+       nv50_fifo_playlist_update_locked(priv);
        mutex_unlock(&nv_subdev(priv)->mutex);
 }
 
@@ -489,7 +495,7 @@ nv50_fifo_init(struct nouveau_object *object)
 
        for (i = 0; i < 128; i++)
                nv_wr32(priv, 0x002600 + (i * 4), 0x00000000);
-       nv50_fifo_playlist_update(priv);
+       nv50_fifo_playlist_update_locked(priv);
 
        nv_wr32(priv, 0x003200, 0x00000001);
        nv_wr32(priv, 0x003250, 0x00000001);
index 0a393f7..5a5961b 100644 (file)
@@ -218,7 +218,7 @@ struct nv04_display_class {
 #define NV50_DISP_DAC_PWR_STATE                                      0x00000040
 #define NV50_DISP_DAC_PWR_STATE_ON                                   0x00000000
 #define NV50_DISP_DAC_PWR_STATE_OFF                                  0x00000040
-#define NV50_DISP_DAC_LOAD                                           0x0002000c
+#define NV50_DISP_DAC_LOAD                                           0x00020100
 #define NV50_DISP_DAC_LOAD_VALUE                                     0x00000007
 
 #define NV50_DISP_PIOR_MTHD                                          0x00030000
index ebf0a68..dd5e01f 100644 (file)
@@ -1554,7 +1554,9 @@ nv50_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector)
 {
        struct nv50_disp *disp = nv50_disp(encoder->dev);
        int ret, or = nouveau_encoder(encoder)->or;
-       u32 load = 0;
+       u32 load = nouveau_drm(encoder->dev)->vbios.dactestval;
+       if (load == 0)
+               load = 340;
 
        ret = nv_exec(disp->core, NV50_DISP_DAC_LOAD + or, &load, sizeof(load));
        if (ret || load != 7)
index 44a7da6..8406c82 100644 (file)
@@ -667,6 +667,8 @@ atombios_digital_setup(struct drm_encoder *encoder, int action)
 int
 atombios_get_encoder_mode(struct drm_encoder *encoder)
 {
+       struct drm_device *dev = encoder->dev;
+       struct radeon_device *rdev = dev->dev_private;
        struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
        struct drm_connector *connector;
        struct radeon_connector *radeon_connector;
@@ -693,7 +695,8 @@ atombios_get_encoder_mode(struct drm_encoder *encoder)
        case DRM_MODE_CONNECTOR_DVII:
        case DRM_MODE_CONNECTOR_HDMIB: /* HDMI-B is basically DL-DVI; analog works fine */
                if (drm_detect_hdmi_monitor(radeon_connector->edid) &&
-                   radeon_audio)
+                   radeon_audio &&
+                   !ASIC_IS_DCE6(rdev)) /* remove once we support DCE6 */
                        return ATOM_ENCODER_MODE_HDMI;
                else if (radeon_connector->use_digital)
                        return ATOM_ENCODER_MODE_DVI;
@@ -704,7 +707,8 @@ atombios_get_encoder_mode(struct drm_encoder *encoder)
        case DRM_MODE_CONNECTOR_HDMIA:
        default:
                if (drm_detect_hdmi_monitor(radeon_connector->edid) &&
-                   radeon_audio)
+                   radeon_audio &&
+                   !ASIC_IS_DCE6(rdev)) /* remove once we support DCE6 */
                        return ATOM_ENCODER_MODE_HDMI;
                else
                        return ATOM_ENCODER_MODE_DVI;
@@ -718,7 +722,8 @@ atombios_get_encoder_mode(struct drm_encoder *encoder)
                    (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP))
                        return ATOM_ENCODER_MODE_DP;
                else if (drm_detect_hdmi_monitor(radeon_connector->edid) &&
-                        radeon_audio)
+                        radeon_audio &&
+                        !ASIC_IS_DCE6(rdev)) /* remove once we support DCE6 */
                        return ATOM_ENCODER_MODE_HDMI;
                else
                        return ATOM_ENCODER_MODE_DVI;
index 8546e3b..0f89ce3 100644 (file)
@@ -4754,6 +4754,12 @@ static int evergreen_startup(struct radeon_device *rdev)
                rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size = 0;
 
        /* Enable IRQ */
+       if (!rdev->irq.installed) {
+               r = radeon_irq_kms_init(rdev);
+               if (r)
+                       return r;
+       }
+
        r = r600_irq_init(rdev);
        if (r) {
                DRM_ERROR("radeon: IH init failed (%d).\n", r);
@@ -4923,10 +4929,6 @@ int evergreen_init(struct radeon_device *rdev)
        if (r)
                return r;
 
-       r = radeon_irq_kms_init(rdev);
-       if (r)
-               return r;
-
        rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ring_obj = NULL;
        r600_ring_init(rdev, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX], 1024 * 1024);
 
index 7969c0c..8458330 100644 (file)
@@ -2025,6 +2025,12 @@ static int cayman_startup(struct radeon_device *rdev)
        }
 
        /* Enable IRQ */
+       if (!rdev->irq.installed) {
+               r = radeon_irq_kms_init(rdev);
+               if (r)
+                       return r;
+       }
+
        r = r600_irq_init(rdev);
        if (r) {
                DRM_ERROR("radeon: IH init failed (%d).\n", r);
@@ -2190,10 +2196,6 @@ int cayman_init(struct radeon_device *rdev)
        if (r)
                return r;
 
-       r = radeon_irq_kms_init(rdev);
-       if (r)
-               return r;
-
        ring->ring_obj = NULL;
        r600_ring_init(rdev, ring, 1024 * 1024);
 
index 4973bff..d0314ec 100644 (file)
@@ -3869,6 +3869,12 @@ static int r100_startup(struct radeon_device *rdev)
        }
 
        /* Enable IRQ */
+       if (!rdev->irq.installed) {
+               r = radeon_irq_kms_init(rdev);
+               if (r)
+                       return r;
+       }
+
        r100_irq_set(rdev);
        rdev->config.r100.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL);
        /* 1M ring buffer */
@@ -4022,9 +4028,6 @@ int r100_init(struct radeon_device *rdev)
        r100_mc_init(rdev);
        /* Fence driver */
        r = radeon_fence_driver_init(rdev);
-       if (r)
-               return r;
-       r = radeon_irq_kms_init(rdev);
        if (r)
                return r;
        /* Memory manager */
index c60350e..b9b776f 100644 (file)
@@ -1382,6 +1382,12 @@ static int r300_startup(struct radeon_device *rdev)
        }
 
        /* Enable IRQ */
+       if (!rdev->irq.installed) {
+               r = radeon_irq_kms_init(rdev);
+               if (r)
+                       return r;
+       }
+
        r100_irq_set(rdev);
        rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL);
        /* 1M ring buffer */
@@ -1514,9 +1520,6 @@ int r300_init(struct radeon_device *rdev)
        r300_mc_init(rdev);
        /* Fence driver */
        r = radeon_fence_driver_init(rdev);
-       if (r)
-               return r;
-       r = radeon_irq_kms_init(rdev);
        if (r)
                return r;
        /* Memory manager */
index 6fce2eb..4e796ec 100644 (file)
@@ -265,6 +265,12 @@ static int r420_startup(struct radeon_device *rdev)
        }
 
        /* Enable IRQ */
+       if (!rdev->irq.installed) {
+               r = radeon_irq_kms_init(rdev);
+               if (r)
+                       return r;
+       }
+
        r100_irq_set(rdev);
        rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL);
        /* 1M ring buffer */
@@ -411,10 +417,6 @@ int r420_init(struct radeon_device *rdev)
        if (r) {
                return r;
        }
-       r = radeon_irq_kms_init(rdev);
-       if (r) {
-               return r;
-       }
        /* Memory manager */
        r = radeon_bo_init(rdev);
        if (r) {
index f795a4e..e1aece7 100644 (file)
@@ -194,6 +194,12 @@ static int r520_startup(struct radeon_device *rdev)
        }
 
        /* Enable IRQ */
+       if (!rdev->irq.installed) {
+               r = radeon_irq_kms_init(rdev);
+               if (r)
+                       return r;
+       }
+
        rs600_irq_set(rdev);
        rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL);
        /* 1M ring buffer */
@@ -295,9 +301,6 @@ int r520_init(struct radeon_device *rdev)
        rv515_debugfs(rdev);
        /* Fence driver */
        r = radeon_fence_driver_init(rdev);
-       if (r)
-               return r;
-       r = radeon_irq_kms_init(rdev);
        if (r)
                return r;
        /* Memory manager */
index b45e648..0e53416 100644 (file)
@@ -1046,6 +1046,24 @@ int r600_mc_wait_for_idle(struct radeon_device *rdev)
        return -1;
 }
 
+uint32_t rs780_mc_rreg(struct radeon_device *rdev, uint32_t reg)
+{
+       uint32_t r;
+
+       WREG32(R_0028F8_MC_INDEX, S_0028F8_MC_IND_ADDR(reg));
+       r = RREG32(R_0028FC_MC_DATA);
+       WREG32(R_0028F8_MC_INDEX, ~C_0028F8_MC_IND_ADDR);
+       return r;
+}
+
+void rs780_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v)
+{
+       WREG32(R_0028F8_MC_INDEX, S_0028F8_MC_IND_ADDR(reg) |
+               S_0028F8_MC_IND_WR_EN(1));
+       WREG32(R_0028FC_MC_DATA, v);
+       WREG32(R_0028F8_MC_INDEX, 0x7F);
+}
+
 static void r600_mc_program(struct radeon_device *rdev)
 {
        struct rv515_mc_save save;
@@ -1181,6 +1199,8 @@ static int r600_mc_init(struct radeon_device *rdev)
 {
        u32 tmp;
        int chansize, numchan;
+       uint32_t h_addr, l_addr;
+       unsigned long long k8_addr;
 
        /* Get VRAM informations */
        rdev->mc.vram_is_ddr = true;
@@ -1221,7 +1241,30 @@ static int r600_mc_init(struct radeon_device *rdev)
        if (rdev->flags & RADEON_IS_IGP) {
                rs690_pm_info(rdev);
                rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev);
+
+               if (rdev->family == CHIP_RS780 || rdev->family == CHIP_RS880) {
+                       /* Use K8 direct mapping for fast fb access. */
+                       rdev->fastfb_working = false;
+                       h_addr = G_000012_K8_ADDR_EXT(RREG32_MC(R_000012_MC_MISC_UMA_CNTL));
+                       l_addr = RREG32_MC(R_000011_K8_FB_LOCATION);
+                       k8_addr = ((unsigned long long)h_addr) << 32 | l_addr;
+#if defined(CONFIG_X86_32) && !defined(CONFIG_X86_PAE)
+                       if (k8_addr + rdev->mc.visible_vram_size < 0x100000000ULL)
+#endif
+                       {
+                               /* FastFB shall be used with UMA memory. Here it is simply disabled when sideport
+                               * memory is present.
+                               */
+                               if (rdev->mc.igp_sideport_enabled == false && radeon_fastfb == 1) {
+                                       DRM_INFO("Direct mapping: aper base at 0x%llx, replaced by direct mapping base 0x%llx.\n",
+                                               (unsigned long long)rdev->mc.aper_base, k8_addr);
+                                       rdev->mc.aper_base = (resource_size_t)k8_addr;
+                                       rdev->fastfb_working = true;
+                               }
+                       }
+               }
        }
+
        radeon_update_bandwidth_info(rdev);
        return 0;
 }
@@ -3202,6 +3245,12 @@ static int r600_startup(struct radeon_device *rdev)
        }
 
        /* Enable IRQ */
+       if (!rdev->irq.installed) {
+               r = radeon_irq_kms_init(rdev);
+               if (r)
+                       return r;
+       }
+
        r = r600_irq_init(rdev);
        if (r) {
                DRM_ERROR("radeon: IH init failed (%d).\n", r);
@@ -3356,10 +3405,6 @@ int r600_init(struct radeon_device *rdev)
        if (r)
                return r;
 
-       r = radeon_irq_kms_init(rdev);
-       if (r)
-               return r;
-
        rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ring_obj = NULL;
        r600_ring_init(rdev, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX], 1024 * 1024);
 
index acb146c..79df558 100644 (file)
 #define        PACKET3_STRMOUT_BASE_UPDATE                     0x72 /* r7xx */
 #define        PACKET3_SURFACE_BASE_UPDATE                     0x73
 
+#define R_000011_K8_FB_LOCATION                 0x11
+#define R_000012_MC_MISC_UMA_CNTL               0x12
+#define   G_000012_K8_ADDR_EXT(x)               (((x) >> 0) & 0xFF)
+#define R_0028F8_MC_INDEX                      0x28F8
+#define        S_0028F8_MC_IND_ADDR(x)                 (((x) & 0x1FF) << 0)
+#define        C_0028F8_MC_IND_ADDR                    0xFFFFFE00
+#define        S_0028F8_MC_IND_WR_EN(x)                (((x) & 0x1) << 9)
+#define R_0028FC_MC_DATA                        0x28FC
 
 #define        R_008020_GRBM_SOFT_RESET                0x8020
 #define                S_008020_SOFT_RESET_CP(x)               (((x) & 1) << 0)
index 06b8c19..a2802b4 100644 (file)
@@ -122,6 +122,10 @@ static void radeon_register_accessor_init(struct radeon_device *rdev)
                rdev->mc_rreg = &rs600_mc_rreg;
                rdev->mc_wreg = &rs600_mc_wreg;
        }
+       if (rdev->family == CHIP_RS780 || rdev->family == CHIP_RS880) {
+               rdev->mc_rreg = &rs780_mc_rreg;
+               rdev->mc_wreg = &rs780_mc_wreg;
+       }
        if (rdev->family >= CHIP_R600) {
                rdev->pciep_rreg = &r600_pciep_rreg;
                rdev->pciep_wreg = &r600_pciep_wreg;
index 2c87365..a72759e 100644 (file)
@@ -347,6 +347,8 @@ extern bool r600_gui_idle(struct radeon_device *rdev);
 extern void r600_pm_misc(struct radeon_device *rdev);
 extern void r600_pm_init_profile(struct radeon_device *rdev);
 extern void rs780_pm_init_profile(struct radeon_device *rdev);
+extern uint32_t rs780_mc_rreg(struct radeon_device *rdev, uint32_t reg);
+extern void rs780_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v);
 extern void r600_pm_get_dynpm_state(struct radeon_device *rdev);
 extern void r600_set_pcie_lanes(struct radeon_device *rdev, int lanes);
 extern int r600_get_pcie_lanes(struct radeon_device *rdev);
index 73051ce..233a9b9 100644 (file)
@@ -417,6 +417,12 @@ static int rs400_startup(struct radeon_device *rdev)
        }
 
        /* Enable IRQ */
+       if (!rdev->irq.installed) {
+               r = radeon_irq_kms_init(rdev);
+               if (r)
+                       return r;
+       }
+
        r100_irq_set(rdev);
        rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL);
        /* 1M ring buffer */
@@ -533,9 +539,6 @@ int rs400_init(struct radeon_device *rdev)
        rs400_mc_init(rdev);
        /* Fence driver */
        r = radeon_fence_driver_init(rdev);
-       if (r)
-               return r;
-       r = radeon_irq_kms_init(rdev);
        if (r)
                return r;
        /* Memory manager */
index 46fa1b0..670b555 100644 (file)
@@ -923,6 +923,12 @@ static int rs600_startup(struct radeon_device *rdev)
        }
 
        /* Enable IRQ */
+       if (!rdev->irq.installed) {
+               r = radeon_irq_kms_init(rdev);
+               if (r)
+                       return r;
+       }
+
        rs600_irq_set(rdev);
        rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL);
        /* 1M ring buffer */
@@ -1045,9 +1051,6 @@ int rs600_init(struct radeon_device *rdev)
        rs600_debugfs(rdev);
        /* Fence driver */
        r = radeon_fence_driver_init(rdev);
-       if (r)
-               return r;
-       r = radeon_irq_kms_init(rdev);
        if (r)
                return r;
        /* Memory manager */
index ab4c86c..55880d5 100644 (file)
@@ -651,6 +651,12 @@ static int rs690_startup(struct radeon_device *rdev)
        }
 
        /* Enable IRQ */
+       if (!rdev->irq.installed) {
+               r = radeon_irq_kms_init(rdev);
+               if (r)
+                       return r;
+       }
+
        rs600_irq_set(rdev);
        rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL);
        /* 1M ring buffer */
@@ -774,9 +780,6 @@ int rs690_init(struct radeon_device *rdev)
        rv515_debugfs(rdev);
        /* Fence driver */
        r = radeon_fence_driver_init(rdev);
-       if (r)
-               return r;
-       r = radeon_irq_kms_init(rdev);
        if (r)
                return r;
        /* Memory manager */
index ffcba73..21c7d7b 100644 (file)
@@ -532,6 +532,12 @@ static int rv515_startup(struct radeon_device *rdev)
        }
 
        /* Enable IRQ */
+       if (!rdev->irq.installed) {
+               r = radeon_irq_kms_init(rdev);
+               if (r)
+                       return r;
+       }
+
        rs600_irq_set(rdev);
        rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL);
        /* 1M ring buffer */
@@ -660,9 +666,6 @@ int rv515_init(struct radeon_device *rdev)
        rv515_debugfs(rdev);
        /* Fence driver */
        r = radeon_fence_driver_init(rdev);
-       if (r)
-               return r;
-       r = radeon_irq_kms_init(rdev);
        if (r)
                return r;
        /* Memory manager */
index 08aef24..4a62ad2 100644 (file)
@@ -1887,6 +1887,12 @@ static int rv770_startup(struct radeon_device *rdev)
                rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size = 0;
 
        /* Enable IRQ */
+       if (!rdev->irq.installed) {
+               r = radeon_irq_kms_init(rdev);
+               if (r)
+                       return r;
+       }
+
        r = r600_irq_init(rdev);
        if (r) {
                DRM_ERROR("radeon: IH init failed (%d).\n", r);
@@ -2045,10 +2051,6 @@ int rv770_init(struct radeon_device *rdev)
        if (r)
                return r;
 
-       r = radeon_irq_kms_init(rdev);
-       if (r)
-               return r;
-
        rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ring_obj = NULL;
        r600_ring_init(rdev, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX], 1024 * 1024);
 
index d1ba9d8..a1b0da6 100644 (file)
@@ -5350,6 +5350,12 @@ static int si_startup(struct radeon_device *rdev)
        }
 
        /* Enable IRQ */
+       if (!rdev->irq.installed) {
+               r = radeon_irq_kms_init(rdev);
+               if (r)
+                       return r;
+       }
+
        r = si_irq_init(rdev);
        if (r) {
                DRM_ERROR("radeon: IH init failed (%d).\n", r);
@@ -5533,10 +5539,6 @@ int si_init(struct radeon_device *rdev)
        if (r)
                return r;
 
-       r = radeon_irq_kms_init(rdev);
-       if (r)
-               return r;
-
        ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
        ring->ring_obj = NULL;
        r600_ring_init(rdev, ring, 1024 * 1024);
index e461e99..7a4d101 100644 (file)
@@ -6,6 +6,7 @@ config DRM_TILCDC
        select DRM_GEM_CMA_HELPER
        select VIDEOMODE_HELPERS
        select BACKLIGHT_CLASS_DEVICE
+       select BACKLIGHT_LCD_SUPPORT
        help
          Choose this option if you have an TI SoC with LCDC display
          controller, for example AM33xx in beagle-bone, DA8xx, or
index 7e76922..f920619 100644 (file)
@@ -331,26 +331,68 @@ static int adm1021_detect(struct i2c_client *client,
        man_id = i2c_smbus_read_byte_data(client, ADM1021_REG_MAN_ID);
        dev_id = i2c_smbus_read_byte_data(client, ADM1021_REG_DEV_ID);
 
+       if (man_id < 0 || dev_id < 0)
+               return -ENODEV;
+
        if (man_id == 0x4d && dev_id == 0x01)
                type_name = "max1617a";
        else if (man_id == 0x41) {
                if ((dev_id & 0xF0) == 0x30)
                        type_name = "adm1023";
-               else
+               else if ((dev_id & 0xF0) == 0x00)
                        type_name = "adm1021";
+               else
+                       return -ENODEV;
        } else if (man_id == 0x49)
                type_name = "thmc10";
        else if (man_id == 0x23)
                type_name = "gl523sm";
        else if (man_id == 0x54)
                type_name = "mc1066";
-       /* LM84 Mfr ID in a different place, and it has more unused bits */
-       else if (conv_rate == 0x00
-                && (config & 0x7F) == 0x00
-                && (status & 0xAB) == 0x00)
-               type_name = "lm84";
-       else
-               type_name = "max1617";
+       else {
+               int lte, rte, lhi, rhi, llo, rlo;
+
+               /* extra checks for LM84 and MAX1617 to avoid misdetections */
+
+               llo = i2c_smbus_read_byte_data(client, ADM1021_REG_THYST_R(0));
+               rlo = i2c_smbus_read_byte_data(client, ADM1021_REG_THYST_R(1));
+
+               /* fail if any of the additional register reads failed */
+               if (llo < 0 || rlo < 0)
+                       return -ENODEV;
+
+               lte = i2c_smbus_read_byte_data(client, ADM1021_REG_TEMP(0));
+               rte = i2c_smbus_read_byte_data(client, ADM1021_REG_TEMP(1));
+               lhi = i2c_smbus_read_byte_data(client, ADM1021_REG_TOS_R(0));
+               rhi = i2c_smbus_read_byte_data(client, ADM1021_REG_TOS_R(1));
+
+               /*
+                * Fail for negative temperatures and negative high limits.
+                * This check also catches read errors on the tested registers.
+                */
+               if ((s8)lte < 0 || (s8)rte < 0 || (s8)lhi < 0 || (s8)rhi < 0)
+                       return -ENODEV;
+
+               /* fail if all registers hold the same value */
+               if (lte == rte && lte == lhi && lte == rhi && lte == llo
+                   && lte == rlo)
+                       return -ENODEV;
+
+               /*
+                * LM84 Mfr ID is in a different place,
+                * and it has more unused bits.
+                */
+               if (conv_rate == 0x00
+                   && (config & 0x7F) == 0x00
+                   && (status & 0xAB) == 0x00) {
+                       type_name = "lm84";
+               } else {
+                       /* fail if low limits are larger than high limits */
+                       if ((s8)llo > lhi || (s8)rlo > rhi)
+                               return -ENODEV;
+                       type_name = "max1617";
+               }
+       }
 
        pr_debug("Detected chip %s at adapter %d, address 0x%02x.\n",
                 type_name, i2c_adapter_id(adapter), client->addr);
index 9201022..9d19ba7 100644 (file)
@@ -64,7 +64,7 @@ struct iio_cb_buffer *iio_channel_get_all_cb(struct device *dev,
        while (chan->indio_dev) {
                if (chan->indio_dev != indio_dev) {
                        ret = -EINVAL;
-                       goto error_release_channels;
+                       goto error_free_scan_mask;
                }
                set_bit(chan->channel->scan_index,
                        cb_buff->buffer.scan_mask);
@@ -73,6 +73,8 @@ struct iio_cb_buffer *iio_channel_get_all_cb(struct device *dev,
 
        return cb_buff;
 
+error_free_scan_mask:
+       kfree(cb_buff->buffer.scan_mask);
 error_release_channels:
        iio_channel_release_all(cb_buff->channels);
 error_free_cb_buff:
@@ -100,6 +102,7 @@ EXPORT_SYMBOL_GPL(iio_channel_stop_all_cb);
 
 void iio_channel_release_all_cb(struct iio_cb_buffer *cb_buff)
 {
+       kfree(cb_buff->buffer.scan_mask);
        iio_channel_release_all(cb_buff->channels);
        kfree(cb_buff);
 }
index a884252..e76d4ac 100644 (file)
@@ -212,7 +212,7 @@ static int adf4350_set_freq(struct adf4350_state *st, unsigned long long freq)
                (pdata->r2_user_settings & (ADF4350_REG2_PD_POLARITY_POS |
                ADF4350_REG2_LDP_6ns | ADF4350_REG2_LDF_INT_N |
                ADF4350_REG2_CHARGE_PUMP_CURR_uA(5000) |
-               ADF4350_REG2_MUXOUT(0x7) | ADF4350_REG2_NOISE_MODE(0x9)));
+               ADF4350_REG2_MUXOUT(0x7) | ADF4350_REG2_NOISE_MODE(0x3)));
 
        st->regs[ADF4350_REG3] = pdata->r3_user_settings &
                                 (ADF4350_REG3_12BIT_CLKDIV(0xFFF) |
index 795d100..98ddc32 100644 (file)
@@ -124,7 +124,7 @@ static int __of_iio_channel_get(struct iio_channel *channel,
        channel->indio_dev = indio_dev;
        index = iiospec.args_count ? iiospec.args[0] : 0;
        if (index >= indio_dev->num_channels) {
-               return -EINVAL;
+               err = -EINVAL;
                goto err_put;
        }
        channel->channel = &indio_dev->channels[index];
@@ -450,7 +450,7 @@ static int iio_convert_raw_to_processed_unlocked(struct iio_channel *chan,
        s64 raw64 = raw;
        int ret;
 
-       ret = iio_channel_read(chan, &offset, NULL, IIO_CHAN_INFO_SCALE);
+       ret = iio_channel_read(chan, &offset, NULL, IIO_CHAN_INFO_OFFSET);
        if (ret == 0)
                raw64 += offset;
 
index 81c7b73..3b9afcc 100644 (file)
@@ -61,7 +61,7 @@ int qib_alloc_lkey(struct qib_mregion *mr, int dma_region)
        if (dma_region) {
                struct qib_mregion *tmr;
 
-               tmr = rcu_dereference(dev->dma_mr);
+               tmr = rcu_access_pointer(dev->dma_mr);
                if (!tmr) {
                        qib_get_mr(mr);
                        rcu_assign_pointer(dev->dma_mr, mr);
index f19b099..2e84ef8 100644 (file)
@@ -5,6 +5,7 @@
  * Copyright (C) 2004 Alex Aizman
  * Copyright (C) 2005 Mike Christie
  * Copyright (c) 2005, 2006 Voltaire, Inc. All rights reserved.
+ * Copyright (c) 2013 Mellanox Technologies. All rights reserved.
  * maintained by openib-general@openib.org
  *
  * This software is available to you under a choice of one of two
index 06f578c..4f069c0 100644 (file)
@@ -8,6 +8,7 @@
  *
  * Copyright (c) 2004, 2005, 2006 Voltaire, Inc. All rights reserved.
  * Copyright (c) 2005, 2006 Cisco Systems.  All rights reserved.
+ * Copyright (c) 2013 Mellanox Technologies. All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
index a00ccd1..b6d81a8 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2004, 2005, 2006 Voltaire, Inc. All rights reserved.
+ * Copyright (c) 2013 Mellanox Technologies. All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
index 68ebb7f..7827baf 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2004, 2005, 2006 Voltaire, Inc. All rights reserved.
+ * Copyright (c) 2013 Mellanox Technologies. All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
index 5278916..2c4941d 100644 (file)
@@ -1,6 +1,7 @@
 /*
  * Copyright (c) 2004, 2005, 2006 Voltaire, Inc. All rights reserved.
  * Copyright (c) 2005, 2006 Cisco Systems.  All rights reserved.
+ * Copyright (c) 2013 Mellanox Technologies. All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
@@ -292,10 +293,10 @@ out_err:
 }
 
 /**
- * releases the FMR pool, QP and CMA ID objects, returns 0 on success,
+ * releases the FMR pool and QP objects, returns 0 on success,
  * -1 on failure
  */
-static int iser_free_ib_conn_res(struct iser_conn *ib_conn, int can_destroy_id)
+static int iser_free_ib_conn_res(struct iser_conn *ib_conn)
 {
        int cq_index;
        BUG_ON(ib_conn == NULL);
@@ -314,13 +315,9 @@ static int iser_free_ib_conn_res(struct iser_conn *ib_conn, int can_destroy_id)
 
                rdma_destroy_qp(ib_conn->cma_id);
        }
-       /* if cma handler context, the caller acts s.t the cma destroy the id */
-       if (ib_conn->cma_id != NULL && can_destroy_id)
-               rdma_destroy_id(ib_conn->cma_id);
 
        ib_conn->fmr_pool = NULL;
        ib_conn->qp       = NULL;
-       ib_conn->cma_id   = NULL;
        kfree(ib_conn->page_vec);
 
        if (ib_conn->login_buf) {
@@ -415,11 +412,16 @@ static void iser_conn_release(struct iser_conn *ib_conn, int can_destroy_id)
        list_del(&ib_conn->conn_list);
        mutex_unlock(&ig.connlist_mutex);
        iser_free_rx_descriptors(ib_conn);
-       iser_free_ib_conn_res(ib_conn, can_destroy_id);
+       iser_free_ib_conn_res(ib_conn);
        ib_conn->device = NULL;
        /* on EVENT_ADDR_ERROR there's no device yet for this conn */
        if (device != NULL)
                iser_device_try_release(device);
+       /* if cma handler context, the caller actually destroy the id */
+       if (ib_conn->cma_id != NULL && can_destroy_id) {
+               rdma_destroy_id(ib_conn->cma_id);
+               ib_conn->cma_id = NULL;
+       }
        iscsi_destroy_endpoint(ib_conn->ep);
 }
 
index 2f78538..b2420ae 100644 (file)
@@ -1379,6 +1379,7 @@ static int synaptics_reconnect(struct psmouse *psmouse)
 {
        struct synaptics_data *priv = psmouse->private;
        struct synaptics_data old_priv = *priv;
+       unsigned char param[2];
        int retry = 0;
        int error;
 
@@ -1394,6 +1395,7 @@ static int synaptics_reconnect(struct psmouse *psmouse)
                         */
                        ssleep(1);
                }
+               ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_GETID);
                error = synaptics_detect(psmouse, 0);
        } while (error && ++retry < 3);
 
index 5c68e44..518282d 100644 (file)
@@ -1966,7 +1966,8 @@ static const struct wacom_features wacom_features_0xF4 =
          63, WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
 static const struct wacom_features wacom_features_0xF8 =
        { "Wacom Cintiq 24HD touch", WACOM_PKGLEN_INTUOS,   104480, 65600, 2047, /* Pen */
-         63, WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, .oVid = USB_VENDOR_ID_WACOM, .oPid = 0xf6 };
+         63, WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES,
+         .oVid = USB_VENDOR_ID_WACOM, .oPid = 0xf6 };
 static const struct wacom_features wacom_features_0xF6 =
        { "Wacom Cintiq 24HD touch", .type = WACOM_24HDT, /* Touch */
          .oVid = USB_VENDOR_ID_WACOM, .oPid = 0xf8, .touch_max = 10 };
@@ -2009,7 +2010,8 @@ static const struct wacom_features wacom_features_0xFA =
          63, WACOM_22HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
 static const struct wacom_features wacom_features_0x5B =
        { "Wacom Cintiq 22HDT", WACOM_PKGLEN_INTUOS,      95840, 54260, 2047,
-         63, WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x5e };
+         63, WACOM_22HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES,
+         .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x5e };
 static const struct wacom_features wacom_features_0x5E =
        { "Wacom Cintiq 22HDT", .type = WACOM_24HDT,
          .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x5b, .touch_max = 10 };
@@ -2042,7 +2044,7 @@ static const struct wacom_features wacom_features_0xE5 =
 static const struct wacom_features wacom_features_0xE6 =
        { "Wacom ISDv4 E6",       WACOM_PKGLEN_TPC2FG,    27760, 15694,  255,
          0, TABLETPC2FG, WACOM_INTUOS_RES, WACOM_INTUOS_RES,
-       .touch_max = 2 };
+         .touch_max = 2 };
 static const struct wacom_features wacom_features_0xEC =
        { "Wacom ISDv4 EC",       WACOM_PKGLEN_GRAPHIRE,  25710, 14500,  255,
          0, TABLETPC,    WACOM_INTUOS_RES, WACOM_INTUOS_RES };
index 29889bb..63b3d4e 100644 (file)
@@ -76,16 +76,10 @@ asmlinkage void __exception_irq_entry icoll_handle_irq(struct pt_regs *regs)
 {
        u32 irqnr;
 
-       do {
-               irqnr = __raw_readl(icoll_base + HW_ICOLL_STAT_OFFSET);
-               if (irqnr != 0x7f) {
-                       __raw_writel(irqnr, icoll_base + HW_ICOLL_VECTOR);
-                       irqnr = irq_find_mapping(icoll_domain, irqnr);
-                       handle_IRQ(irqnr, regs);
-                       continue;
-               }
-               break;
-       } while (1);
+       irqnr = __raw_readl(icoll_base + HW_ICOLL_STAT_OFFSET);
+       __raw_writel(irqnr, icoll_base + HW_ICOLL_VECTOR);
+       irqnr = irq_find_mapping(icoll_domain, irqnr);
+       handle_IRQ(irqnr, regs);
 }
 
 static int icoll_irq_domain_map(struct irq_domain *d, unsigned int virq,
index 065b7a3..47a52ab 100644 (file)
@@ -119,7 +119,7 @@ static int fpga_irqdomain_map(struct irq_domain *d, unsigned int irq,
 
        /* Skip invalid IRQs, only register handlers for the real ones */
        if (!(f->valid & BIT(hwirq)))
-               return -ENOTSUPP;
+               return -EPERM;
        irq_set_chip_data(irq, f);
        irq_set_chip_and_handler(irq, &f->chip,
                                handle_level_irq);
index 884d11c..2bbb004 100644 (file)
@@ -197,7 +197,7 @@ static int vic_irqdomain_map(struct irq_domain *d, unsigned int irq,
 
        /* Skip invalid IRQs, only register handlers for the real ones */
        if (!(v->valid_sources & (1 << hwirq)))
-               return -ENOTSUPP;
+               return -EPERM;
        irq_set_chip_and_handler(irq, &vic_chip, handle_level_irq);
        irq_set_chip_data(irq, v->base);
        set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
index e75774f..aca59d9 100644 (file)
@@ -2230,10 +2230,15 @@ static void __exit atmci_cleanup_slot(struct atmel_mci_slot *slot,
        mmc_free_host(slot->mmc);
 }
 
-static bool atmci_filter(struct dma_chan *chan, void *slave)
+static bool atmci_filter(struct dma_chan *chan, void *pdata)
 {
-       struct mci_dma_data     *sl = slave;
+       struct mci_platform_data *sl_pdata = pdata;
+       struct mci_dma_data *sl;
 
+       if (!sl_pdata)
+               return false;
+
+       sl = sl_pdata->dma_slave;
        if (sl && find_slave_dev(sl) == chan->device->dev) {
                chan->private = slave_data_ptr(sl);
                return true;
@@ -2245,24 +2250,18 @@ static bool atmci_filter(struct dma_chan *chan, void *slave)
 static bool atmci_configure_dma(struct atmel_mci *host)
 {
        struct mci_platform_data        *pdata;
+       dma_cap_mask_t mask;
 
        if (host == NULL)
                return false;
 
        pdata = host->pdev->dev.platform_data;
 
-       if (!pdata)
-               return false;
+       dma_cap_zero(mask);
+       dma_cap_set(DMA_SLAVE, mask);
 
-       if (pdata->dma_slave && find_slave_dev(pdata->dma_slave)) {
-               dma_cap_mask_t mask;
-
-               /* Try to grab a DMA channel */
-               dma_cap_zero(mask);
-               dma_cap_set(DMA_SLAVE, mask);
-               host->dma.chan =
-                       dma_request_channel(mask, atmci_filter, pdata->dma_slave);
-       }
+       host->dma.chan = dma_request_slave_channel_compat(mask, atmci_filter, pdata,
+                                                         &host->pdev->dev, "rxtx");
        if (!host->dma.chan) {
                dev_warn(&host->pdev->dev, "no DMA channel available\n");
                return false;
index 6e44025..eccedc7 100644 (file)
@@ -161,6 +161,7 @@ struct omap_hsmmc_host {
         */
        struct  regulator       *vcc;
        struct  regulator       *vcc_aux;
+       int                     pbias_disable;
        void    __iomem         *base;
        resource_size_t         mapbase;
        spinlock_t              irq_lock; /* Prevent races with irq handler */
@@ -255,11 +256,11 @@ static int omap_hsmmc_set_power(struct device *dev, int slot, int power_on,
        if (!host->vcc)
                return 0;
        /*
-        * With DT, never turn OFF the regulator. This is because
+        * With DT, never turn OFF the regulator for MMC1. This is because
         * the pbias cell programming support is still missing when
         * booting with Device tree
         */
-       if (dev->of_node && !vdd)
+       if (host->pbias_disable && !vdd)
                return 0;
 
        if (mmc_slot(host).before_set_reg)
@@ -1520,10 +1521,10 @@ static void omap_hsmmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
                        (ios->vdd == DUAL_VOLT_OCR_BIT) &&
                        /*
                         * With pbias cell programming missing, this
-                        * can't be allowed when booting with device
+                        * can't be allowed on MMC1 when booting with device
                         * tree.
                         */
-                       !host->dev->of_node) {
+                       !host->pbias_disable) {
                                /*
                                 * The mmc_select_voltage fn of the core does
                                 * not seem to set the power_mode to
@@ -1871,6 +1872,10 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
 
        omap_hsmmc_context_save(host);
 
+       /* This can be removed once we support PBIAS with DT */
+       if (host->dev->of_node && host->mapbase == 0x4809c000)
+               host->pbias_disable = 1;
+
        host->dbclk = clk_get(&pdev->dev, "mmchsdb_fck");
        /*
         * MMC can still work without debounce clock.
@@ -1906,33 +1911,41 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
 
        omap_hsmmc_conf_bus_power(host);
 
-       res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx");
-       if (!res) {
-               dev_err(mmc_dev(host->mmc), "cannot get DMA TX channel\n");
-               ret = -ENXIO;
-               goto err_irq;
-       }
-       tx_req = res->start;
+       if (!pdev->dev.of_node) {
+               res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx");
+               if (!res) {
+                       dev_err(mmc_dev(host->mmc), "cannot get DMA TX channel\n");
+                       ret = -ENXIO;
+                       goto err_irq;
+               }
+               tx_req = res->start;
 
-       res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "rx");
-       if (!res) {
-               dev_err(mmc_dev(host->mmc), "cannot get DMA RX channel\n");
-               ret = -ENXIO;
-               goto err_irq;
+               res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "rx");
+               if (!res) {
+                       dev_err(mmc_dev(host->mmc), "cannot get DMA RX channel\n");
+                       ret = -ENXIO;
+                       goto err_irq;
+               }
+               rx_req = res->start;
        }
-       rx_req = res->start;
 
        dma_cap_zero(mask);
        dma_cap_set(DMA_SLAVE, mask);
 
-       host->rx_chan = dma_request_channel(mask, omap_dma_filter_fn, &rx_req);
+       host->rx_chan =
+               dma_request_slave_channel_compat(mask, omap_dma_filter_fn,
+                                                &rx_req, &pdev->dev, "rx");
+
        if (!host->rx_chan) {
                dev_err(mmc_dev(host->mmc), "unable to obtain RX DMA engine channel %u\n", rx_req);
                ret = -ENXIO;
                goto err_irq;
        }
 
-       host->tx_chan = dma_request_channel(mask, omap_dma_filter_fn, &tx_req);
+       host->tx_chan =
+               dma_request_slave_channel_compat(mask, omap_dma_filter_fn,
+                                                &tx_req, &pdev->dev, "tx");
+
        if (!host->tx_chan) {
                dev_err(mmc_dev(host->mmc), "unable to obtain TX DMA engine channel %u\n", tx_req);
                ret = -ENXIO;
index 7bcf74b..706d9cb 100644 (file)
@@ -87,6 +87,12 @@ static const struct sdhci_ops sdhci_acpi_ops_dflt = {
        .enable_dma = sdhci_acpi_enable_dma,
 };
 
+static const struct sdhci_acpi_slot sdhci_acpi_slot_int_emmc = {
+       .caps    = MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE,
+       .caps2   = MMC_CAP2_HC_ERASE_SZ,
+       .flags   = SDHCI_ACPI_RUNTIME_PM,
+};
+
 static const struct sdhci_acpi_slot sdhci_acpi_slot_int_sdio = {
        .quirks2 = SDHCI_QUIRK2_HOST_OFF_CARD_ON,
        .caps    = MMC_CAP_NONREMOVABLE | MMC_CAP_POWER_OFF_CARD,
@@ -94,23 +100,67 @@ static const struct sdhci_acpi_slot sdhci_acpi_slot_int_sdio = {
        .pm_caps = MMC_PM_KEEP_POWER,
 };
 
+static const struct sdhci_acpi_slot sdhci_acpi_slot_int_sd = {
+};
+
+struct sdhci_acpi_uid_slot {
+       const char *hid;
+       const char *uid;
+       const struct sdhci_acpi_slot *slot;
+};
+
+static const struct sdhci_acpi_uid_slot sdhci_acpi_uids[] = {
+       { "80860F14" , "1" , &sdhci_acpi_slot_int_emmc },
+       { "80860F14" , "3" , &sdhci_acpi_slot_int_sd   },
+       { "INT33BB"  , "2" , &sdhci_acpi_slot_int_sdio },
+       { "INT33C6"  , NULL, &sdhci_acpi_slot_int_sdio },
+       { "PNP0D40"  },
+       { },
+};
+
 static const struct acpi_device_id sdhci_acpi_ids[] = {
-       { "INT33C6", (kernel_ulong_t)&sdhci_acpi_slot_int_sdio },
-       { "PNP0D40" },
+       { "80860F14" },
+       { "INT33BB"  },
+       { "INT33C6"  },
+       { "PNP0D40"  },
        { },
 };
 MODULE_DEVICE_TABLE(acpi, sdhci_acpi_ids);
 
-static const struct sdhci_acpi_slot *sdhci_acpi_get_slot(const char *hid)
+static const struct sdhci_acpi_slot *sdhci_acpi_get_slot_by_ids(const char *hid,
+                                                               const char *uid)
 {
-       const struct acpi_device_id *id;
-
-       for (id = sdhci_acpi_ids; id->id[0]; id++)
-               if (!strcmp(id->id, hid))
-                       return (const struct sdhci_acpi_slot *)id->driver_data;
+       const struct sdhci_acpi_uid_slot *u;
+
+       for (u = sdhci_acpi_uids; u->hid; u++) {
+               if (strcmp(u->hid, hid))
+                       continue;
+               if (!u->uid)
+                       return u->slot;
+               if (uid && !strcmp(u->uid, uid))
+                       return u->slot;
+       }
        return NULL;
 }
 
+static const struct sdhci_acpi_slot *sdhci_acpi_get_slot(acpi_handle handle,
+                                                        const char *hid)
+{
+       const struct sdhci_acpi_slot *slot;
+       struct acpi_device_info *info;
+       const char *uid = NULL;
+       acpi_status status;
+
+       status = acpi_get_object_info(handle, &info);
+       if (!ACPI_FAILURE(status) && (info->valid & ACPI_VALID_UID))
+               uid = info->unique_id.string;
+
+       slot = sdhci_acpi_get_slot_by_ids(hid, uid);
+
+       kfree(info);
+       return slot;
+}
+
 static int sdhci_acpi_probe(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
@@ -148,7 +198,7 @@ static int sdhci_acpi_probe(struct platform_device *pdev)
 
        c = sdhci_priv(host);
        c->host = host;
-       c->slot = sdhci_acpi_get_slot(hid);
+       c->slot = sdhci_acpi_get_slot(handle, hid);
        c->pdev = pdev;
        c->use_runtime_pm = sdhci_acpi_flag(c, SDHCI_ACPI_RUNTIME_PM);
 
@@ -202,6 +252,7 @@ static int sdhci_acpi_probe(struct platform_device *pdev)
                goto err_free;
 
        if (c->use_runtime_pm) {
+               pm_runtime_set_active(dev);
                pm_suspend_ignore_children(dev, 1);
                pm_runtime_set_autosuspend_delay(dev, 50);
                pm_runtime_use_autosuspend(dev);
index 67d6dde..d5f0d59 100644 (file)
@@ -85,6 +85,12 @@ struct pltfm_imx_data {
        struct clk *clk_ipg;
        struct clk *clk_ahb;
        struct clk *clk_per;
+       enum {
+               NO_CMD_PENDING,      /* no multiblock command pending*/
+               MULTIBLK_IN_PROCESS, /* exact multiblock cmd in process */
+               WAIT_FOR_INT,        /* sent CMD12, waiting for response INT */
+       } multiblock_status;
+
 };
 
 static struct platform_device_id imx_esdhc_devtype[] = {
@@ -154,6 +160,8 @@ static inline void esdhc_clrset_le(struct sdhci_host *host, u32 mask, u32 val, i
 
 static u32 esdhc_readl_le(struct sdhci_host *host, int reg)
 {
+       struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+       struct pltfm_imx_data *imx_data = pltfm_host->priv;
        u32 val = readl(host->ioaddr + reg);
 
        if (unlikely(reg == SDHCI_CAPABILITIES)) {
@@ -175,6 +183,18 @@ static u32 esdhc_readl_le(struct sdhci_host *host, int reg)
                        val &= ~ESDHC_INT_VENDOR_SPEC_DMA_ERR;
                        val |= SDHCI_INT_ADMA_ERROR;
                }
+
+               /*
+                * mask off the interrupt we get in response to the manually
+                * sent CMD12
+                */
+               if ((imx_data->multiblock_status == WAIT_FOR_INT) &&
+                   ((val & SDHCI_INT_RESPONSE) == SDHCI_INT_RESPONSE)) {
+                       val &= ~SDHCI_INT_RESPONSE;
+                       writel(SDHCI_INT_RESPONSE, host->ioaddr +
+                                                  SDHCI_INT_STATUS);
+                       imx_data->multiblock_status = NO_CMD_PENDING;
+               }
        }
 
        return val;
@@ -211,6 +231,15 @@ static void esdhc_writel_le(struct sdhci_host *host, u32 val, int reg)
                        v = readl(host->ioaddr + ESDHC_VENDOR_SPEC);
                        v &= ~ESDHC_VENDOR_SPEC_SDIO_QUIRK;
                        writel(v, host->ioaddr + ESDHC_VENDOR_SPEC);
+
+                       if (imx_data->multiblock_status == MULTIBLK_IN_PROCESS)
+                       {
+                               /* send a manual CMD12 with RESPTYP=none */
+                               data = MMC_STOP_TRANSMISSION << 24 |
+                                      SDHCI_CMD_ABORTCMD << 16;
+                               writel(data, host->ioaddr + SDHCI_TRANSFER_MODE);
+                               imx_data->multiblock_status = WAIT_FOR_INT;
+                       }
        }
 
        if (unlikely(reg == SDHCI_INT_ENABLE || reg == SDHCI_SIGNAL_ENABLE)) {
@@ -277,11 +306,13 @@ static void esdhc_writew_le(struct sdhci_host *host, u16 val, int reg)
                }
                return;
        case SDHCI_COMMAND:
-               if ((host->cmd->opcode == MMC_STOP_TRANSMISSION ||
-                    host->cmd->opcode == MMC_SET_BLOCK_COUNT) &&
-                   (imx_data->flags & ESDHC_FLAG_MULTIBLK_NO_INT))
+               if (host->cmd->opcode == MMC_STOP_TRANSMISSION)
                        val |= SDHCI_CMD_ABORTCMD;
 
+               if ((host->cmd->opcode == MMC_SET_BLOCK_COUNT) &&
+                   (imx_data->flags & ESDHC_FLAG_MULTIBLK_NO_INT))
+                       imx_data->multiblock_status = MULTIBLK_IN_PROCESS;
+
                if (is_imx6q_usdhc(imx_data))
                        writel(val << 16,
                               host->ioaddr + SDHCI_TRANSFER_MODE);
@@ -324,8 +355,10 @@ static void esdhc_writeb_le(struct sdhci_host *host, u8 val, int reg)
                /*
                 * Do not touch buswidth bits here. This is done in
                 * esdhc_pltfm_bus_width.
+                * Do not touch the D3CD bit either which is used for the
+                * SDIO interrupt errata workaround.
                 */
-               mask = 0xffff & ~ESDHC_CTRL_BUSWIDTH_MASK;
+               mask = 0xffff & ~(ESDHC_CTRL_BUSWIDTH_MASK | ESDHC_CTRL_D3CD);
 
                esdhc_clrset_le(host, mask, new_val, reg);
                return;
index 0012d3f..701d06d 100644 (file)
@@ -33,6 +33,9 @@
  */
 #define PCI_DEVICE_ID_INTEL_PCH_SDIO0  0x8809
 #define PCI_DEVICE_ID_INTEL_PCH_SDIO1  0x880a
+#define PCI_DEVICE_ID_INTEL_BYT_EMMC   0x0f14
+#define PCI_DEVICE_ID_INTEL_BYT_SDIO   0x0f15
+#define PCI_DEVICE_ID_INTEL_BYT_SD     0x0f16
 
 /*
  * PCI registers
@@ -304,6 +307,33 @@ static const struct sdhci_pci_fixes sdhci_intel_pch_sdio = {
        .probe_slot     = pch_hc_probe_slot,
 };
 
+static int byt_emmc_probe_slot(struct sdhci_pci_slot *slot)
+{
+       slot->host->mmc->caps |= MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE;
+       slot->host->mmc->caps2 |= MMC_CAP2_HC_ERASE_SZ;
+       return 0;
+}
+
+static int byt_sdio_probe_slot(struct sdhci_pci_slot *slot)
+{
+       slot->host->mmc->caps |= MMC_CAP_POWER_OFF_CARD | MMC_CAP_NONREMOVABLE;
+       return 0;
+}
+
+static const struct sdhci_pci_fixes sdhci_intel_byt_emmc = {
+       .allow_runtime_pm = true,
+       .probe_slot     = byt_emmc_probe_slot,
+};
+
+static const struct sdhci_pci_fixes sdhci_intel_byt_sdio = {
+       .quirks2        = SDHCI_QUIRK2_HOST_OFF_CARD_ON,
+       .allow_runtime_pm = true,
+       .probe_slot     = byt_sdio_probe_slot,
+};
+
+static const struct sdhci_pci_fixes sdhci_intel_byt_sd = {
+};
+
 /* O2Micro extra registers */
 #define O2_SD_LOCK_WP          0xD3
 #define O2_SD_MULTI_VCC3V      0xEE
@@ -855,6 +885,30 @@ static const struct pci_device_id pci_ids[] = {
                .driver_data    = (kernel_ulong_t)&sdhci_intel_pch_sdio,
        },
 
+       {
+               .vendor         = PCI_VENDOR_ID_INTEL,
+               .device         = PCI_DEVICE_ID_INTEL_BYT_EMMC,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .driver_data    = (kernel_ulong_t)&sdhci_intel_byt_emmc,
+       },
+
+       {
+               .vendor         = PCI_VENDOR_ID_INTEL,
+               .device         = PCI_DEVICE_ID_INTEL_BYT_SDIO,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .driver_data    = (kernel_ulong_t)&sdhci_intel_byt_sdio,
+       },
+
+       {
+               .vendor         = PCI_VENDOR_ID_INTEL,
+               .device         = PCI_DEVICE_ID_INTEL_BYT_SD,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .driver_data    = (kernel_ulong_t)&sdhci_intel_byt_sd,
+       },
+
        {
                .vendor         = PCI_VENDOR_ID_O2,
                .device         = PCI_DEVICE_ID_O2_8120,
index 9b74d1e..6aa7b32 100644 (file)
@@ -612,9 +612,15 @@ static int esd_usb2_start(struct esd_usb2_net_priv *priv)
 {
        struct esd_usb2 *dev = priv->usb2;
        struct net_device *netdev = priv->netdev;
-       struct esd_usb2_msg msg;
+       struct esd_usb2_msg *msg;
        int err, i;
 
+       msg = kmalloc(sizeof(*msg), GFP_KERNEL);
+       if (!msg) {
+               err = -ENOMEM;
+               goto out;
+       }
+
        /*
         * Enable all IDs
         * The IDADD message takes up to 64 32 bit bitmasks (2048 bits).
@@ -628,33 +634,32 @@ static int esd_usb2_start(struct esd_usb2_net_priv *priv)
         * the number of the starting bitmask (0..64) to the filter.option
         * field followed by only some bitmasks.
         */
-       msg.msg.hdr.cmd = CMD_IDADD;
-       msg.msg.hdr.len = 2 + ESD_MAX_ID_SEGMENT;
-       msg.msg.filter.net = priv->index;
-       msg.msg.filter.option = ESD_ID_ENABLE; /* start with segment 0 */
+       msg->msg.hdr.cmd = CMD_IDADD;
+       msg->msg.hdr.len = 2 + ESD_MAX_ID_SEGMENT;
+       msg->msg.filter.net = priv->index;
+       msg->msg.filter.option = ESD_ID_ENABLE; /* start with segment 0 */
        for (i = 0; i < ESD_MAX_ID_SEGMENT; i++)
-               msg.msg.filter.mask[i] = cpu_to_le32(0xffffffff);
+               msg->msg.filter.mask[i] = cpu_to_le32(0xffffffff);
        /* enable 29bit extended IDs */
-       msg.msg.filter.mask[ESD_MAX_ID_SEGMENT] = cpu_to_le32(0x00000001);
+       msg->msg.filter.mask[ESD_MAX_ID_SEGMENT] = cpu_to_le32(0x00000001);
 
-       err = esd_usb2_send_msg(dev, &msg);
+       err = esd_usb2_send_msg(dev, msg);
        if (err)
-               goto failed;
+               goto out;
 
        err = esd_usb2_setup_rx_urbs(dev);
        if (err)
-               goto failed;
+               goto out;
 
        priv->can.state = CAN_STATE_ERROR_ACTIVE;
 
-       return 0;
-
-failed:
+out:
        if (err == -ENODEV)
                netif_device_detach(netdev);
+       if (err)
+               netdev_err(netdev, "couldn't start device: %d\n", err);
 
-       netdev_err(netdev, "couldn't start device: %d\n", err);
-
+       kfree(msg);
        return err;
 }
 
@@ -833,26 +838,30 @@ nourbmem:
 static int esd_usb2_close(struct net_device *netdev)
 {
        struct esd_usb2_net_priv *priv = netdev_priv(netdev);
-       struct esd_usb2_msg msg;
+       struct esd_usb2_msg *msg;
        int i;
 
+       msg = kmalloc(sizeof(*msg), GFP_KERNEL);
+       if (!msg)
+               return -ENOMEM;
+
        /* Disable all IDs (see esd_usb2_start()) */
-       msg.msg.hdr.cmd = CMD_IDADD;
-       msg.msg.hdr.len = 2 + ESD_MAX_ID_SEGMENT;
-       msg.msg.filter.net = priv->index;
-       msg.msg.filter.option = ESD_ID_ENABLE; /* start with segment 0 */
+       msg->msg.hdr.cmd = CMD_IDADD;
+       msg->msg.hdr.len = 2 + ESD_MAX_ID_SEGMENT;
+       msg->msg.filter.net = priv->index;
+       msg->msg.filter.option = ESD_ID_ENABLE; /* start with segment 0 */
        for (i = 0; i <= ESD_MAX_ID_SEGMENT; i++)
-               msg.msg.filter.mask[i] = 0;
-       if (esd_usb2_send_msg(priv->usb2, &msg) < 0)
+               msg->msg.filter.mask[i] = 0;
+       if (esd_usb2_send_msg(priv->usb2, msg) < 0)
                netdev_err(netdev, "sending idadd message failed\n");
 
        /* set CAN controller to reset mode */
-       msg.msg.hdr.len = 2;
-       msg.msg.hdr.cmd = CMD_SETBAUD;
-       msg.msg.setbaud.net = priv->index;
-       msg.msg.setbaud.rsvd = 0;
-       msg.msg.setbaud.baud = cpu_to_le32(ESD_USB2_NO_BAUDRATE);
-       if (esd_usb2_send_msg(priv->usb2, &msg) < 0)
+       msg->msg.hdr.len = 2;
+       msg->msg.hdr.cmd = CMD_SETBAUD;
+       msg->msg.setbaud.net = priv->index;
+       msg->msg.setbaud.rsvd = 0;
+       msg->msg.setbaud.baud = cpu_to_le32(ESD_USB2_NO_BAUDRATE);
+       if (esd_usb2_send_msg(priv->usb2, msg) < 0)
                netdev_err(netdev, "sending setbaud message failed\n");
 
        priv->can.state = CAN_STATE_STOPPED;
@@ -861,6 +870,8 @@ static int esd_usb2_close(struct net_device *netdev)
 
        close_candev(netdev);
 
+       kfree(msg);
+
        return 0;
 }
 
@@ -886,7 +897,8 @@ static int esd_usb2_set_bittiming(struct net_device *netdev)
 {
        struct esd_usb2_net_priv *priv = netdev_priv(netdev);
        struct can_bittiming *bt = &priv->can.bittiming;
-       struct esd_usb2_msg msg;
+       struct esd_usb2_msg *msg;
+       int err;
        u32 canbtr;
        int sjw_shift;
 
@@ -912,15 +924,22 @@ static int esd_usb2_set_bittiming(struct net_device *netdev)
        if (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES)
                canbtr |= ESD_USB2_3_SAMPLES;
 
-       msg.msg.hdr.len = 2;
-       msg.msg.hdr.cmd = CMD_SETBAUD;
-       msg.msg.setbaud.net = priv->index;
-       msg.msg.setbaud.rsvd = 0;
-       msg.msg.setbaud.baud = cpu_to_le32(canbtr);
+       msg = kmalloc(sizeof(*msg), GFP_KERNEL);
+       if (!msg)
+               return -ENOMEM;
+
+       msg->msg.hdr.len = 2;
+       msg->msg.hdr.cmd = CMD_SETBAUD;
+       msg->msg.setbaud.net = priv->index;
+       msg->msg.setbaud.rsvd = 0;
+       msg->msg.setbaud.baud = cpu_to_le32(canbtr);
 
        netdev_info(netdev, "setting BTR=%#x\n", canbtr);
 
-       return esd_usb2_send_msg(priv->usb2, &msg);
+       err = esd_usb2_send_msg(priv->usb2, msg);
+
+       kfree(msg);
+       return err;
 }
 
 static int esd_usb2_get_berr_counter(const struct net_device *netdev,
@@ -1022,7 +1041,7 @@ static int esd_usb2_probe(struct usb_interface *intf,
                         const struct usb_device_id *id)
 {
        struct esd_usb2 *dev;
-       struct esd_usb2_msg msg;
+       struct esd_usb2_msg *msg;
        int i, err;
 
        dev = kzalloc(sizeof(*dev), GFP_KERNEL);
@@ -1037,27 +1056,33 @@ static int esd_usb2_probe(struct usb_interface *intf,
 
        usb_set_intfdata(intf, dev);
 
+       msg = kmalloc(sizeof(*msg), GFP_KERNEL);
+       if (!msg) {
+               err = -ENOMEM;
+               goto free_msg;
+       }
+
        /* query number of CAN interfaces (nets) */
-       msg.msg.hdr.cmd = CMD_VERSION;
-       msg.msg.hdr.len = 2;
-       msg.msg.version.rsvd = 0;
-       msg.msg.version.flags = 0;
-       msg.msg.version.drv_version = 0;
+       msg->msg.hdr.cmd = CMD_VERSION;
+       msg->msg.hdr.len = 2;
+       msg->msg.version.rsvd = 0;
+       msg->msg.version.flags = 0;
+       msg->msg.version.drv_version = 0;
 
-       err = esd_usb2_send_msg(dev, &msg);
+       err = esd_usb2_send_msg(dev, msg);
        if (err < 0) {
                dev_err(&intf->dev, "sending version message failed\n");
-               goto free_dev;
+               goto free_msg;
        }
 
-       err = esd_usb2_wait_msg(dev, &msg);
+       err = esd_usb2_wait_msg(dev, msg);
        if (err < 0) {
                dev_err(&intf->dev, "no version message answer\n");
-               goto free_dev;
+               goto free_msg;
        }
 
-       dev->net_count = (int)msg.msg.version_reply.nets;
-       dev->version = le32_to_cpu(msg.msg.version_reply.version);
+       dev->net_count = (int)msg->msg.version_reply.nets;
+       dev->version = le32_to_cpu(msg->msg.version_reply.version);
 
        if (device_create_file(&intf->dev, &dev_attr_firmware))
                dev_err(&intf->dev,
@@ -1075,10 +1100,10 @@ static int esd_usb2_probe(struct usb_interface *intf,
        for (i = 0; i < dev->net_count; i++)
                esd_usb2_probe_one_net(intf, i);
 
-       return 0;
-
-free_dev:
-       kfree(dev);
+free_msg:
+       kfree(msg);
+       if (err)
+               kfree(dev);
 done:
        return err;
 }
index 45cb9f3..3b95465 100644 (file)
 #define KVASER_CTRL_MODE_SELFRECEPTION 3
 #define KVASER_CTRL_MODE_OFF           4
 
+/* log message */
+#define KVASER_EXTENDED_FRAME          BIT(31)
+
 struct kvaser_msg_simple {
        u8 tid;
        u8 channel;
@@ -817,8 +820,13 @@ static void kvaser_usb_rx_can_msg(const struct kvaser_usb *dev,
        priv = dev->nets[channel];
        stats = &priv->netdev->stats;
 
-       if (msg->u.rx_can.flag & (MSG_FLAG_ERROR_FRAME | MSG_FLAG_NERR |
-                                 MSG_FLAG_OVERRUN)) {
+       if ((msg->u.rx_can.flag & MSG_FLAG_ERROR_FRAME) &&
+           (msg->id == CMD_LOG_MESSAGE)) {
+               kvaser_usb_rx_error(dev, msg);
+               return;
+       } else if (msg->u.rx_can.flag & (MSG_FLAG_ERROR_FRAME |
+                                        MSG_FLAG_NERR |
+                                        MSG_FLAG_OVERRUN)) {
                kvaser_usb_rx_can_err(priv, msg);
                return;
        } else if (msg->u.rx_can.flag & ~MSG_FLAG_REMOTE_FRAME) {
@@ -834,22 +842,40 @@ static void kvaser_usb_rx_can_msg(const struct kvaser_usb *dev,
                return;
        }
 
-       cf->can_id = ((msg->u.rx_can.msg[0] & 0x1f) << 6) |
-                    (msg->u.rx_can.msg[1] & 0x3f);
-       cf->can_dlc = get_can_dlc(msg->u.rx_can.msg[5]);
+       if (msg->id == CMD_LOG_MESSAGE) {
+               cf->can_id = le32_to_cpu(msg->u.log_message.id);
+               if (cf->can_id & KVASER_EXTENDED_FRAME)
+                       cf->can_id &= CAN_EFF_MASK | CAN_EFF_FLAG;
+               else
+                       cf->can_id &= CAN_SFF_MASK;
 
-       if (msg->id == CMD_RX_EXT_MESSAGE) {
-               cf->can_id <<= 18;
-               cf->can_id |= ((msg->u.rx_can.msg[2] & 0x0f) << 14) |
-                             ((msg->u.rx_can.msg[3] & 0xff) << 6) |
-                             (msg->u.rx_can.msg[4] & 0x3f);
-               cf->can_id |= CAN_EFF_FLAG;
-       }
+               cf->can_dlc = get_can_dlc(msg->u.log_message.dlc);
 
-       if (msg->u.rx_can.flag & MSG_FLAG_REMOTE_FRAME)
-               cf->can_id |= CAN_RTR_FLAG;
-       else
-               memcpy(cf->data, &msg->u.rx_can.msg[6], cf->can_dlc);
+               if (msg->u.log_message.flags & MSG_FLAG_REMOTE_FRAME)
+                       cf->can_id |= CAN_RTR_FLAG;
+               else
+                       memcpy(cf->data, &msg->u.log_message.data,
+                              cf->can_dlc);
+       } else {
+               cf->can_id = ((msg->u.rx_can.msg[0] & 0x1f) << 6) |
+                            (msg->u.rx_can.msg[1] & 0x3f);
+
+               if (msg->id == CMD_RX_EXT_MESSAGE) {
+                       cf->can_id <<= 18;
+                       cf->can_id |= ((msg->u.rx_can.msg[2] & 0x0f) << 14) |
+                                     ((msg->u.rx_can.msg[3] & 0xff) << 6) |
+                                     (msg->u.rx_can.msg[4] & 0x3f);
+                       cf->can_id |= CAN_EFF_FLAG;
+               }
+
+               cf->can_dlc = get_can_dlc(msg->u.rx_can.msg[5]);
+
+               if (msg->u.rx_can.flag & MSG_FLAG_REMOTE_FRAME)
+                       cf->can_id |= CAN_RTR_FLAG;
+               else
+                       memcpy(cf->data, &msg->u.rx_can.msg[6],
+                              cf->can_dlc);
+       }
 
        netif_rx(skb);
 
@@ -911,6 +937,7 @@ static void kvaser_usb_handle_message(const struct kvaser_usb *dev,
 
        case CMD_RX_STD_MESSAGE:
        case CMD_RX_EXT_MESSAGE:
+       case CMD_LOG_MESSAGE:
                kvaser_usb_rx_can_msg(dev, msg);
                break;
 
@@ -919,11 +946,6 @@ static void kvaser_usb_handle_message(const struct kvaser_usb *dev,
                kvaser_usb_rx_error(dev, msg);
                break;
 
-       case CMD_LOG_MESSAGE:
-               if (msg->u.log_message.flags & MSG_FLAG_ERROR_FRAME)
-                       kvaser_usb_rx_error(dev, msg);
-               break;
-
        case CMD_TX_ACKNOWLEDGE:
                kvaser_usb_tx_acknowledge(dev, msg);
                break;
index 30d79bf..8ee9d15 100644 (file)
@@ -504,15 +504,24 @@ static int pcan_usb_pro_restart_async(struct peak_usb_device *dev,
        return usb_submit_urb(urb, GFP_ATOMIC);
 }
 
-static void pcan_usb_pro_drv_loaded(struct peak_usb_device *dev, int loaded)
+static int pcan_usb_pro_drv_loaded(struct peak_usb_device *dev, int loaded)
 {
-       u8 buffer[16];
+       u8 *buffer;
+       int err;
+
+       buffer = kmalloc(PCAN_USBPRO_FCT_DRVLD_REQ_LEN, GFP_KERNEL);
+       if (!buffer)
+               return -ENOMEM;
 
        buffer[0] = 0;
        buffer[1] = !!loaded;
 
-       pcan_usb_pro_send_req(dev, PCAN_USBPRO_REQ_FCT,
-                             PCAN_USBPRO_FCT_DRVLD, buffer, sizeof(buffer));
+       err = pcan_usb_pro_send_req(dev, PCAN_USBPRO_REQ_FCT,
+                                   PCAN_USBPRO_FCT_DRVLD, buffer,
+                                   PCAN_USBPRO_FCT_DRVLD_REQ_LEN);
+       kfree(buffer);
+
+       return err;
 }
 
 static inline
@@ -851,21 +860,24 @@ static int pcan_usb_pro_stop(struct peak_usb_device *dev)
  */
 static int pcan_usb_pro_init(struct peak_usb_device *dev)
 {
-       struct pcan_usb_pro_interface *usb_if;
        struct pcan_usb_pro_device *pdev =
                        container_of(dev, struct pcan_usb_pro_device, dev);
+       struct pcan_usb_pro_interface *usb_if = NULL;
+       struct pcan_usb_pro_fwinfo *fi = NULL;
+       struct pcan_usb_pro_blinfo *bi = NULL;
+       int err;
 
        /* do this for 1st channel only */
        if (!dev->prev_siblings) {
-               struct pcan_usb_pro_fwinfo fi;
-               struct pcan_usb_pro_blinfo bi;
-               int err;
-
                /* allocate netdevices common structure attached to first one */
                usb_if = kzalloc(sizeof(struct pcan_usb_pro_interface),
                                 GFP_KERNEL);
-               if (!usb_if)
-                       return -ENOMEM;
+               fi = kmalloc(sizeof(struct pcan_usb_pro_fwinfo), GFP_KERNEL);
+               bi = kmalloc(sizeof(struct pcan_usb_pro_blinfo), GFP_KERNEL);
+               if (!usb_if || !fi || !bi) {
+                       err = -ENOMEM;
+                       goto err_out;
+               }
 
                /* number of ts msgs to ignore before taking one into account */
                usb_if->cm_ignore_count = 5;
@@ -877,34 +889,34 @@ static int pcan_usb_pro_init(struct peak_usb_device *dev)
                 */
                err = pcan_usb_pro_send_req(dev, PCAN_USBPRO_REQ_INFO,
                                            PCAN_USBPRO_INFO_FW,
-                                           &fi, sizeof(fi));
+                                           fi, sizeof(*fi));
                if (err) {
-                       kfree(usb_if);
                        dev_err(dev->netdev->dev.parent,
                                "unable to read %s firmware info (err %d)\n",
                                pcan_usb_pro.name, err);
-                       return err;
+                       goto err_out;
                }
 
                err = pcan_usb_pro_send_req(dev, PCAN_USBPRO_REQ_INFO,
                                            PCAN_USBPRO_INFO_BL,
-                                           &bi, sizeof(bi));
+                                           bi, sizeof(*bi));
                if (err) {
-                       kfree(usb_if);
                        dev_err(dev->netdev->dev.parent,
                                "unable to read %s bootloader info (err %d)\n",
                                pcan_usb_pro.name, err);
-                       return err;
+                       goto err_out;
                }
 
+               /* tell the device the can driver is running */
+               err = pcan_usb_pro_drv_loaded(dev, 1);
+               if (err)
+                       goto err_out;
+
                dev_info(dev->netdev->dev.parent,
                     "PEAK-System %s hwrev %u serial %08X.%08X (%u channels)\n",
                     pcan_usb_pro.name,
-                    bi.hw_rev, bi.serial_num_hi, bi.serial_num_lo,
+                    bi->hw_rev, bi->serial_num_hi, bi->serial_num_lo,
                     pcan_usb_pro.ctrl_count);
-
-               /* tell the device the can driver is running */
-               pcan_usb_pro_drv_loaded(dev, 1);
        } else {
                usb_if = pcan_usb_pro_dev_if(dev->prev_siblings);
        }
@@ -916,6 +928,13 @@ static int pcan_usb_pro_init(struct peak_usb_device *dev)
        pcan_usb_pro_set_led(dev, 0, 1);
 
        return 0;
+
+ err_out:
+       kfree(bi);
+       kfree(fi);
+       kfree(usb_if);
+
+       return err;
 }
 
 static void pcan_usb_pro_exit(struct peak_usb_device *dev)
index a869918..32275af 100644 (file)
@@ -29,6 +29,7 @@
 
 /* Vendor Request value for XXX_FCT */
 #define PCAN_USBPRO_FCT_DRVLD          5 /* tell device driver is loaded */
+#define PCAN_USBPRO_FCT_DRVLD_REQ_LEN  16
 
 /* PCAN_USBPRO_INFO_BL vendor request record type */
 struct __packed pcan_usb_pro_blinfo {
index be59ec4..638e554 100644 (file)
@@ -3192,11 +3192,11 @@ static u32 bnx2x_xmit_type(struct bnx2x *bp, struct sk_buff *skb)
                rc |= XMIT_CSUM_TCP;
 
        if (skb_is_gso_v6(skb)) {
-               rc |= (XMIT_GSO_V6 | XMIT_CSUM_TCP | XMIT_CSUM_V6);
+               rc |= (XMIT_GSO_V6 | XMIT_CSUM_TCP);
                if (rc & XMIT_CSUM_ENC)
                        rc |= XMIT_GSO_ENC_V6;
        } else if (skb_is_gso(skb)) {
-               rc |= (XMIT_GSO_V4 | XMIT_CSUM_V4 | XMIT_CSUM_TCP);
+               rc |= (XMIT_GSO_V4 | XMIT_CSUM_TCP);
                if (rc & XMIT_CSUM_ENC)
                        rc |= XMIT_GSO_ENC_V4;
        }
@@ -3483,19 +3483,18 @@ static void bnx2x_update_pbds_gso_enc(struct sk_buff *skb,
 {
        u16 hlen_w = 0;
        u8 outerip_off, outerip_len = 0;
+
        /* from outer IP to transport */
        hlen_w = (skb_inner_transport_header(skb) -
                  skb_network_header(skb)) >> 1;
 
        /* transport len */
-       if (xmit_type & XMIT_CSUM_TCP)
-               hlen_w += inner_tcp_hdrlen(skb) >> 1;
-       else
-               hlen_w += sizeof(struct udphdr) >> 1;
+       hlen_w += inner_tcp_hdrlen(skb) >> 1;
 
        pbd2->fw_ip_hdr_to_payload_w = hlen_w;
 
-       if (xmit_type & XMIT_CSUM_ENC_V4) {
+       /* outer IP header info */
+       if (xmit_type & XMIT_CSUM_V4) {
                struct iphdr *iph = ip_hdr(skb);
                pbd2->fw_ip_csum_wo_len_flags_frag =
                        bswab16(csum_fold((~iph->check) -
@@ -3818,8 +3817,7 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
                        bnx2x_set_pbd_gso_e2(skb, &pbd_e2_parsing_data,
                                             xmit_type);
                else
-                       bnx2x_set_pbd_gso(skb, pbd_e1x, tx_start_bd,
-                                         xmit_type);
+                       bnx2x_set_pbd_gso(skb, pbd_e1x, first_bd, xmit_type);
        }
 
        /* Set the PBD's parsing_data field if not zero
index 1f2dd92..0f493c8 100644 (file)
@@ -9468,6 +9468,14 @@ static void tg3_rss_write_indir_tbl(struct tg3 *tp)
        }
 }
 
+static inline u32 tg3_lso_rd_dma_workaround_bit(struct tg3 *tp)
+{
+       if (tg3_asic_rev(tp) == ASIC_REV_5719)
+               return TG3_LSO_RD_DMA_TX_LENGTH_WA_5719;
+       else
+               return TG3_LSO_RD_DMA_TX_LENGTH_WA_5720;
+}
+
 /* tp->lock is held. */
 static int tg3_reset_hw(struct tg3 *tp, bool reset_phy)
 {
@@ -10153,16 +10161,17 @@ static int tg3_reset_hw(struct tg3 *tp, bool reset_phy)
        tw32_f(RDMAC_MODE, rdmac_mode);
        udelay(40);
 
-       if (tg3_asic_rev(tp) == ASIC_REV_5719) {
+       if (tg3_asic_rev(tp) == ASIC_REV_5719 ||
+           tg3_asic_rev(tp) == ASIC_REV_5720) {
                for (i = 0; i < TG3_NUM_RDMA_CHANNELS; i++) {
                        if (tr32(TG3_RDMA_LENGTH + (i << 2)) > TG3_MAX_MTU(tp))
                                break;
                }
                if (i < TG3_NUM_RDMA_CHANNELS) {
                        val = tr32(TG3_LSO_RD_DMA_CRPTEN_CTRL);
-                       val |= TG3_LSO_RD_DMA_TX_LENGTH_WA;
+                       val |= tg3_lso_rd_dma_workaround_bit(tp);
                        tw32(TG3_LSO_RD_DMA_CRPTEN_CTRL, val);
-                       tg3_flag_set(tp, 5719_RDMA_BUG);
+                       tg3_flag_set(tp, 5719_5720_RDMA_BUG);
                }
        }
 
@@ -10526,15 +10535,15 @@ static void tg3_periodic_fetch_stats(struct tg3 *tp)
        TG3_STAT_ADD32(&sp->tx_ucast_packets, MAC_TX_STATS_UCAST);
        TG3_STAT_ADD32(&sp->tx_mcast_packets, MAC_TX_STATS_MCAST);
        TG3_STAT_ADD32(&sp->tx_bcast_packets, MAC_TX_STATS_BCAST);
-       if (unlikely(tg3_flag(tp, 5719_RDMA_BUG) &&
+       if (unlikely(tg3_flag(tp, 5719_5720_RDMA_BUG) &&
                     (sp->tx_ucast_packets.low + sp->tx_mcast_packets.low +
                      sp->tx_bcast_packets.low) > TG3_NUM_RDMA_CHANNELS)) {
                u32 val;
 
                val = tr32(TG3_LSO_RD_DMA_CRPTEN_CTRL);
-               val &= ~TG3_LSO_RD_DMA_TX_LENGTH_WA;
+               val &= ~tg3_lso_rd_dma_workaround_bit(tp);
                tw32(TG3_LSO_RD_DMA_CRPTEN_CTRL, val);
-               tg3_flag_clear(tp, 5719_RDMA_BUG);
+               tg3_flag_clear(tp, 5719_5720_RDMA_BUG);
        }
 
        TG3_STAT_ADD32(&sp->rx_octets, MAC_RX_STATS_OCTETS);
index 9b2d3ac..ff6e30e 100644 (file)
 #define TG3_LSO_RD_DMA_CRPTEN_CTRL     0x00004910
 #define TG3_LSO_RD_DMA_CRPTEN_CTRL_BLEN_BD_4K   0x00030000
 #define TG3_LSO_RD_DMA_CRPTEN_CTRL_BLEN_LSO_4K  0x000c0000
-#define TG3_LSO_RD_DMA_TX_LENGTH_WA     0x02000000
+#define TG3_LSO_RD_DMA_TX_LENGTH_WA_5719        0x02000000
+#define TG3_LSO_RD_DMA_TX_LENGTH_WA_5720        0x00200000
 /* 0x4914 --> 0x4be0 unused */
 
 #define TG3_NUM_RDMA_CHANNELS          4
@@ -3059,7 +3060,7 @@ enum TG3_FLAGS {
        TG3_FLAG_APE_HAS_NCSI,
        TG3_FLAG_TX_TSTAMP_EN,
        TG3_FLAG_4K_FIFO_LIMIT,
-       TG3_FLAG_5719_RDMA_BUG,
+       TG3_FLAG_5719_5720_RDMA_BUG,
        TG3_FLAG_RESET_TASK_PENDING,
        TG3_FLAG_PTP_CAPABLE,
        TG3_FLAG_5705_PLUS,
index f544b29..0a51068 100644 (file)
@@ -262,6 +262,7 @@ struct be_rx_compl_info {
        u8 ipv6;
        u8 vtm;
        u8 pkt_type;
+       u8 ip_frag;
 };
 
 struct be_rx_obj {
index a236ecd..1db2df6 100644 (file)
@@ -562,7 +562,7 @@ int lancer_test_and_set_rdy_state(struct be_adapter *adapter)
 
        resource_error = lancer_provisioning_error(adapter);
        if (resource_error)
-               return -1;
+               return -EAGAIN;
 
        status = lancer_wait_ready(adapter);
        if (!status) {
@@ -590,8 +590,8 @@ int lancer_test_and_set_rdy_state(struct be_adapter *adapter)
         * when PF provisions resources.
         */
        resource_error = lancer_provisioning_error(adapter);
-       if (status == -1 && !resource_error)
-               adapter->eeh_error = true;
+       if (resource_error)
+               status = -EAGAIN;
 
        return status;
 }
index 3c1099b..8780183 100644 (file)
@@ -356,7 +356,7 @@ struct amap_eth_rx_compl_v0 {
        u8 ip_version;          /* dword 1 */
        u8 macdst[6];           /* dword 1 */
        u8 vtp;                 /* dword 1 */
-       u8 rsvd0;               /* dword 1 */
+       u8 ip_frag;             /* dword 1 */
        u8 fragndx[10];         /* dword 1 */
        u8 ct[2];               /* dword 1 */
        u8 sw;                  /* dword 1 */
index ca2967b..8bc1b21 100644 (file)
@@ -1599,6 +1599,8 @@ static void be_parse_rx_compl_v0(struct be_eth_rx_compl *compl,
                                               compl);
        }
        rxcp->port = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, port, compl);
+       rxcp->ip_frag = AMAP_GET_BITS(struct amap_eth_rx_compl_v0,
+                                     ip_frag, compl);
 }
 
 static struct be_rx_compl_info *be_rx_compl_get(struct be_rx_obj *rxo)
@@ -1620,6 +1622,9 @@ static struct be_rx_compl_info *be_rx_compl_get(struct be_rx_obj *rxo)
        else
                be_parse_rx_compl_v0(compl, rxcp);
 
+       if (rxcp->ip_frag)
+               rxcp->l4_csum = 0;
+
        if (rxcp->vlanf) {
                /* vlanf could be wrongly set in some cards.
                 * ignore if vtm is not set */
@@ -2168,7 +2173,7 @@ static irqreturn_t be_msix(int irq, void *dev)
 
 static inline bool do_gro(struct be_rx_compl_info *rxcp)
 {
-       return (rxcp->tcpf && !rxcp->err) ? true : false;
+       return (rxcp->tcpf && !rxcp->err && rxcp->l4_csum) ? true : false;
 }
 
 static int be_process_rx(struct be_rx_obj *rxo, struct napi_struct *napi,
@@ -4093,6 +4098,7 @@ static int be_get_initial_config(struct be_adapter *adapter)
 
 static int lancer_recover_func(struct be_adapter *adapter)
 {
+       struct device *dev = &adapter->pdev->dev;
        int status;
 
        status = lancer_test_and_set_rdy_state(adapter);
@@ -4104,8 +4110,7 @@ static int lancer_recover_func(struct be_adapter *adapter)
 
        be_clear(adapter);
 
-       adapter->hw_error = false;
-       adapter->fw_timeout = false;
+       be_clear_all_error(adapter);
 
        status = be_setup(adapter);
        if (status)
@@ -4117,13 +4122,13 @@ static int lancer_recover_func(struct be_adapter *adapter)
                        goto err;
        }
 
-       dev_err(&adapter->pdev->dev,
-               "Adapter SLIPORT recovery succeeded\n");
+       dev_err(dev, "Error recovery successful\n");
        return 0;
 err:
-       if (adapter->eeh_error)
-               dev_err(&adapter->pdev->dev,
-                       "Adapter SLIPORT recovery failed\n");
+       if (status == -EAGAIN)
+               dev_err(dev, "Waiting for resource provisioning\n");
+       else
+               dev_err(dev, "Error recovery failed\n");
 
        return status;
 }
@@ -4132,28 +4137,27 @@ static void be_func_recovery_task(struct work_struct *work)
 {
        struct be_adapter *adapter =
                container_of(work, struct be_adapter,  func_recovery_work.work);
-       int status;
+       int status = 0;
 
        be_detect_error(adapter);
 
        if (adapter->hw_error && lancer_chip(adapter)) {
 
-               if (adapter->eeh_error)
-                       goto out;
-
                rtnl_lock();
                netif_device_detach(adapter->netdev);
                rtnl_unlock();
 
                status = lancer_recover_func(adapter);
-
                if (!status)
                        netif_device_attach(adapter->netdev);
        }
 
-out:
-       schedule_delayed_work(&adapter->func_recovery_work,
-                             msecs_to_jiffies(1000));
+       /* In Lancer, for all errors other than provisioning error (-EAGAIN),
+        * no need to attempt further recovery.
+        */
+       if (!status || status == -EAGAIN)
+               schedule_delayed_work(&adapter->func_recovery_work,
+                                     msecs_to_jiffies(1000));
 }
 
 static void be_worker(struct work_struct *work)
@@ -4436,20 +4440,19 @@ static pci_ers_result_t be_eeh_err_detected(struct pci_dev *pdev,
 
        dev_err(&adapter->pdev->dev, "EEH error detected\n");
 
-       adapter->eeh_error = true;
-
-       cancel_delayed_work_sync(&adapter->func_recovery_work);
+       if (!adapter->eeh_error) {
+               adapter->eeh_error = true;
 
-       rtnl_lock();
-       netif_device_detach(netdev);
-       rtnl_unlock();
+               cancel_delayed_work_sync(&adapter->func_recovery_work);
 
-       if (netif_running(netdev)) {
                rtnl_lock();
-               be_close(netdev);
+               netif_device_detach(netdev);
+               if (netif_running(netdev))
+                       be_close(netdev);
                rtnl_unlock();
+
+               be_clear(adapter);
        }
-       be_clear(adapter);
 
        if (state == pci_channel_io_perm_failure)
                return PCI_ERS_RESULT_DISCONNECT;
@@ -4474,7 +4477,6 @@ static pci_ers_result_t be_eeh_reset(struct pci_dev *pdev)
        int status;
 
        dev_info(&adapter->pdev->dev, "EEH reset\n");
-       be_clear_all_error(adapter);
 
        status = pci_enable_device(pdev);
        if (status)
@@ -4492,6 +4494,7 @@ static pci_ers_result_t be_eeh_reset(struct pci_dev *pdev)
                return PCI_ERS_RESULT_DISCONNECT;
 
        pci_cleanup_aer_uncorrect_error_status(pdev);
+       be_clear_all_error(adapter);
        return PCI_ERS_RESULT_RECOVERED;
 }
 
index 85a0603..a667015 100644 (file)
@@ -1038,6 +1038,18 @@ static void fec_get_mac(struct net_device *ndev)
                iap = &tmpaddr[0];
        }
 
+       /*
+        * 5) random mac address
+        */
+       if (!is_valid_ether_addr(iap)) {
+               /* Report it and use a random ethernet address instead */
+               netdev_err(ndev, "Invalid MAC address: %pM\n", iap);
+               eth_hw_addr_random(ndev);
+               netdev_info(ndev, "Using random MAC address: %pM\n",
+                           ndev->dev_addr);
+               return;
+       }
+
        memcpy(ndev->dev_addr, iap, ETH_ALEN);
 
        /* Adjust MAC if using macaddr */
index 1df56cc..0e572a5 100644 (file)
@@ -222,8 +222,6 @@ static int mlx4_comm_cmd_poll(struct mlx4_dev *dev, u8 cmd, u16 param,
                 * FLR process. The only non-zero result in the RESET command
                 * is MLX4_DELAY_RESET_SLAVE*/
                if ((MLX4_COMM_CMD_RESET == cmd)) {
-                       mlx4_warn(dev, "Got slave FLRed from Communication"
-                                 " channel (ret:0x%x)\n", ret_from_pending);
                        err = MLX4_DELAY_RESET_SLAVE;
                } else {
                        mlx4_warn(dev, "Communication channel timed out\n");
index b35f947..89c47ea 100644 (file)
@@ -1323,6 +1323,7 @@ static void mlx4_en_auto_moderation(struct mlx4_en_priv *priv)
                        priv->last_moder_time[ring] = moder_time;
                        cq = &priv->rx_cq[ring];
                        cq->moder_time = moder_time;
+                       cq->moder_cnt = priv->rx_frames;
                        err = mlx4_en_set_cq_moder(priv, cq);
                        if (err)
                                en_err(priv, "Failed modifying moderation for cq:%d\n",
@@ -2118,6 +2119,7 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
        struct mlx4_en_priv *priv;
        int i;
        int err;
+       u64 mac_u64;
 
        dev = alloc_etherdev_mqs(sizeof(struct mlx4_en_priv),
                                 MAX_TX_RINGS, MAX_RX_RINGS);
@@ -2191,10 +2193,17 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
        dev->addr_len = ETH_ALEN;
        mlx4_en_u64_to_mac(dev->dev_addr, mdev->dev->caps.def_mac[priv->port]);
        if (!is_valid_ether_addr(dev->dev_addr)) {
-               en_err(priv, "Port: %d, invalid mac burned: %pM, quiting\n",
-                      priv->port, dev->dev_addr);
-               err = -EINVAL;
-               goto out;
+               if (mlx4_is_slave(priv->mdev->dev)) {
+                       eth_hw_addr_random(dev);
+                       en_warn(priv, "Assigned random MAC address %pM\n", dev->dev_addr);
+                       mac_u64 = mlx4_en_mac_to_u64(dev->dev_addr);
+                       mdev->dev->caps.def_mac[priv->port] = mac_u64;
+               } else {
+                       en_err(priv, "Port: %d, invalid mac burned: %pM, quiting\n",
+                              priv->port, dev->dev_addr);
+                       err = -EINVAL;
+                       goto out;
+               }
        }
 
        memcpy(priv->prev_mac, dev->dev_addr, sizeof(priv->prev_mac));
index 58a8e53..2c97901 100644 (file)
@@ -840,12 +840,16 @@ int mlx4_QUERY_PORT_wrapper(struct mlx4_dev *dev, int slave,
                           MLX4_CMD_NATIVE);
 
        if (!err && dev->caps.function != slave) {
-               /* set slave default_mac address */
-               MLX4_GET(def_mac, outbox->buf, QUERY_PORT_MAC_OFFSET);
-               def_mac += slave << 8;
                /* if config MAC in DB use it */
                if (priv->mfunc.master.vf_oper[slave].vport[vhcr->in_modifier].state.mac)
                        def_mac = priv->mfunc.master.vf_oper[slave].vport[vhcr->in_modifier].state.mac;
+               else {
+                       /* set slave default_mac address */
+                       MLX4_GET(def_mac, outbox->buf, QUERY_PORT_MAC_OFFSET);
+                       def_mac += slave << 8;
+                       priv->mfunc.master.vf_admin[slave].vport[vhcr->in_modifier].mac = def_mac;
+               }
+
                MLX4_PUT(outbox->buf, def_mac, QUERY_PORT_MAC_OFFSET);
 
                /* get port type - currently only eth is enabled */
index 0d32a82..2f4a260 100644 (file)
@@ -1290,7 +1290,6 @@ static int mlx4_init_slave(struct mlx4_dev *dev)
 {
        struct mlx4_priv *priv = mlx4_priv(dev);
        u64 dma = (u64) priv->mfunc.vhcr_dma;
-       int num_of_reset_retries = NUM_OF_RESET_RETRIES;
        int ret_from_reset = 0;
        u32 slave_read;
        u32 cmd_channel_ver;
@@ -1304,18 +1303,10 @@ static int mlx4_init_slave(struct mlx4_dev *dev)
         * NUM_OF_RESET_RETRIES times before leaving.*/
        if (ret_from_reset) {
                if (MLX4_DELAY_RESET_SLAVE == ret_from_reset) {
-                       msleep(SLEEP_TIME_IN_RESET);
-                       while (ret_from_reset && num_of_reset_retries) {
-                               mlx4_warn(dev, "slave is currently in the"
-                                         "middle of FLR. retrying..."
-                                         "(try num:%d)\n",
-                                         (NUM_OF_RESET_RETRIES -
-                                          num_of_reset_retries  + 1));
-                               ret_from_reset =
-                                       mlx4_comm_cmd(dev, MLX4_COMM_CMD_RESET,
-                                                     0, MLX4_COMM_TIME);
-                               num_of_reset_retries = num_of_reset_retries - 1;
-                       }
+                       mlx4_warn(dev, "slave is currently in the "
+                                 "middle of FLR. Deferring probe.\n");
+                       mutex_unlock(&priv->cmd.slave_cmd_mutex);
+                       return -EPROBE_DEFER;
                } else
                        goto err;
        }
@@ -1526,7 +1517,8 @@ static int mlx4_init_hca(struct mlx4_dev *dev)
        } else {
                err = mlx4_init_slave(dev);
                if (err) {
-                       mlx4_err(dev, "Failed to initialize slave\n");
+                       if (err != -EPROBE_DEFER)
+                               mlx4_err(dev, "Failed to initialize slave\n");
                        return err;
                }
 
index 50235d2..f87cc21 100644 (file)
@@ -4717,6 +4717,7 @@ static int qlge_probe(struct pci_dev *pdev,
                dev_err(&pdev->dev, "net device registration failed.\n");
                ql_release_all(pdev);
                pci_disable_device(pdev);
+               free_netdev(ndev);
                return err;
        }
        /* Start up the timer to trigger EEH if
index 919b983..b7268b3 100644 (file)
@@ -946,7 +946,8 @@ static int xemaclite_open(struct net_device *dev)
                phy_write(lp->phy_dev, MII_CTRL1000, 0);
 
                /* Advertise only 10 and 100mbps full/half duplex speeds */
-               phy_write(lp->phy_dev, MII_ADVERTISE, ADVERTISE_ALL);
+               phy_write(lp->phy_dev, MII_ADVERTISE, ADVERTISE_ALL |
+                         ADVERTISE_CSMA);
 
                /* Restart auto negotiation */
                bmcr = phy_read(lp->phy_dev, MII_BMCR);
index 088c554..ab2307b 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/inetdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
+#include <linux/if_vlan.h>
 #include <linux/in.h>
 #include <linux/slab.h>
 #include <net/arp.h>
@@ -284,7 +285,7 @@ int netvsc_recv_callback(struct hv_device *device_obj,
 
        skb->protocol = eth_type_trans(skb, net);
        skb->ip_summed = CHECKSUM_NONE;
-       skb->vlan_tci = packet->vlan_tci;
+       __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), packet->vlan_tci);
 
        net->stats.rx_packets++;
        net->stats.rx_bytes += packet->total_data_buflen;
index c14f147..38f0b31 100644 (file)
@@ -1044,7 +1044,7 @@ int phy_init_eee(struct phy_device *phydev, bool clk_stop_enable)
                adv = mmd_eee_adv_to_ethtool_adv_t(eee_adv);
                lp = mmd_eee_adv_to_ethtool_adv_t(eee_lp);
                idx = phy_find_setting(phydev->speed, phydev->duplex);
-               if ((lp & adv & settings[idx].setting))
+               if (!(lp & adv & settings[idx].setting))
                        goto eee_exit;
 
                if (clk_stop_enable) {
index 7c43261..d016a76 100644 (file)
@@ -2374,7 +2374,8 @@ static int team_nl_send_port_list_get(struct team *team, u32 portid, u32 seq,
        bool incomplete;
        int i;
 
-       port = list_first_entry(&team->port_list, struct team_port, list);
+       port = list_first_entry_or_null(&team->port_list,
+                                       struct team_port, list);
 
 start_again:
        err = __send_and_alloc_skb(&skb, team, portid, send_func);
@@ -2402,8 +2403,8 @@ start_again:
                err = team_nl_fill_one_port_get(skb, one_port);
                if (err)
                        goto errout;
-       } else {
-               list_for_each_entry(port, &team->port_list, list) {
+       } else if (port) {
+               list_for_each_entry_from(port, &team->port_list, list) {
                        err = team_nl_fill_one_port_get(skb, port);
                        if (err) {
                                if (err == -EMSGSIZE) {
index f042b03..89776c5 100644 (file)
@@ -1585,6 +1585,10 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
                else
                        return -EINVAL;
 
+               if (!!(ifr->ifr_flags & IFF_MULTI_QUEUE) !=
+                   !!(tun->flags & TUN_TAP_MQ))
+                       return -EINVAL;
+
                if (tun_not_capable(tun))
                        return -EPERM;
                err = security_tun_dev_open(tun->security);
index 54ba42f..874f657 100644 (file)
 #define AR9300_BASE_ADDR 0x3ff
 #define AR9300_BASE_ADDR_512 0x1ff
 
-#define AR9300_OTP_BASE                        (AR_SREV_9340(ah) ? 0x30000 : 0x14000)
-#define AR9300_OTP_STATUS              (AR_SREV_9340(ah) ? 0x30018 : 0x15f18)
+#define AR9300_OTP_BASE \
+               ((AR_SREV_9340(ah) || AR_SREV_9550(ah)) ? 0x30000 : 0x14000)
+#define AR9300_OTP_STATUS \
+               ((AR_SREV_9340(ah) || AR_SREV_9550(ah)) ? 0x30018 : 0x15f18)
 #define AR9300_OTP_STATUS_TYPE         0x7
 #define AR9300_OTP_STATUS_VALID                0x4
 #define AR9300_OTP_STATUS_ACCESS_BUSY  0x2
 #define AR9300_OTP_STATUS_SM_BUSY      0x1
-#define AR9300_OTP_READ_DATA           (AR_SREV_9340(ah) ? 0x3001c : 0x15f1c)
+#define AR9300_OTP_READ_DATA \
+               ((AR_SREV_9340(ah) || AR_SREV_9550(ah)) ? 0x3001c : 0x15f1c)
 
 enum targetPowerHTRates {
        HT_TARGET_RATE_0_8_16,
index 2bf6548..e1714d7 100644 (file)
@@ -334,7 +334,8 @@ static void ar9003_hw_spur_ofdm(struct ath_hw *ah,
        REG_RMW_FIELD(ah, AR_PHY_SPUR_REG,
                      AR_PHY_SPUR_REG_EN_VIT_SPUR_RSSI, 1);
 
-       if (REG_READ_FIELD(ah, AR_PHY_MODE,
+       if (!AR_SREV_9340(ah) &&
+           REG_READ_FIELD(ah, AR_PHY_MODE,
                           AR_PHY_MODE_DYNAMIC) == 0x1)
                REG_RMW_FIELD(ah, AR_PHY_SPUR_REG,
                              AR_PHY_SPUR_REG_ENABLE_NF_RSSI_SPUR_MIT, 1);
index 366002f..42b03dc 100644 (file)
@@ -251,10 +251,9 @@ struct ath_atx_tid {
        int tidno;
        int baw_head;   /* first un-acked tx buffer */
        int baw_tail;   /* next unused tx buffer slot */
-       int sched;
-       int paused;
-       u8 state;
-       bool stop_cb;
+       bool sched;
+       bool paused;
+       bool active;
 };
 
 struct ath_node {
@@ -275,10 +274,6 @@ struct ath_node {
 #endif
 };
 
-#define AGGR_CLEANUP         BIT(1)
-#define AGGR_ADDBA_COMPLETE  BIT(2)
-#define AGGR_ADDBA_PROGRESS  BIT(3)
-
 struct ath_tx_control {
        struct ath_txq *txq;
        struct ath_node *an;
@@ -352,8 +347,7 @@ void ath_tx_tasklet(struct ath_softc *sc);
 void ath_tx_edma_tasklet(struct ath_softc *sc);
 int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
                      u16 tid, u16 *ssn);
-bool ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid,
-                     bool flush);
+void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid);
 void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid);
 
 void ath_tx_aggr_wakeup(struct ath_softc *sc, struct ath_node *an);
index 7f25da8..15dfefc 100644 (file)
@@ -1172,6 +1172,7 @@ u32 ath9k_regd_get_ctl(struct ath_regulatory *reg, struct ath9k_channel *chan)
 static inline void ath9k_hw_set_dma(struct ath_hw *ah)
 {
        struct ath_common *common = ath9k_hw_common(ah);
+       int txbuf_size;
 
        ENABLE_REGWRITE_BUFFER(ah);
 
@@ -1225,13 +1226,17 @@ static inline void ath9k_hw_set_dma(struct ath_hw *ah)
                 * So set the usable tx buf size also to half to
                 * avoid data/delimiter underruns
                 */
-               REG_WRITE(ah, AR_PCU_TXBUF_CTRL,
-                         AR_9285_PCU_TXBUF_CTRL_USABLE_SIZE);
-       } else if (!AR_SREV_9271(ah)) {
-               REG_WRITE(ah, AR_PCU_TXBUF_CTRL,
-                         AR_PCU_TXBUF_CTRL_USABLE_SIZE);
+               txbuf_size = AR_9285_PCU_TXBUF_CTRL_USABLE_SIZE;
+       } else if (AR_SREV_9340_13_OR_LATER(ah)) {
+               /* Uses fewer entries for AR934x v1.3+ to prevent rx overruns */
+               txbuf_size = AR_9340_PCU_TXBUF_CTRL_USABLE_SIZE;
+       } else {
+               txbuf_size = AR_PCU_TXBUF_CTRL_USABLE_SIZE;
        }
 
+       if (!AR_SREV_9271(ah))
+               REG_WRITE(ah, AR_PCU_TXBUF_CTRL, txbuf_size);
+
        REGWRITE_BUFFER_FLUSH(ah);
 
        if (AR_SREV_9300_20_OR_LATER(ah))
@@ -1306,9 +1311,13 @@ static bool ath9k_hw_set_reset(struct ath_hw *ah, int type)
                        AR_RTC_RC_COLD_RESET | AR_RTC_RC_WARM_RESET;
        } else {
                tmpReg = REG_READ(ah, AR_INTR_SYNC_CAUSE);
-               if (tmpReg &
-                   (AR_INTR_SYNC_LOCAL_TIMEOUT |
-                    AR_INTR_SYNC_RADM_CPL_TIMEOUT)) {
+               if (AR_SREV_9340(ah))
+                       tmpReg &= AR9340_INTR_SYNC_LOCAL_TIMEOUT;
+               else
+                       tmpReg &= AR_INTR_SYNC_LOCAL_TIMEOUT |
+                                 AR_INTR_SYNC_RADM_CPL_TIMEOUT;
+
+               if (tmpReg) {
                        u32 val;
                        REG_WRITE(ah, AR_INTR_SYNC_ENABLE, 0);
 
index 498fee0..566109a 100644 (file)
@@ -410,7 +410,7 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
 
        REG_WRITE(ah, AR_QMISC(q), AR_Q_MISC_DCU_EARLY_TERM_REQ);
 
-       if (AR_SREV_9340(ah))
+       if (AR_SREV_9340(ah) && !AR_SREV_9340_13_OR_LATER(ah))
                REG_WRITE(ah, AR_DMISC(q),
                          AR_D_MISC_CW_BKOFF_EN | AR_D_MISC_FRAG_WAIT_EN | 0x1);
        else
index 2382d12..5092eca 100644 (file)
@@ -1709,7 +1709,8 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw,
                flush = true;
        case IEEE80211_AMPDU_TX_STOP_CONT:
                ath9k_ps_wakeup(sc);
-               if (ath_tx_aggr_stop(sc, sta, tid, flush))
+               ath_tx_aggr_stop(sc, sta, tid);
+               if (!flush)
                        ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
                ath9k_ps_restore(sc);
                break;
index aa4d368..7eb1f4b 100644 (file)
@@ -1227,10 +1227,7 @@ static bool ath_tx_aggr_check(struct ath_softc *sc, struct ieee80211_sta *sta,
                return false;
 
        txtid = ATH_AN_2_TID(an, tidno);
-
-       if (!(txtid->state & (AGGR_ADDBA_COMPLETE | AGGR_ADDBA_PROGRESS)))
-                       return true;
-       return false;
+       return !txtid->active;
 }
 
 
index 5c4ab50..f7c90cc 100644 (file)
 #define AR_SREV_REVISION_9485_10       0
 #define AR_SREV_REVISION_9485_11        1
 #define AR_SREV_VERSION_9340           0x300
+#define AR_SREV_REVISION_9340_10       0
+#define AR_SREV_REVISION_9340_11       1
+#define AR_SREV_REVISION_9340_12       2
+#define AR_SREV_REVISION_9340_13       3
 #define AR_SREV_VERSION_9580           0x1C0
 #define AR_SREV_REVISION_9580_10       4 /* AR9580 1.0 */
 #define AR_SREV_VERSION_9462           0x280
 #define AR_SREV_9340(_ah) \
        (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9340))
 
+#define AR_SREV_9340_13_OR_LATER(_ah) \
+       (AR_SREV_9340((_ah)) && \
+        ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9340_13))
+
 #define AR_SREV_9285E_20(_ah) \
     (AR_SREV_9285_12_OR_LATER(_ah) && \
      ((REG_READ(_ah, AR_AN_SYNTH9) & 0x7) == 0x1))
@@ -1007,6 +1015,8 @@ enum {
                                AR_INTR_SYNC_LOCAL_TIMEOUT |
                                AR_INTR_SYNC_MAC_SLEEP_ACCESS),
 
+       AR9340_INTR_SYNC_LOCAL_TIMEOUT = 0x00000010,
+
        AR_INTR_SYNC_SPURIOUS = 0xFFFFFFFF,
 
 };
@@ -1881,6 +1891,7 @@ enum {
 #define AR_PCU_TXBUF_CTRL_SIZE_MASK     0x7FF
 #define AR_PCU_TXBUF_CTRL_USABLE_SIZE   0x700
 #define AR_9285_PCU_TXBUF_CTRL_USABLE_SIZE   0x380
+#define AR_9340_PCU_TXBUF_CTRL_USABLE_SIZE   0x500
 
 #define AR_PCU_MISC_MODE2               0x8344
 #define AR_PCU_MISC_MODE2_MGMT_CRYPTO_ENABLE           0x00000002
index 14bb335..1c9b1ba 100644 (file)
@@ -125,24 +125,6 @@ static void ath_tx_queue_tid(struct ath_txq *txq, struct ath_atx_tid *tid)
        list_add_tail(&ac->list, &txq->axq_acq);
 }
 
-static void ath_tx_resume_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
-{
-       struct ath_txq *txq = tid->ac->txq;
-
-       WARN_ON(!tid->paused);
-
-       ath_txq_lock(sc, txq);
-       tid->paused = false;
-
-       if (skb_queue_empty(&tid->buf_q))
-               goto unlock;
-
-       ath_tx_queue_tid(txq, tid);
-       ath_txq_schedule(sc, txq);
-unlock:
-       ath_txq_unlock_complete(sc, txq);
-}
-
 static struct ath_frame_info *get_frame_info(struct sk_buff *skb)
 {
        struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
@@ -164,20 +146,7 @@ static void ath_set_rates(struct ieee80211_vif *vif, struct ieee80211_sta *sta,
                               ARRAY_SIZE(bf->rates));
 }
 
-static void ath_tx_clear_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
-{
-       tid->state &= ~AGGR_ADDBA_COMPLETE;
-       tid->state &= ~AGGR_CLEANUP;
-       if (!tid->stop_cb)
-               return;
-
-       ieee80211_start_tx_ba_cb_irqsafe(tid->an->vif, tid->an->sta->addr,
-                                        tid->tidno);
-       tid->stop_cb = false;
-}
-
-static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid,
-                            bool flush_packets)
+static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
 {
        struct ath_txq *txq = tid->ac->txq;
        struct sk_buff *skb;
@@ -194,15 +163,16 @@ static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid,
        while ((skb = __skb_dequeue(&tid->buf_q))) {
                fi = get_frame_info(skb);
                bf = fi->bf;
-               if (!bf && !flush_packets)
-                       bf = ath_tx_setup_buffer(sc, txq, tid, skb);
 
                if (!bf) {
-                       ieee80211_free_txskb(sc->hw, skb);
-                       continue;
+                       bf = ath_tx_setup_buffer(sc, txq, tid, skb);
+                       if (!bf) {
+                               ieee80211_free_txskb(sc->hw, skb);
+                               continue;
+                       }
                }
 
-               if (fi->retries || flush_packets) {
+               if (fi->retries) {
                        list_add_tail(&bf->list, &bf_head);
                        ath_tx_update_baw(sc, tid, bf->bf_state.seqno);
                        ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0);
@@ -213,10 +183,7 @@ static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid,
                }
        }
 
-       if (tid->baw_head == tid->baw_tail)
-               ath_tx_clear_tid(sc, tid);
-
-       if (sendbar && !flush_packets) {
+       if (sendbar) {
                ath_txq_unlock(sc, txq);
                ath_send_bar(tid, tid->seq_start);
                ath_txq_lock(sc, txq);
@@ -499,19 +466,19 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
                tx_info = IEEE80211_SKB_CB(skb);
                fi = get_frame_info(skb);
 
-               if (ATH_BA_ISSET(ba, ATH_BA_INDEX(seq_st, seqno))) {
+               if (!BAW_WITHIN(tid->seq_start, tid->baw_size, seqno)) {
+                       /*
+                        * Outside of the current BlockAck window,
+                        * maybe part of a previous session
+                        */
+                       txfail = 1;
+               } else if (ATH_BA_ISSET(ba, ATH_BA_INDEX(seq_st, seqno))) {
                        /* transmit completion, subframe is
                         * acked by block ack */
                        acked_cnt++;
                } else if (!isaggr && txok) {
                        /* transmit completion */
                        acked_cnt++;
-               } else if (tid->state & AGGR_CLEANUP) {
-                       /*
-                        * cleanup in progress, just fail
-                        * the un-acked sub-frames
-                        */
-                       txfail = 1;
                } else if (flush) {
                        txpending = 1;
                } else if (fi->retries < ATH_MAX_SW_RETRIES) {
@@ -535,7 +502,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
                if (bf_next != NULL || !bf_last->bf_stale)
                        list_move_tail(&bf->list, &bf_head);
 
-               if (!txpending || (tid->state & AGGR_CLEANUP)) {
+               if (!txpending) {
                        /*
                         * complete the acked-ones/xretried ones; update
                         * block-ack window
@@ -609,9 +576,6 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
                ath_txq_lock(sc, txq);
        }
 
-       if (tid->state & AGGR_CLEANUP)
-               ath_tx_flush_tid(sc, tid, false);
-
        rcu_read_unlock();
 
        if (needreset)
@@ -1244,9 +1208,6 @@ int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
        an = (struct ath_node *)sta->drv_priv;
        txtid = ATH_AN_2_TID(an, tid);
 
-       if (txtid->state & (AGGR_CLEANUP | AGGR_ADDBA_COMPLETE))
-               return -EAGAIN;
-
        /* update ampdu factor/density, they may have changed. This may happen
         * in HT IBSS when a beacon with HT-info is received after the station
         * has already been added.
@@ -1258,7 +1219,7 @@ int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
                an->mpdudensity = density;
        }
 
-       txtid->state |= AGGR_ADDBA_PROGRESS;
+       txtid->active = true;
        txtid->paused = true;
        *ssn = txtid->seq_start = txtid->seq_next;
        txtid->bar_index = -1;
@@ -1269,45 +1230,17 @@ int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
        return 0;
 }
 
-bool ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid,
-                     bool flush)
+void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid)
 {
        struct ath_node *an = (struct ath_node *)sta->drv_priv;
        struct ath_atx_tid *txtid = ATH_AN_2_TID(an, tid);
        struct ath_txq *txq = txtid->ac->txq;
-       bool ret = !flush;
-
-       if (flush)
-               txtid->stop_cb = false;
-
-       if (txtid->state & AGGR_CLEANUP)
-               return false;
-
-       if (!(txtid->state & AGGR_ADDBA_COMPLETE)) {
-               txtid->state &= ~AGGR_ADDBA_PROGRESS;
-               return ret;
-       }
 
        ath_txq_lock(sc, txq);
+       txtid->active = false;
        txtid->paused = true;
-
-       /*
-        * If frames are still being transmitted for this TID, they will be
-        * cleaned up during tx completion. To prevent race conditions, this
-        * TID can only be reused after all in-progress subframes have been
-        * completed.
-        */
-       if (txtid->baw_head != txtid->baw_tail) {
-               txtid->state |= AGGR_CLEANUP;
-               ret = false;
-               txtid->stop_cb = !flush;
-       } else {
-               txtid->state &= ~AGGR_ADDBA_COMPLETE;
-       }
-
-       ath_tx_flush_tid(sc, txtid, flush);
+       ath_tx_flush_tid(sc, txtid);
        ath_txq_unlock_complete(sc, txq);
-       return ret;
 }
 
 void ath_tx_aggr_sleep(struct ieee80211_sta *sta, struct ath_softc *sc,
@@ -1371,18 +1304,28 @@ void ath_tx_aggr_wakeup(struct ath_softc *sc, struct ath_node *an)
        }
 }
 
-void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid)
+void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta,
+                       u16 tidno)
 {
-       struct ath_atx_tid *txtid;
+       struct ath_atx_tid *tid;
        struct ath_node *an;
+       struct ath_txq *txq;
 
        an = (struct ath_node *)sta->drv_priv;
+       tid = ATH_AN_2_TID(an, tidno);
+       txq = tid->ac->txq;
 
-       txtid = ATH_AN_2_TID(an, tid);
-       txtid->baw_size = IEEE80211_MIN_AMPDU_BUF << sta->ht_cap.ampdu_factor;
-       txtid->state |= AGGR_ADDBA_COMPLETE;
-       txtid->state &= ~AGGR_ADDBA_PROGRESS;
-       ath_tx_resume_tid(sc, txtid);
+       ath_txq_lock(sc, txq);
+
+       tid->baw_size = IEEE80211_MIN_AMPDU_BUF << sta->ht_cap.ampdu_factor;
+       tid->paused = false;
+
+       if (!skb_queue_empty(&tid->buf_q)) {
+               ath_tx_queue_tid(txq, tid);
+               ath_txq_schedule(sc, txq);
+       }
+
+       ath_txq_unlock_complete(sc, txq);
 }
 
 /********************/
@@ -2431,13 +2374,10 @@ void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an)
                tid->baw_head  = tid->baw_tail = 0;
                tid->sched     = false;
                tid->paused    = false;
-               tid->state &= ~AGGR_CLEANUP;
+               tid->active        = false;
                __skb_queue_head_init(&tid->buf_q);
                acno = TID_TO_WME_AC(tidno);
                tid->ac = &an->ac[acno];
-               tid->state &= ~AGGR_ADDBA_COMPLETE;
-               tid->state &= ~AGGR_ADDBA_PROGRESS;
-               tid->stop_cb = false;
        }
 
        for (acno = 0, ac = &an->ac[acno];
@@ -2474,7 +2414,7 @@ void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an)
                }
 
                ath_tid_drain(sc, txq, tid);
-               ath_tx_clear_tid(sc, tid);
+               tid->active = false;
 
                ath_txq_unlock(sc, txq);
        }
index 830bb1d..b827d51 100644 (file)
@@ -1624,7 +1624,7 @@ struct net_device *init_atmel_card(unsigned short irq, unsigned long port,
 
        netif_carrier_off(dev);
 
-       if (!proc_create_data("driver/atmel", 0, NULL, &atmel_proc_fops, priv));
+       if (!proc_create_data("driver/atmel", 0, NULL, &atmel_proc_fops, priv))
                printk(KERN_WARNING "atmel: unable to create /proc entry.\n");
 
        printk(KERN_INFO "%s: Atmel at76c50x. Version %d.%d. MAC %pM\n",
index be0787c..9431af2 100644 (file)
@@ -27,7 +27,6 @@
 #include "tracepoint.h"
 
 #define PKTFILTER_BUF_SIZE             128
-#define BRCMF_ARPOL_MODE               0xb     /* agent|snoop|peer_autoreply */
 #define BRCMF_DEFAULT_BCN_TIMEOUT      3
 #define BRCMF_DEFAULT_SCAN_CHANNEL_TIME        40
 #define BRCMF_DEFAULT_SCAN_UNASSOC_TIME        40
@@ -338,23 +337,6 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
                goto done;
        }
 
-       /* Try to set and enable ARP offload feature, this may fail */
-       err = brcmf_fil_iovar_int_set(ifp, "arp_ol", BRCMF_ARPOL_MODE);
-       if (err) {
-               brcmf_dbg(TRACE, "failed to set ARP offload mode to 0x%x, err = %d\n",
-                         BRCMF_ARPOL_MODE, err);
-               err = 0;
-       } else {
-               err = brcmf_fil_iovar_int_set(ifp, "arpoe", 1);
-               if (err) {
-                       brcmf_dbg(TRACE, "failed to enable ARP offload err = %d\n",
-                                 err);
-                       err = 0;
-               } else
-                       brcmf_dbg(TRACE, "successfully enabled ARP offload to 0x%x\n",
-                                 BRCMF_ARPOL_MODE);
-       }
-
        /* Setup packet filter */
        brcmf_c_pktfilter_offload_set(ifp, BRCMF_DEFAULT_PACKET_FILTER);
        brcmf_c_pktfilter_offload_enable(ifp, BRCMF_DEFAULT_PACKET_FILTER,
index 59c2546..b98f223 100644 (file)
@@ -653,10 +653,13 @@ int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked)
 
        brcmf_dbg(INFO, "%s: Broadcom Dongle Host Driver\n", ndev->name);
 
+       ndev->destructor = free_netdev;
        return 0;
 
 fail:
+       drvr->iflist[ifp->bssidx] = NULL;
        ndev->netdev_ops = NULL;
+       free_netdev(ndev);
        return -EBADE;
 }
 
@@ -720,6 +723,9 @@ static int brcmf_net_p2p_attach(struct brcmf_if *ifp)
        return 0;
 
 fail:
+       ifp->drvr->iflist[ifp->bssidx] = NULL;
+       ndev->netdev_ops = NULL;
+       free_netdev(ndev);
        return -EBADE;
 }
 
@@ -788,6 +794,7 @@ void brcmf_del_if(struct brcmf_pub *drvr, s32 bssidx)
        struct brcmf_if *ifp;
 
        ifp = drvr->iflist[bssidx];
+       drvr->iflist[bssidx] = NULL;
        if (!ifp) {
                brcmf_err("Null interface, idx=%d\n", bssidx);
                return;
@@ -808,15 +815,13 @@ void brcmf_del_if(struct brcmf_pub *drvr, s32 bssidx)
                        cancel_work_sync(&ifp->setmacaddr_work);
                        cancel_work_sync(&ifp->multicast_work);
                }
-
+               /* unregister will take care of freeing it */
                unregister_netdev(ifp->ndev);
                if (bssidx == 0)
                        brcmf_cfg80211_detach(drvr->config);
-               free_netdev(ifp->ndev);
        } else {
                kfree(ifp);
        }
-       drvr->iflist[bssidx] = NULL;
 }
 
 int brcmf_attach(uint bus_hdrlen, struct device *dev)
@@ -925,8 +930,6 @@ fail:
                        brcmf_fws_del_interface(ifp);
                        brcmf_fws_deinit(drvr);
                }
-               free_netdev(ifp->ndev);
-               drvr->iflist[0] = NULL;
                if (p2p_ifp) {
                        free_netdev(p2p_ifp->ndev);
                        drvr->iflist[1] = NULL;
@@ -934,7 +937,8 @@ fail:
                return ret;
        }
        if ((brcmf_p2p_enable) && (p2p_ifp))
-               brcmf_net_p2p_attach(p2p_ifp);
+               if (brcmf_net_p2p_attach(p2p_ifp) < 0)
+                       brcmf_p2p_enable = 0;
 
        return 0;
 }
index 5a64280..83ee53a 100644 (file)
@@ -202,7 +202,8 @@ static void brcmf_fweh_handle_if_event(struct brcmf_pub *drvr,
                        return;
                brcmf_fws_add_interface(ifp);
                if (!drvr->fweh.evt_handler[BRCMF_E_IF])
-                       err = brcmf_net_attach(ifp, false);
+                       if (brcmf_net_attach(ifp, false) < 0)
+                               return;
        }
 
        if (ifevent->action == BRCMF_E_IF_CHANGE)
index 0f2c83b..665ef69 100644 (file)
 
 #define BRCMF_FIL_ACTION_FRAME_SIZE    1800
 
+/* ARP Offload feature flags for arp_ol iovar */
+#define BRCMF_ARP_OL_AGENT             0x00000001
+#define BRCMF_ARP_OL_SNOOP             0x00000002
+#define BRCMF_ARP_OL_HOST_AUTO_REPLY   0x00000004
+#define BRCMF_ARP_OL_PEER_AUTO_REPLY   0x00000008
+
 
 enum brcmf_fil_p2p_if_types {
        BRCMF_FIL_P2P_IF_CLIENT,
index e7a1a47..79555f0 100644 (file)
@@ -47,6 +47,7 @@
 #define IS_P2P_SOCIAL_CHANNEL(channel) ((channel == SOCIAL_CHAN_1) || \
                                         (channel == SOCIAL_CHAN_2) || \
                                         (channel == SOCIAL_CHAN_3))
+#define BRCMF_P2P_TEMP_CHAN    SOCIAL_CHAN_3
 #define SOCIAL_CHAN_CNT                3
 #define AF_PEER_SEARCH_CNT     2
 
@@ -1954,21 +1955,21 @@ s32 brcmf_p2p_attach(struct brcmf_cfg80211_info *cfg)
                err = brcmf_fil_iovar_int_set(pri_ifp, "p2p_disc", 1);
                if (err < 0) {
                        brcmf_err("set p2p_disc error\n");
-                       brcmf_free_vif(p2p_vif);
+                       brcmf_free_vif(cfg, p2p_vif);
                        goto exit;
                }
                /* obtain bsscfg index for P2P discovery */
                err = brcmf_fil_iovar_int_get(pri_ifp, "p2p_dev", &bssidx);
                if (err < 0) {
                        brcmf_err("retrieving discover bsscfg index failed\n");
-                       brcmf_free_vif(p2p_vif);
+                       brcmf_free_vif(cfg, p2p_vif);
                        goto exit;
                }
                /* Verify that firmware uses same bssidx as driver !! */
                if (p2p_ifp->bssidx != bssidx) {
                        brcmf_err("Incorrect bssidx=%d, compared to p2p_ifp->bssidx=%d\n",
                                  bssidx, p2p_ifp->bssidx);
-                       brcmf_free_vif(p2p_vif);
+                       brcmf_free_vif(cfg, p2p_vif);
                        goto exit;
                }
 
@@ -1996,7 +1997,7 @@ void brcmf_p2p_detach(struct brcmf_p2p_info *p2p)
                brcmf_p2p_cancel_remain_on_channel(vif->ifp);
                brcmf_p2p_deinit_discovery(p2p);
                /* remove discovery interface */
-               brcmf_free_vif(vif);
+               brcmf_free_vif(p2p->cfg, vif);
                p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif = NULL;
        }
        /* just set it all to zero */
@@ -2013,17 +2014,30 @@ static void brcmf_p2p_get_current_chanspec(struct brcmf_p2p_info *p2p,
                                           u16 *chanspec)
 {
        struct brcmf_if *ifp;
-       struct brcmf_fil_chan_info_le ci;
+       u8 mac_addr[ETH_ALEN];
        struct brcmu_chan ch;
-       s32 err;
+       struct brcmf_bss_info_le *bi;
+       u8 *buf;
 
        ifp = p2p->bss_idx[P2PAPI_BSSCFG_PRIMARY].vif->ifp;
 
-       ch.chnum = 11;
-
-       err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_CHANNEL, &ci, sizeof(ci));
-       if (!err)
-               ch.chnum = le32_to_cpu(ci.hw_channel);
+       if (brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSSID, mac_addr,
+                                  ETH_ALEN) == 0) {
+               buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
+               if (buf != NULL) {
+                       *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
+                       if (brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO,
+                                                  buf, WL_BSS_INFO_MAX) == 0) {
+                               bi = (struct brcmf_bss_info_le *)(buf + 4);
+                               *chanspec = le16_to_cpu(bi->chanspec);
+                               kfree(buf);
+                               return;
+                       }
+                       kfree(buf);
+               }
+       }
+       /* Use default channel for P2P */
+       ch.chnum = BRCMF_P2P_TEMP_CHAN;
        ch.bw = BRCMU_CHAN_BW_20;
        p2p->cfg->d11inf.encchspec(&ch);
        *chanspec = ch.chspec;
@@ -2208,7 +2222,7 @@ static struct wireless_dev *brcmf_p2p_create_p2pdev(struct brcmf_p2p_info *p2p,
        return &p2p_vif->wdev;
 
 fail:
-       brcmf_free_vif(p2p_vif);
+       brcmf_free_vif(p2p->cfg, p2p_vif);
        return ERR_PTR(err);
 }
 
@@ -2217,13 +2231,31 @@ fail:
  *
  * @vif: virtual interface object to delete.
  */
-static void brcmf_p2p_delete_p2pdev(struct brcmf_cfg80211_vif *vif)
+static void brcmf_p2p_delete_p2pdev(struct brcmf_cfg80211_info *cfg,
+                                   struct brcmf_cfg80211_vif *vif)
 {
-       struct brcmf_p2p_info *p2p = &vif->ifp->drvr->config->p2p;
-
        cfg80211_unregister_wdev(&vif->wdev);
-       p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif = NULL;
-       brcmf_free_vif(vif);
+       cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif = NULL;
+       brcmf_free_vif(cfg, vif);
+}
+
+/**
+ * brcmf_p2p_free_p2p_if() - free up net device related data.
+ *
+ * @ndev: net device that needs to be freed.
+ */
+static void brcmf_p2p_free_p2p_if(struct net_device *ndev)
+{
+       struct brcmf_cfg80211_info *cfg;
+       struct brcmf_cfg80211_vif *vif;
+       struct brcmf_if *ifp;
+
+       ifp = netdev_priv(ndev);
+       cfg = ifp->drvr->config;
+       vif = ifp->vif;
+
+       brcmf_free_vif(cfg, vif);
+       free_netdev(ifp->ndev);
 }
 
 /**
@@ -2303,6 +2335,9 @@ struct wireless_dev *brcmf_p2p_add_vif(struct wiphy *wiphy, const char *name,
                brcmf_err("Registering netdevice failed\n");
                goto fail;
        }
+       /* override destructor */
+       ifp->ndev->destructor = brcmf_p2p_free_p2p_if;
+
        cfg->p2p.bss_idx[P2PAPI_BSSCFG_CONNECTION].vif = vif;
        /* Disable firmware roaming for P2P interface  */
        brcmf_fil_iovar_int_set(ifp, "roam_off", 1);
@@ -2314,7 +2349,7 @@ struct wireless_dev *brcmf_p2p_add_vif(struct wiphy *wiphy, const char *name,
        return &ifp->vif->wdev;
 
 fail:
-       brcmf_free_vif(vif);
+       brcmf_free_vif(cfg, vif);
        return ERR_PTR(err);
 }
 
@@ -2350,7 +2385,7 @@ int brcmf_p2p_del_vif(struct wiphy *wiphy, struct wireless_dev *wdev)
                break;
 
        case NL80211_IFTYPE_P2P_DEVICE:
-               brcmf_p2p_delete_p2pdev(vif);
+               brcmf_p2p_delete_p2pdev(cfg, vif);
                return 0;
        default:
                return -ENOTSUPP;
@@ -2378,7 +2413,6 @@ int brcmf_p2p_del_vif(struct wiphy *wiphy, struct wireless_dev *wdev)
                        err = 0;
        }
        brcmf_cfg80211_arm_vif_event(cfg, NULL);
-       brcmf_free_vif(vif);
        p2p->bss_idx[P2PAPI_BSSCFG_CONNECTION].vif = NULL;
 
        return err;
index 761f501..301e572 100644 (file)
@@ -459,6 +459,38 @@ send_key_to_dongle(struct net_device *ndev, struct brcmf_wsec_key *key)
        return err;
 }
 
+static s32
+brcmf_configure_arp_offload(struct brcmf_if *ifp, bool enable)
+{
+       s32 err;
+       u32 mode;
+
+       if (enable)
+               mode = BRCMF_ARP_OL_AGENT | BRCMF_ARP_OL_PEER_AUTO_REPLY;
+       else
+               mode = 0;
+
+       /* Try to set and enable ARP offload feature, this may fail, then it  */
+       /* is simply not supported and err 0 will be returned                 */
+       err = brcmf_fil_iovar_int_set(ifp, "arp_ol", mode);
+       if (err) {
+               brcmf_dbg(TRACE, "failed to set ARP offload mode to 0x%x, err = %d\n",
+                         mode, err);
+               err = 0;
+       } else {
+               err = brcmf_fil_iovar_int_set(ifp, "arpoe", enable);
+               if (err) {
+                       brcmf_dbg(TRACE, "failed to configure (%d) ARP offload err = %d\n",
+                                 enable, err);
+                       err = 0;
+               } else
+                       brcmf_dbg(TRACE, "successfully configured (%d) ARP offload to 0x%x\n",
+                                 enable, mode);
+       }
+
+       return err;
+}
+
 static struct wireless_dev *brcmf_cfg80211_add_iface(struct wiphy *wiphy,
                                                     const char *name,
                                                     enum nl80211_iftype type,
@@ -2216,6 +2248,11 @@ brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev,
        }
 
        pm = enabled ? PM_FAST : PM_OFF;
+       /* Do not enable the power save after assoc if it is a p2p interface */
+       if (ifp->vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT) {
+               brcmf_dbg(INFO, "Do not enable power save for P2P clients\n");
+               pm = PM_OFF;
+       }
        brcmf_dbg(INFO, "power save %s\n", (pm ? "enabled" : "disabled"));
 
        err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, pm);
@@ -3639,11 +3676,29 @@ brcmf_config_ap_mgmt_ie(struct brcmf_cfg80211_vif *vif,
        return err;
 }
 
+static s32
+brcmf_cfg80211_set_channel(struct brcmf_cfg80211_info *cfg,
+                          struct brcmf_if *ifp,
+                          struct ieee80211_channel *channel)
+{
+       u16 chanspec;
+       s32 err;
+
+       brcmf_dbg(TRACE, "band=%d, center_freq=%d\n", channel->band,
+                 channel->center_freq);
+
+       chanspec = channel_to_chanspec(&cfg->d11inf, channel);
+       err = brcmf_fil_iovar_int_set(ifp, "chanspec", chanspec);
+
+       return err;
+}
+
 static s32
 brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
                        struct cfg80211_ap_settings *settings)
 {
        s32 ie_offset;
+       struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
        struct brcmf_if *ifp = netdev_priv(ndev);
        struct brcmf_tlv *ssid_ie;
        struct brcmf_ssid_le ssid_le;
@@ -3683,6 +3738,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
        }
 
        brcmf_set_mpc(ifp, 0);
+       brcmf_configure_arp_offload(ifp, false);
 
        /* find the RSN_IE */
        rsn_ie = brcmf_parse_tlvs((u8 *)settings->beacon.tail,
@@ -3713,6 +3769,12 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
 
        brcmf_config_ap_mgmt_ie(ifp->vif, &settings->beacon);
 
+       err = brcmf_cfg80211_set_channel(cfg, ifp, settings->chandef.chan);
+       if (err < 0) {
+               brcmf_err("Set Channel failed, %d\n", err);
+               goto exit;
+       }
+
        if (settings->beacon_interval) {
                err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD,
                                            settings->beacon_interval);
@@ -3789,8 +3851,10 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
        set_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
 
 exit:
-       if (err)
+       if (err) {
                brcmf_set_mpc(ifp, 1);
+               brcmf_configure_arp_offload(ifp, true);
+       }
        return err;
 }
 
@@ -3831,6 +3895,7 @@ static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
                        brcmf_err("bss_enable config failed %d\n", err);
        }
        brcmf_set_mpc(ifp, 1);
+       brcmf_configure_arp_offload(ifp, true);
        set_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state);
        clear_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
 
@@ -4148,7 +4213,7 @@ static const struct ieee80211_iface_limit brcmf_iface_limits[] = {
 static const struct ieee80211_iface_combination brcmf_iface_combos[] = {
        {
                 .max_interfaces = BRCMF_IFACE_MAX_CNT,
-                .num_different_channels = 1, /* no multi-channel for now */
+                .num_different_channels = 2,
                 .n_limits = ARRAY_SIZE(brcmf_iface_limits),
                 .limits = brcmf_iface_limits
        }
@@ -4256,20 +4321,16 @@ struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg,
        return vif;
 }
 
-void brcmf_free_vif(struct brcmf_cfg80211_vif *vif)
+void brcmf_free_vif(struct brcmf_cfg80211_info *cfg,
+                   struct brcmf_cfg80211_vif *vif)
 {
-       struct brcmf_cfg80211_info *cfg;
-       struct wiphy *wiphy;
-
-       wiphy = vif->wdev.wiphy;
-       cfg = wiphy_priv(wiphy);
        list_del(&vif->list);
        cfg->vif_cnt--;
 
        kfree(vif);
        if (!cfg->vif_cnt) {
-               wiphy_unregister(wiphy);
-               wiphy_free(wiphy);
+               wiphy_unregister(cfg->wiphy);
+               wiphy_free(cfg->wiphy);
        }
 }
 
@@ -4646,7 +4707,6 @@ static s32 brcmf_notify_vif_event(struct brcmf_if *ifp,
                return 0;
 
        case BRCMF_E_IF_DEL:
-               ifp->vif = NULL;
                mutex_unlock(&event->vif_event_lock);
                /* event may not be upon user request */
                if (brcmf_cfg80211_vif_event_armed(cfg))
@@ -4852,8 +4912,7 @@ cfg80211_p2p_attach_out:
        wl_deinit_priv(cfg);
 
 cfg80211_attach_out:
-       brcmf_free_vif(vif);
-       wiphy_free(wiphy);
+       brcmf_free_vif(cfg, vif);
        return NULL;
 }
 
@@ -4865,7 +4924,7 @@ void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg)
        wl_deinit_priv(cfg);
        brcmf_btcoex_detach(cfg);
        list_for_each_entry_safe(vif, tmp, &cfg->vif_list, list) {
-               brcmf_free_vif(vif);
+               brcmf_free_vif(cfg, vif);
        }
 }
 
@@ -5229,6 +5288,8 @@ static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg)
        if (err)
                goto default_conf_out;
 
+       brcmf_configure_arp_offload(ifp, true);
+
        cfg->dongle_up = true;
 default_conf_out:
 
index a71cff8..d9bdaf9 100644 (file)
@@ -487,7 +487,8 @@ enum nl80211_iftype brcmf_cfg80211_get_iftype(struct brcmf_if *ifp);
 struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg,
                                           enum nl80211_iftype type,
                                           bool pm_block);
-void brcmf_free_vif(struct brcmf_cfg80211_vif *vif);
+void brcmf_free_vif(struct brcmf_cfg80211_info *cfg,
+                   struct brcmf_cfg80211_vif *vif);
 
 s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag,
                          const u8 *vndr_ie_buf, u32 vndr_ie_len);
index db183b4..c3c13ce 100644 (file)
@@ -735,7 +735,7 @@ void iwl_restore_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
                                        memcpy(&lq, priv->stations[i].lq,
                                               sizeof(struct iwl_link_quality_cmd));
 
-                               if (!memcmp(&lq, &zero_lq, sizeof(lq)))
+                               if (memcmp(&lq, &zero_lq, sizeof(lq)))
                                        send_lq = true;
                        }
                        spin_unlock_bh(&priv->sta_lock);
index 4775d4e..74a852e 100644 (file)
@@ -28,7 +28,7 @@ config NFC_WILINK
 
 config NFC_MEI_PHY
        tristate "MEI bus NFC device support"
-       depends on INTEL_MEI_BUS_NFC && NFC_HCI
+       depends on INTEL_MEI && NFC_HCI
        help
          This adds support to use an mei bus nfc device. Select this if you
          will use an HCI NFC driver for an NFC chip connected behind an
index b8f8abc..1201bdb 100644 (file)
@@ -64,6 +64,15 @@ int nfc_mei_phy_enable(void *phy_id)
                 return r;
        }
 
+       r = mei_cl_register_event_cb(phy->device, nfc_mei_event_cb, phy);
+       if (r) {
+               pr_err("MEY_PHY: Event cb registration failed\n");
+               mei_cl_disable_device(phy->device);
+               phy->powered = 0;
+
+               return r;
+       }
+
        phy->powered = 1;
 
        return 0;
index 1ad044d..cdf1bc5 100644 (file)
@@ -43,24 +43,16 @@ static int microread_mei_probe(struct mei_cl_device *device,
                return -ENOMEM;
        }
 
-       r = mei_cl_register_event_cb(device, nfc_mei_event_cb, phy);
-       if (r) {
-               pr_err(MICROREAD_DRIVER_NAME ": event cb registration failed\n");
-               goto err_out;
-       }
-
        r = microread_probe(phy, &mei_phy_ops, LLC_NOP_NAME,
                            MEI_NFC_HEADER_SIZE, 0, MEI_NFC_MAX_HCI_PAYLOAD,
                            &phy->hdev);
-       if (r < 0)
-               goto err_out;
-
-       return 0;
+       if (r < 0) {
+               nfc_mei_phy_free(phy);
 
-err_out:
-       nfc_mei_phy_free(phy);
+               return r;
+       }
 
-       return r;
+       return 0;
 }
 
 static int microread_mei_remove(struct mei_cl_device *device)
@@ -71,8 +63,6 @@ static int microread_mei_remove(struct mei_cl_device *device)
 
        microread_remove(phy->hdev);
 
-       nfc_mei_phy_disable(phy);
-
        nfc_mei_phy_free(phy);
 
        return 0;
index 1eb4884..b5d3d18 100644 (file)
@@ -43,24 +43,16 @@ static int pn544_mei_probe(struct mei_cl_device *device,
                return -ENOMEM;
        }
 
-       r = mei_cl_register_event_cb(device, nfc_mei_event_cb, phy);
-       if (r) {
-               pr_err(PN544_DRIVER_NAME ": event cb registration failed\n");
-               goto err_out;
-       }
-
        r = pn544_hci_probe(phy, &mei_phy_ops, LLC_NOP_NAME,
                            MEI_NFC_HEADER_SIZE, 0, MEI_NFC_MAX_HCI_PAYLOAD,
                            &phy->hdev);
-       if (r < 0)
-               goto err_out;
-
-       return 0;
+       if (r < 0) {
+               nfc_mei_phy_free(phy);
 
-err_out:
-       nfc_mei_phy_free(phy);
+               return r;
+       }
 
-       return r;
+       return 0;
 }
 
 static int pn544_mei_remove(struct mei_cl_device *device)
@@ -71,8 +63,6 @@ static int pn544_mei_remove(struct mei_cl_device *device)
 
        pn544_hci_remove(phy->hdev);
 
-       nfc_mei_phy_disable(phy);
-
        nfc_mei_phy_free(phy);
 
        return 0;
index 791a671..8cd90e7 100644 (file)
@@ -2357,27 +2357,48 @@ static const unsigned int sdhi3_wp_mux[] = {
 };
 /* - USB0 ------------------------------------------------------------------- */
 static const unsigned int usb0_pins[] = {
-       /* OVC */
-       150, 154,
+       /* PENC */
+       154,
 };
 static const unsigned int usb0_mux[] = {
-       USB_OVC0_MARK, USB_PENC0_MARK,
+       USB_PENC0_MARK,
+};
+static const unsigned int usb0_ovc_pins[] = {
+       /* USB_OVC */
+       150
+};
+static const unsigned int usb0_ovc_mux[] = {
+       USB_OVC0_MARK,
 };
 /* - USB1 ------------------------------------------------------------------- */
 static const unsigned int usb1_pins[] = {
-       /* OVC */
-       152, 155,
+       /* PENC */
+       155,
 };
 static const unsigned int usb1_mux[] = {
-       USB_OVC1_MARK, USB_PENC1_MARK,
+       USB_PENC1_MARK,
+};
+static const unsigned int usb1_ovc_pins[] = {
+       /* USB_OVC */
+       152,
+};
+static const unsigned int usb1_ovc_mux[] = {
+       USB_OVC1_MARK,
 };
 /* - USB2 ------------------------------------------------------------------- */
 static const unsigned int usb2_pins[] = {
-       /* OVC, PENC */
-       125, 156,
+       /* PENC */
+       156,
 };
 static const unsigned int usb2_mux[] = {
-       USB_OVC2_MARK, USB_PENC2_MARK,
+       USB_PENC2_MARK,
+};
+static const unsigned int usb2_ovc_pins[] = {
+       /* USB_OVC */
+       125,
+};
+static const unsigned int usb2_ovc_mux[] = {
+       USB_OVC2_MARK,
 };
 
 static const struct sh_pfc_pin_group pinmux_groups[] = {
@@ -2501,8 +2522,11 @@ static const struct sh_pfc_pin_group pinmux_groups[] = {
        SH_PFC_PIN_GROUP(sdhi3_cd),
        SH_PFC_PIN_GROUP(sdhi3_wp),
        SH_PFC_PIN_GROUP(usb0),
+       SH_PFC_PIN_GROUP(usb0_ovc),
        SH_PFC_PIN_GROUP(usb1),
+       SH_PFC_PIN_GROUP(usb1_ovc),
        SH_PFC_PIN_GROUP(usb2),
+       SH_PFC_PIN_GROUP(usb2_ovc),
 };
 
 static const char * const du0_groups[] = {
@@ -2683,14 +2707,17 @@ static const char * const sdhi3_groups[] = {
 
 static const char * const usb0_groups[] = {
        "usb0",
+       "usb0_ovc",
 };
 
 static const char * const usb1_groups[] = {
        "usb1",
+       "usb1_ovc",
 };
 
 static const char * const usb2_groups[] = {
        "usb2",
+       "usb2_ovc",
 };
 
 static const struct sh_pfc_function pinmux_functions[] = {
index 8df0c5a..d111c86 100644 (file)
@@ -703,7 +703,7 @@ static int hp_wmi_rfkill_setup(struct platform_device *device)
                }
                rfkill_init_sw_state(gps_rfkill,
                                     hp_wmi_get_sw_state(HPWMI_GPS));
-               rfkill_set_hw_state(bluetooth_rfkill,
+               rfkill_set_hw_state(gps_rfkill,
                                    hp_wmi_get_hw_state(HPWMI_GPS));
                err = rfkill_register(gps_rfkill);
                if (err)
index bea9451..71a2559 100644 (file)
@@ -628,9 +628,10 @@ pch_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 
        chip->caps = ptp_pch_caps;
        chip->ptp_clock = ptp_clock_register(&chip->caps, &pdev->dev);
-
-       if (IS_ERR(chip->ptp_clock))
-               return PTR_ERR(chip->ptp_clock);
+       if (IS_ERR(chip->ptp_clock)) {
+               ret = PTR_ERR(chip->ptp_clock);
+               goto err_ptp_clock_reg;
+       }
 
        spin_lock_init(&chip->register_lock);
 
@@ -669,6 +670,7 @@ pch_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 
 err_req_irq:
        ptp_clock_unregister(chip->ptp_clock);
+err_ptp_clock_reg:
        iounmap(chip->regs);
        chip->regs = NULL;
 
index 6e50178..815d6df 100644 (file)
@@ -1539,7 +1539,10 @@ static void regulator_ena_gpio_free(struct regulator_dev *rdev)
 }
 
 /**
- * Balance enable_count of each GPIO and actual GPIO pin control.
+ * regulator_ena_gpio_ctrl - balance enable_count of each GPIO and actual GPIO pin control
+ * @rdev: regulator_dev structure
+ * @enable: enable GPIO at initial use?
+ *
  * GPIO is enabled in case of initial use. (enable_count is 0)
  * GPIO is disabled when it is not shared any more. (enable_count <= 1)
  */
@@ -2702,7 +2705,7 @@ EXPORT_SYMBOL_GPL(regulator_get_voltage);
 /**
  * regulator_set_current_limit - set regulator output current limit
  * @regulator: regulator source
- * @min_uA: Minimuum supported current in uA
+ * @min_uA: Minimum supported current in uA
  * @max_uA: Maximum supported current in uA
  *
  * Sets current sink to the desired output current. This can be set during
index 89bd2fa..ce89f78 100644 (file)
 static int power_state_active_cnt; /* will initialize to zero */
 static DEFINE_SPINLOCK(power_state_active_lock);
 
-int power_state_active_get(void)
-{
-       unsigned long flags;
-       int cnt;
-
-       spin_lock_irqsave(&power_state_active_lock, flags);
-       cnt = power_state_active_cnt;
-       spin_unlock_irqrestore(&power_state_active_lock, flags);
-
-       return cnt;
-}
-
 void power_state_active_enable(void)
 {
        unsigned long flags;
@@ -65,6 +53,18 @@ out:
 
 #ifdef CONFIG_REGULATOR_DEBUG
 
+static int power_state_active_get(void)
+{
+       unsigned long flags;
+       int cnt;
+
+       spin_lock_irqsave(&power_state_active_lock, flags);
+       cnt = power_state_active_cnt;
+       spin_unlock_irqrestore(&power_state_active_lock, flags);
+
+       return cnt;
+}
+
 static struct ux500_regulator_debug {
        struct dentry *dir;
        struct dentry *status_file;
index 92ceed0..3ae44ac 100644 (file)
@@ -840,7 +840,7 @@ static int palmas_regulators_probe(struct platform_device *pdev)
                        break;
                }
 
-               if ((id == PALMAS_REG_SMPS6) && (id == PALMAS_REG_SMPS8))
+               if ((id == PALMAS_REG_SMPS6) || (id == PALMAS_REG_SMPS8))
                        ramp_delay_support = true;
 
                if (ramp_delay_support) {
@@ -878,7 +878,7 @@ static int palmas_regulators_probe(struct platform_device *pdev)
                        pmic->desc[id].vsel_mask = SMPS10_VSEL;
                        pmic->desc[id].enable_reg =
                                        PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE,
-                                                       PALMAS_SMPS10_STATUS);
+                                                       PALMAS_SMPS10_CTRL);
                        pmic->desc[id].enable_mask = SMPS10_BOOST_EN;
                        pmic->desc[id].min_uV = 3750000;
                        pmic->desc[id].uV_step = 1250000;
index 4361d97..d72a921 100644 (file)
@@ -3440,8 +3440,16 @@ void dasd_generic_path_event(struct ccw_device *cdev, int *path_event)
                        device->path_data.opm &= ~eventlpm;
                        device->path_data.ppm &= ~eventlpm;
                        device->path_data.npm &= ~eventlpm;
-                       if (oldopm && !device->path_data.opm)
-                               dasd_generic_last_path_gone(device);
+                       if (oldopm && !device->path_data.opm) {
+                               dev_warn(&device->cdev->dev,
+                                        "No verified channel paths remain "
+                                        "for the device\n");
+                               DBF_DEV_EVENT(DBF_WARNING, device,
+                                             "%s", "last verified path gone");
+                               dasd_eer_write(device, NULL, DASD_EER_NOPATH);
+                               dasd_device_set_stop_bits(device,
+                                                         DASD_STOPPED_DC_WAIT);
+                       }
                }
                if (path_event[chp] & PE_PATH_AVAILABLE) {
                        device->path_data.opm &= ~eventlpm;
index ceb1c64..6dc27da 100644 (file)
@@ -264,6 +264,8 @@ static long alarm_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
        }
 
        rv = alarm_do_ioctl(file, cmd, &ts);
+       if (rv)
+               return rv;
 
        switch (ANDROID_ALARM_BASE_CMD(cmd)) {
        case ANDROID_ALARM_GET_TIME(0):
@@ -272,7 +274,7 @@ static long alarm_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                break;
        }
 
-       return rv;
+       return 0;
 }
 #ifdef CONFIG_COMPAT
 static long alarm_compat_ioctl(struct file *file, unsigned int cmd,
@@ -295,6 +297,8 @@ static long alarm_compat_ioctl(struct file *file, unsigned int cmd,
        }
 
        rv = alarm_do_ioctl(file, cmd, &ts);
+       if (rv)
+               return rv;
 
        switch (ANDROID_ALARM_BASE_CMD(cmd)) {
        case ANDROID_ALARM_GET_TIME(0): /* NOTE: we modified cmd above */
@@ -303,7 +307,7 @@ static long alarm_compat_ioctl(struct file *file, unsigned int cmd,
                break;
        }
 
-       return rv;
+       return 0;
 }
 #endif
 
index 827ab78..8551cce 100644 (file)
@@ -2804,9 +2804,8 @@ int dwc2_hcd_init(struct dwc2_hsotg *hsotg, int irq,
 
        /* Set device flags indicating whether the HCD supports DMA */
        if (hsotg->core_params->dma_enable > 0) {
-               if (dma_set_mask(hsotg->dev, DMA_BIT_MASK(31)) < 0)
-                       dev_warn(hsotg->dev,
-                                "can't enable workaround for >2GB RAM\n");
+               if (dma_set_mask(hsotg->dev, DMA_BIT_MASK(32)) < 0)
+                       dev_warn(hsotg->dev, "can't set DMA mask\n");
                if (dma_set_coherent_mask(hsotg->dev, DMA_BIT_MASK(31)) < 0)
                        dev_warn(hsotg->dev,
                                 "can't enable workaround for >2GB RAM\n");
index e1f91d5..a858666 100644 (file)
 #ifndef _ZCACHE_RAMSTER_H_
 #define _ZCACHE_RAMSTER_H_
 
-#ifdef CONFIG_RAMSTER_MODULE
-#define CONFIG_RAMSTER
-#endif
-
 #ifdef CONFIG_RAMSTER
 #include "ramster/ramster.h"
 #else
index 327e4f0..5b26ee9 100644 (file)
@@ -1,6 +1,8 @@
 #include <linux/atomic.h>
 #include "debug.h"
 
+ssize_t ramster_foreign_eph_pages;
+ssize_t ramster_foreign_pers_pages;
 #ifdef CONFIG_DEBUG_FS
 #include <linux/debugfs.h>
 
index b18b887..a937ce1 100644 (file)
@@ -66,8 +66,6 @@ static int ramster_remote_target_nodenum __read_mostly = -1;
 
 /* Used by this code. */
 long ramster_flnodes;
-ssize_t ramster_foreign_eph_pages;
-ssize_t ramster_foreign_pers_pages;
 /* FIXME frontswap selfshrinking knobs in debugfs? */
 
 static LIST_HEAD(ramster_rem_op_list);
@@ -399,14 +397,18 @@ void ramster_count_foreign_pages(bool eph, int count)
                        inc_ramster_foreign_eph_pages();
                } else {
                        dec_ramster_foreign_eph_pages();
+#ifdef CONFIG_RAMSTER_DEBUG
                        WARN_ON_ONCE(ramster_foreign_eph_pages < 0);
+#endif
                }
        } else {
                if (count > 0) {
                        inc_ramster_foreign_pers_pages();
                } else {
                        dec_ramster_foreign_pers_pages();
+#ifdef CONFIG_RAMSTER_DEBUG
                        WARN_ON_ONCE(ramster_foreign_pers_pages < 0);
+#endif
                }
        }
 }
index 46528d5..86c00b1 100644 (file)
@@ -2755,7 +2755,7 @@ static void __init serial8250_isa_init_ports(void)
        if (nr_uarts > UART_NR)
                nr_uarts = UART_NR;
 
-       for (i = 0; i < UART_NR; i++) {
+       for (i = 0; i < nr_uarts; i++) {
                struct uart_8250_port *up = &serial8250_ports[i];
                struct uart_port *port = &up->port;
 
@@ -2916,7 +2916,7 @@ static int __init serial8250_console_setup(struct console *co, char *options)
         * if so, search for the first available port that does have
         * console support.
         */
-       if (co->index >= UART_NR)
+       if (co->index >= nr_uarts)
                co->index = 0;
        port = &serial8250_ports[co->index].port;
        if (!port->iobase && !port->membase)
@@ -2957,7 +2957,7 @@ int serial8250_find_port(struct uart_port *p)
        int line;
        struct uart_port *port;
 
-       for (line = 0; line < UART_NR; line++) {
+       for (line = 0; line < nr_uarts; line++) {
                port = &serial8250_ports[line].port;
                if (uart_match_port(p, port))
                        return line;
@@ -3110,7 +3110,7 @@ static int serial8250_remove(struct platform_device *dev)
 {
        int i;
 
-       for (i = 0; i < UART_NR; i++) {
+       for (i = 0; i < nr_uarts; i++) {
                struct uart_8250_port *up = &serial8250_ports[i];
 
                if (up->port.dev == &dev->dev)
@@ -3178,7 +3178,7 @@ static struct uart_8250_port *serial8250_find_match_or_unused(struct uart_port *
        /*
         * First, find a port entry which matches.
         */
-       for (i = 0; i < UART_NR; i++)
+       for (i = 0; i < nr_uarts; i++)
                if (uart_match_port(&serial8250_ports[i].port, port))
                        return &serial8250_ports[i];
 
@@ -3187,7 +3187,7 @@ static struct uart_8250_port *serial8250_find_match_or_unused(struct uart_port *
         * free entry.  We look for one which hasn't been previously
         * used (indicated by zero iobase).
         */
-       for (i = 0; i < UART_NR; i++)
+       for (i = 0; i < nr_uarts; i++)
                if (serial8250_ports[i].port.type == PORT_UNKNOWN &&
                    serial8250_ports[i].port.iobase == 0)
                        return &serial8250_ports[i];
@@ -3196,7 +3196,7 @@ static struct uart_8250_port *serial8250_find_match_or_unused(struct uart_port *
         * That also failed.  Last resort is to find any entry which
         * doesn't have a real port associated with it.
         */
-       for (i = 0; i < UART_NR; i++)
+       for (i = 0; i < nr_uarts; i++)
                if (serial8250_ports[i].port.type == PORT_UNKNOWN)
                        return &serial8250_ports[i];
 
index 147c9e1..8cdfbd3 100644 (file)
@@ -761,6 +761,8 @@ static int imx_startup(struct uart_port *port)
 
        temp = readl(sport->port.membase + UCR2);
        temp |= (UCR2_RXEN | UCR2_TXEN);
+       if (!sport->have_rtscts)
+               temp |= UCR2_IRTS;
        writel(temp, sport->port.membase + UCR2);
 
        if (USE_IRDA(sport)) {
index 8942941..0c8a9fa 100644 (file)
@@ -1166,6 +1166,18 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport,
                ourport->tx_irq = ret;
 
        ourport->clk    = clk_get(&platdev->dev, "uart");
+       if (IS_ERR(ourport->clk)) {
+               pr_err("%s: Controller clock not found\n",
+                               dev_name(&platdev->dev));
+               return PTR_ERR(ourport->clk);
+       }
+
+       ret = clk_prepare_enable(ourport->clk);
+       if (ret) {
+               pr_err("uart: clock failed to prepare+enable: %d\n", ret);
+               clk_put(ourport->clk);
+               return ret;
+       }
 
        /* Keep all interrupts masked and cleared */
        if (s3c24xx_serial_has_interrupt_mask(port)) {
@@ -1180,6 +1192,7 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport,
 
        /* reset the fifos (and setup the uart) */
        s3c24xx_serial_resetport(port, cfg);
+       clk_disable_unprepare(ourport->clk);
        return 0;
 }
 
index caefc80..c88c4fb 100644 (file)
@@ -1287,9 +1287,13 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
                        goto error;
                }
                for (totlen = u = 0; u < uurb->number_of_packets; u++) {
-                       /* arbitrary limit,
-                        * sufficient for USB 2.0 high-bandwidth iso */
-                       if (isopkt[u].length > 8192) {
+                       /*
+                        * arbitrary limit need for USB 3.0
+                        * bMaxBurst (0~15 allowed, 1~16 packets)
+                        * bmAttributes (bit 1:0, mult 0~2, 1~3 packets)
+                        * sizemax: 1024 * 16 * 3 = 49152
+                        */
+                       if (isopkt[u].length > 49152) {
                                ret = -EINVAL;
                                goto error;
                        }
index 929e7dd..8ce9d7f 100644 (file)
@@ -164,9 +164,9 @@ static int dwc3_exynos_remove(struct platform_device *pdev)
 {
        struct dwc3_exynos      *exynos = platform_get_drvdata(pdev);
 
+       device_for_each_child(&pdev->dev, NULL, dwc3_exynos_remove_child);
        platform_device_unregister(exynos->usb2_phy);
        platform_device_unregister(exynos->usb3_phy);
-       device_for_each_child(&pdev->dev, NULL, dwc3_exynos_remove_child);
 
        clk_disable_unprepare(exynos->clk);
 
index 227d4a7..eba9e2b 100644 (file)
@@ -196,9 +196,9 @@ static void dwc3_pci_remove(struct pci_dev *pci)
 {
        struct dwc3_pci *glue = pci_get_drvdata(pci);
 
+       platform_device_unregister(glue->dwc3);
        platform_device_unregister(glue->usb2_phy);
        platform_device_unregister(glue->usb3_phy);
-       platform_device_unregister(glue->dwc3);
        pci_set_drvdata(pci, NULL);
        pci_disable_device(pci);
 }
index 2b6e7e0..b5e5b35 100644 (file)
@@ -1706,11 +1706,19 @@ static void dwc3_gadget_free_endpoints(struct dwc3 *dwc)
                dep = dwc->eps[epnum];
                if (!dep)
                        continue;
-
-               dwc3_free_trb_pool(dep);
-
-               if (epnum != 0 && epnum != 1)
+               /*
+                * Physical endpoints 0 and 1 are special; they form the
+                * bi-directional USB endpoint 0.
+                *
+                * For those two physical endpoints, we don't allocate a TRB
+                * pool nor do we add them the endpoints list. Due to that, we
+                * shouldn't do these two operations otherwise we would end up
+                * with all sorts of bugs when removing dwc3.ko.
+                */
+               if (epnum != 0 && epnum != 1) {
+                       dwc3_free_trb_pool(dep);
                        list_del(&dep->endpoint.ep_list);
+               }
 
                kfree(dep);
        }
index acff5b8..f80d033 100644 (file)
@@ -213,7 +213,7 @@ static inline unsigned char tt_start_uframe(struct ehci_hcd *ehci, __hc32 mask)
 }
 
 static const unsigned char
-max_tt_usecs[] = { 125, 125, 125, 125, 125, 125, 125, 25 };
+max_tt_usecs[] = { 125, 125, 125, 125, 125, 125, 30, 0 };
 
 /* carryover low/fullspeed bandwidth that crosses uframe boundries */
 static inline void carryover_tt_bandwidth(unsigned short tt_usecs[8])
@@ -646,6 +646,10 @@ static void end_unlink_intr(struct ehci_hcd *ehci, struct ehci_qh *qh)
        /* reschedule QH iff another request is queued */
        if (!list_empty(&qh->qtd_list) && ehci->rh_state == EHCI_RH_RUNNING) {
                rc = qh_schedule(ehci, qh);
+               if (rc == 0) {
+                       qh_refresh(ehci, qh);
+                       qh_link_periodic(ehci, qh);
+               }
 
                /* An error here likely indicates handshake failure
                 * or no space left in the schedule.  Neither fault
@@ -653,9 +657,10 @@ static void end_unlink_intr(struct ehci_hcd *ehci, struct ehci_qh *qh)
                 *
                 * FIXME kill the now-dysfunctional queued urbs
                 */
-               if (rc != 0)
+               else {
                        ehci_err(ehci, "can't reschedule qh %p, err %d\n",
                                        qh, rc);
+               }
        }
 
        /* maybe turn off periodic schedule */
index 2cfc465..fbf75e5 100644 (file)
@@ -1827,6 +1827,9 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci)
        }
        spin_unlock_irqrestore(&xhci->lock, flags);
 
+       if (!xhci->rh_bw)
+               goto no_bw;
+
        num_ports = HCS_MAX_PORTS(xhci->hcs_params1);
        for (i = 0; i < num_ports; i++) {
                struct xhci_interval_bw_table *bwt = &xhci->rh_bw[i].bw_table;
@@ -1845,6 +1848,7 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci)
                }
        }
 
+no_bw:
        xhci->num_usb2_ports = 0;
        xhci->num_usb3_ports = 0;
        xhci->num_active_eps = 0;
@@ -2256,6 +2260,9 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
        u32 page_size, temp;
        int i;
 
+       INIT_LIST_HEAD(&xhci->lpm_failed_devs);
+       INIT_LIST_HEAD(&xhci->cancel_cmd_list);
+
        page_size = xhci_readl(xhci, &xhci->op_regs->page_size);
        xhci_dbg(xhci, "Supported page size register = 0x%x\n", page_size);
        for (i = 0; i < 16; i++) {
@@ -2334,7 +2341,6 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
        xhci->cmd_ring = xhci_ring_alloc(xhci, 1, 1, TYPE_COMMAND, flags);
        if (!xhci->cmd_ring)
                goto fail;
-       INIT_LIST_HEAD(&xhci->cancel_cmd_list);
        xhci_dbg(xhci, "Allocated command ring at %p\n", xhci->cmd_ring);
        xhci_dbg(xhci, "First segment DMA is 0x%llx\n",
                        (unsigned long long)xhci->cmd_ring->first_seg->dma);
@@ -2445,8 +2451,6 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
        if (xhci_setup_port_arrays(xhci, flags))
                goto fail;
 
-       INIT_LIST_HEAD(&xhci->lpm_failed_devs);
-
        /* Enable USB 3.0 device notifications for function remote wake, which
         * is necessary for allowing USB 3.0 devices to do remote wakeup from
         * U3 (device suspend).
index 1a30c38..cc24e39 100644 (file)
@@ -221,6 +221,14 @@ static void xhci_pci_remove(struct pci_dev *dev)
 static int xhci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup)
 {
        struct xhci_hcd *xhci = hcd_to_xhci(hcd);
+       struct pci_dev          *pdev = to_pci_dev(hcd->self.controller);
+
+       /*
+        * Systems with the TI redriver that loses port status change events
+        * need to have the registers polled during D3, so avoid D3cold.
+        */
+       if (xhci_compliance_mode_recovery_timer_quirk_check())
+               pdev->no_d3cold = true;
 
        return xhci_suspend(xhci);
 }
index b4aa79d..d8f640b 100644 (file)
@@ -466,7 +466,7 @@ static void compliance_mode_recovery_timer_init(struct xhci_hcd *xhci)
  * Systems:
  * Vendor: Hewlett-Packard -> System Models: Z420, Z620 and Z820
  */
-static bool compliance_mode_recovery_timer_quirk_check(void)
+bool xhci_compliance_mode_recovery_timer_quirk_check(void)
 {
        const char *dmi_product_name, *dmi_sys_vendor;
 
@@ -517,7 +517,7 @@ int xhci_init(struct usb_hcd *hcd)
        xhci_dbg(xhci, "Finished xhci_init\n");
 
        /* Initializing Compliance Mode Recovery Data If Needed */
-       if (compliance_mode_recovery_timer_quirk_check()) {
+       if (xhci_compliance_mode_recovery_timer_quirk_check()) {
                xhci->quirks |= XHCI_COMP_MODE_QUIRK;
                compliance_mode_recovery_timer_init(xhci);
        }
@@ -956,6 +956,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
        struct usb_hcd          *hcd = xhci_to_hcd(xhci);
        struct usb_hcd          *secondary_hcd;
        int                     retval = 0;
+       bool                    comp_timer_running = false;
 
        /* Wait a bit if either of the roothubs need to settle from the
         * transition into bus suspend.
@@ -993,6 +994,13 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
 
        /* If restore operation fails, re-initialize the HC during resume */
        if ((temp & STS_SRE) || hibernated) {
+
+               if ((xhci->quirks & XHCI_COMP_MODE_QUIRK) &&
+                               !(xhci_all_ports_seen_u0(xhci))) {
+                       del_timer_sync(&xhci->comp_mode_recovery_timer);
+                       xhci_dbg(xhci, "Compliance Mode Recovery Timer deleted!\n");
+               }
+
                /* Let the USB core know _both_ roothubs lost power. */
                usb_root_hub_lost_power(xhci->main_hcd->self.root_hub);
                usb_root_hub_lost_power(xhci->shared_hcd->self.root_hub);
@@ -1035,6 +1043,8 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
                retval = xhci_init(hcd->primary_hcd);
                if (retval)
                        return retval;
+               comp_timer_running = true;
+
                xhci_dbg(xhci, "Start the primary HCD\n");
                retval = xhci_run(hcd->primary_hcd);
                if (!retval) {
@@ -1076,7 +1086,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
         * to suffer the Compliance Mode issue again. It doesn't matter if
         * ports have entered previously to U0 before system's suspension.
         */
-       if (xhci->quirks & XHCI_COMP_MODE_QUIRK)
+       if ((xhci->quirks & XHCI_COMP_MODE_QUIRK) && !comp_timer_running)
                compliance_mode_recovery_timer_init(xhci);
 
        /* Re-enable port polling. */
index 29c978e..77600ce 100644 (file)
@@ -1853,4 +1853,7 @@ struct xhci_input_control_ctx *xhci_get_input_control_ctx(struct xhci_hcd *xhci,
 struct xhci_slot_ctx *xhci_get_slot_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx);
 struct xhci_ep_ctx *xhci_get_ep_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx, unsigned int ep_index);
 
+/* xHCI quirks */
+bool xhci_compliance_mode_recovery_timer_quirk_check(void);
+
 #endif /* __LINUX_XHCI_HCD_H */
index 8914dec..9d3044b 100644 (file)
@@ -1232,7 +1232,6 @@ void musb_host_tx(struct musb *musb, u8 epnum)
        void __iomem            *mbase = musb->mregs;
        struct dma_channel      *dma;
        bool                    transfer_pending = false;
-       static bool use_sg;
 
        musb_ep_select(mbase, epnum);
        tx_csr = musb_readw(epio, MUSB_TXCSR);
@@ -1463,9 +1462,9 @@ done:
         * NULL.
         */
        if (!urb->transfer_buffer)
-               use_sg = true;
+               qh->use_sg = true;
 
-       if (use_sg) {
+       if (qh->use_sg) {
                /* sg_miter_start is already done in musb_ep_program */
                if (!sg_miter_next(&qh->sg_miter)) {
                        dev_err(musb->controller, "error: sg list empty\n");
@@ -1484,9 +1483,9 @@ done:
 
        qh->segsize = length;
 
-       if (use_sg) {
+       if (qh->use_sg) {
                if (offset + length >= urb->transfer_buffer_length)
-                       use_sg = false;
+                       qh->use_sg = false;
        }
 
        musb_ep_select(mbase, epnum);
@@ -1552,7 +1551,6 @@ void musb_host_rx(struct musb *musb, u8 epnum)
        bool                    done = false;
        u32                     status;
        struct dma_channel      *dma;
-       static bool use_sg;
        unsigned int sg_flags = SG_MITER_ATOMIC | SG_MITER_TO_SG;
 
        musb_ep_select(mbase, epnum);
@@ -1878,12 +1876,12 @@ void musb_host_rx(struct musb *musb, u8 epnum)
                         * NULL.
                         */
                        if (!urb->transfer_buffer) {
-                               use_sg = true;
+                               qh->use_sg = true;
                                sg_miter_start(&qh->sg_miter, urb->sg, 1,
                                                sg_flags);
                        }
 
-                       if (use_sg) {
+                       if (qh->use_sg) {
                                if (!sg_miter_next(&qh->sg_miter)) {
                                        dev_err(musb->controller, "error: sg list empty\n");
                                        sg_miter_stop(&qh->sg_miter);
@@ -1913,8 +1911,8 @@ finish:
        urb->actual_length += xfer_len;
        qh->offset += xfer_len;
        if (done) {
-               if (use_sg)
-                       use_sg = false;
+               if (qh->use_sg)
+                       qh->use_sg = false;
 
                if (urb->status == -EINPROGRESS)
                        urb->status = status;
index 5a9c8fe..738f7eb 100644 (file)
@@ -74,6 +74,7 @@ struct musb_qh {
        u16                     frame;          /* for periodic schedule */
        unsigned                iso_idx;        /* in urb->iso_frame_desc[] */
        struct sg_mapping_iter sg_miter;        /* for highmem in PIO mode */
+       bool                    use_sg;         /* to track urb using sglist */
 };
 
 /* map from control or bulk queue head to the first qh on that ring */
index 3b16118..40e7fd9 100644 (file)
@@ -43,7 +43,7 @@
 #define DRIVER_NAME "ark3116"
 
 /* usb timeout of 1 second */
-#define ARK_TIMEOUT (1*HZ)
+#define ARK_TIMEOUT 1000
 
 static const struct usb_device_id id_table[] = {
        { USB_DEVICE(0x6547, 0x0232) },
index d341555..0821201 100644 (file)
@@ -65,6 +65,7 @@ static const struct usb_device_id id_table_earthmate[] = {
 static const struct usb_device_id id_table_cyphidcomrs232[] = {
        { USB_DEVICE(VENDOR_ID_CYPRESS, PRODUCT_ID_CYPHIDCOM) },
        { USB_DEVICE(VENDOR_ID_POWERCOM, PRODUCT_ID_UPS) },
+       { USB_DEVICE(VENDOR_ID_FRWD, PRODUCT_ID_CYPHIDCOM_FRWD) },
        { }                                             /* Terminating entry */
 };
 
@@ -78,6 +79,7 @@ static const struct usb_device_id id_table_combined[] = {
        { USB_DEVICE(VENDOR_ID_DELORME, PRODUCT_ID_EARTHMATEUSB_LT20) },
        { USB_DEVICE(VENDOR_ID_CYPRESS, PRODUCT_ID_CYPHIDCOM) },
        { USB_DEVICE(VENDOR_ID_POWERCOM, PRODUCT_ID_UPS) },
+       { USB_DEVICE(VENDOR_ID_FRWD, PRODUCT_ID_CYPHIDCOM_FRWD) },
        { USB_DEVICE(VENDOR_ID_DAZZLE, PRODUCT_ID_CA42) },
        { }                                             /* Terminating entry */
 };
@@ -229,6 +231,12 @@ static struct usb_serial_driver * const serial_drivers[] = {
  * Cypress serial helper functions
  *****************************************************************************/
 
+/* FRWD Dongle hidcom needs to skip reset and speed checks */
+static inline bool is_frwd(struct usb_device *dev)
+{
+       return ((le16_to_cpu(dev->descriptor.idVendor) == VENDOR_ID_FRWD) &&
+               (le16_to_cpu(dev->descriptor.idProduct) == PRODUCT_ID_CYPHIDCOM_FRWD));
+}
 
 static int analyze_baud_rate(struct usb_serial_port *port, speed_t new_rate)
 {
@@ -238,6 +246,10 @@ static int analyze_baud_rate(struct usb_serial_port *port, speed_t new_rate)
        if (unstable_bauds)
                return new_rate;
 
+       /* FRWD Dongle uses 115200 bps */
+       if (is_frwd(port->serial->dev))
+               return new_rate;
+
        /*
         * The general purpose firmware for the Cypress M8 allows for
         * a maximum speed of 57600bps (I have no idea whether DeLorme
@@ -448,7 +460,11 @@ static int cypress_generic_port_probe(struct usb_serial_port *port)
                return -ENOMEM;
        }
 
-       usb_reset_configuration(serial->dev);
+       /* Skip reset for FRWD device. It is a workaound:
+          device hangs if it receives SET_CONFIGURE in Configured
+          state. */
+       if (!is_frwd(serial->dev))
+               usb_reset_configuration(serial->dev);
 
        priv->cmd_ctrl = 0;
        priv->line_control = 0;
index 67cf608..b461311 100644 (file)
 #define VENDOR_ID_CYPRESS              0x04b4
 #define PRODUCT_ID_CYPHIDCOM           0x5500
 
+/* FRWD Dongle - a GPS sports watch */
+#define VENDOR_ID_FRWD                 0x6737
+#define PRODUCT_ID_CYPHIDCOM_FRWD      0x0001
+
 /* Powercom UPS, chip CY7C63723 */
 #define VENDOR_ID_POWERCOM             0x0d9f
 #define PRODUCT_ID_UPS                 0x0002
index 9d74c27..790673e 100644 (file)
@@ -287,7 +287,7 @@ static int bulk_immediate(struct usb_serial_port *port, u8 *buf, u8 count)
            usb_bulk_msg(serial->dev,
                         usb_sndbulkpipe(serial->dev,
                                         port->bulk_out_endpointAddress), buf,
-                        count, &actual, HZ * 1);
+                        count, &actual, 1000);
 
        if (status != IUU_OPERATION_OK)
                dev_dbg(&port->dev, "%s - error = %2x\n", __func__, status);
@@ -307,7 +307,7 @@ static int read_immediate(struct usb_serial_port *port, u8 *buf, u8 count)
            usb_bulk_msg(serial->dev,
                         usb_rcvbulkpipe(serial->dev,
                                         port->bulk_in_endpointAddress), buf,
-                        count, &actual, HZ * 1);
+                        count, &actual, 1000);
 
        if (status != IUU_OPERATION_OK)
                dev_dbg(&port->dev, "%s - error = %2x\n", __func__, status);
index eb30d7b..3549d07 100644 (file)
@@ -1548,7 +1548,6 @@ static int keyspan_usa26_send_setup(struct usb_serial *serial,
        struct keyspan_serial_private           *s_priv;
        struct keyspan_port_private             *p_priv;
        const struct keyspan_device_details     *d_details;
-       int                                     outcont_urb;
        struct urb                              *this_urb;
        int                                     device_port, err;
 
@@ -1559,7 +1558,6 @@ static int keyspan_usa26_send_setup(struct usb_serial *serial,
        d_details = s_priv->device_details;
        device_port = port->number - port->serial->minor;
 
-       outcont_urb = d_details->outcont_endpoints[port->number];
        this_urb = p_priv->outcont_urb;
 
        dev_dbg(&port->dev, "%s - endpoint %d\n", __func__, usb_pipeendpoint(this_urb->pipe));
@@ -1685,14 +1683,6 @@ static int keyspan_usa26_send_setup(struct usb_serial *serial,
        err = usb_submit_urb(this_urb, GFP_ATOMIC);
        if (err != 0)
                dev_dbg(&port->dev, "%s - usb_submit_urb(setup) failed (%d)\n", __func__, err);
-#if 0
-       else {
-               dev_dbg(&port->dev, "%s - usb_submit_urb(%d) OK %d bytes (end %d)\n", __func__
-                       outcont_urb, this_urb->transfer_buffer_length,
-                       usb_pipeendpoint(this_urb->pipe));
-       }
-#endif
-
        return 0;
 }
 
index cc0e543..f27c621 100644 (file)
@@ -40,7 +40,7 @@
 #define DRIVER_DESC "Moschip USB Serial Driver"
 
 /* default urb timeout */
-#define MOS_WDR_TIMEOUT        (HZ * 5)
+#define MOS_WDR_TIMEOUT        5000
 
 #define MOS_MAX_PORT   0x02
 #define MOS_WRITE      0x0E
@@ -227,11 +227,22 @@ static int read_mos_reg(struct usb_serial *serial, unsigned int serial_portnum,
        __u8 requesttype = (__u8)0xc0;
        __u16 index = get_reg_index(reg);
        __u16 value = get_reg_value(reg, serial_portnum);
-       int status = usb_control_msg(usbdev, pipe, request, requesttype, value,
-                                    index, data, 1, MOS_WDR_TIMEOUT);
-       if (status < 0)
+       u8 *buf;
+       int status;
+
+       buf = kmalloc(1, GFP_KERNEL);
+       if (!buf)
+               return -ENOMEM;
+
+       status = usb_control_msg(usbdev, pipe, request, requesttype, value,
+                                    index, buf, 1, MOS_WDR_TIMEOUT);
+       if (status == 1)
+               *data = *buf;
+       else if (status < 0)
                dev_err(&usbdev->dev,
                        "mos7720: usb_control_msg() failed: %d", status);
+       kfree(buf);
+
        return status;
 }
 
@@ -1618,7 +1629,7 @@ static void change_port_settings(struct tty_struct *tty,
                mos7720_port->shadowMCR |= (UART_MCR_XONANY);
                /* To set hardware flow control to the specified *
                 * serial port, in SP1/2_CONTROL_REG             */
-               if (port->number)
+               if (port_number)
                        write_mos_reg(serial, dummy, SP_CONTROL_REG, 0x01);
                else
                        write_mos_reg(serial, dummy, SP_CONTROL_REG, 0x02);
@@ -1927,7 +1938,7 @@ static int mos7720_startup(struct usb_serial *serial)
 
        /* setting configuration feature to one */
        usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
-                       (__u8)0x03, 0x00, 0x01, 0x00, NULL, 0x00, 5*HZ);
+                       (__u8)0x03, 0x00, 0x01, 0x00, NULL, 0x00, 5000);
 
        /* start the interrupt urb */
        ret_val = usb_submit_urb(serial->port[0]->interrupt_in_urb, GFP_KERNEL);
@@ -1970,7 +1981,7 @@ static void mos7720_release(struct usb_serial *serial)
                /* wait for synchronous usb calls to return */
                if (mos_parport->msg_pending)
                        wait_for_completion_timeout(&mos_parport->syncmsg_compl,
-                                                   MOS_WDR_TIMEOUT);
+                                           msecs_to_jiffies(MOS_WDR_TIMEOUT));
 
                parport_remove_port(mos_parport->pp);
                usb_set_serial_data(serial, NULL);
index a0d5ea5..7e99808 100644 (file)
@@ -2142,13 +2142,21 @@ static int mos7840_ioctl(struct tty_struct *tty,
 static int mos7810_check(struct usb_serial *serial)
 {
        int i, pass_count = 0;
+       u8 *buf;
        __u16 data = 0, mcr_data = 0;
        __u16 test_pattern = 0x55AA;
+       int res;
+
+       buf = kmalloc(VENDOR_READ_LENGTH, GFP_KERNEL);
+       if (!buf)
+               return 0;       /* failed to identify 7810 */
 
        /* Store MCR setting */
-       usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
+       res = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
                MCS_RDREQ, MCS_RD_RTYPE, 0x0300, MODEM_CONTROL_REGISTER,
-               &mcr_data, VENDOR_READ_LENGTH, MOS_WDR_TIMEOUT);
+               buf, VENDOR_READ_LENGTH, MOS_WDR_TIMEOUT);
+       if (res == VENDOR_READ_LENGTH)
+               mcr_data = *buf;
 
        for (i = 0; i < 16; i++) {
                /* Send the 1-bit test pattern out to MCS7810 test pin */
@@ -2158,9 +2166,12 @@ static int mos7810_check(struct usb_serial *serial)
                        MODEM_CONTROL_REGISTER, NULL, 0, MOS_WDR_TIMEOUT);
 
                /* Read the test pattern back */
-               usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
-                       MCS_RDREQ, MCS_RD_RTYPE, 0, GPIO_REGISTER, &data,
-                       VENDOR_READ_LENGTH, MOS_WDR_TIMEOUT);
+               res = usb_control_msg(serial->dev,
+                               usb_rcvctrlpipe(serial->dev, 0), MCS_RDREQ,
+                               MCS_RD_RTYPE, 0, GPIO_REGISTER, buf,
+                               VENDOR_READ_LENGTH, MOS_WDR_TIMEOUT);
+               if (res == VENDOR_READ_LENGTH)
+                       data = *buf;
 
                /* If this is a MCS7810 device, both test patterns must match */
                if (((test_pattern >> i) ^ (~data >> 1)) & 0x0001)
@@ -2174,6 +2185,8 @@ static int mos7810_check(struct usb_serial *serial)
                MCS_WR_RTYPE, 0x0300 | mcr_data, MODEM_CONTROL_REGISTER, NULL,
                0, MOS_WDR_TIMEOUT);
 
+       kfree(buf);
+
        if (pass_count == 16)
                return 1;
 
@@ -2183,11 +2196,17 @@ static int mos7810_check(struct usb_serial *serial)
 static int mos7840_calc_num_ports(struct usb_serial *serial)
 {
        __u16 data = 0x00;
+       u8 *buf;
        int mos7840_num_ports;
 
-       usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
-               MCS_RDREQ, MCS_RD_RTYPE, 0, GPIO_REGISTER, &data,
-               VENDOR_READ_LENGTH, MOS_WDR_TIMEOUT);
+       buf = kzalloc(VENDOR_READ_LENGTH, GFP_KERNEL);
+       if (buf) {
+               usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
+                       MCS_RDREQ, MCS_RD_RTYPE, 0, GPIO_REGISTER, buf,
+                       VENDOR_READ_LENGTH, MOS_WDR_TIMEOUT);
+               data = *buf;
+               kfree(buf);
+       }
 
        if (serial->dev->descriptor.idProduct == MOSCHIP_DEVICE_ID_7810 ||
                serial->dev->descriptor.idProduct == MOSCHIP_DEVICE_ID_7820) {
index 93d02bc..bd4323d 100644 (file)
@@ -250,13 +250,7 @@ static void option_instat_callback(struct urb *urb);
 #define ZTE_PRODUCT_MF622                      0x0001
 #define ZTE_PRODUCT_MF628                      0x0015
 #define ZTE_PRODUCT_MF626                      0x0031
-#define ZTE_PRODUCT_CDMA_TECH                  0xfffe
-#define ZTE_PRODUCT_AC8710                     0xfff1
-#define ZTE_PRODUCT_AC2726                     0xfff5
-#define ZTE_PRODUCT_AC8710T                    0xffff
 #define ZTE_PRODUCT_MC2718                     0xffe8
-#define ZTE_PRODUCT_AD3812                     0xffeb
-#define ZTE_PRODUCT_MC2716                     0xffed
 
 #define BENQ_VENDOR_ID                         0x04a5
 #define BENQ_PRODUCT_H10                       0x4068
@@ -495,18 +489,10 @@ static const struct option_blacklist_info zte_k3765_z_blacklist = {
        .reserved = BIT(4),
 };
 
-static const struct option_blacklist_info zte_ad3812_z_blacklist = {
-       .sendsetup = BIT(0) | BIT(1) | BIT(2),
-};
-
 static const struct option_blacklist_info zte_mc2718_z_blacklist = {
        .sendsetup = BIT(1) | BIT(2) | BIT(3) | BIT(4),
 };
 
-static const struct option_blacklist_info zte_mc2716_z_blacklist = {
-       .sendsetup = BIT(1) | BIT(2) | BIT(3),
-};
-
 static const struct option_blacklist_info huawei_cdc12_blacklist = {
        .reserved = BIT(1) | BIT(2),
 };
@@ -593,6 +579,8 @@ static const struct usb_device_id option_ids[] = {
                .driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist },
        { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3765, 0xff, 0xff, 0xff),
                .driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist },
+       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x14ac, 0xff, 0xff, 0xff),    /* Huawei E1820 */
+               .driver_info = (kernel_ulong_t) &net_intf1_blacklist },
        { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4605, 0xff, 0xff, 0xff),
                .driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist },
        { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0xff, 0xff) },
@@ -797,7 +785,6 @@ static const struct usb_device_id option_ids[] = {
        { USB_DEVICE_INTERFACE_CLASS(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1012, 0xff) },
        { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC650) },
        { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC680) },
-       { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6000)}, /* ZTE AC8700 */
        { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */
        { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x9000)}, /* SIMCom SIM5218 */
        { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6280) }, /* BP3-USB & BP3-EXT HSDPA */
@@ -1199,16 +1186,9 @@ static const struct usb_device_id option_ids[] = {
        { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0178, 0xff, 0xff, 0xff),
                .driver_info = (kernel_ulong_t)&net_intf3_blacklist },
 
-       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH, 0xff, 0xff, 0xff) },
-       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC8710, 0xff, 0xff, 0xff) },
-       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC2726, 0xff, 0xff, 0xff) },
-       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC8710T, 0xff, 0xff, 0xff) },
+       /* NOTE: most ZTE CDMA devices should be driven by zte_ev, not option */
        { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MC2718, 0xff, 0xff, 0xff),
         .driver_info = (kernel_ulong_t)&zte_mc2718_z_blacklist },
-       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AD3812, 0xff, 0xff, 0xff),
-        .driver_info = (kernel_ulong_t)&zte_ad3812_z_blacklist },
-       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MC2716, 0xff, 0xff, 0xff),
-        .driver_info = (kernel_ulong_t)&zte_mc2716_z_blacklist },
        { USB_VENDOR_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff, 0x02, 0x01) },
        { USB_VENDOR_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff, 0x02, 0x05) },
        { USB_VENDOR_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff, 0x86, 0x10) },
index 59b32b7..bd794b4 100644 (file)
@@ -118,6 +118,7 @@ static const struct usb_device_id id_table[] = {
        {USB_DEVICE(0x1199, 0x901b)},   /* Sierra Wireless MC7770 */
        {USB_DEVICE(0x12D1, 0x14F0)},   /* Sony Gobi 3000 QDL */
        {USB_DEVICE(0x12D1, 0x14F1)},   /* Sony Gobi 3000 Composite */
+       {USB_DEVICE(0x0AF0, 0x8120)},   /* Option GTM681W */
 
        /* non Gobi Qualcomm serial devices */
        {USB_DEVICE_INTERFACE_NUMBER(0x0f3d, 0x68a2, 0)},       /* Sierra Wireless MC7700 Device Management */
index 4753c00..5f6b1ff 100644 (file)
@@ -408,7 +408,7 @@ static int serial_ioctl(struct tty_struct *tty,
                                        unsigned int cmd, unsigned long arg)
 {
        struct usb_serial_port *port = tty->driver_data;
-       int retval = -ENODEV;
+       int retval = -ENOIOCTLCMD;
 
        dev_dbg(tty->dev, "%s - cmd 0x%.4x\n", __func__, cmd);
 
@@ -420,8 +420,6 @@ static int serial_ioctl(struct tty_struct *tty,
        default:
                if (port->serial->type->ioctl)
                        retval = port->serial->type->ioctl(tty, cmd, arg);
-               else
-                       retval = -ENOIOCTLCMD;
        }
 
        return retval;
index 7573ec8..9910aa2 100644 (file)
@@ -560,10 +560,19 @@ static int treo_attach(struct usb_serial *serial)
        */
 #define COPY_PORT(dest, src)                                           \
        do { \
+               int i;                                                  \
+                                                                       \
+               for (i = 0; i < ARRAY_SIZE(src->read_urbs); ++i) {      \
+                       dest->read_urbs[i] = src->read_urbs[i];         \
+                       dest->read_urbs[i]->context = dest;             \
+                       dest->bulk_in_buffers[i] = src->bulk_in_buffers[i]; \
+               }                                                       \
                dest->read_urb = src->read_urb;                         \
                dest->bulk_in_endpointAddress = src->bulk_in_endpointAddress;\
                dest->bulk_in_buffer = src->bulk_in_buffer;             \
+               dest->bulk_in_size = src->bulk_in_size;                 \
                dest->interrupt_in_urb = src->interrupt_in_urb;         \
+               dest->interrupt_in_urb->context = dest;                 \
                dest->interrupt_in_endpointAddress = \
                                        src->interrupt_in_endpointAddress;\
                dest->interrupt_in_buffer = src->interrupt_in_buffer;   \
index b9fca35..347caad 100644 (file)
@@ -649,7 +649,7 @@ static void firm_setup_port(struct tty_struct *tty)
        struct whiteheat_port_settings port_settings;
        unsigned int cflag = tty->termios.c_cflag;
 
-       port_settings.port = port->number + 1;
+       port_settings.port = port->number - port->serial->minor + 1;
 
        /* get the byte size */
        switch (cflag & CSIZE) {
index 39ee737..fca4c75 100644 (file)
@@ -41,9 +41,6 @@ static int zte_ev_usb_serial_open(struct tty_struct *tty,
        int len;
        unsigned char *buf;
 
-       if (port->number != 0)
-               return -ENODEV;
-
        buf = kmalloc(MAX_SETUP_DATA_SIZE, GFP_KERNEL);
        if (!buf)
                return -ENOMEM;
@@ -53,7 +50,7 @@ static int zte_ev_usb_serial_open(struct tty_struct *tty,
        result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
                                 0x22, 0x21,
                                 0x0001, 0x0000, NULL, len,
-                                HZ * USB_CTRL_GET_TIMEOUT);
+                                USB_CTRL_GET_TIMEOUT);
        dev_dbg(dev, "result = %d\n", result);
 
        /* send  2st cmd and recieve data */
@@ -65,7 +62,7 @@ static int zte_ev_usb_serial_open(struct tty_struct *tty,
        result = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
                                 0x21, 0xa1,
                                 0x0000, 0x0000, buf, len,
-                                HZ * USB_CTRL_GET_TIMEOUT);
+                                USB_CTRL_GET_TIMEOUT);
        debug_data(dev, __func__, len, buf, result);
 
        /* send 3 cmd */
@@ -84,7 +81,7 @@ static int zte_ev_usb_serial_open(struct tty_struct *tty,
        result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
                                 0x20, 0x21,
                                 0x0000, 0x0000, buf, len,
-                                HZ * USB_CTRL_GET_TIMEOUT);
+                                USB_CTRL_GET_TIMEOUT);
        debug_data(dev, __func__, len, buf, result);
 
        /* send 4 cmd */
@@ -95,7 +92,7 @@ static int zte_ev_usb_serial_open(struct tty_struct *tty,
        result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
                                 0x22, 0x21,
                                 0x0003, 0x0000, NULL, len,
-                                HZ * USB_CTRL_GET_TIMEOUT);
+                                USB_CTRL_GET_TIMEOUT);
        dev_dbg(dev, "result = %d\n", result);
 
        /* send 5 cmd */
@@ -107,7 +104,7 @@ static int zte_ev_usb_serial_open(struct tty_struct *tty,
        result = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
                                 0x21, 0xa1,
                                 0x0000, 0x0000, buf, len,
-                                HZ * USB_CTRL_GET_TIMEOUT);
+                                USB_CTRL_GET_TIMEOUT);
        debug_data(dev, __func__, len, buf, result);
 
        /* send 6 cmd */
@@ -126,7 +123,7 @@ static int zte_ev_usb_serial_open(struct tty_struct *tty,
        result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
                                 0x20, 0x21,
                                 0x0000, 0x0000, buf, len,
-                                HZ * USB_CTRL_GET_TIMEOUT);
+                                USB_CTRL_GET_TIMEOUT);
        debug_data(dev, __func__, len, buf, result);
        kfree(buf);
 
@@ -166,9 +163,6 @@ static void zte_ev_usb_serial_close(struct usb_serial_port *port)
        int len;
        unsigned char *buf;
 
-       if (port->number != 0)
-               return;
-
        buf = kmalloc(MAX_SETUP_DATA_SIZE, GFP_KERNEL);
        if (!buf)
                return;
@@ -178,7 +172,7 @@ static void zte_ev_usb_serial_close(struct usb_serial_port *port)
        result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
                                 0x22, 0x21,
                                 0x0002, 0x0000, NULL, len,
-                                HZ * USB_CTRL_GET_TIMEOUT);
+                                USB_CTRL_GET_TIMEOUT);
        dev_dbg(dev, "result = %d\n", result);
 
        /* send 2st ctl cmd(CTL    21 22 03 00  00 00 00 00 ) */
@@ -186,7 +180,7 @@ static void zte_ev_usb_serial_close(struct usb_serial_port *port)
        result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
                                 0x22, 0x21,
                                 0x0003, 0x0000, NULL, len,
-                                HZ * USB_CTRL_GET_TIMEOUT);
+                                USB_CTRL_GET_TIMEOUT);
        dev_dbg(dev, "result = %d\n", result);
 
        /* send  3st cmd and recieve data */
@@ -198,7 +192,7 @@ static void zte_ev_usb_serial_close(struct usb_serial_port *port)
        result = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
                                 0x21, 0xa1,
                                 0x0000, 0x0000, buf, len,
-                                HZ * USB_CTRL_GET_TIMEOUT);
+                                USB_CTRL_GET_TIMEOUT);
        debug_data(dev, __func__, len, buf, result);
 
        /* send 4 cmd */
@@ -217,7 +211,7 @@ static void zte_ev_usb_serial_close(struct usb_serial_port *port)
        result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
                                 0x20, 0x21,
                                 0x0000, 0x0000, buf, len,
-                                HZ * USB_CTRL_GET_TIMEOUT);
+                                USB_CTRL_GET_TIMEOUT);
        debug_data(dev, __func__, len, buf, result);
 
        /* send 5 cmd */
@@ -228,7 +222,7 @@ static void zte_ev_usb_serial_close(struct usb_serial_port *port)
        result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
                                 0x22, 0x21,
                                 0x0003, 0x0000, NULL, len,
-                                HZ * USB_CTRL_GET_TIMEOUT);
+                                USB_CTRL_GET_TIMEOUT);
        dev_dbg(dev, "result = %d\n", result);
 
        /* send 6 cmd */
@@ -240,7 +234,7 @@ static void zte_ev_usb_serial_close(struct usb_serial_port *port)
        result = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
                                 0x21, 0xa1,
                                 0x0000, 0x0000, buf, len,
-                                HZ * USB_CTRL_GET_TIMEOUT);
+                                USB_CTRL_GET_TIMEOUT);
        debug_data(dev, __func__, len, buf, result);
 
        /* send 7 cmd */
@@ -259,7 +253,7 @@ static void zte_ev_usb_serial_close(struct usb_serial_port *port)
        result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
                                 0x20, 0x21,
                                 0x0000, 0x0000, buf, len,
-                                HZ * USB_CTRL_GET_TIMEOUT);
+                                USB_CTRL_GET_TIMEOUT);
        debug_data(dev, __func__, len, buf, result);
 
        /* send 8 cmd */
@@ -270,7 +264,7 @@ static void zte_ev_usb_serial_close(struct usb_serial_port *port)
        result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
                                 0x22, 0x21,
                                 0x0003, 0x0000, NULL, len,
-                                HZ * USB_CTRL_GET_TIMEOUT);
+                                USB_CTRL_GET_TIMEOUT);
        dev_dbg(dev, "result = %d\n", result);
 
        kfree(buf);
@@ -279,11 +273,29 @@ static void zte_ev_usb_serial_close(struct usb_serial_port *port)
 }
 
 static const struct usb_device_id id_table[] = {
-       { USB_DEVICE(0x19d2, 0xffff) }, /* AC8700 */
-       { USB_DEVICE(0x19d2, 0xfffe) },
-       { USB_DEVICE(0x19d2, 0xfffd) }, /* MG880 */
+       /* AC8710, AC8710T */
+       { USB_DEVICE_AND_INTERFACE_INFO(0x19d2, 0xffff, 0xff, 0xff, 0xff) },
+        /* AC8700 */
+       { USB_DEVICE_AND_INTERFACE_INFO(0x19d2, 0xfffe, 0xff, 0xff, 0xff) },
+       /* MG880 */
+       { USB_DEVICE(0x19d2, 0xfffd) },
+       { USB_DEVICE(0x19d2, 0xfffc) },
+       { USB_DEVICE(0x19d2, 0xfffb) },
+       /* AC2726, AC8710_V3 */
+       { USB_DEVICE_AND_INTERFACE_INFO(0x19d2, 0xfff1, 0xff, 0xff, 0xff) },
+       { USB_DEVICE(0x19d2, 0xfff6) },
+       { USB_DEVICE(0x19d2, 0xfff7) },
+       { USB_DEVICE(0x19d2, 0xfff8) },
+       { USB_DEVICE(0x19d2, 0xfff9) },
+       { USB_DEVICE(0x19d2, 0xffee) },
+       /* AC2716, MC2716 */
+       { USB_DEVICE_AND_INTERFACE_INFO(0x19d2, 0xffed, 0xff, 0xff, 0xff) },
+       /* AD3812 */
+       { USB_DEVICE_AND_INTERFACE_INFO(0x19d2, 0xffeb, 0xff, 0xff, 0xff) },
+       { USB_DEVICE(0x19d2, 0xffec) },
        { USB_DEVICE(0x05C6, 0x3197) },
        { USB_DEVICE(0x05C6, 0x6000) },
+       { USB_DEVICE(0x05C6, 0x9008) },
        { },
 };
 MODULE_DEVICE_TABLE(usb, id_table);
index acb7121..6d78736 100644 (file)
@@ -1360,7 +1360,7 @@ static const struct file_operations vfio_device_fops = {
  */
 static char *vfio_devnode(struct device *dev, umode_t *mode)
 {
-       if (MINOR(dev->devt) == 0)
+       if (mode && (MINOR(dev->devt) == 0))
                *mode = S_IRUGO | S_IWUGO;
 
        return kasprintf(GFP_KERNEL, "vfio/%s", dev_name(dev));
index 5b97e56..e3bc39b 100644 (file)
@@ -3279,8 +3279,8 @@ build_unc_path_to_root(const struct smb_vol *vol,
        pos = full_path + unc_len;
 
        if (pplen) {
-               *pos++ = CIFS_DIR_SEP(cifs_sb);
-               strncpy(pos, vol->prepath, pplen);
+               *pos = CIFS_DIR_SEP(cifs_sb);
+               strncpy(pos + 1, vol->prepath, pplen);
                pos += pplen;
        }
 
index 201f0a0..a7abbea 100644 (file)
@@ -295,6 +295,12 @@ static int ecryptfs_release(struct inode *inode, struct file *file)
 static int
 ecryptfs_fsync(struct file *file, loff_t start, loff_t end, int datasync)
 {
+       int rc;
+
+       rc = filemap_write_and_wait(file->f_mapping);
+       if (rc)
+               return rc;
+
        return vfs_fsync(ecryptfs_file_to_lower(file), datasync);
 }
 
index 254df56..f3f783d 100644 (file)
@@ -180,6 +180,8 @@ u64 fuse_get_attr_version(struct fuse_conn *fc)
 static int fuse_dentry_revalidate(struct dentry *entry, unsigned int flags)
 {
        struct inode *inode;
+       struct dentry *parent;
+       struct fuse_conn *fc;
 
        inode = ACCESS_ONCE(entry->d_inode);
        if (inode && is_bad_inode(inode))
@@ -187,10 +189,8 @@ static int fuse_dentry_revalidate(struct dentry *entry, unsigned int flags)
        else if (fuse_dentry_time(entry) < get_jiffies_64()) {
                int err;
                struct fuse_entry_out outarg;
-               struct fuse_conn *fc;
                struct fuse_req *req;
                struct fuse_forget_link *forget;
-               struct dentry *parent;
                u64 attr_version;
 
                /* For negative dentries, always do a fresh lookup */
@@ -241,8 +241,14 @@ static int fuse_dentry_revalidate(struct dentry *entry, unsigned int flags)
                                       entry_attr_timeout(&outarg),
                                       attr_version);
                fuse_change_entry_timeout(entry, &outarg);
+       } else if (inode) {
+               fc = get_fuse_conn(inode);
+               if (fc->readdirplus_auto) {
+                       parent = dget_parent(entry);
+                       fuse_advise_use_readdirplus(parent->d_inode);
+                       dput(parent);
+               }
        }
-       fuse_advise_use_readdirplus(inode);
        return 1;
 }
 
index d1c9b85..e570081 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/compat.h>
 #include <linux/swap.h>
 #include <linux/aio.h>
+#include <linux/falloc.h>
 
 static const struct file_operations fuse_direct_io_file_operations;
 
@@ -1278,7 +1279,10 @@ ssize_t fuse_direct_io(struct fuse_io_priv *io, const struct iovec *iov,
 
        iov_iter_init(&ii, iov, nr_segs, count, 0);
 
-       req = fuse_get_req(fc, fuse_iter_npages(&ii));
+       if (io->async)
+               req = fuse_get_req_for_background(fc, fuse_iter_npages(&ii));
+       else
+               req = fuse_get_req(fc, fuse_iter_npages(&ii));
        if (IS_ERR(req))
                return PTR_ERR(req);
 
@@ -1314,7 +1318,11 @@ ssize_t fuse_direct_io(struct fuse_io_priv *io, const struct iovec *iov,
                        break;
                if (count) {
                        fuse_put_request(fc, req);
-                       req = fuse_get_req(fc, fuse_iter_npages(&ii));
+                       if (io->async)
+                               req = fuse_get_req_for_background(fc,
+                                       fuse_iter_npages(&ii));
+                       else
+                               req = fuse_get_req(fc, fuse_iter_npages(&ii));
                        if (IS_ERR(req))
                                break;
                }
@@ -2365,6 +2373,11 @@ static void fuse_do_truncate(struct file *file)
        fuse_do_setattr(inode, &attr, file);
 }
 
+static inline loff_t fuse_round_up(loff_t off)
+{
+       return round_up(off, FUSE_MAX_PAGES_PER_REQ << PAGE_SHIFT);
+}
+
 static ssize_t
 fuse_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
                        loff_t offset, unsigned long nr_segs)
@@ -2372,6 +2385,7 @@ fuse_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
        ssize_t ret = 0;
        struct file *file = iocb->ki_filp;
        struct fuse_file *ff = file->private_data;
+       bool async_dio = ff->fc->async_dio;
        loff_t pos = 0;
        struct inode *inode;
        loff_t i_size;
@@ -2383,10 +2397,10 @@ fuse_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
        i_size = i_size_read(inode);
 
        /* optimization for short read */
-       if (rw != WRITE && offset + count > i_size) {
+       if (async_dio && rw != WRITE && offset + count > i_size) {
                if (offset >= i_size)
                        return 0;
-               count = i_size - offset;
+               count = min_t(loff_t, count, fuse_round_up(i_size - offset));
        }
 
        io = kmalloc(sizeof(struct fuse_io_priv), GFP_KERNEL);
@@ -2404,7 +2418,7 @@ fuse_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
         * By default, we want to optimize all I/Os with async request
         * submission to the client filesystem if supported.
         */
-       io->async = ff->fc->async_dio;
+       io->async = async_dio;
        io->iocb = iocb;
 
        /*
@@ -2412,7 +2426,7 @@ fuse_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
         * to wait on real async I/O requests, so we must submit this request
         * synchronously.
         */
-       if (!is_sync_kiocb(iocb) && (offset + count > i_size))
+       if (!is_sync_kiocb(iocb) && (offset + count > i_size) && rw == WRITE)
                io->async = false;
 
        if (rw == WRITE)
@@ -2424,7 +2438,7 @@ fuse_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
                fuse_aio_complete(io, ret < 0 ? ret : 0, -1);
 
                /* we have a non-extending, async request, so return */
-               if (ret > 0 && !is_sync_kiocb(iocb))
+               if (!is_sync_kiocb(iocb))
                        return -EIOCBQUEUED;
 
                ret = wait_on_sync_kiocb(iocb);
@@ -2446,6 +2460,7 @@ static long fuse_file_fallocate(struct file *file, int mode, loff_t offset,
                                loff_t length)
 {
        struct fuse_file *ff = file->private_data;
+       struct inode *inode = file->f_inode;
        struct fuse_conn *fc = ff->fc;
        struct fuse_req *req;
        struct fuse_fallocate_in inarg = {
@@ -2459,9 +2474,16 @@ static long fuse_file_fallocate(struct file *file, int mode, loff_t offset,
        if (fc->no_fallocate)
                return -EOPNOTSUPP;
 
+       if (mode & FALLOC_FL_PUNCH_HOLE) {
+               mutex_lock(&inode->i_mutex);
+               fuse_set_nowrite(inode);
+       }
+
        req = fuse_get_req_nopages(fc);
-       if (IS_ERR(req))
-               return PTR_ERR(req);
+       if (IS_ERR(req)) {
+               err = PTR_ERR(req);
+               goto out;
+       }
 
        req->in.h.opcode = FUSE_FALLOCATE;
        req->in.h.nodeid = ff->nodeid;
@@ -2476,6 +2498,24 @@ static long fuse_file_fallocate(struct file *file, int mode, loff_t offset,
        }
        fuse_put_request(fc, req);
 
+       if (err)
+               goto out;
+
+       /* we could have extended the file */
+       if (!(mode & FALLOC_FL_KEEP_SIZE))
+               fuse_write_update_size(inode, offset + length);
+
+       if (mode & FALLOC_FL_PUNCH_HOLE)
+               truncate_pagecache_range(inode, offset, offset + length - 1);
+
+       fuse_invalidate_attr(inode);
+
+out:
+       if (mode & FALLOC_FL_PUNCH_HOLE) {
+               fuse_release_nowrite(inode);
+               mutex_unlock(&inode->i_mutex);
+       }
+
        return err;
 }
 
index 6201f81..9a0cdde 100644 (file)
@@ -867,10 +867,11 @@ static void process_init_reply(struct fuse_conn *fc, struct fuse_req *req)
                                fc->dont_mask = 1;
                        if (arg->flags & FUSE_AUTO_INVAL_DATA)
                                fc->auto_inval_data = 1;
-                       if (arg->flags & FUSE_DO_READDIRPLUS)
+                       if (arg->flags & FUSE_DO_READDIRPLUS) {
                                fc->do_readdirplus = 1;
-                       if (arg->flags & FUSE_READDIRPLUS_AUTO)
-                               fc->readdirplus_auto = 1;
+                               if (arg->flags & FUSE_READDIRPLUS_AUTO)
+                                       fc->readdirplus_auto = 1;
+                       }
                        if (arg->flags & FUSE_ASYNC_DIO)
                                fc->async_dio = 1;
                } else {
index 1dc9a13..93b5809 100644 (file)
@@ -1286,17 +1286,26 @@ int gfs2_setattr_size(struct inode *inode, u64 newsize)
        if (ret)
                return ret;
 
+       ret = get_write_access(inode);
+       if (ret)
+               return ret;
+
        inode_dio_wait(inode);
 
        ret = gfs2_rs_alloc(GFS2_I(inode));
        if (ret)
-               return ret;
+               goto out;
 
        oldsize = inode->i_size;
-       if (newsize >= oldsize)
-               return do_grow(inode, newsize);
+       if (newsize >= oldsize) {
+               ret = do_grow(inode, newsize);
+               goto out;
+       }
 
-       return do_shrink(inode, oldsize, newsize);
+       ret = do_shrink(inode, oldsize, newsize);
+out:
+       put_write_access(inode);
+       return ret;
 }
 
 int gfs2_truncatei_resume(struct gfs2_inode *ip)
index c3e82bd..b631c90 100644 (file)
@@ -354,22 +354,31 @@ static __be64 *gfs2_dir_get_hash_table(struct gfs2_inode *ip)
                return ERR_PTR(-EIO);
        }
 
-       hc = kmalloc(hsize, GFP_NOFS);
-       ret = -ENOMEM;
+       hc = kmalloc(hsize, GFP_NOFS | __GFP_NOWARN);
+       if (hc == NULL)
+               hc = __vmalloc(hsize, GFP_NOFS, PAGE_KERNEL);
+
        if (hc == NULL)
                return ERR_PTR(-ENOMEM);
 
        ret = gfs2_dir_read_data(ip, hc, hsize);
        if (ret < 0) {
-               kfree(hc);
+               if (is_vmalloc_addr(hc))
+                       vfree(hc);
+               else
+                       kfree(hc);
                return ERR_PTR(ret);
        }
 
        spin_lock(&inode->i_lock);
-       if (ip->i_hash_cache)
-               kfree(hc);
-       else
+       if (ip->i_hash_cache) {
+               if (is_vmalloc_addr(hc))
+                       vfree(hc);
+               else
+                       kfree(hc);
+       } else {
                ip->i_hash_cache = hc;
+       }
        spin_unlock(&inode->i_lock);
 
        return ip->i_hash_cache;
@@ -385,7 +394,10 @@ void gfs2_dir_hash_inval(struct gfs2_inode *ip)
 {
        __be64 *hc = ip->i_hash_cache;
        ip->i_hash_cache = NULL;
-       kfree(hc);
+       if (is_vmalloc_addr(hc))
+               vfree(hc);
+       else
+               kfree(hc);
 }
 
 static inline int gfs2_dirent_sentinel(const struct gfs2_dirent *dent)
@@ -1113,7 +1125,10 @@ static int dir_double_exhash(struct gfs2_inode *dip)
        if (IS_ERR(hc))
                return PTR_ERR(hc);
 
-       h = hc2 = kmalloc(hsize_bytes * 2, GFP_NOFS);
+       h = hc2 = kmalloc(hsize_bytes * 2, GFP_NOFS | __GFP_NOWARN);
+       if (hc2 == NULL)
+               hc2 = __vmalloc(hsize_bytes * 2, GFP_NOFS, PAGE_KERNEL);
+
        if (!hc2)
                return -ENOMEM;
 
@@ -1145,7 +1160,10 @@ fail:
        gfs2_dinode_out(dip, dibh->b_data);
        brelse(dibh);
 out_kfree:
-       kfree(hc2);
+       if (is_vmalloc_addr(hc2))
+               vfree(hc2);
+       else
+               kfree(hc2);
        return error;
 }
 
@@ -1846,6 +1864,8 @@ static int leaf_dealloc(struct gfs2_inode *dip, u32 index, u32 len,
        memset(&rlist, 0, sizeof(struct gfs2_rgrp_list));
 
        ht = kzalloc(size, GFP_NOFS);
+       if (ht == NULL)
+               ht = vzalloc(size);
        if (!ht)
                return -ENOMEM;
 
@@ -1933,7 +1953,10 @@ out_rlist:
        gfs2_rlist_free(&rlist);
        gfs2_quota_unhold(dip);
 out:
-       kfree(ht);
+       if (is_vmalloc_addr(ht))
+               vfree(ht);
+       else
+               kfree(ht);
        return error;
 }
 
index acd1676..ad0dc38 100644 (file)
@@ -402,16 +402,20 @@ static int gfs2_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
        /* Update file times before taking page lock */
        file_update_time(vma->vm_file);
 
+       ret = get_write_access(inode);
+       if (ret)
+               goto out;
+
        ret = gfs2_rs_alloc(ip);
        if (ret)
-               return ret;
+               goto out_write_access;
 
        gfs2_size_hint(vma->vm_file, pos, PAGE_CACHE_SIZE);
 
        gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh);
        ret = gfs2_glock_nq(&gh);
        if (ret)
-               goto out;
+               goto out_uninit;
 
        set_bit(GLF_DIRTY, &ip->i_gl->gl_flags);
        set_bit(GIF_SW_PAGED, &ip->i_flags);
@@ -480,12 +484,15 @@ out_quota_unlock:
        gfs2_quota_unlock(ip);
 out_unlock:
        gfs2_glock_dq(&gh);
-out:
+out_uninit:
        gfs2_holder_uninit(&gh);
        if (ret == 0) {
                set_page_dirty(page);
                wait_for_stable_page(page);
        }
+out_write_access:
+       put_write_access(inode);
+out:
        sb_end_pagefault(inode->i_sb);
        return block_page_mkwrite_return(ret);
 }
@@ -594,10 +601,10 @@ static int gfs2_release(struct inode *inode, struct file *file)
        kfree(file->private_data);
        file->private_data = NULL;
 
-       if ((file->f_mode & FMODE_WRITE) &&
-           (atomic_read(&inode->i_writecount) == 1))
-               gfs2_rs_delete(ip);
+       if (!(file->f_mode & FMODE_WRITE))
+               return 0;
 
+       gfs2_rs_delete(ip);
        return 0;
 }
 
index 8833a4f..62b484e 100644 (file)
@@ -189,6 +189,7 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned int type,
        return inode;
 
 fail_refresh:
+       ip->i_iopen_gh.gh_flags |= GL_NOCACHE;
        ip->i_iopen_gh.gh_gl->gl_object = NULL;
        gfs2_glock_dq_uninit(&ip->i_iopen_gh);
 fail_iopen:
index 68b4c8f..6c33d7b 100644 (file)
@@ -419,7 +419,9 @@ static void gfs2_before_commit(struct gfs2_sbd *sdp, unsigned int limit,
                if (total > limit)
                        num = limit;
                gfs2_log_unlock(sdp);
-               page = gfs2_get_log_desc(sdp, GFS2_LOG_DESC_METADATA, num + 1, num);
+               page = gfs2_get_log_desc(sdp,
+                                        is_databuf ? GFS2_LOG_DESC_JDATA :
+                                        GFS2_LOG_DESC_METADATA, num + 1, num);
                ld = page_address(page);
                gfs2_log_lock(sdp);
                ptr = (__be64 *)(ld + 1);
index 5232525..9809156 100644 (file)
@@ -638,8 +638,10 @@ void gfs2_rs_deltree(struct gfs2_blkreserv *rs)
  */
 void gfs2_rs_delete(struct gfs2_inode *ip)
 {
+       struct inode *inode = &ip->i_inode;
+
        down_write(&ip->i_rw_mutex);
-       if (ip->i_res) {
+       if (ip->i_res && atomic_read(&inode->i_writecount) <= 1) {
                gfs2_rs_deltree(ip->i_res);
                BUG_ON(ip->i_res->rs_free);
                kmem_cache_free(gfs2_rsrv_cachep, ip->i_res);
index 917c8e1..e5639de 100644 (file)
@@ -1444,6 +1444,7 @@ static void gfs2_evict_inode(struct inode *inode)
        /* Must not read inode block until block type has been verified */
        error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, GL_SKIP, &gh);
        if (unlikely(error)) {
+               ip->i_iopen_gh.gh_flags |= GL_NOCACHE;
                gfs2_glock_dq_uninit(&ip->i_iopen_gh);
                goto out;
        }
@@ -1514,8 +1515,10 @@ out_unlock:
        if (gfs2_rs_active(ip->i_res))
                gfs2_rs_deltree(ip->i_res);
 
-       if (test_bit(HIF_HOLDER, &ip->i_iopen_gh.gh_iflags))
+       if (test_bit(HIF_HOLDER, &ip->i_iopen_gh.gh_iflags)) {
+               ip->i_iopen_gh.gh_flags |= GL_NOCACHE;
                gfs2_glock_dq(&ip->i_iopen_gh);
+       }
        gfs2_holder_uninit(&ip->i_iopen_gh);
        gfs2_glock_dq_uninit(&gh);
        if (error && error != GLR_TRYFAILED && error != -EROFS)
@@ -1534,6 +1537,7 @@ out:
        ip->i_gl = NULL;
        if (ip->i_iopen_gh.gh_gl) {
                ip->i_iopen_gh.gh_gl->gl_object = NULL;
+               ip->i_iopen_gh.gh_flags |= GL_NOCACHE;
                gfs2_glock_dq_uninit(&ip->i_iopen_gh);
        }
 }
index 3027f4d..e4ba5fe 100644 (file)
@@ -109,10 +109,14 @@ static void hpfs_write_failed(struct address_space *mapping, loff_t to)
 {
        struct inode *inode = mapping->host;
 
+       hpfs_lock(inode->i_sb);
+
        if (to > inode->i_size) {
                truncate_pagecache(inode, to, inode->i_size);
                hpfs_truncate(inode);
        }
+
+       hpfs_unlock(inode->i_sb);
 }
 
 static int hpfs_write_begin(struct file *file, struct address_space *mapping,
index c57499d..360d27c 100644 (file)
@@ -2009,7 +2009,13 @@ static int lbmRead(struct jfs_log * log, int pn, struct lbuf ** bpp)
 
        bio->bi_end_io = lbmIODone;
        bio->bi_private = bp;
-       submit_bio(READ_SYNC, bio);
+       /*check if journaling to disk has been disabled*/
+       if (log->no_integrity) {
+               bio->bi_size = 0;
+               lbmIODone(bio, 0);
+       } else {
+               submit_bio(READ_SYNC, bio);
+       }
 
        wait_event(bp->l_ioevent, (bp->l_flag != lbmREAD));
 
index 2003e83..788e0a9 100644 (file)
@@ -611,11 +611,28 @@ static int jfs_freeze(struct super_block *sb)
 {
        struct jfs_sb_info *sbi = JFS_SBI(sb);
        struct jfs_log *log = sbi->log;
+       int rc = 0;
 
        if (!(sb->s_flags & MS_RDONLY)) {
                txQuiesce(sb);
-               lmLogShutdown(log);
-               updateSuper(sb, FM_CLEAN);
+               rc = lmLogShutdown(log);
+               if (rc) {
+                       jfs_error(sb, "jfs_freeze: lmLogShutdown failed");
+
+                       /* let operations fail rather than hang */
+                       txResume(sb);
+
+                       return rc;
+               }
+               rc = updateSuper(sb, FM_CLEAN);
+               if (rc) {
+                       jfs_err("jfs_freeze: updateSuper failed\n");
+                       /*
+                        * Don't fail here. Everything succeeded except
+                        * marking the superblock clean, so there's really
+                        * no harm in leaving it frozen for now.
+                        */
+               }
        }
        return 0;
 }
@@ -627,13 +644,18 @@ static int jfs_unfreeze(struct super_block *sb)
        int rc = 0;
 
        if (!(sb->s_flags & MS_RDONLY)) {
-               updateSuper(sb, FM_MOUNT);
-               if ((rc = lmLogInit(log)))
-                       jfs_err("jfs_unlock failed with return code %d", rc);
-               else
-                       txResume(sb);
+               rc = updateSuper(sb, FM_MOUNT);
+               if (rc) {
+                       jfs_error(sb, "jfs_unfreeze: updateSuper failed");
+                       goto out;
+               }
+               rc = lmLogInit(log);
+               if (rc)
+                       jfs_error(sb, "jfs_unfreeze: lmLogInit failed");
+out:
+               txResume(sb);
        }
-       return 0;
+       return rc;
 }
 
 static struct dentry *jfs_do_mount(struct file_system_type *fs_type,
index dd51e50..c3834da 100644 (file)
@@ -2118,6 +2118,7 @@ static int show_timer(struct seq_file *m, void *v)
                nstr[notify & ~SIGEV_THREAD_ID],
                (notify & SIGEV_THREAD_ID) ? "tid" : "pid",
                pid_nr_ns(timer->it_pid, tp->ns));
+       seq_printf(m, "ClockID: %d\n", timer->it_clock);
 
        return 0;
 }
index 1d32f1d..306d883 100644 (file)
@@ -21,6 +21,8 @@
 #include "xfs_bmap_btree.h"
 #include "xfs_inode.h"
 #include "xfs_vnodeops.h"
+#include "xfs_sb.h"
+#include "xfs_mount.h"
 #include "xfs_trace.h"
 #include <linux/slab.h>
 #include <linux/xattr.h>
@@ -34,7 +36,9 @@
  */
 
 STATIC struct posix_acl *
-xfs_acl_from_disk(struct xfs_acl *aclp)
+xfs_acl_from_disk(
+       struct xfs_acl  *aclp,
+       int             max_entries)
 {
        struct posix_acl_entry *acl_e;
        struct posix_acl *acl;
@@ -42,7 +46,7 @@ xfs_acl_from_disk(struct xfs_acl *aclp)
        unsigned int count, i;
 
        count = be32_to_cpu(aclp->acl_cnt);
-       if (count > XFS_ACL_MAX_ENTRIES)
+       if (count > max_entries)
                return ERR_PTR(-EFSCORRUPTED);
 
        acl = posix_acl_alloc(count, GFP_KERNEL);
@@ -108,9 +112,9 @@ xfs_get_acl(struct inode *inode, int type)
        struct xfs_inode *ip = XFS_I(inode);
        struct posix_acl *acl;
        struct xfs_acl *xfs_acl;
-       int len = sizeof(struct xfs_acl);
        unsigned char *ea_name;
        int error;
+       int len;
 
        acl = get_cached_acl(inode, type);
        if (acl != ACL_NOT_CACHED)
@@ -133,8 +137,8 @@ xfs_get_acl(struct inode *inode, int type)
         * If we have a cached ACLs value just return it, not need to
         * go out to the disk.
         */
-
-       xfs_acl = kzalloc(sizeof(struct xfs_acl), GFP_KERNEL);
+       len = XFS_ACL_MAX_SIZE(ip->i_mount);
+       xfs_acl = kzalloc(len, GFP_KERNEL);
        if (!xfs_acl)
                return ERR_PTR(-ENOMEM);
 
@@ -153,7 +157,7 @@ xfs_get_acl(struct inode *inode, int type)
                goto out;
        }
 
-       acl = xfs_acl_from_disk(xfs_acl);
+       acl = xfs_acl_from_disk(xfs_acl, XFS_ACL_MAX_ENTRIES(ip->i_mount));
        if (IS_ERR(acl))
                goto out;
 
@@ -189,16 +193,17 @@ xfs_set_acl(struct inode *inode, int type, struct posix_acl *acl)
 
        if (acl) {
                struct xfs_acl *xfs_acl;
-               int len;
+               int len = XFS_ACL_MAX_SIZE(ip->i_mount);
 
-               xfs_acl = kzalloc(sizeof(struct xfs_acl), GFP_KERNEL);
+               xfs_acl = kzalloc(len, GFP_KERNEL);
                if (!xfs_acl)
                        return -ENOMEM;
 
                xfs_acl_to_disk(xfs_acl, acl);
-               len = sizeof(struct xfs_acl) -
-                       (sizeof(struct xfs_acl_entry) *
-                        (XFS_ACL_MAX_ENTRIES - acl->a_count));
+
+               /* subtract away the unused acl entries */
+               len -= sizeof(struct xfs_acl_entry) *
+                        (XFS_ACL_MAX_ENTRIES(ip->i_mount) - acl->a_count);
 
                error = -xfs_attr_set(ip, ea_name, (unsigned char *)xfs_acl,
                                len, ATTR_ROOT);
@@ -243,7 +248,7 @@ xfs_set_mode(struct inode *inode, umode_t mode)
 static int
 xfs_acl_exists(struct inode *inode, unsigned char *name)
 {
-       int len = sizeof(struct xfs_acl);
+       int len = XFS_ACL_MAX_SIZE(XFS_M(inode->i_sb));
 
        return (xfs_attr_get(XFS_I(inode), name, NULL, &len,
                            ATTR_ROOT|ATTR_KERNOVAL) == 0);
@@ -379,7 +384,7 @@ xfs_xattr_acl_set(struct dentry *dentry, const char *name,
                goto out_release;
 
        error = -EINVAL;
-       if (acl->a_count > XFS_ACL_MAX_ENTRIES)
+       if (acl->a_count > XFS_ACL_MAX_ENTRIES(XFS_M(inode->i_sb)))
                goto out_release;
 
        if (type == ACL_TYPE_ACCESS) {
index 39632d9..4016a56 100644 (file)
@@ -22,19 +22,36 @@ struct inode;
 struct posix_acl;
 struct xfs_inode;
 
-#define XFS_ACL_MAX_ENTRIES 25
 #define XFS_ACL_NOT_PRESENT (-1)
 
 /* On-disk XFS access control list structure */
+struct xfs_acl_entry {
+       __be32  ae_tag;
+       __be32  ae_id;
+       __be16  ae_perm;
+       __be16  ae_pad;         /* fill the implicit hole in the structure */
+};
+
 struct xfs_acl {
-       __be32          acl_cnt;
-       struct xfs_acl_entry {
-               __be32  ae_tag;
-               __be32  ae_id;
-               __be16  ae_perm;
-       } acl_entry[XFS_ACL_MAX_ENTRIES];
+       __be32                  acl_cnt;
+       struct xfs_acl_entry    acl_entry[0];
 };
 
+/*
+ * The number of ACL entries allowed is defined by the on-disk format.
+ * For v4 superblocks, that is limited to 25 entries. For v5 superblocks, it is
+ * limited only by the maximum size of the xattr that stores the information.
+ */
+#define XFS_ACL_MAX_ENTRIES(mp)        \
+       (xfs_sb_version_hascrc(&mp->m_sb) \
+               ?  (XATTR_SIZE_MAX - sizeof(struct xfs_acl)) / \
+                                               sizeof(struct xfs_acl_entry) \
+               : 25)
+
+#define XFS_ACL_MAX_SIZE(mp) \
+       (sizeof(struct xfs_acl) + \
+               sizeof(struct xfs_acl_entry) * XFS_ACL_MAX_ENTRIES((mp)))
+
 /* On-disk XFS extended attribute names */
 #define SGI_ACL_FILE           (unsigned char *)"SGI_ACL_FILE"
 #define SGI_ACL_DEFAULT                (unsigned char *)"SGI_ACL_DEFAULT"
index d788302..31d3cd1 100644 (file)
@@ -3258,7 +3258,7 @@ xfs_attr3_leaf_inactive(
                        name_rmt = xfs_attr3_leaf_name_remote(leaf, i);
                        if (name_rmt->valueblk) {
                                lp->valueblk = be32_to_cpu(name_rmt->valueblk);
-                               lp->valuelen = XFS_B_TO_FSB(dp->i_mount,
+                               lp->valuelen = xfs_attr3_rmt_blocks(dp->i_mount,
                                                    be32_to_cpu(name_rmt->valuelen));
                                lp++;
                        }
index a41f8bf..044e97a 100644 (file)
@@ -249,8 +249,11 @@ xfs_qm_init_dquot_blk(
                d->dd_diskdq.d_version = XFS_DQUOT_VERSION;
                d->dd_diskdq.d_id = cpu_to_be32(curid);
                d->dd_diskdq.d_flags = type;
-               if (xfs_sb_version_hascrc(&mp->m_sb))
+               if (xfs_sb_version_hascrc(&mp->m_sb)) {
                        uuid_copy(&d->dd_uuid, &mp->m_sb.sb_uuid);
+                       xfs_update_cksum((char *)d, sizeof(struct xfs_dqblk),
+                                        XFS_DQUOT_CRC_OFF);
+               }
        }
 
        xfs_trans_dquot_buf(tp, bp,
@@ -286,23 +289,6 @@ xfs_dquot_set_prealloc_limits(struct xfs_dquot *dqp)
        dqp->q_low_space[XFS_QLOWSP_5_PCNT] = space * 5;
 }
 
-STATIC void
-xfs_dquot_buf_calc_crc(
-       struct xfs_mount        *mp,
-       struct xfs_buf          *bp)
-{
-       struct xfs_dqblk        *d = (struct xfs_dqblk *)bp->b_addr;
-       int                     i;
-
-       if (!xfs_sb_version_hascrc(&mp->m_sb))
-               return;
-
-       for (i = 0; i < mp->m_quotainfo->qi_dqperchunk; i++, d++) {
-               xfs_update_cksum((char *)d, sizeof(struct xfs_dqblk),
-                                offsetof(struct xfs_dqblk, dd_crc));
-       }
-}
-
 STATIC bool
 xfs_dquot_buf_verify_crc(
        struct xfs_mount        *mp,
@@ -328,12 +314,11 @@ xfs_dquot_buf_verify_crc(
 
        for (i = 0; i < ndquots; i++, d++) {
                if (!xfs_verify_cksum((char *)d, sizeof(struct xfs_dqblk),
-                                offsetof(struct xfs_dqblk, dd_crc)))
+                                XFS_DQUOT_CRC_OFF))
                        return false;
                if (!uuid_equal(&d->dd_uuid, &mp->m_sb.sb_uuid))
                        return false;
        }
-
        return true;
 }
 
@@ -393,6 +378,11 @@ xfs_dquot_buf_read_verify(
        }
 }
 
+/*
+ * we don't calculate the CRC here as that is done when the dquot is flushed to
+ * the buffer after the update is done. This ensures that the dquot in the
+ * buffer always has an up-to-date CRC value.
+ */
 void
 xfs_dquot_buf_write_verify(
        struct xfs_buf  *bp)
@@ -404,7 +394,6 @@ xfs_dquot_buf_write_verify(
                xfs_buf_ioerror(bp, EFSCORRUPTED);
                return;
        }
-       xfs_dquot_buf_calc_crc(mp, bp);
 }
 
 const struct xfs_buf_ops xfs_dquot_buf_ops = {
@@ -1151,11 +1140,17 @@ xfs_qm_dqflush(
         * copy the lsn into the on-disk dquot now while we have the in memory
         * dquot here. This can't be done later in the write verifier as we
         * can't get access to the log item at that point in time.
+        *
+        * We also calculate the CRC here so that the on-disk dquot in the
+        * buffer always has a valid CRC. This ensures there is no possibility
+        * of a dquot without an up-to-date CRC getting to disk.
         */
        if (xfs_sb_version_hascrc(&mp->m_sb)) {
                struct xfs_dqblk *dqb = (struct xfs_dqblk *)ddqp;
 
                dqb->dd_lsn = cpu_to_be64(dqp->q_logitem.qli_item.li_lsn);
+               xfs_update_cksum((char *)dqb, sizeof(struct xfs_dqblk),
+                                XFS_DQUOT_CRC_OFF);
        }
 
        /*
index efbe1ac..7f7be5f 100644 (file)
@@ -1638,6 +1638,10 @@ xfs_iunlink(
                dip->di_next_unlinked = agi->agi_unlinked[bucket_index];
                offset = ip->i_imap.im_boffset +
                        offsetof(xfs_dinode_t, di_next_unlinked);
+
+               /* need to recalc the inode CRC if appropriate */
+               xfs_dinode_calc_crc(mp, dip);
+
                xfs_trans_inode_buf(tp, ibp);
                xfs_trans_log_buf(tp, ibp, offset,
                                  (offset + sizeof(xfs_agino_t) - 1));
@@ -1723,6 +1727,10 @@ xfs_iunlink_remove(
                        dip->di_next_unlinked = cpu_to_be32(NULLAGINO);
                        offset = ip->i_imap.im_boffset +
                                offsetof(xfs_dinode_t, di_next_unlinked);
+
+                       /* need to recalc the inode CRC if appropriate */
+                       xfs_dinode_calc_crc(mp, dip);
+
                        xfs_trans_inode_buf(tp, ibp);
                        xfs_trans_log_buf(tp, ibp, offset,
                                          (offset + sizeof(xfs_agino_t) - 1));
@@ -1796,6 +1804,10 @@ xfs_iunlink_remove(
                        dip->di_next_unlinked = cpu_to_be32(NULLAGINO);
                        offset = ip->i_imap.im_boffset +
                                offsetof(xfs_dinode_t, di_next_unlinked);
+
+                       /* need to recalc the inode CRC if appropriate */
+                       xfs_dinode_calc_crc(mp, dip);
+
                        xfs_trans_inode_buf(tp, ibp);
                        xfs_trans_log_buf(tp, ibp, offset,
                                          (offset + sizeof(xfs_agino_t) - 1));
@@ -1809,6 +1821,10 @@ xfs_iunlink_remove(
                last_dip->di_next_unlinked = cpu_to_be32(next_agino);
                ASSERT(next_agino != 0);
                offset = last_offset + offsetof(xfs_dinode_t, di_next_unlinked);
+
+               /* need to recalc the inode CRC if appropriate */
+               xfs_dinode_calc_crc(mp, last_dip);
+
                xfs_trans_inode_buf(tp, last_ibp);
                xfs_trans_log_buf(tp, last_ibp, offset,
                                  (offset + sizeof(xfs_agino_t) - 1));
index d9e4d3c..45a85ff 100644 (file)
@@ -1599,10 +1599,43 @@ xlog_recover_add_to_trans(
 }
 
 /*
- * Sort the log items in the transaction. Cancelled buffers need
- * to be put first so they are processed before any items that might
- * modify the buffers. If they are cancelled, then the modifications
- * don't need to be replayed.
+ * Sort the log items in the transaction.
+ *
+ * The ordering constraints are defined by the inode allocation and unlink
+ * behaviour. The rules are:
+ *
+ *     1. Every item is only logged once in a given transaction. Hence it
+ *        represents the last logged state of the item. Hence ordering is
+ *        dependent on the order in which operations need to be performed so
+ *        required initial conditions are always met.
+ *
+ *     2. Cancelled buffers are recorded in pass 1 in a separate table and
+ *        there's nothing to replay from them so we can simply cull them
+ *        from the transaction. However, we can't do that until after we've
+ *        replayed all the other items because they may be dependent on the
+ *        cancelled buffer and replaying the cancelled buffer can remove it
+ *        form the cancelled buffer table. Hence they have tobe done last.
+ *
+ *     3. Inode allocation buffers must be replayed before inode items that
+ *        read the buffer and replay changes into it.
+ *
+ *     4. Inode unlink buffers must be replayed after inode items are replayed.
+ *        This ensures that inodes are completely flushed to the inode buffer
+ *        in a "free" state before we remove the unlinked inode list pointer.
+ *
+ * Hence the ordering needs to be inode allocation buffers first, inode items
+ * second, inode unlink buffers third and cancelled buffers last.
+ *
+ * But there's a problem with that - we can't tell an inode allocation buffer
+ * apart from a regular buffer, so we can't separate them. We can, however,
+ * tell an inode unlink buffer from the others, and so we can separate them out
+ * from all the other buffers and move them to last.
+ *
+ * Hence, 4 lists, in order from head to tail:
+ *     - buffer_list for all buffers except cancelled/inode unlink buffers
+ *     - item_list for all non-buffer items
+ *     - inode_buffer_list for inode unlink buffers
+ *     - cancel_list for the cancelled buffers
  */
 STATIC int
 xlog_recover_reorder_trans(
@@ -1612,6 +1645,10 @@ xlog_recover_reorder_trans(
 {
        xlog_recover_item_t     *item, *n;
        LIST_HEAD(sort_list);
+       LIST_HEAD(cancel_list);
+       LIST_HEAD(buffer_list);
+       LIST_HEAD(inode_buffer_list);
+       LIST_HEAD(inode_list);
 
        list_splice_init(&trans->r_itemq, &sort_list);
        list_for_each_entry_safe(item, n, &sort_list, ri_list) {
@@ -1619,12 +1656,18 @@ xlog_recover_reorder_trans(
 
                switch (ITEM_TYPE(item)) {
                case XFS_LI_BUF:
-                       if (!(buf_f->blf_flags & XFS_BLF_CANCEL)) {
+                       if (buf_f->blf_flags & XFS_BLF_CANCEL) {
                                trace_xfs_log_recover_item_reorder_head(log,
                                                        trans, item, pass);
-                               list_move(&item->ri_list, &trans->r_itemq);
+                               list_move(&item->ri_list, &cancel_list);
+                               break;
+                       }
+                       if (buf_f->blf_flags & XFS_BLF_INODE_BUF) {
+                               list_move(&item->ri_list, &inode_buffer_list);
                                break;
                        }
+                       list_move_tail(&item->ri_list, &buffer_list);
+                       break;
                case XFS_LI_INODE:
                case XFS_LI_DQUOT:
                case XFS_LI_QUOTAOFF:
@@ -1632,7 +1675,7 @@ xlog_recover_reorder_trans(
                case XFS_LI_EFI:
                        trace_xfs_log_recover_item_reorder_tail(log,
                                                        trans, item, pass);
-                       list_move_tail(&item->ri_list, &trans->r_itemq);
+                       list_move_tail(&item->ri_list, &inode_list);
                        break;
                default:
                        xfs_warn(log->l_mp,
@@ -1643,6 +1686,14 @@ xlog_recover_reorder_trans(
                }
        }
        ASSERT(list_empty(&sort_list));
+       if (!list_empty(&buffer_list))
+               list_splice(&buffer_list, &trans->r_itemq);
+       if (!list_empty(&inode_list))
+               list_splice_tail(&inode_list, &trans->r_itemq);
+       if (!list_empty(&inode_buffer_list))
+               list_splice_tail(&inode_buffer_list, &trans->r_itemq);
+       if (!list_empty(&cancel_list))
+               list_splice_tail(&cancel_list, &trans->r_itemq);
        return 0;
 }
 
@@ -1861,6 +1912,15 @@ xlog_recover_do_inode_buffer(
                buffer_nextp = (xfs_agino_t *)xfs_buf_offset(bp,
                                              next_unlinked_offset);
                *buffer_nextp = *logged_nextp;
+
+               /*
+                * If necessary, recalculate the CRC in the on-disk inode. We
+                * have to leave the inode in a consistent state for whoever
+                * reads it next....
+                */
+               xfs_dinode_calc_crc(mp, (struct xfs_dinode *)
+                               xfs_buf_offset(bp, i * mp->m_sb.sb_inodesize));
+
        }
 
        return 0;
@@ -2266,6 +2326,12 @@ xfs_qm_dqcheck(
        d->dd_diskdq.d_flags = type;
        d->dd_diskdq.d_id = cpu_to_be32(id);
 
+       if (xfs_sb_version_hascrc(&mp->m_sb)) {
+               uuid_copy(&d->dd_uuid, &mp->m_sb.sb_uuid);
+               xfs_update_cksum((char *)d, sizeof(struct xfs_dqblk),
+                                XFS_DQUOT_CRC_OFF);
+       }
+
        return errs;
 }
 
@@ -2793,6 +2859,10 @@ xlog_recover_dquot_pass2(
        }
 
        memcpy(ddq, recddq, item->ri_buf[1].i_len);
+       if (xfs_sb_version_hascrc(&mp->m_sb)) {
+               xfs_update_cksum((char *)ddq, sizeof(struct xfs_dqblk),
+                                XFS_DQUOT_CRC_OFF);
+       }
 
        ASSERT(dq_f->qlf_size == 2);
        ASSERT(bp->b_target->bt_mount == mp);
index f41702b..b75c9bb 100644 (file)
@@ -41,6 +41,7 @@
 #include "xfs_qm.h"
 #include "xfs_trace.h"
 #include "xfs_icache.h"
+#include "xfs_cksum.h"
 
 /*
  * The global quota manager. There is only one of these for the entire
@@ -839,7 +840,7 @@ xfs_qm_reset_dqcounts(
        xfs_dqid_t      id,
        uint            type)
 {
-       xfs_disk_dquot_t        *ddq;
+       struct xfs_dqblk        *dqb;
        int                     j;
 
        trace_xfs_reset_dqcounts(bp, _RET_IP_);
@@ -853,8 +854,12 @@ xfs_qm_reset_dqcounts(
        do_div(j, sizeof(xfs_dqblk_t));
        ASSERT(mp->m_quotainfo->qi_dqperchunk == j);
 #endif
-       ddq = bp->b_addr;
+       dqb = bp->b_addr;
        for (j = 0; j < mp->m_quotainfo->qi_dqperchunk; j++) {
+               struct xfs_disk_dquot   *ddq;
+
+               ddq = (struct xfs_disk_dquot *)&dqb[j];
+
                /*
                 * Do a sanity check, and if needed, repair the dqblk. Don't
                 * output any warnings because it's perfectly possible to
@@ -871,7 +876,12 @@ xfs_qm_reset_dqcounts(
                ddq->d_bwarns = 0;
                ddq->d_iwarns = 0;
                ddq->d_rtbwarns = 0;
-               ddq = (xfs_disk_dquot_t *) ((xfs_dqblk_t *)ddq + 1);
+
+               if (xfs_sb_version_hascrc(&mp->m_sb)) {
+                       xfs_update_cksum((char *)&dqb[j],
+                                        sizeof(struct xfs_dqblk),
+                                        XFS_DQUOT_CRC_OFF);
+               }
        }
 }
 
@@ -907,19 +917,29 @@ xfs_qm_dqiter_bufs(
                              XFS_FSB_TO_DADDR(mp, bno),
                              mp->m_quotainfo->qi_dqchunklen, 0, &bp,
                              &xfs_dquot_buf_ops);
-               if (error)
-                       break;
 
                /*
-                * XXX(hch): need to figure out if it makes sense to validate
-                *           the CRC here.
+                * CRC and validation errors will return a EFSCORRUPTED here. If
+                * this occurs, re-read without CRC validation so that we can
+                * repair the damage via xfs_qm_reset_dqcounts(). This process
+                * will leave a trace in the log indicating corruption has
+                * been detected.
                 */
+               if (error == EFSCORRUPTED) {
+                       error = xfs_trans_read_buf(mp, NULL, mp->m_ddev_targp,
+                                     XFS_FSB_TO_DADDR(mp, bno),
+                                     mp->m_quotainfo->qi_dqchunklen, 0, &bp,
+                                     NULL);
+               }
+
+               if (error)
+                       break;
+
                xfs_qm_reset_dqcounts(mp, bp, firstid, type);
                xfs_buf_delwri_queue(bp, buffer_list);
                xfs_buf_relse(bp);
-               /*
-                * goto the next block.
-                */
+
+               /* goto the next block. */
                bno++;
                firstid += mp->m_quotainfo->qi_dqperchunk;
        }
index c61e31c..c38068f 100644 (file)
@@ -87,6 +87,8 @@ typedef struct xfs_dqblk {
        uuid_t            dd_uuid;      /* location information */
 } xfs_dqblk_t;
 
+#define XFS_DQUOT_CRC_OFF      offsetof(struct xfs_dqblk, dd_crc)
+
 /*
  * flags for q_flags field in the dquot.
  */
index ea341ce..3033ba5 100644 (file)
@@ -1372,6 +1372,17 @@ xfs_finish_flags(
                }
        }
 
+       /*
+        * V5 filesystems always use attr2 format for attributes.
+        */
+       if (xfs_sb_version_hascrc(&mp->m_sb) &&
+           (mp->m_flags & XFS_MOUNT_NOATTR2)) {
+               xfs_warn(mp,
+"Cannot mount a V5 filesystem as %s. %s is always enabled for V5 filesystems.",
+                       MNTOPT_NOATTR2, MNTOPT_ATTR2);
+               return XFS_ERROR(EINVAL);
+       }
+
        /*
         * mkfs'ed attr2 will turn on attr2 mount unless explicitly
         * told by noattr2 to turn it off
index ac9da00..d5afe96 100644 (file)
@@ -343,8 +343,12 @@ extern void ioport_unmap(void __iomem *p);
 #endif /* CONFIG_GENERIC_IOMAP */
 #endif /* CONFIG_HAS_IOPORT */
 
+#ifndef xlate_dev_kmem_ptr
 #define xlate_dev_kmem_ptr(p)  p
+#endif
+#ifndef xlate_dev_mem_ptr
 #define xlate_dev_mem_ptr(p)   __va(p)
+#endif
 
 #ifdef CONFIG_VIRT_TO_BUS
 #ifndef virt_to_bus
index b1b1fa6..13821c3 100644 (file)
@@ -97,11 +97,9 @@ struct mmu_gather {
        unsigned long           start;
        unsigned long           end;
        unsigned int            need_flush : 1, /* Did free PTEs */
-                               fast_mode  : 1; /* No batching   */
-
        /* we are in the middle of an operation to clear
         * a full mm and can make some optimizations */
-       unsigned int            fullmm : 1,
+                               fullmm : 1,
        /* we have performed an operation which
         * requires a complete flush of the tlb */
                                need_flush_all : 1;
@@ -114,19 +112,6 @@ struct mmu_gather {
 
 #define HAVE_GENERIC_MMU_GATHER
 
-static inline int tlb_fast_mode(struct mmu_gather *tlb)
-{
-#ifdef CONFIG_SMP
-       return tlb->fast_mode;
-#else
-       /*
-        * For UP we don't need to worry about TLB flush
-        * and page free order so much..
-        */
-       return 1;
-#endif
-}
-
 void tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, bool fullmm);
 void tlb_flush_mmu(struct mmu_gather *tlb);
 void tlb_finish_mmu(struct mmu_gather *tlb, unsigned long start,
index 5047355..8bda129 100644 (file)
@@ -707,7 +707,7 @@ struct cgroup *cgroup_rightmost_descendant(struct cgroup *pos);
  *
  * If a subsystem synchronizes against the parent in its ->css_online() and
  * before starting iterating, and synchronizes against @pos on each
- * iteration, any descendant cgroup which finished ->css_offline() is
+ * iteration, any descendant cgroup which finished ->css_online() is
  * guaranteed to be visible in the future iterations.
  *
  * In other words, the following guarantees that a descendant can't escape
index 6a1f8df..b83e565 100644 (file)
@@ -361,6 +361,17 @@ static inline void list_splice_tail_init(struct list_head *list,
 #define list_first_entry(ptr, type, member) \
        list_entry((ptr)->next, type, member)
 
+/**
+ * list_first_entry_or_null - get the first element from a list
+ * @ptr:       the list head to take the element from.
+ * @type:      the type of the struct this is embedded in.
+ * @member:    the name of the list_struct within the struct.
+ *
+ * Note that if the list is empty, it returns NULL.
+ */
+#define list_first_entry_or_null(ptr, type, member) \
+       (!list_empty(ptr) ? list_first_entry(ptr, type, member) : NULL)
+
 /**
  * list_for_each       -       iterate over a list
  * @pos:       the &struct list_head to use as a loop cursor.
index 98ffb54..2d4df6c 100644 (file)
@@ -17,6 +17,22 @@ extern __sum16 nf_ip6_checksum(struct sk_buff *skb, unsigned int hook,
 
 extern int ipv6_netfilter_init(void);
 extern void ipv6_netfilter_fini(void);
+
+/*
+ * Hook functions for ipv6 to allow xt_* modules to be built-in even
+ * if IPv6 is a module.
+ */
+struct nf_ipv6_ops {
+       int (*chk_addr)(struct net *net, const struct in6_addr *addr,
+                       const struct net_device *dev, int strict);
+};
+
+extern const struct nf_ipv6_ops __rcu *nf_ipv6_ops;
+static inline const struct nf_ipv6_ops *nf_get_ipv6_ops(void)
+{
+       return rcu_dereference(nf_ipv6_ops);
+}
+
 #else /* CONFIG_NETFILTER */
 static inline int ipv6_netfilter_init(void) { return 0; }
 static inline void ipv6_netfilter_fini(void) { return; }
index 8089e35..f4b1001 100644 (file)
@@ -460,6 +460,26 @@ static inline void hlist_add_after_rcu(struct hlist_node *prev,
                pos = hlist_entry_safe(rcu_dereference_raw(hlist_next_rcu(\
                        &(pos)->member)), typeof(*(pos)), member))
 
+/**
+ * hlist_for_each_entry_rcu_notrace - iterate over rcu list of given type (for tracing)
+ * @pos:       the type * to use as a loop cursor.
+ * @head:      the head for your list.
+ * @member:    the name of the hlist_node within the struct.
+ *
+ * This list-traversal primitive may safely run concurrently with
+ * the _rcu list-mutation primitives such as hlist_add_head_rcu()
+ * as long as the traversal is guarded by rcu_read_lock().
+ *
+ * This is the same as hlist_for_each_entry_rcu() except that it does
+ * not do any RCU debugging or tracing.
+ */
+#define hlist_for_each_entry_rcu_notrace(pos, head, member)                    \
+       for (pos = hlist_entry_safe (rcu_dereference_raw_notrace(hlist_first_rcu(head)),\
+                       typeof(*(pos)), member);                        \
+               pos;                                                    \
+               pos = hlist_entry_safe(rcu_dereference_raw_notrace(hlist_next_rcu(\
+                       &(pos)->member)), typeof(*(pos)), member))
+
 /**
  * hlist_for_each_entry_rcu_bh - iterate over rcu list of given type
  * @pos:       the type * to use as a loop cursor.
index 2ae1371..1c33dd7 100644 (file)
@@ -105,9 +105,14 @@ static inline void hlist_nulls_add_head_rcu(struct hlist_nulls_node *n,
  * @head:      the head for your list.
  * @member:    the name of the hlist_nulls_node within the struct.
  *
+ * The barrier() is needed to make sure compiler doesn't cache first element [1],
+ * as this loop can be restarted [2]
+ * [1] Documentation/atomic_ops.txt around line 114
+ * [2] Documentation/RCU/rculist_nulls.txt around line 146
  */
 #define hlist_nulls_for_each_entry_rcu(tpos, pos, head, member)                        \
-       for (pos = rcu_dereference_raw(hlist_nulls_first_rcu(head));            \
+       for (({barrier();}),                                                    \
+            pos = rcu_dereference_raw(hlist_nulls_first_rcu(head));            \
                (!is_a_nulls(pos)) &&                                           \
                ({ tpos = hlist_nulls_entry(pos, typeof(*tpos), member); 1; }); \
                pos = rcu_dereference_raw(hlist_nulls_next_rcu(pos)))
index 4ccd68e..ddcc782 100644 (file)
@@ -640,6 +640,15 @@ static inline void rcu_preempt_sleep_check(void)
 
 #define rcu_dereference_raw(p) rcu_dereference_check(p, 1) /*@@@ needed? @@@*/
 
+/*
+ * The tracing infrastructure traces RCU (we want that), but unfortunately
+ * some of the RCU checks causes tracing to lock up the system.
+ *
+ * The tracing version of rcu_dereference_raw() must not call
+ * rcu_read_lock_held().
+ */
+#define rcu_dereference_raw_notrace(p) __rcu_dereference_check((p), 1, __rcu)
+
 /**
  * rcu_access_index() - fetch RCU index with no dereferencing
  * @p: The index to read
index 2e0ced1..9c676ea 100644 (file)
@@ -2852,6 +2852,21 @@ static inline int skb_tnl_header_len(const struct sk_buff *inner_skb)
                SKB_GSO_CB(inner_skb)->mac_offset;
 }
 
+static inline int gso_pskb_expand_head(struct sk_buff *skb, int extra)
+{
+       int new_headroom, headroom;
+       int ret;
+
+       headroom = skb_headroom(skb);
+       ret = pskb_expand_head(skb, extra, 0, GFP_ATOMIC);
+       if (ret)
+               return ret;
+
+       new_headroom = skb_headroom(skb);
+       SKB_GSO_CB(skb)->mac_offset += (new_headroom - headroom);
+       return 0;
+}
+
 static inline bool skb_is_gso(const struct sk_buff *skb)
 {
        return skb_shinfo(skb)->gso_size;
index 33bf2df..b10ce4b 100644 (file)
@@ -320,6 +320,9 @@ extern int put_cmsg(struct msghdr*, int level, int type, int len, void *data);
 
 struct timespec;
 
+/* The __sys_...msg variants allow MSG_CMSG_COMPAT */
+extern long __sys_recvmsg(int fd, struct msghdr __user *msg, unsigned flags);
+extern long __sys_sendmsg(int fd, struct msghdr __user *msg, unsigned flags);
 extern int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen,
                          unsigned int flags, struct timespec *timeout);
 extern int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg,
index 84a6440..21f7027 100644 (file)
@@ -65,7 +65,7 @@ extern int                    addrconf_set_dstaddr(struct net *net,
 
 extern int                     ipv6_chk_addr(struct net *net,
                                              const struct in6_addr *addr,
-                                             struct net_device *dev,
+                                             const struct net_device *dev,
                                              int strict);
 
 #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
index f10818f..e7f4e21 100644 (file)
@@ -679,22 +679,26 @@ static inline struct sk_buff *skb_act_clone(struct sk_buff *skb, gfp_t gfp_mask,
 #endif
 
 struct psched_ratecfg {
-       u64 rate_bps;
-       u32 mult;
-       u32 shift;
+       u64     rate_bps;
+       u32     mult;
+       u16     overhead;
+       u8      shift;
 };
 
 static inline u64 psched_l2t_ns(const struct psched_ratecfg *r,
                                unsigned int len)
 {
-       return ((u64)len * r->mult) >> r->shift;
+       return ((u64)(len + r->overhead) * r->mult) >> r->shift;
 }
 
-extern void psched_ratecfg_precompute(struct psched_ratecfg *r, u32 rate);
+extern void psched_ratecfg_precompute(struct psched_ratecfg *r, const struct tc_ratespec *conf);
 
-static inline u32 psched_ratecfg_getrate(const struct psched_ratecfg *r)
+static inline void psched_ratecfg_getrate(struct tc_ratespec *res,
+                                         const struct psched_ratecfg *r)
 {
-       return r->rate_bps >> 3;
+       memset(res, 0, sizeof(*res));
+       res->rate = r->rate_bps >> 3;
+       res->overhead = r->overhead;
 }
 
 #endif
index ae16531..94ce082 100644 (file)
@@ -1160,6 +1160,8 @@ static inline void xfrm_sk_free_policy(struct sock *sk)
        }
 }
 
+extern void xfrm_garbage_collect(struct net *net);
+
 #else
 
 static inline void xfrm_sk_free_policy(struct sock *sk) {}
@@ -1194,6 +1196,9 @@ static inline int xfrm6_policy_check_reverse(struct sock *sk, int dir,
 {
        return 1;
 }
+static inline void xfrm_garbage_collect(struct net *net)
+{
+}
 #endif
 
 static __inline__
index 2a99262..a7c9e6d 100644 (file)
@@ -1686,11 +1686,14 @@ static struct dentry *cgroup_mount(struct file_system_type *fs_type,
                 */
                cgroup_drop_root(opts.new_root);
 
-               if (((root->flags | opts.flags) & CGRP_ROOT_SANE_BEHAVIOR) &&
-                   root->flags != opts.flags) {
-                       pr_err("cgroup: sane_behavior: new mount options should match the existing superblock\n");
-                       ret = -EINVAL;
-                       goto drop_new_super;
+               if (root->flags != opts.flags) {
+                       if ((root->flags | opts.flags) & CGRP_ROOT_SANE_BEHAVIOR) {
+                               pr_err("cgroup: sane_behavior: new mount options should match the existing superblock\n");
+                               ret = -EINVAL;
+                               goto drop_new_super;
+                       } else {
+                               pr_warning("cgroup: new mount options do not match the existing superblock, will be ignored\n");
+                       }
                }
 
                /* no subsys rebinding, so refcounts don't change */
@@ -2699,13 +2702,14 @@ static int cgroup_add_file(struct cgroup *cgrp, struct cgroup_subsys *subsys,
                goto out;
        }
 
+       cfe->type = (void *)cft;
+       cfe->dentry = dentry;
+       dentry->d_fsdata = cfe;
+       simple_xattrs_init(&cfe->xattrs);
+
        mode = cgroup_file_mode(cft);
        error = cgroup_create_file(dentry, mode | S_IFREG, cgrp->root->sb);
        if (!error) {
-               cfe->type = (void *)cft;
-               cfe->dentry = dentry;
-               dentry->d_fsdata = cfe;
-               simple_xattrs_init(&cfe->xattrs);
                list_add_tail(&cfe->node, &parent->files);
                cfe = NULL;
        }
@@ -2953,11 +2957,8 @@ struct cgroup *cgroup_next_descendant_pre(struct cgroup *pos,
        WARN_ON_ONCE(!rcu_read_lock_held());
 
        /* if first iteration, pretend we just visited @cgroup */
-       if (!pos) {
-               if (list_empty(&cgroup->children))
-                       return NULL;
+       if (!pos)
                pos = cgroup;
-       }
 
        /* visit the first child if exists */
        next = list_first_or_null_rcu(&pos->children, struct cgroup, sibling);
@@ -2965,14 +2966,14 @@ struct cgroup *cgroup_next_descendant_pre(struct cgroup *pos,
                return next;
 
        /* no child, visit my or the closest ancestor's next sibling */
-       do {
+       while (pos != cgroup) {
                next = list_entry_rcu(pos->sibling.next, struct cgroup,
                                      sibling);
                if (&next->sibling != &pos->parent->children)
                        return next;
 
                pos = pos->parent;
-       } while (pos != cgroup);
+       }
 
        return NULL;
 }
index 5a83dde..54a4d52 100644 (file)
@@ -143,7 +143,10 @@ static unsigned int irq_domain_legacy_revmap(struct irq_domain *domain,
  * irq_domain_add_simple() - Allocate and register a simple irq_domain.
  * @of_node: pointer to interrupt controller's device tree node.
  * @size: total number of irqs in mapping
- * @first_irq: first number of irq block assigned to the domain
+ * @first_irq: first number of irq block assigned to the domain,
+ *     pass zero to assign irqs on-the-fly. This will result in a
+ *     linear IRQ domain so it is important to use irq_create_mapping()
+ *     for each used IRQ, especially when SPARSE_IRQ is enabled.
  * @ops: map/unmap domain callbacks
  * @host_data: Controller private data pointer
  *
@@ -191,6 +194,7 @@ struct irq_domain *irq_domain_add_simple(struct device_node *of_node,
        /* A linear domain is the default */
        return irq_domain_add_linear(of_node, size, ops, host_data);
 }
+EXPORT_SYMBOL_GPL(irq_domain_add_simple);
 
 /**
  * irq_domain_add_legacy() - Allocate and register a legacy revmap irq_domain.
@@ -397,11 +401,12 @@ static void irq_domain_disassociate_many(struct irq_domain *domain,
        while (count--) {
                int irq = irq_base + count;
                struct irq_data *irq_data = irq_get_irq_data(irq);
-               irq_hw_number_t hwirq = irq_data->hwirq;
+               irq_hw_number_t hwirq;
 
                if (WARN_ON(!irq_data || irq_data->domain != domain))
                        continue;
 
+               hwirq = irq_data->hwirq;
                irq_set_status_flags(irq, IRQ_NOREQUEST);
 
                /* remove chip and handler */
index 12ff13a..8f5b3b9 100644 (file)
@@ -874,7 +874,6 @@ static void hardpps_update_phase(long error)
 void __hardpps(const struct timespec *phase_ts, const struct timespec *raw_ts)
 {
        struct pps_normtime pts_norm, freq_norm;
-       unsigned long flags;
 
        pts_norm = pps_normalize_ts(*phase_ts);
 
index 24938d5..0c73942 100644 (file)
@@ -511,6 +511,12 @@ again:
                }
        }
 
+       /*
+        * Remove the current cpu from the pending mask. The event is
+        * delivered immediately in tick_do_broadcast() !
+        */
+       cpumask_clear_cpu(smp_processor_id(), tick_broadcast_pending_mask);
+
        /* Take care of enforced broadcast requests */
        cpumask_or(tmpmask, tmpmask, tick_broadcast_force_mask);
        cpumask_clear(tick_broadcast_force_mask);
@@ -575,8 +581,8 @@ void tick_broadcast_oneshot_control(unsigned long reason)
 
        raw_spin_lock_irqsave(&tick_broadcast_lock, flags);
        if (reason == CLOCK_EVT_NOTIFY_BROADCAST_ENTER) {
-               WARN_ON_ONCE(cpumask_test_cpu(cpu, tick_broadcast_pending_mask));
                if (!cpumask_test_and_set_cpu(cpu, tick_broadcast_oneshot_mask)) {
+                       WARN_ON_ONCE(cpumask_test_cpu(cpu, tick_broadcast_pending_mask));
                        clockevents_set_mode(dev, CLOCK_EVT_MODE_SHUTDOWN);
                        /*
                         * We only reprogram the broadcast timer if we
index 98cd470..baeeb5c 100644 (file)
@@ -975,6 +975,14 @@ static int timekeeping_suspend(void)
 
        read_persistent_clock(&timekeeping_suspend_time);
 
+       /*
+        * On some systems the persistent_clock can not be detected at
+        * timekeeping_init by its return value, so if we see a valid
+        * value returned, update the persistent_clock_exists flag.
+        */
+       if (timekeeping_suspend_time.tv_sec || timekeeping_suspend_time.tv_nsec)
+               persistent_clock_exist = true;
+
        raw_spin_lock_irqsave(&timekeeper_lock, flags);
        write_seqcount_begin(&timekeeper_seq);
        timekeeping_forward_now(tk);
index b549b0f..6c508ff 100644 (file)
@@ -120,22 +120,22 @@ static void ftrace_ops_no_ops(unsigned long ip, unsigned long parent_ip);
 
 /*
  * Traverse the ftrace_global_list, invoking all entries.  The reason that we
- * can use rcu_dereference_raw() is that elements removed from this list
+ * can use rcu_dereference_raw_notrace() is that elements removed from this list
  * are simply leaked, so there is no need to interact with a grace-period
- * mechanism.  The rcu_dereference_raw() calls are needed to handle
+ * mechanism.  The rcu_dereference_raw_notrace() calls are needed to handle
  * concurrent insertions into the ftrace_global_list.
  *
  * Silly Alpha and silly pointer-speculation compiler optimizations!
  */
 #define do_for_each_ftrace_op(op, list)                        \
-       op = rcu_dereference_raw(list);                 \
+       op = rcu_dereference_raw_notrace(list);                 \
        do
 
 /*
  * Optimized for just a single item in the list (as that is the normal case).
  */
 #define while_for_each_ftrace_op(op)                           \
-       while (likely(op = rcu_dereference_raw((op)->next)) &&  \
+       while (likely(op = rcu_dereference_raw_notrace((op)->next)) &&  \
               unlikely((op) != &ftrace_list_end))
 
 static inline void ftrace_ops_init(struct ftrace_ops *ops)
@@ -779,7 +779,7 @@ ftrace_find_profiled_func(struct ftrace_profile_stat *stat, unsigned long ip)
        if (hlist_empty(hhd))
                return NULL;
 
-       hlist_for_each_entry_rcu(rec, hhd, node) {
+       hlist_for_each_entry_rcu_notrace(rec, hhd, node) {
                if (rec->ip == ip)
                        return rec;
        }
@@ -1165,7 +1165,7 @@ ftrace_lookup_ip(struct ftrace_hash *hash, unsigned long ip)
 
        hhd = &hash->buckets[key];
 
-       hlist_for_each_entry_rcu(entry, hhd, hlist) {
+       hlist_for_each_entry_rcu_notrace(entry, hhd, hlist) {
                if (entry->ip == ip)
                        return entry;
        }
@@ -1422,8 +1422,8 @@ ftrace_ops_test(struct ftrace_ops *ops, unsigned long ip)
        struct ftrace_hash *notrace_hash;
        int ret;
 
-       filter_hash = rcu_dereference_raw(ops->filter_hash);
-       notrace_hash = rcu_dereference_raw(ops->notrace_hash);
+       filter_hash = rcu_dereference_raw_notrace(ops->filter_hash);
+       notrace_hash = rcu_dereference_raw_notrace(ops->notrace_hash);
 
        if ((ftrace_hash_empty(filter_hash) ||
             ftrace_lookup_ip(filter_hash, ip)) &&
@@ -2920,7 +2920,7 @@ static void function_trace_probe_call(unsigned long ip, unsigned long parent_ip,
         * on the hash. rcu_read_lock is too dangerous here.
         */
        preempt_disable_notrace();
-       hlist_for_each_entry_rcu(entry, hhd, node) {
+       hlist_for_each_entry_rcu_notrace(entry, hhd, node) {
                if (entry->ip == ip)
                        entry->ops->func(ip, parent_ip, &entry->data);
        }
index 4d79485..1a41023 100644 (file)
@@ -843,7 +843,15 @@ __update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu)
 
        memcpy(max_data->comm, tsk->comm, TASK_COMM_LEN);
        max_data->pid = tsk->pid;
-       max_data->uid = task_uid(tsk);
+       /*
+        * If tsk == current, then use current_uid(), as that does not use
+        * RCU. The irq tracer can be called out of RCU scope.
+        */
+       if (tsk == current)
+               max_data->uid = current_uid();
+       else
+               max_data->uid = task_uid(tsk);
+
        max_data->nice = tsk->static_prio - 20 - MAX_RT_PRIO;
        max_data->policy = tsk->policy;
        max_data->rt_priority = tsk->rt_priority;
index 55e2cf6..2901e3b 100644 (file)
@@ -1159,7 +1159,7 @@ trace_selftest_startup_branch(struct tracer *trace, struct trace_array *tr)
        /* stop the tracing. */
        tracing_stop();
        /* check the trace buffer */
-       ret = trace_test_buffer(tr, &count);
+       ret = trace_test_buffer(&tr->trace_buffer, &count);
        trace->reset(tr);
        tracing_start();
 
index 6dc1882..61a262b 100644 (file)
@@ -220,7 +220,6 @@ void tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, bool fullmm)
        tlb->start      = -1UL;
        tlb->end        = 0;
        tlb->need_flush = 0;
-       tlb->fast_mode  = (num_possible_cpus() == 1);
        tlb->local.next = NULL;
        tlb->local.nr   = 0;
        tlb->local.max  = ARRAY_SIZE(tlb->__pages);
@@ -244,9 +243,6 @@ void tlb_flush_mmu(struct mmu_gather *tlb)
        tlb_table_flush(tlb);
 #endif
 
-       if (tlb_fast_mode(tlb))
-               return;
-
        for (batch = &tlb->local; batch; batch = batch->next) {
                free_pages_and_swap_cache(batch->pages, batch->nr);
                batch->nr = 0;
@@ -288,11 +284,6 @@ int __tlb_remove_page(struct mmu_gather *tlb, struct page *page)
 
        VM_BUG_ON(!tlb->need_flush);
 
-       if (tlb_fast_mode(tlb)) {
-               free_page_and_swap_cache(page);
-               return 1; /* avoid calling tlb_flush_mmu() */
-       }
-
        batch = tlb->active;
        batch->pages[batch->nr++] = page;
        if (batch->nr == batch->max) {
index 79ae884..f0a1ba6 100644 (file)
@@ -734,19 +734,25 @@ static unsigned char nas[21] = {
 
 asmlinkage long compat_sys_sendmsg(int fd, struct compat_msghdr __user *msg, unsigned int flags)
 {
-       return sys_sendmsg(fd, (struct msghdr __user *)msg, flags | MSG_CMSG_COMPAT);
+       if (flags & MSG_CMSG_COMPAT)
+               return -EINVAL;
+       return __sys_sendmsg(fd, (struct msghdr __user *)msg, flags | MSG_CMSG_COMPAT);
 }
 
 asmlinkage long compat_sys_sendmmsg(int fd, struct compat_mmsghdr __user *mmsg,
                                    unsigned int vlen, unsigned int flags)
 {
+       if (flags & MSG_CMSG_COMPAT)
+               return -EINVAL;
        return __sys_sendmmsg(fd, (struct mmsghdr __user *)mmsg, vlen,
                              flags | MSG_CMSG_COMPAT);
 }
 
 asmlinkage long compat_sys_recvmsg(int fd, struct compat_msghdr __user *msg, unsigned int flags)
 {
-       return sys_recvmsg(fd, (struct msghdr __user *)msg, flags | MSG_CMSG_COMPAT);
+       if (flags & MSG_CMSG_COMPAT)
+               return -EINVAL;
+       return __sys_recvmsg(fd, (struct msghdr __user *)msg, flags | MSG_CMSG_COMPAT);
 }
 
 asmlinkage long compat_sys_recv(int fd, void __user *buf, size_t len, unsigned int flags)
@@ -768,6 +774,9 @@ asmlinkage long compat_sys_recvmmsg(int fd, struct compat_mmsghdr __user *mmsg,
        int datagrams;
        struct timespec ktspec;
 
+       if (flags & MSG_CMSG_COMPAT)
+               return -EINVAL;
+
        if (COMPAT_USE_64BIT_TIME)
                return __sys_recvmmsg(fd, (struct mmsghdr __user *)mmsg, vlen,
                                      flags | MSG_CMSG_COMPAT,
index c013f38..6cda4e2 100644 (file)
@@ -39,6 +39,7 @@ static int __hw_addr_create_ex(struct netdev_hw_addr_list *list,
        ha->refcount = 1;
        ha->global_use = global;
        ha->synced = sync;
+       ha->sync_cnt = 0;
        list_add_tail_rcu(&ha->list, &list->list);
        list->count++;
 
@@ -66,7 +67,7 @@ static int __hw_addr_add_ex(struct netdev_hw_addr_list *list,
                        }
                        if (sync) {
                                if (ha->synced)
-                                       return 0;
+                                       return -EEXIST;
                                else
                                        ha->synced = true;
                        }
@@ -139,10 +140,13 @@ static int __hw_addr_sync_one(struct netdev_hw_addr_list *to_list,
 
        err = __hw_addr_add_ex(to_list, ha->addr, addr_len, ha->type,
                               false, true);
-       if (err)
+       if (err && err != -EEXIST)
                return err;
-       ha->sync_cnt++;
-       ha->refcount++;
+
+       if (!err) {
+               ha->sync_cnt++;
+               ha->refcount++;
+       }
 
        return 0;
 }
@@ -159,7 +163,8 @@ static void __hw_addr_unsync_one(struct netdev_hw_addr_list *to_list,
        if (err)
                return;
        ha->sync_cnt--;
-       __hw_addr_del_entry(from_list, ha, false, true);
+       /* address on from list is not marked synced */
+       __hw_addr_del_entry(from_list, ha, false, false);
 }
 
 static int __hw_addr_sync_multiple(struct netdev_hw_addr_list *to_list,
@@ -796,7 +801,7 @@ int dev_mc_sync_multiple(struct net_device *to, struct net_device *from)
                return -EINVAL;
 
        netif_addr_lock_nested(to);
-       err = __hw_addr_sync(&to->mc, &from->mc, to->addr_len);
+       err = __hw_addr_sync_multiple(&to->mc, &from->mc, to->addr_len);
        if (!err)
                __dev_set_rx_mode(to);
        netif_addr_unlock(to);
index af9185d..cfd777b 100644 (file)
@@ -195,7 +195,7 @@ struct sk_buff *__alloc_skb_head(gfp_t gfp_mask, int node)
         * the tail pointer in struct sk_buff!
         */
        memset(skb, 0, offsetof(struct sk_buff, tail));
-       skb->data = NULL;
+       skb->head = NULL;
        skb->truesize = sizeof(struct sk_buff);
        atomic_set(&skb->users, 1);
 
@@ -611,7 +611,7 @@ static void skb_release_head_state(struct sk_buff *skb)
 static void skb_release_all(struct sk_buff *skb)
 {
        skb_release_head_state(skb);
-       if (likely(skb->data))
+       if (likely(skb->head))
                skb_release_data(skb);
 }
 
index 6ba327d..88868a9 100644 (file)
@@ -210,7 +210,7 @@ static const char *const af_family_key_strings[AF_MAX+1] = {
   "sk_lock-AF_TIPC"  , "sk_lock-AF_BLUETOOTH", "sk_lock-IUCV"        ,
   "sk_lock-AF_RXRPC" , "sk_lock-AF_ISDN"     , "sk_lock-AF_PHONET"   ,
   "sk_lock-AF_IEEE802154", "sk_lock-AF_CAIF" , "sk_lock-AF_ALG"      ,
-  "sk_lock-AF_NFC"   , "sk_lock-AF_MAX"
+  "sk_lock-AF_NFC"   , "sk_lock-AF_VSOCK"    , "sk_lock-AF_MAX"
 };
 static const char *const af_family_slock_key_strings[AF_MAX+1] = {
   "slock-AF_UNSPEC", "slock-AF_UNIX"     , "slock-AF_INET"     ,
@@ -226,7 +226,7 @@ static const char *const af_family_slock_key_strings[AF_MAX+1] = {
   "slock-AF_TIPC"  , "slock-AF_BLUETOOTH", "slock-AF_IUCV"     ,
   "slock-AF_RXRPC" , "slock-AF_ISDN"     , "slock-AF_PHONET"   ,
   "slock-AF_IEEE802154", "slock-AF_CAIF" , "slock-AF_ALG"      ,
-  "slock-AF_NFC"   , "slock-AF_MAX"
+  "slock-AF_NFC"   , "slock-AF_VSOCK"    ,"slock-AF_MAX"
 };
 static const char *const af_family_clock_key_strings[AF_MAX+1] = {
   "clock-AF_UNSPEC", "clock-AF_UNIX"     , "clock-AF_INET"     ,
@@ -242,7 +242,7 @@ static const char *const af_family_clock_key_strings[AF_MAX+1] = {
   "clock-AF_TIPC"  , "clock-AF_BLUETOOTH", "clock-AF_IUCV"     ,
   "clock-AF_RXRPC" , "clock-AF_ISDN"     , "clock-AF_PHONET"   ,
   "clock-AF_IEEE802154", "clock-AF_CAIF" , "clock-AF_ALG"      ,
-  "clock-AF_NFC"   , "clock-AF_MAX"
+  "clock-AF_NFC"   , "clock-AF_VSOCK"    , "clock-AF_MAX"
 };
 
 /*
index e4147ec..be2f8da 100644 (file)
@@ -503,6 +503,7 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev,
 
        inner_iph = (const struct iphdr *)skb_inner_network_header(skb);
 
+       memset(IPCB(skb), 0, sizeof(*IPCB(skb)));
        dst = tnl_params->daddr;
        if (dst == 0) {
                /* NBMA tunnel */
@@ -658,7 +659,6 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev,
 
        skb_dst_drop(skb);
        skb_dst_set(skb, &rt->dst);
-       memset(IPCB(skb), 0, sizeof(*IPCB(skb)));
 
        /* Push down and install the IP header. */
        skb_push(skb, sizeof(struct iphdr));
index cf08218..ff4b781 100644 (file)
@@ -231,8 +231,10 @@ static void ipt_ulog_packet(struct net *net,
        put_unaligned(tv.tv_usec, &pm->timestamp_usec);
        put_unaligned(skb->mark, &pm->mark);
        pm->hook = hooknum;
-       if (prefix != NULL)
-               strncpy(pm->prefix, prefix, sizeof(pm->prefix));
+       if (prefix != NULL) {
+               strncpy(pm->prefix, prefix, sizeof(pm->prefix) - 1);
+               pm->prefix[sizeof(pm->prefix) - 1] = '\0';
+       }
        else if (loginfo->prefix[0] != '\0')
                strncpy(pm->prefix, loginfo->prefix, sizeof(pm->prefix));
        else
index 550781a..d35bbf0 100644 (file)
@@ -737,10 +737,15 @@ static void ip_do_redirect(struct dst_entry *dst, struct sock *sk, struct sk_buf
 {
        struct rtable *rt;
        struct flowi4 fl4;
+       const struct iphdr *iph = (const struct iphdr *) skb->data;
+       int oif = skb->dev->ifindex;
+       u8 tos = RT_TOS(iph->tos);
+       u8 prot = iph->protocol;
+       u32 mark = skb->mark;
 
        rt = (struct rtable *) dst;
 
-       ip_rt_build_flow_key(&fl4, sk, skb);
+       __build_flow_key(&fl4, sk, iph, oif, tos, prot, mark, 0);
        __ip_do_redirect(rt, skb, &fl4, true);
 }
 
index d1ab6ab..1bbf744 100644 (file)
@@ -1487,7 +1487,7 @@ static int ipv6_count_addresses(struct inet6_dev *idev)
 }
 
 int ipv6_chk_addr(struct net *net, const struct in6_addr *addr,
-                 struct net_device *dev, int strict)
+                 const struct net_device *dev, int strict)
 {
        struct inet6_ifaddr *ifp;
        unsigned int hash = inet6_addr_hash(addr);
@@ -2658,8 +2658,10 @@ static void init_loopback(struct net_device *dev)
                        sp_rt = addrconf_dst_alloc(idev, &sp_ifa->addr, 0);
 
                        /* Failure cases are ignored */
-                       if (!IS_ERR(sp_rt))
+                       if (!IS_ERR(sp_rt)) {
+                               sp_ifa->rt = sp_rt;
                                ip6_ins_rt(sp_rt);
+                       }
                }
                read_unlock_bh(&idev->lock);
        }
index 72836f4..95f3f1d 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/netfilter.h>
 #include <linux/netfilter_ipv6.h>
 #include <linux/export.h>
+#include <net/addrconf.h>
 #include <net/dst.h>
 #include <net/ipv6.h>
 #include <net/ip6_route.h>
@@ -186,6 +187,10 @@ static __sum16 nf_ip6_checksum_partial(struct sk_buff *skb, unsigned int hook,
        return csum;
 };
 
+static const struct nf_ipv6_ops ipv6ops = {
+       .chk_addr       = ipv6_chk_addr,
+};
+
 static const struct nf_afinfo nf_ip6_afinfo = {
        .family                 = AF_INET6,
        .checksum               = nf_ip6_checksum,
@@ -198,6 +203,7 @@ static const struct nf_afinfo nf_ip6_afinfo = {
 
 int __init ipv6_netfilter_init(void)
 {
+       RCU_INIT_POINTER(nf_ipv6_ops, &ipv6ops);
        return nf_register_afinfo(&nf_ip6_afinfo);
 }
 
@@ -206,5 +212,6 @@ int __init ipv6_netfilter_init(void)
  */
 void ipv6_netfilter_fini(void)
 {
+       RCU_INIT_POINTER(nf_ipv6_ops, NULL);
        nf_unregister_afinfo(&nf_ip6_afinfo);
 }
index f3c1ff4..51c3285 100644 (file)
@@ -90,7 +90,7 @@ static const struct snmp_mib snmp6_ipstats_list[] = {
        SNMP_MIB_ITEM("Ip6OutMcastOctets", IPSTATS_MIB_OUTMCASTOCTETS),
        SNMP_MIB_ITEM("Ip6InBcastOctets", IPSTATS_MIB_INBCASTOCTETS),
        SNMP_MIB_ITEM("Ip6OutBcastOctets", IPSTATS_MIB_OUTBCASTOCTETS),
-       SNMP_MIB_ITEM("InCsumErrors", IPSTATS_MIB_CSUMERRORS),
+       /* IPSTATS_MIB_CSUMERRORS is not relevant in IPv6 (no checksum) */
        SNMP_MIB_SENTINEL
 };
 
index 3bb3a89..d3cfaf9 100644 (file)
@@ -46,11 +46,12 @@ static struct sk_buff *udp6_ufo_fragment(struct sk_buff *skb,
        unsigned int mss;
        unsigned int unfrag_ip6hlen, unfrag_len;
        struct frag_hdr *fptr;
-       u8 *mac_start, *prevhdr;
+       u8 *packet_start, *prevhdr;
        u8 nexthdr;
        u8 frag_hdr_sz = sizeof(struct frag_hdr);
        int offset;
        __wsum csum;
+       int tnl_hlen;
 
        mss = skb_shinfo(skb)->gso_size;
        if (unlikely(skb->len <= mss))
@@ -83,9 +84,11 @@ static struct sk_buff *udp6_ufo_fragment(struct sk_buff *skb,
        skb->ip_summed = CHECKSUM_NONE;
 
        /* Check if there is enough headroom to insert fragment header. */
-       if ((skb_mac_header(skb) < skb->head + frag_hdr_sz) &&
-           pskb_expand_head(skb, frag_hdr_sz, 0, GFP_ATOMIC))
-               goto out;
+       tnl_hlen = skb_tnl_header_len(skb);
+       if (skb_headroom(skb) < (tnl_hlen + frag_hdr_sz)) {
+               if (gso_pskb_expand_head(skb, tnl_hlen + frag_hdr_sz))
+                       goto out;
+       }
 
        /* Find the unfragmentable header and shift it left by frag_hdr_sz
         * bytes to insert fragment header.
@@ -93,11 +96,12 @@ static struct sk_buff *udp6_ufo_fragment(struct sk_buff *skb,
        unfrag_ip6hlen = ip6_find_1stfragopt(skb, &prevhdr);
        nexthdr = *prevhdr;
        *prevhdr = NEXTHDR_FRAGMENT;
-       unfrag_len = skb_network_header(skb) - skb_mac_header(skb) +
-                    unfrag_ip6hlen;
-       mac_start = skb_mac_header(skb);
-       memmove(mac_start-frag_hdr_sz, mac_start, unfrag_len);
+       unfrag_len = (skb_network_header(skb) - skb_mac_header(skb)) +
+                    unfrag_ip6hlen + tnl_hlen;
+       packet_start = (u8 *) skb->head + SKB_GSO_CB(skb)->mac_offset;
+       memmove(packet_start-frag_hdr_sz, packet_start, unfrag_len);
 
+       SKB_GSO_CB(skb)->mac_offset -= frag_hdr_sz;
        skb->mac_header -= frag_hdr_sz;
        skb->network_header -= frag_hdr_sz;
 
index 5b1e5af..c5fbd75 100644 (file)
@@ -2366,6 +2366,8 @@ static int pfkey_spddelete(struct sock *sk, struct sk_buff *skb, const struct sa
 
 out:
        xfrm_pol_put(xp);
+       if (err == 0)
+               xfrm_garbage_collect(net);
        return err;
 }
 
@@ -2615,6 +2617,8 @@ static int pfkey_spdget(struct sock *sk, struct sk_buff *skb, const struct sadb_
 
 out:
        xfrm_pol_put(xp);
+       if (delete && err == 0)
+               xfrm_garbage_collect(net);
        return err;
 }
 
index 60f1ce5..98d20c0 100644 (file)
@@ -159,9 +159,10 @@ static int ieee80211_change_mtu(struct net_device *dev, int new_mtu)
        return 0;
 }
 
-static int ieee80211_verify_mac(struct ieee80211_local *local, u8 *addr)
+static int ieee80211_verify_mac(struct ieee80211_sub_if_data *sdata, u8 *addr)
 {
-       struct ieee80211_sub_if_data *sdata;
+       struct ieee80211_local *local = sdata->local;
+       struct ieee80211_sub_if_data *iter;
        u64 new, mask, tmp;
        u8 *m;
        int ret = 0;
@@ -181,11 +182,14 @@ static int ieee80211_verify_mac(struct ieee80211_local *local, u8 *addr)
 
 
        mutex_lock(&local->iflist_mtx);
-       list_for_each_entry(sdata, &local->interfaces, list) {
-               if (sdata->vif.type == NL80211_IFTYPE_MONITOR)
+       list_for_each_entry(iter, &local->interfaces, list) {
+               if (iter == sdata)
+                       continue;
+
+               if (iter->vif.type == NL80211_IFTYPE_MONITOR)
                        continue;
 
-               m = sdata->vif.addr;
+               m = iter->vif.addr;
                tmp =   ((u64)m[0] << 5*8) | ((u64)m[1] << 4*8) |
                        ((u64)m[2] << 3*8) | ((u64)m[3] << 2*8) |
                        ((u64)m[4] << 1*8) | ((u64)m[5] << 0*8);
@@ -209,7 +213,7 @@ static int ieee80211_change_mac(struct net_device *dev, void *addr)
        if (ieee80211_sdata_running(sdata))
                return -EBUSY;
 
-       ret = ieee80211_verify_mac(sdata->local, sa->sa_data);
+       ret = ieee80211_verify_mac(sdata, sa->sa_data);
        if (ret)
                return ret;
 
@@ -474,6 +478,9 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up)
                        master->control_port_protocol;
                sdata->control_port_no_encrypt =
                        master->control_port_no_encrypt;
+               sdata->vif.cab_queue = master->vif.cab_queue;
+               memcpy(sdata->vif.hw_queue, master->vif.hw_queue,
+                      sizeof(sdata->vif.hw_queue));
                break;
                }
        case NL80211_IFTYPE_AP:
@@ -653,7 +660,11 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up)
 
        ieee80211_recalc_ps(local, -1);
 
-       if (dev) {
+       if (sdata->vif.type == NL80211_IFTYPE_MONITOR ||
+           sdata->vif.type == NL80211_IFTYPE_AP_VLAN) {
+               /* XXX: for AP_VLAN, actually track AP queues */
+               netif_tx_start_all_queues(dev);
+       } else if (dev) {
                unsigned long flags;
                int n_acs = IEEE80211_NUM_ACS;
                int ac;
@@ -1479,7 +1490,17 @@ static void ieee80211_assign_perm_addr(struct ieee80211_local *local,
                        break;
                }
 
+               /*
+                * Pick address of existing interface in case user changed
+                * MAC address manually, default to perm_addr.
+                */
                m = local->hw.wiphy->perm_addr;
+               list_for_each_entry(sdata, &local->interfaces, list) {
+                       if (sdata->vif.type == NL80211_IFTYPE_MONITOR)
+                               continue;
+                       m = sdata->vif.addr;
+                       break;
+               }
                start = ((u64)m[0] << 5*8) | ((u64)m[1] << 4*8) |
                        ((u64)m[2] << 3*8) | ((u64)m[3] << 2*8) |
                        ((u64)m[4] << 1*8) | ((u64)m[5] << 0*8);
@@ -1696,6 +1717,15 @@ void ieee80211_remove_interfaces(struct ieee80211_local *local)
 
        ASSERT_RTNL();
 
+       /*
+        * Close all AP_VLAN interfaces first, as otherwise they
+        * might be closed while the AP interface they belong to
+        * is closed, causing unregister_netdevice_many() to crash.
+        */
+       list_for_each_entry(sdata, &local->interfaces, list)
+               if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
+                       dev_close(sdata->dev);
+
        mutex_lock(&local->iflist_mtx);
        list_for_each_entry_safe(sdata, tmp, &local->interfaces, list) {
                list_del(&sdata->list);
index a46e490..a8c2130 100644 (file)
@@ -3321,10 +3321,6 @@ static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata)
        if (WARN_ON_ONCE(!auth_data))
                return -EINVAL;
 
-       if (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)
-               tx_flags = IEEE80211_TX_CTL_REQ_TX_STATUS |
-                          IEEE80211_TX_INTFL_MLME_CONN_TX;
-
        auth_data->tries++;
 
        if (auth_data->tries > IEEE80211_AUTH_MAX_TRIES) {
@@ -3358,6 +3354,10 @@ static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata)
                        auth_data->expected_transaction = trans;
                }
 
+               if (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)
+                       tx_flags = IEEE80211_TX_CTL_REQ_TX_STATUS |
+                                  IEEE80211_TX_INTFL_MLME_CONN_TX;
+
                ieee80211_send_auth(sdata, trans, auth_data->algorithm, status,
                                    auth_data->data, auth_data->data_len,
                                    auth_data->bss->bssid,
@@ -3381,12 +3381,12 @@ static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata)
                 * will not answer to direct packet in unassociated state.
                 */
                ieee80211_send_probe_req(sdata, NULL, ssidie + 2, ssidie[1],
-                                        NULL, 0, (u32) -1, true, tx_flags,
+                                        NULL, 0, (u32) -1, true, 0,
                                         auth_data->bss->channel, false);
                rcu_read_unlock();
        }
 
-       if (!(local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)) {
+       if (tx_flags == 0) {
                auth_data->timeout = jiffies + IEEE80211_AUTH_TIMEOUT;
                ifmgd->auth_data->timeout_started = true;
                run_again(ifmgd, auth_data->timeout);
index 07c865a..857ca9f 100644 (file)
@@ -30,6 +30,8 @@ static DEFINE_MUTEX(afinfo_mutex);
 
 const struct nf_afinfo __rcu *nf_afinfo[NFPROTO_NUMPROTO] __read_mostly;
 EXPORT_SYMBOL(nf_afinfo);
+const struct nf_ipv6_ops __rcu *nf_ipv6_ops __read_mostly;
+EXPORT_SYMBOL_GPL(nf_ipv6_ops);
 
 int nf_register_afinfo(const struct nf_afinfo *afinfo)
 {
index 085b588..05565d2 100644 (file)
@@ -1001,6 +1001,32 @@ static inline int is_tcp_reset(const struct sk_buff *skb, int nh_len)
        return th->rst;
 }
 
+static inline bool is_new_conn(const struct sk_buff *skb,
+                              struct ip_vs_iphdr *iph)
+{
+       switch (iph->protocol) {
+       case IPPROTO_TCP: {
+               struct tcphdr _tcph, *th;
+
+               th = skb_header_pointer(skb, iph->len, sizeof(_tcph), &_tcph);
+               if (th == NULL)
+                       return false;
+               return th->syn;
+       }
+       case IPPROTO_SCTP: {
+               sctp_chunkhdr_t *sch, schunk;
+
+               sch = skb_header_pointer(skb, iph->len + sizeof(sctp_sctphdr_t),
+                                        sizeof(schunk), &schunk);
+               if (sch == NULL)
+                       return false;
+               return sch->type == SCTP_CID_INIT;
+       }
+       default:
+               return false;
+       }
+}
+
 /* Handle response packets: rewrite addresses and send away...
  */
 static unsigned int
@@ -1612,6 +1638,15 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb, int af)
         * Check if the packet belongs to an existing connection entry
         */
        cp = pp->conn_in_get(af, skb, &iph, 0);
+
+       if (unlikely(sysctl_expire_nodest_conn(ipvs)) && cp && cp->dest &&
+           unlikely(!atomic_read(&cp->dest->weight)) && !iph.fragoffs &&
+           is_new_conn(skb, &iph)) {
+               ip_vs_conn_expire_now(cp);
+               __ip_vs_conn_put(cp);
+               cp = NULL;
+       }
+
        if (unlikely(!cp) && !iph.fragoffs) {
                /* No (second) fragments need to enter here, as nf_defrag_ipv6
                 * replayed fragment zero will already have created the cp
index 0df269d..a65edfe 100644 (file)
@@ -67,8 +67,8 @@ struct ip_vs_sh_bucket {
 #define IP_VS_SH_TAB_MASK               (IP_VS_SH_TAB_SIZE - 1)
 
 struct ip_vs_sh_state {
-       struct ip_vs_sh_bucket          buckets[IP_VS_SH_TAB_SIZE];
        struct rcu_head                 rcu_head;
+       struct ip_vs_sh_bucket          buckets[IP_VS_SH_TAB_SIZE];
 };
 
 /*
index 491c7d8..5ab2484 100644 (file)
@@ -737,7 +737,7 @@ static void dump_ipv6_packet(struct sbuff *m,
                dump_sk_uid_gid(m, skb->sk);
 
        /* Max length: 16 "MARK=0xFFFFFFFF " */
-       if (!recurse && skb->mark)
+       if (recurse && skb->mark)
                sb_add(m, "MARK=0x%x ", skb->mark);
 }
 
index 49c5ff7..68ff29f 100644 (file)
@@ -22,6 +22,7 @@
 #include <net/ip6_fib.h>
 #endif
 
+#include <linux/netfilter_ipv6.h>
 #include <linux/netfilter/xt_addrtype.h>
 #include <linux/netfilter/x_tables.h>
 
@@ -33,12 +34,12 @@ MODULE_ALIAS("ip6t_addrtype");
 
 #if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
 static u32 match_lookup_rt6(struct net *net, const struct net_device *dev,
-                           const struct in6_addr *addr)
+                           const struct in6_addr *addr, u16 mask)
 {
        const struct nf_afinfo *afinfo;
        struct flowi6 flow;
        struct rt6_info *rt;
-       u32 ret;
+       u32 ret = 0;
        int route_err;
 
        memset(&flow, 0, sizeof(flow));
@@ -49,12 +50,19 @@ static u32 match_lookup_rt6(struct net *net, const struct net_device *dev,
        rcu_read_lock();
 
        afinfo = nf_get_afinfo(NFPROTO_IPV6);
-       if (afinfo != NULL)
+       if (afinfo != NULL) {
+               const struct nf_ipv6_ops *v6ops;
+
+               if (dev && (mask & XT_ADDRTYPE_LOCAL)) {
+                       v6ops = nf_get_ipv6_ops();
+                       if (v6ops && v6ops->chk_addr(net, addr, dev, true))
+                               ret = XT_ADDRTYPE_LOCAL;
+               }
                route_err = afinfo->route(net, (struct dst_entry **)&rt,
-                                       flowi6_to_flowi(&flow), !!dev);
-       else
+                                         flowi6_to_flowi(&flow), false);
+       } else {
                route_err = 1;
-
+       }
        rcu_read_unlock();
 
        if (route_err)
@@ -62,15 +70,12 @@ static u32 match_lookup_rt6(struct net *net, const struct net_device *dev,
 
        if (rt->rt6i_flags & RTF_REJECT)
                ret = XT_ADDRTYPE_UNREACHABLE;
-       else
-               ret = 0;
 
-       if (rt->rt6i_flags & RTF_LOCAL)
+       if (dev == NULL && rt->rt6i_flags & RTF_LOCAL)
                ret |= XT_ADDRTYPE_LOCAL;
        if (rt->rt6i_flags & RTF_ANYCAST)
                ret |= XT_ADDRTYPE_ANYCAST;
 
-
        dst_release(&rt->dst);
        return ret;
 }
@@ -90,7 +95,7 @@ static bool match_type6(struct net *net, const struct net_device *dev,
 
        if ((XT_ADDRTYPE_LOCAL | XT_ADDRTYPE_ANYCAST |
             XT_ADDRTYPE_UNREACHABLE) & mask)
-               return !!(mask & match_lookup_rt6(net, dev, addr));
+               return !!(mask & match_lookup_rt6(net, dev, addr, mask));
        return true;
 }
 
index 12ac6b4..d0b3dd6 100644 (file)
@@ -747,7 +747,7 @@ static void netlink_skb_destructor(struct sk_buff *skb)
                atomic_dec(&ring->pending);
                sock_put(sk);
 
-               skb->data = NULL;
+               skb->head = NULL;
        }
 #endif
        if (skb->sk != NULL)
index fb799de..a76f453 100644 (file)
@@ -5,7 +5,6 @@
 obj-$(CONFIG_NFC) += nfc.o
 obj-$(CONFIG_NFC_NCI) += nci/
 obj-$(CONFIG_NFC_HCI) += hci/
-#obj-$(CONFIG_NFC_LLCP) += llcp/
 
 nfc-objs := core.o netlink.o af_nfc.o rawsock.o llcp_core.o llcp_commands.o \
                llcp_sock.o
index 823463a..189e3c5 100644 (file)
@@ -231,14 +231,14 @@ override:
        }
        if (R_tab) {
                police->rate_present = true;
-               psched_ratecfg_precompute(&police->rate, R_tab->rate.rate);
+               psched_ratecfg_precompute(&police->rate, &R_tab->rate);
                qdisc_put_rtab(R_tab);
        } else {
                police->rate_present = false;
        }
        if (P_tab) {
                police->peak_present = true;
-               psched_ratecfg_precompute(&police->peak, P_tab->rate.rate);
+               psched_ratecfg_precompute(&police->peak, &P_tab->rate);
                qdisc_put_rtab(P_tab);
        } else {
                police->peak_present = false;
@@ -376,9 +376,9 @@ tcf_act_police_dump(struct sk_buff *skb, struct tc_action *a, int bind, int ref)
        };
 
        if (police->rate_present)
-               opt.rate.rate = psched_ratecfg_getrate(&police->rate);
+               psched_ratecfg_getrate(&opt.rate, &police->rate);
        if (police->peak_present)
-               opt.peakrate.rate = psched_ratecfg_getrate(&police->peak);
+               psched_ratecfg_getrate(&opt.peakrate, &police->peak);
        if (nla_put(skb, TCA_POLICE_TBF, sizeof(opt), &opt))
                goto nla_put_failure;
        if (police->tcfp_result &&
index eac7e0e..2022408 100644 (file)
@@ -898,14 +898,16 @@ void dev_shutdown(struct net_device *dev)
        WARN_ON(timer_pending(&dev->watchdog_timer));
 }
 
-void psched_ratecfg_precompute(struct psched_ratecfg *r, u32 rate)
+void psched_ratecfg_precompute(struct psched_ratecfg *r,
+                              const struct tc_ratespec *conf)
 {
        u64 factor;
        u64 mult;
        int shift;
 
-       r->rate_bps = (u64)rate << 3;
-       r->shift = 0;
+       memset(r, 0, sizeof(*r));
+       r->overhead = conf->overhead;
+       r->rate_bps = (u64)conf->rate << 3;
        r->mult = 1;
        /*
         * Calibrate mult, shift so that token counting is accurate
index 79b1876..adaedd7 100644 (file)
@@ -109,7 +109,7 @@ struct htb_class {
        } un;
        struct rb_node node[TC_HTB_NUMPRIO];    /* node for self or feed tree */
        struct rb_node pq_node; /* node for event queue */
-       psched_time_t pq_key;
+       s64     pq_key;
 
        int prio_activity;      /* for which prios are we active */
        enum htb_cmode cmode;   /* current mode of the class */
@@ -121,10 +121,10 @@ struct htb_class {
        /* token bucket parameters */
        struct psched_ratecfg rate;
        struct psched_ratecfg ceil;
-       s64 buffer, cbuffer;    /* token bucket depth/rate */
-       psched_tdiff_t mbuffer; /* max wait time */
-       s64 tokens, ctokens;    /* current number of tokens */
-       psched_time_t t_c;      /* checkpoint time */
+       s64     buffer, cbuffer;        /* token bucket depth/rate */
+       s64     mbuffer;                /* max wait time */
+       s64     tokens, ctokens;        /* current number of tokens */
+       s64     t_c;                    /* checkpoint time */
 };
 
 struct htb_sched {
@@ -141,15 +141,15 @@ struct htb_sched {
        struct rb_root wait_pq[TC_HTB_MAXDEPTH];
 
        /* time of nearest event per level (row) */
-       psched_time_t near_ev_cache[TC_HTB_MAXDEPTH];
+       s64     near_ev_cache[TC_HTB_MAXDEPTH];
 
        int defcls;             /* class where unclassified flows go to */
 
        /* filters for qdisc itself */
        struct tcf_proto *filter_list;
 
-       int rate2quantum;       /* quant = rate / rate2quantum */
-       psched_time_t now;      /* cached dequeue time */
+       int     rate2quantum;   /* quant = rate / rate2quantum */
+       s64     now;    /* cached dequeue time */
        struct qdisc_watchdog watchdog;
 
        /* non shaped skbs; let them go directly thru */
@@ -664,8 +664,8 @@ static void htb_charge_class(struct htb_sched *q, struct htb_class *cl,
  * next pending event (0 for no event in pq, q->now for too many events).
  * Note: Applied are events whose have cl->pq_key <= q->now.
  */
-static psched_time_t htb_do_events(struct htb_sched *q, int level,
-                                  unsigned long start)
+static s64 htb_do_events(struct htb_sched *q, int level,
+                        unsigned long start)
 {
        /* don't run for longer than 2 jiffies; 2 is used instead of
         * 1 to simplify things when jiffy is going to be incremented
@@ -857,7 +857,7 @@ static struct sk_buff *htb_dequeue(struct Qdisc *sch)
        struct sk_buff *skb;
        struct htb_sched *q = qdisc_priv(sch);
        int level;
-       psched_time_t next_event;
+       s64 next_event;
        unsigned long start_at;
 
        /* try to dequeue direct packets as high prio (!) to minimize cpu work */
@@ -880,7 +880,7 @@ ok:
        for (level = 0; level < TC_HTB_MAXDEPTH; level++) {
                /* common case optimization - skip event handler quickly */
                int m;
-               psched_time_t event;
+               s64 event;
 
                if (q->now >= q->near_ev_cache[level]) {
                        event = htb_do_events(q, level, start_at);
@@ -1090,9 +1090,9 @@ static int htb_dump_class(struct Qdisc *sch, unsigned long arg,
 
        memset(&opt, 0, sizeof(opt));
 
-       opt.rate.rate = psched_ratecfg_getrate(&cl->rate);
+       psched_ratecfg_getrate(&opt.rate, &cl->rate);
        opt.buffer = PSCHED_NS2TICKS(cl->buffer);
-       opt.ceil.rate = psched_ratecfg_getrate(&cl->ceil);
+       psched_ratecfg_getrate(&opt.ceil, &cl->ceil);
        opt.cbuffer = PSCHED_NS2TICKS(cl->cbuffer);
        opt.quantum = cl->quantum;
        opt.prio = cl->prio;
@@ -1117,8 +1117,8 @@ htb_dump_class_stats(struct Qdisc *sch, unsigned long arg, struct gnet_dump *d)
 
        if (!cl->level && cl->un.leaf.q)
                cl->qstats.qlen = cl->un.leaf.q->q.qlen;
-       cl->xstats.tokens = cl->tokens;
-       cl->xstats.ctokens = cl->ctokens;
+       cl->xstats.tokens = PSCHED_NS2TICKS(cl->tokens);
+       cl->xstats.ctokens = PSCHED_NS2TICKS(cl->ctokens);
 
        if (gnet_stats_copy_basic(d, &cl->bstats) < 0 ||
            gnet_stats_copy_rate_est(d, NULL, &cl->rate_est) < 0 ||
@@ -1200,7 +1200,7 @@ static void htb_parent_to_leaf(struct htb_sched *q, struct htb_class *cl,
        parent->un.leaf.q = new_q ? new_q : &noop_qdisc;
        parent->tokens = parent->buffer;
        parent->ctokens = parent->cbuffer;
-       parent->t_c = psched_get_time();
+       parent->t_c = ktime_to_ns(ktime_get());
        parent->cmode = HTB_CAN_SEND;
 }
 
@@ -1417,8 +1417,8 @@ static int htb_change_class(struct Qdisc *sch, u32 classid,
                /* set class to be in HTB_CAN_SEND state */
                cl->tokens = PSCHED_TICKS2NS(hopt->buffer);
                cl->ctokens = PSCHED_TICKS2NS(hopt->cbuffer);
-               cl->mbuffer = 60 * PSCHED_TICKS_PER_SEC;        /* 1min */
-               cl->t_c = psched_get_time();
+               cl->mbuffer = 60ULL * NSEC_PER_SEC;     /* 1min */
+               cl->t_c = ktime_to_ns(ktime_get());
                cl->cmode = HTB_CAN_SEND;
 
                /* attach to the hash list and parent's family */
@@ -1459,8 +1459,8 @@ static int htb_change_class(struct Qdisc *sch, u32 classid,
                        cl->prio = TC_HTB_NUMPRIO - 1;
        }
 
-       psched_ratecfg_precompute(&cl->rate, hopt->rate.rate);
-       psched_ratecfg_precompute(&cl->ceil, hopt->ceil.rate);
+       psched_ratecfg_precompute(&cl->rate, &hopt->rate);
+       psched_ratecfg_precompute(&cl->ceil, &hopt->ceil);
 
        cl->buffer = PSCHED_TICKS2NS(hopt->buffer);
        cl->cbuffer = PSCHED_TICKS2NS(hopt->buffer);
index c8388f3..e478d31 100644 (file)
@@ -298,9 +298,9 @@ static int tbf_change(struct Qdisc *sch, struct nlattr *opt)
        q->tokens = q->buffer;
        q->ptokens = q->mtu;
 
-       psched_ratecfg_precompute(&q->rate, rtab->rate.rate);
+       psched_ratecfg_precompute(&q->rate, &rtab->rate);
        if (ptab) {
-               psched_ratecfg_precompute(&q->peak, ptab->rate.rate);
+               psched_ratecfg_precompute(&q->peak, &ptab->rate);
                q->peak_present = true;
        } else {
                q->peak_present = false;
@@ -350,9 +350,9 @@ static int tbf_dump(struct Qdisc *sch, struct sk_buff *skb)
                goto nla_put_failure;
 
        opt.limit = q->limit;
-       opt.rate.rate = psched_ratecfg_getrate(&q->rate);
+       psched_ratecfg_getrate(&opt.rate, &q->rate);
        if (q->peak_present)
-               opt.peakrate.rate = psched_ratecfg_getrate(&q->peak);
+               psched_ratecfg_getrate(&opt.peakrate, &q->peak);
        else
                memset(&opt.peakrate, 0, sizeof(opt.peakrate));
        opt.mtu = PSCHED_NS2TICKS(q->mtu);
index 6b94633..4ca1526 100644 (file)
@@ -1956,7 +1956,7 @@ struct used_address {
        unsigned int name_len;
 };
 
-static int __sys_sendmsg(struct socket *sock, struct msghdr __user *msg,
+static int ___sys_sendmsg(struct socket *sock, struct msghdr __user *msg,
                         struct msghdr *msg_sys, unsigned int flags,
                         struct used_address *used_address)
 {
@@ -2071,22 +2071,30 @@ out:
  *     BSD sendmsg interface
  */
 
-SYSCALL_DEFINE3(sendmsg, int, fd, struct msghdr __user *, msg, unsigned int, flags)
+long __sys_sendmsg(int fd, struct msghdr __user *msg, unsigned flags)
 {
        int fput_needed, err;
        struct msghdr msg_sys;
-       struct socket *sock = sockfd_lookup_light(fd, &err, &fput_needed);
+       struct socket *sock;
 
+       sock = sockfd_lookup_light(fd, &err, &fput_needed);
        if (!sock)
                goto out;
 
-       err = __sys_sendmsg(sock, msg, &msg_sys, flags, NULL);
+       err = ___sys_sendmsg(sock, msg, &msg_sys, flags, NULL);
 
        fput_light(sock->file, fput_needed);
 out:
        return err;
 }
 
+SYSCALL_DEFINE3(sendmsg, int, fd, struct msghdr __user *, msg, unsigned int, flags)
+{
+       if (flags & MSG_CMSG_COMPAT)
+               return -EINVAL;
+       return __sys_sendmsg(fd, msg, flags);
+}
+
 /*
  *     Linux sendmmsg interface
  */
@@ -2117,15 +2125,16 @@ int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen,
 
        while (datagrams < vlen) {
                if (MSG_CMSG_COMPAT & flags) {
-                       err = __sys_sendmsg(sock, (struct msghdr __user *)compat_entry,
-                                           &msg_sys, flags, &used_address);
+                       err = ___sys_sendmsg(sock, (struct msghdr __user *)compat_entry,
+                                            &msg_sys, flags, &used_address);
                        if (err < 0)
                                break;
                        err = __put_user(err, &compat_entry->msg_len);
                        ++compat_entry;
                } else {
-                       err = __sys_sendmsg(sock, (struct msghdr __user *)entry,
-                                           &msg_sys, flags, &used_address);
+                       err = ___sys_sendmsg(sock,
+                                            (struct msghdr __user *)entry,
+                                            &msg_sys, flags, &used_address);
                        if (err < 0)
                                break;
                        err = put_user(err, &entry->msg_len);
@@ -2149,10 +2158,12 @@ int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen,
 SYSCALL_DEFINE4(sendmmsg, int, fd, struct mmsghdr __user *, mmsg,
                unsigned int, vlen, unsigned int, flags)
 {
+       if (flags & MSG_CMSG_COMPAT)
+               return -EINVAL;
        return __sys_sendmmsg(fd, mmsg, vlen, flags);
 }
 
-static int __sys_recvmsg(struct socket *sock, struct msghdr __user *msg,
+static int ___sys_recvmsg(struct socket *sock, struct msghdr __user *msg,
                         struct msghdr *msg_sys, unsigned int flags, int nosec)
 {
        struct compat_msghdr __user *msg_compat =
@@ -2244,23 +2255,31 @@ out:
  *     BSD recvmsg interface
  */
 
-SYSCALL_DEFINE3(recvmsg, int, fd, struct msghdr __user *, msg,
-               unsigned int, flags)
+long __sys_recvmsg(int fd, struct msghdr __user *msg, unsigned flags)
 {
        int fput_needed, err;
        struct msghdr msg_sys;
-       struct socket *sock = sockfd_lookup_light(fd, &err, &fput_needed);
+       struct socket *sock;
 
+       sock = sockfd_lookup_light(fd, &err, &fput_needed);
        if (!sock)
                goto out;
 
-       err = __sys_recvmsg(sock, msg, &msg_sys, flags, 0);
+       err = ___sys_recvmsg(sock, msg, &msg_sys, flags, 0);
 
        fput_light(sock->file, fput_needed);
 out:
        return err;
 }
 
+SYSCALL_DEFINE3(recvmsg, int, fd, struct msghdr __user *, msg,
+               unsigned int, flags)
+{
+       if (flags & MSG_CMSG_COMPAT)
+               return -EINVAL;
+       return __sys_recvmsg(fd, msg, flags);
+}
+
 /*
  *     Linux recvmmsg interface
  */
@@ -2298,17 +2317,18 @@ int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen,
                 * No need to ask LSM for more than the first datagram.
                 */
                if (MSG_CMSG_COMPAT & flags) {
-                       err = __sys_recvmsg(sock, (struct msghdr __user *)compat_entry,
-                                           &msg_sys, flags & ~MSG_WAITFORONE,
-                                           datagrams);
+                       err = ___sys_recvmsg(sock, (struct msghdr __user *)compat_entry,
+                                            &msg_sys, flags & ~MSG_WAITFORONE,
+                                            datagrams);
                        if (err < 0)
                                break;
                        err = __put_user(err, &compat_entry->msg_len);
                        ++compat_entry;
                } else {
-                       err = __sys_recvmsg(sock, (struct msghdr __user *)entry,
-                                           &msg_sys, flags & ~MSG_WAITFORONE,
-                                           datagrams);
+                       err = ___sys_recvmsg(sock,
+                                            (struct msghdr __user *)entry,
+                                            &msg_sys, flags & ~MSG_WAITFORONE,
+                                            datagrams);
                        if (err < 0)
                                break;
                        err = put_user(err, &entry->msg_len);
@@ -2375,6 +2395,9 @@ SYSCALL_DEFINE5(recvmmsg, int, fd, struct mmsghdr __user *, mmsg,
        int datagrams;
        struct timespec timeout_sys;
 
+       if (flags & MSG_CMSG_COMPAT)
+               return -EINVAL;
+
        if (!timeout)
                return __sys_recvmmsg(fd, mmsg, vlen, flags, NULL);
 
index dfdb5e6..d5aed3b 100644 (file)
@@ -3411,7 +3411,7 @@ static int nl80211_send_station(struct sk_buff *msg, u32 portid, u32 seq,
                        (u32)sinfo->rx_bytes))
                goto nla_put_failure;
        if ((sinfo->filled & (STATION_INFO_TX_BYTES |
-                             NL80211_STA_INFO_TX_BYTES64)) &&
+                             STATION_INFO_TX_BYTES64)) &&
            nla_put_u32(msg, NL80211_STA_INFO_TX_BYTES,
                        (u32)sinfo->tx_bytes))
                goto nla_put_failure;
index 8b5eddf..3ed35c3 100644 (file)
@@ -231,6 +231,9 @@ void cfg80211_conn_work(struct work_struct *work)
        mutex_lock(&rdev->sched_scan_mtx);
 
        list_for_each_entry(wdev, &rdev->wdev_list, list) {
+               if (!wdev->netdev)
+                       continue;
+
                wdev_lock(wdev);
                if (!netif_running(wdev->netdev)) {
                        wdev_unlock(wdev);
index 23cea0f..ea970b8 100644 (file)
@@ -2557,11 +2557,12 @@ static void __xfrm_garbage_collect(struct net *net)
        }
 }
 
-static void xfrm_garbage_collect(struct net *net)
+void xfrm_garbage_collect(struct net *net)
 {
        flow_cache_flush();
        __xfrm_garbage_collect(net);
 }
+EXPORT_SYMBOL(xfrm_garbage_collect);
 
 static void xfrm_garbage_collect_deferred(struct net *net)
 {
index aa77874..3f565e4 100644 (file)
@@ -1681,6 +1681,8 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
 
 out:
        xfrm_pol_put(xp);
+       if (delete && err == 0)
+               xfrm_garbage_collect(net);
        return err;
 }
 
index 51bb3de..8337663 100644 (file)
@@ -264,7 +264,7 @@ $(obj)/%.dtb.S: $(obj)/%.dtb
 quiet_cmd_dtc = DTC     $@
 cmd_dtc = $(CPP) $(dtc_cpp_flags) -x assembler-with-cpp -o $(dtc-tmp) $< ; \
        $(objtree)/scripts/dtc/dtc -O dtb -o $@ -b 0 \
-               -i $(srctree)/arch/$(SRCARCH)/boot/dts $(DTC_FLAGS) \
+               -i $(dir $<) $(DTC_FLAGS) \
                -d $(depfile).dtc $(dtc-tmp) ; \
        cat $(depfile).pre $(depfile).dtc > $(depfile)
 
index bb4d3de..a65ecbb 100755 (executable)
@@ -105,7 +105,7 @@ while [ "$1" != "" ] ; do
                ;;
        --refresh)
                ;;
-       --*-after)
+       --*-after|-E|-D|-M)
                checkarg "$1"
                A=$ARG
                checkarg "$2"
index 48d382e..38cd69c 100644 (file)
@@ -303,10 +303,11 @@ do_resize:
                                }
                }
 
-               if (i < max_choice ||
-                   key == KEY_UP || key == KEY_DOWN ||
-                   key == '-' || key == '+' ||
-                   key == KEY_PPAGE || key == KEY_NPAGE) {
+               if (item_count() != 0 &&
+                   (i < max_choice ||
+                    key == KEY_UP || key == KEY_DOWN ||
+                    key == '-' || key == '+' ||
+                    key == KEY_PPAGE || key == KEY_NPAGE)) {
                        /* Remove highligt of current item */
                        print_item(scroll + choice, choice, FALSE);
 
index 387dc8d..a69cbd7 100644 (file)
@@ -670,11 +670,12 @@ static void conf(struct menu *menu, struct menu *active_menu)
                                  active_menu, &s_scroll);
                if (res == 1 || res == KEY_ESC || res == -ERRDISPLAYTOOSMALL)
                        break;
-               if (!item_activate_selected())
-                       continue;
-               if (!item_tag())
-                       continue;
-
+               if (item_count() != 0) {
+                       if (!item_activate_selected())
+                               continue;
+                       if (!item_tag())
+                               continue;
+               }
                submenu = item_data();
                active_menu = item_data();
                if (submenu)
index b5c7d90..fd3f018 100644 (file)
@@ -146,11 +146,24 @@ struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *e
                        struct menu *menu = current_entry;
 
                        while ((menu = menu->parent) != NULL) {
+                               struct expr *dup_expr;
+
                                if (!menu->visibility)
                                        continue;
+                               /*
+                                * Do not add a reference to the
+                                * menu's visibility expression but
+                                * use a copy of it.  Otherwise the
+                                * expression reduction functions
+                                * will modify expressions that have
+                                * multiple references which can
+                                * cause unwanted side effects.
+                                */
+                               dup_expr = expr_copy(menu->visibility);
+
                                prop->visible.expr
                                        = expr_alloc_and(prop->visible.expr,
-                                                        menu->visibility);
+                                                        dup_expr);
                        }
                }
 
index 8ab2951..d030818 100644 (file)
@@ -316,6 +316,7 @@ int selinux_xfrm_policy_clone(struct xfrm_sec_ctx *old_ctx,
 
                memcpy(new_ctx, old_ctx, sizeof(*new_ctx));
                memcpy(new_ctx->ctx_str, old_ctx->ctx_str, new_ctx->ctx_len);
+               atomic_inc(&selinux_xfrm_refcount);
                *new_ctxp = new_ctx;
        }
        return 0;
@@ -326,6 +327,7 @@ int selinux_xfrm_policy_clone(struct xfrm_sec_ctx *old_ctx,
  */
 void selinux_xfrm_policy_free(struct xfrm_sec_ctx *ctx)
 {
+       atomic_dec(&selinux_xfrm_refcount);
        kfree(ctx);
 }
 
@@ -335,17 +337,13 @@ void selinux_xfrm_policy_free(struct xfrm_sec_ctx *ctx)
 int selinux_xfrm_policy_delete(struct xfrm_sec_ctx *ctx)
 {
        const struct task_security_struct *tsec = current_security();
-       int rc = 0;
 
-       if (ctx) {
-               rc = avc_has_perm(tsec->sid, ctx->ctx_sid,
-                                 SECCLASS_ASSOCIATION,
-                                 ASSOCIATION__SETCONTEXT, NULL);
-               if (rc == 0)
-                       atomic_dec(&selinux_xfrm_refcount);
-       }
+       if (!ctx)
+               return 0;
 
-       return rc;
+       return avc_has_perm(tsec->sid, ctx->ctx_sid,
+                           SECCLASS_ASSOCIATION, ASSOCIATION__SETCONTEXT,
+                           NULL);
 }
 
 /*
@@ -370,8 +368,8 @@ int selinux_xfrm_state_alloc(struct xfrm_state *x, struct xfrm_user_sec_ctx *uct
  */
 void selinux_xfrm_state_free(struct xfrm_state *x)
 {
-       struct xfrm_sec_ctx *ctx = x->security;
-       kfree(ctx);
+       atomic_dec(&selinux_xfrm_refcount);
+       kfree(x->security);
 }
 
  /*
@@ -381,17 +379,13 @@ int selinux_xfrm_state_delete(struct xfrm_state *x)
 {
        const struct task_security_struct *tsec = current_security();
        struct xfrm_sec_ctx *ctx = x->security;
-       int rc = 0;
 
-       if (ctx) {
-               rc = avc_has_perm(tsec->sid, ctx->ctx_sid,
-                                 SECCLASS_ASSOCIATION,
-                                 ASSOCIATION__SETCONTEXT, NULL);
-               if (rc == 0)
-                       atomic_dec(&selinux_xfrm_refcount);
-       }
+       if (!ctx)
+               return 0;
 
-       return rc;
+       return avc_has_perm(tsec->sid, ctx->ctx_sid,
+                           SECCLASS_ASSOCIATION, ASSOCIATION__SETCONTEXT,
+                           NULL);
 }
 
 /*
index ae85bbd..4b1524a 100644 (file)
@@ -788,6 +788,8 @@ static void set_pin_eapd(struct hda_codec *codec, hda_nid_t pin, bool enable)
                return;
        if (codec->inv_eapd)
                enable = !enable;
+       if (spec->keep_eapd_on && !enable)
+               return;
        snd_hda_codec_update_cache(codec, pin, 0,
                                   AC_VERB_SET_EAPD_BTLENABLE,
                                   enable ? 0x02 : 0x00);
@@ -1938,17 +1940,7 @@ static int create_speaker_out_ctls(struct hda_codec *codec)
  * independent HP controls
  */
 
-/* update HP auto-mute state too */
-static void update_hp_automute_hook(struct hda_codec *codec)
-{
-       struct hda_gen_spec *spec = codec->spec;
-
-       if (spec->hp_automute_hook)
-               spec->hp_automute_hook(codec, NULL);
-       else
-               snd_hda_gen_hp_automute(codec, NULL);
-}
-
+static void call_hp_automute(struct hda_codec *codec, struct hda_jack_tbl *jack);
 static int indep_hp_info(struct snd_kcontrol *kcontrol,
                         struct snd_ctl_elem_info *uinfo)
 {
@@ -2009,7 +2001,7 @@ static int indep_hp_put(struct snd_kcontrol *kcontrol,
                else
                        *dacp = spec->alt_dac_nid;
 
-               update_hp_automute_hook(codec);
+               call_hp_automute(codec, NULL);
                ret = 1;
        }
  unlock:
@@ -2305,7 +2297,7 @@ static void update_hp_mic(struct hda_codec *codec, int adc_mux, bool force)
                else
                        val = PIN_HP;
                set_pin_target(codec, pin, val, true);
-               update_hp_automute_hook(codec);
+               call_hp_automute(codec, NULL);
        }
 }
 
@@ -2714,7 +2706,7 @@ static int hp_mic_jack_mode_put(struct snd_kcontrol *kcontrol,
                        val = snd_hda_get_default_vref(codec, nid);
        }
        snd_hda_set_pin_ctl_cache(codec, nid, val);
-       update_hp_automute_hook(codec);
+       call_hp_automute(codec, NULL);
 
        return 1;
 }
@@ -3859,20 +3851,42 @@ void snd_hda_gen_mic_autoswitch(struct hda_codec *codec, struct hda_jack_tbl *ja
 }
 EXPORT_SYMBOL_HDA(snd_hda_gen_mic_autoswitch);
 
-/* update jack retasking */
-static void update_automute_all(struct hda_codec *codec)
+/* call appropriate hooks */
+static void call_hp_automute(struct hda_codec *codec, struct hda_jack_tbl *jack)
 {
        struct hda_gen_spec *spec = codec->spec;
+       if (spec->hp_automute_hook)
+               spec->hp_automute_hook(codec, jack);
+       else
+               snd_hda_gen_hp_automute(codec, jack);
+}
 
-       update_hp_automute_hook(codec);
+static void call_line_automute(struct hda_codec *codec,
+                              struct hda_jack_tbl *jack)
+{
+       struct hda_gen_spec *spec = codec->spec;
        if (spec->line_automute_hook)
-               spec->line_automute_hook(codec, NULL);
+               spec->line_automute_hook(codec, jack);
        else
-               snd_hda_gen_line_automute(codec, NULL);
+               snd_hda_gen_line_automute(codec, jack);
+}
+
+static void call_mic_autoswitch(struct hda_codec *codec,
+                               struct hda_jack_tbl *jack)
+{
+       struct hda_gen_spec *spec = codec->spec;
        if (spec->mic_autoswitch_hook)
-               spec->mic_autoswitch_hook(codec, NULL);
+               spec->mic_autoswitch_hook(codec, jack);
        else
-               snd_hda_gen_mic_autoswitch(codec, NULL);
+               snd_hda_gen_mic_autoswitch(codec, jack);
+}
+
+/* update jack retasking */
+static void update_automute_all(struct hda_codec *codec)
+{
+       call_hp_automute(codec, NULL);
+       call_line_automute(codec, NULL);
+       call_mic_autoswitch(codec, NULL);
 }
 
 /*
@@ -4009,9 +4023,7 @@ static int check_auto_mute_availability(struct hda_codec *codec)
                snd_printdd("hda-codec: Enable HP auto-muting on NID 0x%x\n",
                            nid);
                snd_hda_jack_detect_enable_callback(codec, nid, HDA_GEN_HP_EVENT,
-                                                   spec->hp_automute_hook ?
-                                                   spec->hp_automute_hook :
-                                                   snd_hda_gen_hp_automute);
+                                                   call_hp_automute);
                spec->detect_hp = 1;
        }
 
@@ -4024,9 +4036,7 @@ static int check_auto_mute_availability(struct hda_codec *codec)
                                snd_printdd("hda-codec: Enable Line-Out auto-muting on NID 0x%x\n", nid);
                                snd_hda_jack_detect_enable_callback(codec, nid,
                                                                    HDA_GEN_FRONT_EVENT,
-                                                                   spec->line_automute_hook ?
-                                                                   spec->line_automute_hook :
-                                                                   snd_hda_gen_line_automute);
+                                                                   call_line_automute);
                                spec->detect_lo = 1;
                        }
                spec->automute_lo_possible = spec->detect_hp;
@@ -4068,9 +4078,7 @@ static bool auto_mic_check_imux(struct hda_codec *codec)
                snd_hda_jack_detect_enable_callback(codec,
                                                    spec->am_entry[i].pin,
                                                    HDA_GEN_MIC_EVENT,
-                                                   spec->mic_autoswitch_hook ?
-                                                   spec->mic_autoswitch_hook :
-                                                   snd_hda_gen_mic_autoswitch);
+                                                   call_mic_autoswitch);
        return true;
 }
 
index 54e6651..7620031 100644 (file)
@@ -222,6 +222,7 @@ struct hda_gen_spec {
        unsigned int multi_cap_vol:1; /* allow multiple capture xxx volumes */
        unsigned int inv_dmic_split:1; /* inverted dmic w/a for conexant */
        unsigned int own_eapd_ctl:1; /* set EAPD by own function */
+       unsigned int keep_eapd_on:1; /* don't turn off EAPD automatically */
        unsigned int vmaster_mute_enum:1; /* add vmaster mute mode enum */
        unsigned int indep_hp:1; /* independent HP supported */
        unsigned int prefer_hp_amp:1; /* enable HP amp for speaker if any */
index 59d2e91..02e22b4 100644 (file)
@@ -3493,6 +3493,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x1028, 0x05f4, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1028, 0x05f5, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1028, 0x05f6, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
+       SND_PCI_QUIRK(0x1028, 0x05f8, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
+       SND_PCI_QUIRK(0x1028, 0x0609, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2),
        SND_PCI_QUIRK(0x103c, 0x18e6, "HP", ALC269_FIXUP_HP_GPIO_LED),
        SND_PCI_QUIRK(0x103c, 0x1973, "HP Pavilion", ALC269_FIXUP_HP_MUTE_LED_MIC1),
@@ -3530,6 +3532,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x17aa, 0x21fa, "Thinkpad X230", ALC269_FIXUP_LENOVO_DOCK),
        SND_PCI_QUIRK(0x17aa, 0x21f3, "Thinkpad T430", ALC269_FIXUP_LENOVO_DOCK),
        SND_PCI_QUIRK(0x17aa, 0x21fb, "Thinkpad T430s", ALC269_FIXUP_LENOVO_DOCK),
+       SND_PCI_QUIRK(0x17aa, 0x2208, "Thinkpad T431s", ALC269_FIXUP_LENOVO_DOCK),
        SND_PCI_QUIRK(0x17aa, 0x2203, "Thinkpad X230 Tablet", ALC269_FIXUP_LENOVO_DOCK),
        SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_PCM_44K),
        SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
index e0dadcf..e524554 100644 (file)
@@ -136,6 +136,7 @@ static struct via_spec *via_new_spec(struct hda_codec *codec)
                spec->codec_type = VT1708S;
        spec->no_pin_power_ctl = 1;
        spec->gen.indep_hp = 1;
+       spec->gen.keep_eapd_on = 1;
        spec->gen.pcm_playback_hook = via_playback_pcm_hook;
        return spec;
 }
@@ -231,9 +232,14 @@ static void vt1708_update_hp_work(struct hda_codec *codec)
 
 static void set_widgets_power_state(struct hda_codec *codec)
 {
+#if 0 /* FIXME: the assumed connections don't match always with the
+       * actual routes by the generic parser, so better to disable
+       * the control for safety.
+       */
        struct via_spec *spec = codec->spec;
        if (spec->set_widgets_power_state)
                spec->set_widgets_power_state(codec);
+#endif
 }
 
 static void update_power_state(struct hda_codec *codec, hda_nid_t nid,
@@ -478,7 +484,9 @@ static int via_suspend(struct hda_codec *codec)
                /* Fix pop noise on headphones */
                int i;
                for (i = 0; i < spec->gen.autocfg.hp_outs; i++)
-                       snd_hda_set_pin_ctl(codec, spec->gen.autocfg.hp_pins[i], 0);
+                       snd_hda_codec_write(codec, spec->gen.autocfg.hp_pins[i],
+                                           0, AC_VERB_SET_PIN_WIDGET_CONTROL,
+                                           0x00);
        }
 
        return 0;
index d59abe1..748e82d 100644 (file)
@@ -1341,7 +1341,8 @@ static int sis_chip_create(struct snd_card *card,
        if (rc)
                goto error_out;
 
-       if (pci_set_dma_mask(pci, DMA_BIT_MASK(30)) < 0) {
+       rc = pci_set_dma_mask(pci, DMA_BIT_MASK(30));
+       if (rc < 0) {
                dev_err(&pci->dev, "architecture does not support 30-bit PCI busmaster DMA");
                goto error_out_enabled;
        }
index ca4739c..e5c7f9f 100644 (file)
@@ -886,6 +886,7 @@ static void volume_control_quirks(struct usb_mixer_elem_info *cval,
        case USB_ID(0x046d, 0x0808):
        case USB_ID(0x046d, 0x0809):
        case USB_ID(0x046d, 0x081d): /* HD Webcam c510 */
+       case USB_ID(0x046d, 0x0825): /* HD Webcam c270 */
        case USB_ID(0x046d, 0x0991):
        /* Most audio usb devices lie about volume resolution.
         * Most Logitech webcams have res = 384.
index 7f1722f..8b75bcf 100644 (file)
        .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL
 },
 {
-       USB_DEVICE(0x046d, 0x0990),
+       .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
+                      USB_DEVICE_ID_MATCH_INT_CLASS |
+                      USB_DEVICE_ID_MATCH_INT_SUBCLASS,
+       .idVendor = 0x046d,
+       .idProduct = 0x0990,
+       .bInterfaceClass = USB_CLASS_AUDIO,
+       .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL,
        .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
                .vendor_name = "Logitech, Inc.",
                .product_name = "QuickCam Pro 9000",
@@ -1792,7 +1798,11 @@ YAMAHA_DEVICE(0x7010, "UB99"),
        USB_DEVICE_VENDOR_SPEC(0x0582, 0x0108),
        .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
                .ifnum = 0,
-               .type = QUIRK_MIDI_STANDARD_INTERFACE
+               .type = QUIRK_MIDI_FIXED_ENDPOINT,
+               .data = & (const struct snd_usb_midi_endpoint_info) {
+                       .out_cables = 0x0007,
+                       .in_cables  = 0x0007
+               }
        }
 },
 {