aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/DocBook/device-drivers.tmpl5
-rw-r--r--Documentation/DocBook/deviceiobook.tmpl2
-rw-r--r--Documentation/power/basic-pm-debugging.txt2
-rw-r--r--Documentation/power/freezing-of-tasks.txt8
-rw-r--r--Documentation/thermal/sysfs-api.txt2
-rw-r--r--MAINTAINERS13
-rw-r--r--arch/arm/Makefile1
-rw-r--r--arch/arm/configs/imx_v6_v7_defconfig (renamed from arch/arm/configs/mx5_defconfig)61
-rw-r--r--arch/arm/configs/mx3_defconfig144
-rw-r--r--arch/arm/mach-imx/Kconfig239
-rw-r--r--arch/arm/mach-imx/Makefile21
-rw-r--r--arch/arm/mach-imx/Makefile.boot12
-rw-r--r--arch/arm/mach-imx/clock-mx51-mx53.c (renamed from arch/arm/mach-mx5/clock-mx51-mx53.c)2
-rw-r--r--arch/arm/mach-imx/cpu-imx5.c (renamed from arch/arm/mach-mx5/cpu.c)0
-rw-r--r--arch/arm/mach-imx/cpu_op-mx51.c (renamed from arch/arm/mach-mx5/cpu_op-mx51.c)0
-rw-r--r--arch/arm/mach-imx/cpu_op-mx51.h (renamed from arch/arm/mach-mx5/cpu_op-mx51.h)0
-rw-r--r--arch/arm/mach-imx/crm-regs-imx5.h (renamed from arch/arm/mach-mx5/crm_regs.h)0
-rw-r--r--arch/arm/mach-imx/devices-imx50.h (renamed from arch/arm/mach-mx5/devices-imx50.h)0
-rw-r--r--arch/arm/mach-imx/devices-imx51.h (renamed from arch/arm/mach-mx5/devices-imx51.h)0
-rw-r--r--arch/arm/mach-imx/devices-imx53.h (renamed from arch/arm/mach-mx5/devices-imx53.h)0
-rw-r--r--arch/arm/mach-imx/efika.h (renamed from arch/arm/mach-mx5/efika.h)0
-rw-r--r--arch/arm/mach-imx/ehci-imx5.c (renamed from arch/arm/mach-mx5/ehci.c)0
-rw-r--r--arch/arm/mach-imx/eukrea_mbimx51-baseboard.c (renamed from arch/arm/mach-mx5/eukrea_mbimx51-baseboard.c)0
-rw-r--r--arch/arm/mach-imx/eukrea_mbimxsd-baseboard.c (renamed from arch/arm/mach-mx5/eukrea_mbimxsd-baseboard.c)0
-rw-r--r--arch/arm/mach-imx/imx51-dt.c (renamed from arch/arm/mach-mx5/imx51-dt.c)0
-rw-r--r--arch/arm/mach-imx/imx53-dt.c (renamed from arch/arm/mach-mx5/imx53-dt.c)0
-rw-r--r--arch/arm/mach-imx/mach-cpuimx51.c (renamed from arch/arm/mach-mx5/board-cpuimx51.c)0
-rw-r--r--arch/arm/mach-imx/mach-cpuimx51sd.c (renamed from arch/arm/mach-mx5/board-cpuimx51sd.c)0
-rw-r--r--arch/arm/mach-imx/mach-mx50_rdp.c (renamed from arch/arm/mach-mx5/board-mx50_rdp.c)0
-rw-r--r--arch/arm/mach-imx/mach-mx51_3ds.c (renamed from arch/arm/mach-mx5/board-mx51_3ds.c)0
-rw-r--r--arch/arm/mach-imx/mach-mx51_babbage.c (renamed from arch/arm/mach-mx5/board-mx51_babbage.c)0
-rw-r--r--arch/arm/mach-imx/mach-mx51_efikamx.c (renamed from arch/arm/mach-mx5/board-mx51_efikamx.c)0
-rw-r--r--arch/arm/mach-imx/mach-mx51_efikasb.c (renamed from arch/arm/mach-mx5/board-mx51_efikasb.c)0
-rw-r--r--arch/arm/mach-imx/mach-mx53_ard.c (renamed from arch/arm/mach-mx5/board-mx53_ard.c)1
-rw-r--r--arch/arm/mach-imx/mach-mx53_evk.c (renamed from arch/arm/mach-mx5/board-mx53_evk.c)1
-rw-r--r--arch/arm/mach-imx/mach-mx53_loco.c (renamed from arch/arm/mach-mx5/board-mx53_loco.c)1
-rw-r--r--arch/arm/mach-imx/mach-mx53_smd.c (renamed from arch/arm/mach-mx5/board-mx53_smd.c)1
-rw-r--r--arch/arm/mach-imx/mm-imx5.c (renamed from arch/arm/mach-mx5/mm.c)0
-rw-r--r--arch/arm/mach-imx/mx51_efika.c (renamed from arch/arm/mach-mx5/mx51_efika.c)0
-rw-r--r--arch/arm/mach-imx/pm-imx5.c (renamed from arch/arm/mach-mx5/system.c)89
-rw-r--r--arch/arm/mach-mx5/Kconfig244
-rw-r--r--arch/arm/mach-mx5/Makefile26
-rw-r--r--arch/arm/mach-mx5/Makefile.boot9
-rw-r--r--arch/arm/mach-mx5/pm-imx5.c83
-rw-r--r--arch/arm/plat-mxc/Kconfig15
-rw-r--r--arch/m68k/atari/config.c8
-rw-r--r--arch/m68k/include/asm/irq.h13
-rw-r--r--arch/m68k/kernel/process_mm.c2
-rw-r--r--arch/m68k/kernel/process_no.c4
-rw-r--r--arch/m68k/kernel/traps.c36
-rw-r--r--arch/m68k/mm/cache.c6
-rw-r--r--arch/powerpc/boot/dts/fsl/mpc8536si-post.dtsi4
-rw-r--r--arch/powerpc/boot/dts/fsl/p1010si-post.dtsi3
-rw-r--r--arch/powerpc/boot/dts/fsl/p1020si-post.dtsi4
-rw-r--r--arch/powerpc/boot/dts/fsl/p1022si-post.dtsi3
-rw-r--r--arch/powerpc/boot/dts/fsl/p2020si-post.dtsi4
-rw-r--r--arch/powerpc/boot/dts/p1020rdb.dtsi13
-rw-r--r--arch/powerpc/boot/dts/p1021mds.dts3
-rw-r--r--arch/powerpc/boot/dts/p2020ds.dtsi3
-rw-r--r--arch/powerpc/boot/dts/p2020rdb.dts3
-rw-r--r--arch/powerpc/kernel/crash.c2
-rw-r--r--arch/powerpc/kernel/legacy_serial.c2
-rw-r--r--arch/powerpc/platforms/85xx/p1022_ds.c1
-rw-r--r--arch/powerpc/platforms/powernv/pci-ioda.c43
-rw-r--r--arch/powerpc/platforms/pseries/Kconfig2
-rw-r--r--arch/powerpc/sysdev/fsl_pci.c5
-rw-r--r--arch/s390/include/asm/kexec.h18
-rw-r--r--arch/score/kernel/entry.S2
-rw-r--r--arch/x86/net/bpf_jit_comp.c36
-rw-r--r--crypto/sha512_generic.c62
-rw-r--r--drivers/acpi/Makefile1
-rw-r--r--drivers/acpi/apei/apei-base.c35
-rw-r--r--drivers/acpi/apei/einj.c95
-rw-r--r--drivers/acpi/atomicio.c422
-rw-r--r--drivers/acpi/osl.c152
-rw-r--r--drivers/acpi/processor_driver.c154
-rw-r--r--drivers/acpi/sleep.c8
-rw-r--r--drivers/base/bus.c9
-rw-r--r--drivers/base/firmware_class.c3
-rw-r--r--drivers/base/regmap/regmap.c3
-rw-r--r--drivers/gpu/drm/drm_auth.c6
-rw-r--r--drivers/gpu/drm/drm_fops.c5
-rw-r--r--drivers/gpu/drm/gma500/gtt.c5
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_bo.c4
-rw-r--r--drivers/gpu/drm/radeon/atombios_crtc.c60
-rw-r--r--drivers/gpu/drm/radeon/atombios_dp.c22
-rw-r--r--drivers/gpu/drm/radeon/atombios_encoders.c89
-rw-r--r--drivers/gpu/drm/radeon/evergreen.c1
-rw-r--r--drivers/gpu/drm/radeon/evergreend.h1
-rw-r--r--drivers/gpu/drm/radeon/ni.c1
-rw-r--r--drivers/gpu/drm/radeon/nid.h1
-rw-r--r--drivers/gpu/drm/radeon/radeon.h84
-rw-r--r--drivers/gpu/drm/radeon/radeon_atpx_handler.c4
-rw-r--r--drivers/gpu/drm/radeon/radeon_bios.c2
-rw-r--r--drivers/gpu/drm/radeon/radeon_device.c8
-rw-r--r--drivers/gpu/drm/radeon/radeon_display.c6
-rw-r--r--drivers/gpu/drm/radeon/radeon_encoders.c77
-rw-r--r--drivers/gpu/drm/radeon/radeon_irq_kms.c6
-rw-r--r--drivers/gpu/drm/radeon/radeon_mode.h8
-rw-r--r--drivers/gpu/drm/radeon/radeon_ring.c37
-rw-r--r--drivers/gpu/drm/sis/sis_drv.c3
-rw-r--r--drivers/gpu/drm/ttm/ttm_bo.c17
-rw-r--r--drivers/idle/intel_idle.c2
-rw-r--r--drivers/leds/Kconfig7
-rw-r--r--drivers/leds/Makefile1
-rw-r--r--drivers/leds/leds-ot200.c171
-rw-r--r--drivers/net/bonding/bond_alb.c27
-rw-r--r--drivers/net/dsa/mv88e6060.c1
-rw-r--r--drivers/net/dsa/mv88e6123_61_65.c22
-rw-r--r--drivers/net/dsa/mv88e6131.c1
-rw-r--r--drivers/net/dsa/mv88e6xxx.c1
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c2
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c111
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c11
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c44
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h11
-rw-r--r--drivers/net/ethernet/broadcom/tg3.c9
-rw-r--r--drivers/net/ethernet/cisco/enic/enic.h2
-rw-r--r--drivers/net/ethernet/cisco/enic/enic_main.c38
-rw-r--r--drivers/net/ethernet/emulex/benet/be_main.c3
-rw-r--r--drivers/net/ethernet/faraday/ftgmac100.c1
-rw-r--r--drivers/net/ethernet/faraday/ftmac100.c1
-rw-r--r--drivers/net/ethernet/intel/igb/Makefile2
-rw-r--r--drivers/net/ethernet/intel/igb/e1000_82575.c2
-rw-r--r--drivers/net/ethernet/intel/igb/e1000_82575.h2
-rw-r--r--drivers/net/ethernet/intel/igb/e1000_defines.h2
-rw-r--r--drivers/net/ethernet/intel/igb/e1000_hw.h2
-rw-r--r--drivers/net/ethernet/intel/igb/e1000_mac.c4
-rw-r--r--drivers/net/ethernet/intel/igb/e1000_mac.h2
-rw-r--r--drivers/net/ethernet/intel/igb/e1000_mbx.c2
-rw-r--r--drivers/net/ethernet/intel/igb/e1000_mbx.h2
-rw-r--r--drivers/net/ethernet/intel/igb/e1000_nvm.c2
-rw-r--r--drivers/net/ethernet/intel/igb/e1000_nvm.h2
-rw-r--r--drivers/net/ethernet/intel/igb/e1000_phy.c2
-rw-r--r--drivers/net/ethernet/intel/igb/e1000_phy.h2
-rw-r--r--drivers/net/ethernet/intel/igb/e1000_regs.h2
-rw-r--r--drivers/net/ethernet/intel/igb/igb.h2
-rw-r--r--drivers/net/ethernet/intel/igb/igb_ethtool.c2
-rw-r--r--drivers/net/ethernet/intel/igb/igb_main.c10
-rw-r--r--drivers/net/ethernet/intel/igbvf/ethtool.c3
-rw-r--r--drivers/net/ethernet/intel/igbvf/netdev.c5
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_type.h32
-rw-r--r--drivers/net/ethernet/intel/ixgbevf/ethtool.c5
-rw-r--r--drivers/net/ethernet/intel/ixgbevf/ixgbevf.h8
-rw-r--r--drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c41
-rw-r--r--drivers/net/ethernet/intel/ixgbevf/mbx.c3
-rw-r--r--drivers/net/ethernet/intel/ixgbevf/vf.c7
-rw-r--r--drivers/net/ethernet/intel/ixgbevf/vf.h2
-rw-r--r--drivers/net/ethernet/marvell/mv643xx_eth.c14
-rw-r--r--drivers/net/ethernet/marvell/skge.c109
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/cmd.c9
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/cq.c4
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_ethtool.c159
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_main.c6
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_netdev.c38
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_rx.c8
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/eq.c21
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/fw.c7
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/fw.h1
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/main.c3
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/mlx4.h8
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/mlx4_en.h3
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/mr.c2
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/pd.c3
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/port.c23
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/profile.c2
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/qp.c2
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/resource_tracker.c39
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/srq.c2
-rw-r--r--drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c17
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c2
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c6
-rw-r--r--drivers/net/hyperv/netvsc_drv.c5
-rw-r--r--drivers/net/macvlan.c1
-rw-r--r--drivers/net/phy/mdio_bus.c5
-rw-r--r--drivers/net/team/team.c136
-rw-r--r--drivers/net/wireless/b43/Kconfig6
-rw-r--r--drivers/net/wireless/b43/main.c2
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/main.c10
-rw-r--r--drivers/pci/pci.c6
-rw-r--r--drivers/regulator/core.c2
-rw-r--r--drivers/scsi/mac_esp.c3
-rw-r--r--drivers/scsi/mac_scsi.c6
-rw-r--r--drivers/thermal/thermal_sys.c4
-rw-r--r--drivers/video/backlight/adp8860_bl.c2
-rw-r--r--drivers/video/backlight/adp8870_bl.c2
-rw-r--r--drivers/video/backlight/l4f00242t03.c2
-rw-r--r--drivers/video/macfb.c60
-rw-r--r--fs/cifs/Kconfig3
-rw-r--r--fs/cifs/cifs_debug.c11
-rw-r--r--fs/cifs/cifs_spnego.c10
-rw-r--r--fs/cifs/cifs_unicode.c41
-rw-r--r--fs/cifs/cifs_unicode.h20
-rw-r--r--fs/cifs/cifsacl.c2
-rw-r--r--fs/cifs/cifsencrypt.c21
-rw-r--r--fs/cifs/cifsglob.h2
-rw-r--r--fs/cifs/cifssmb.c162
-rw-r--r--fs/cifs/connect.c305
-rw-r--r--fs/cifs/readdir.c9
-rw-r--r--fs/cifs/sess.c34
-rw-r--r--fs/cifs/smbencrypt.c2
-rw-r--r--fs/debugfs/file.c2
-rw-r--r--fs/ecryptfs/crypto.c54
-rw-r--r--fs/ecryptfs/ecryptfs_kernel.h5
-rw-r--r--fs/ecryptfs/inode.c48
-rw-r--r--fs/ecryptfs/keystore.c5
-rw-r--r--fs/ecryptfs/miscdev.c140
-rw-r--r--fs/ecryptfs/mmap.c8
-rw-r--r--fs/ecryptfs/read_write.c96
-rw-r--r--fs/ext2/ioctl.c22
-rw-r--r--fs/jbd/checkpoint.c27
-rw-r--r--fs/jbd/recovery.c4
-rw-r--r--fs/proc/task_mmu.c3
-rw-r--r--fs/quota/dquot.c8
-rw-r--r--fs/xfs/xfs_vnodeops.c3
-rw-r--r--include/acpi/acpiosxf.h4
-rw-r--r--include/acpi/atomicio.h10
-rw-r--r--include/acpi/processor.h1
-rw-r--r--include/drm/drmP.h1
-rw-r--r--include/keys/user-type.h3
-rw-r--r--include/linux/device.h15
-rw-r--r--include/linux/fs.h2
-rw-r--r--include/linux/if_team.h10
-rw-r--r--include/linux/kexec.h2
-rw-r--r--include/linux/migrate.h14
-rw-r--r--include/linux/migrate_mode.h16
-rw-r--r--include/linux/mlx4/device.h1
-rw-r--r--include/linux/quota.h6
-rw-r--r--include/linux/res_counter.h11
-rw-r--r--include/linux/sched.h4
-rw-r--r--include/linux/shmem_fs.h1
-rw-r--r--include/linux/snmp.h1
-rw-r--r--include/linux/suspend.h19
-rw-r--r--include/linux/swap.h2
-rw-r--r--include/linux/thermal.h4
-rw-r--r--include/linux/usb.h1
-rw-r--r--include/net/bluetooth/hci.h2
-rw-r--r--include/net/cfg80211.h6
-rw-r--r--include/net/netprio_cgroup.h1
-rw-r--r--include/net/sock.h13
-rw-r--r--ipc/mqueue.c3
-rw-r--r--ipc/shm.c37
-rw-r--r--kernel/auditsc.c5
-rw-r--r--kernel/kprobes.c2
-rw-r--r--kernel/power/snapshot.c3
-rw-r--r--kernel/rcutorture.c8
-rw-r--r--kernel/res_counter.c25
-rw-r--r--kernel/sched/cpupri.c3
-rw-r--r--mm/hugetlb.c9
-rw-r--r--mm/memblock.c7
-rw-r--r--mm/memcontrol.c6
-rw-r--r--mm/memory.c37
-rw-r--r--mm/page_alloc.c20
-rw-r--r--mm/shmem.c53
-rw-r--r--mm/vmscan.c124
-rw-r--r--net/bluetooth/hci_core.c2
-rw-r--r--net/core/ethtool.c1
-rw-r--r--net/core/flow_dissector.c1
-rw-r--r--net/core/pktgen.c4
-rw-r--r--net/core/sock.c4
-rw-r--r--net/ipv4/proc.c1
-rw-r--r--net/ipv4/tcp_bic.c11
-rw-r--r--net/ipv4/tcp_cubic.c10
-rw-r--r--net/ipv4/tcp_input.c41
-rw-r--r--net/ipv4/tcp_ipv4.c2
-rw-r--r--net/ipv6/addrconf.c61
-rw-r--r--net/ipv6/tcp_ipv6.c2
-rw-r--r--net/llc/af_llc.c5
-rw-r--r--net/mac80211/debugfs_key.c7
-rw-r--r--net/mac80211/mesh_hwmp.c8
-rw-r--r--net/mac80211/mesh_plink.c4
-rw-r--r--net/mac80211/mlme.c38
-rw-r--r--net/rds/af_rds.c20
-rw-r--r--net/sched/sch_netem.c2
-rwxr-xr-xscripts/kernel-doc3
-rw-r--r--security/keys/internal.h1
-rw-r--r--security/keys/key.c1
-rw-r--r--security/keys/user_defined.c37
-rw-r--r--sound/pci/hda/alc880_quirks.c17
-rw-r--r--sound/pci/hda/alc882_quirks.c15
-rw-r--r--sound/pci/hda/hda_intel.c6
-rw-r--r--sound/pci/hda/patch_conexant.c2
-rw-r--r--sound/pci/hda/patch_realtek.c47
-rw-r--r--sound/pci/hda/patch_sigmatel.c10
-rw-r--r--sound/soc/codecs/sgtl5000.c17
-rw-r--r--sound/soc/codecs/tlv320aic32x4.c110
-rw-r--r--sound/soc/codecs/wm2000.c31
-rw-r--r--sound/soc/codecs/wm5100.c3
-rw-r--r--sound/soc/codecs/wm8958-dsp2.c2
-rw-r--r--sound/soc/codecs/wm8996.c7
-rw-r--r--sound/soc/codecs/wm8996.h4
-rw-r--r--sound/soc/mxs/mxs-saif.c5
292 files changed, 3377 insertions, 2653 deletions
diff --git a/Documentation/DocBook/device-drivers.tmpl b/Documentation/DocBook/device-drivers.tmpl
index b638e50cf8f6..2f7fd4360848 100644
--- a/Documentation/DocBook/device-drivers.tmpl
+++ b/Documentation/DocBook/device-drivers.tmpl
@@ -50,7 +50,9 @@
<sect1><title>Delaying, scheduling, and timer routines</title>
!Iinclude/linux/sched.h
-!Ekernel/sched.c
+!Ekernel/sched/core.c
+!Ikernel/sched/cpupri.c
+!Ikernel/sched/fair.c
!Iinclude/linux/completion.h
!Ekernel/timer.c
</sect1>
@@ -216,7 +218,6 @@ X!Isound/sound_firmware.c
<chapter id="uart16x50">
<title>16x50 UART Driver</title>
-!Iinclude/linux/serial_core.h
!Edrivers/tty/serial/serial_core.c
!Edrivers/tty/serial/8250.c
</chapter>
diff --git a/Documentation/DocBook/deviceiobook.tmpl b/Documentation/DocBook/deviceiobook.tmpl
index c1ed6a49e598..54199a0dcf9a 100644
--- a/Documentation/DocBook/deviceiobook.tmpl
+++ b/Documentation/DocBook/deviceiobook.tmpl
@@ -317,7 +317,7 @@ CPU B: spin_unlock_irqrestore(&amp;dev_lock, flags)
<chapter id="pubfunctions">
<title>Public Functions Provided</title>
!Iarch/x86/include/asm/io.h
-!Elib/iomap.c
+!Elib/pci_iomap.c
</chapter>
</book>
diff --git a/Documentation/power/basic-pm-debugging.txt b/Documentation/power/basic-pm-debugging.txt
index 40a4c65f380a..262acf56fa79 100644
--- a/Documentation/power/basic-pm-debugging.txt
+++ b/Documentation/power/basic-pm-debugging.txt
@@ -15,7 +15,7 @@ test at least a couple of times in a row for confidence. [This is necessary,
because some problems only show up on a second attempt at suspending and
resuming the system.] Moreover, hibernating in the "reboot" and "shutdown"
modes causes the PM core to skip some platform-related callbacks which on ACPI
-systems might be necessary to make hibernation work. Thus, if you machine fails
+systems might be necessary to make hibernation work. Thus, if your machine fails
to hibernate or resume in the "reboot" mode, you should try the "platform" mode:
# echo platform > /sys/power/disk
diff --git a/Documentation/power/freezing-of-tasks.txt b/Documentation/power/freezing-of-tasks.txt
index 6ccb68f68da6..ebd7490ef1df 100644
--- a/Documentation/power/freezing-of-tasks.txt
+++ b/Documentation/power/freezing-of-tasks.txt
@@ -120,10 +120,10 @@ So in practice, the 'at all' may become a 'why freeze kernel threads?' and
freezing user threads I don't find really objectionable."
Still, there are kernel threads that may want to be freezable. For example, if
-a kernel that belongs to a device driver accesses the device directly, it in
-principle needs to know when the device is suspended, so that it doesn't try to
-access it at that time. However, if the kernel thread is freezable, it will be
-frozen before the driver's .suspend() callback is executed and it will be
+a kernel thread that belongs to a device driver accesses the device directly, it
+in principle needs to know when the device is suspended, so that it doesn't try
+to access it at that time. However, if the kernel thread is freezable, it will
+be frozen before the driver's .suspend() callback is executed and it will be
thawed after the driver's .resume() callback has run, so it won't be accessing
the device while it's suspended.
diff --git a/Documentation/thermal/sysfs-api.txt b/Documentation/thermal/sysfs-api.txt
index b61e46f449aa..1733ab947a95 100644
--- a/Documentation/thermal/sysfs-api.txt
+++ b/Documentation/thermal/sysfs-api.txt
@@ -284,7 +284,7 @@ method, the sys I/F structure will be built like this:
The framework includes a simple notification mechanism, in the form of a
netlink event. Netlink socket initialization is done during the _init_
of the framework. Drivers which intend to use the notification mechanism
-just need to call generate_netlink_event() with two arguments viz
+just need to call thermal_generate_netlink_event() with two arguments viz
(originator, event). Typically the originator will be an integer assigned
to a thermal_zone_device when it registers itself with the framework. The
event will be one of:{THERMAL_AUX0, THERMAL_AUX1, THERMAL_CRITICAL,
diff --git a/MAINTAINERS b/MAINTAINERS
index 89b70df91f4f..260d9c1785d0 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2246,6 +2246,17 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/teigland/dlm.git
S: Supported
F: fs/dlm/
+DMA BUFFER SHARING FRAMEWORK
+M: Sumit Semwal <sumit.semwal@linaro.org>
+S: Maintained
+L: linux-media@vger.kernel.org
+L: dri-devel@lists.freedesktop.org
+L: linaro-mm-sig@lists.linaro.org
+F: drivers/base/dma-buf*
+F: include/linux/dma-buf*
+F: Documentation/dma-buf-sharing.txt
+T: git git://git.linaro.org/people/sumitsemwal/linux-dma-buf.git
+
DMA GENERIC OFFLOAD ENGINE SUBSYSTEM
M: Vinod Koul <vinod.koul@intel.com>
M: Dan Williams <dan.j.williams@intel.com>
@@ -2391,7 +2402,7 @@ F: net/bridge/netfilter/ebt*.c
ECRYPT FILE SYSTEM
M: Tyler Hicks <tyhicks@canonical.com>
-M: Dustin Kirkland <kirkland@canonical.com>
+M: Dustin Kirkland <dustin.kirkland@gazzang.com>
L: ecryptfs@vger.kernel.org
W: https://launchpad.net/ecryptfs
S: Supported
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 40319d91bb7f..1683bfb9166f 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -160,7 +160,6 @@ machine-$(CONFIG_ARCH_MSM) := msm
machine-$(CONFIG_ARCH_MV78XX0) := mv78xx0
machine-$(CONFIG_ARCH_IMX_V4_V5) := imx
machine-$(CONFIG_ARCH_IMX_V6_V7) := imx
-machine-$(CONFIG_ARCH_MX5) := mx5
machine-$(CONFIG_ARCH_MXS) := mxs
machine-$(CONFIG_ARCH_NETX) := netx
machine-$(CONFIG_ARCH_NOMADIK) := nomadik
diff --git a/arch/arm/configs/mx5_defconfig b/arch/arm/configs/imx_v6_v7_defconfig
index d0d8dfece37e..3a4fb2e5fc68 100644
--- a/arch/arm/configs/mx5_defconfig
+++ b/arch/arm/configs/imx_v6_v7_defconfig
@@ -3,6 +3,7 @@ CONFIG_EXPERIMENTAL=y
CONFIG_KERNEL_LZO=y
CONFIG_SYSVIPC=y
CONFIG_LOG_BUF_SHIFT=18
+CONFIG_CGROUPS=y
CONFIG_RELAY=y
CONFIG_EXPERT=y
# CONFIG_SLUB_DEBUG is not set
@@ -14,20 +15,31 @@ CONFIG_MODULE_SRCVERSION_ALL=y
# CONFIG_LBDAF is not set
# CONFIG_BLK_DEV_BSG is not set
CONFIG_ARCH_MXC=y
-CONFIG_ARCH_MX5=y
-CONFIG_MACH_MX51_BABBAGE=y
+CONFIG_MACH_MX31LILLY=y
+CONFIG_MACH_MX31LITE=y
+CONFIG_MACH_PCM037=y
+CONFIG_MACH_PCM037_EET=y
+CONFIG_MACH_MX31_3DS=y
+CONFIG_MACH_MX31MOBOARD=y
+CONFIG_MACH_QONG=y
+CONFIG_MACH_ARMADILLO5X0=y
+CONFIG_MACH_KZM_ARM11_01=y
+CONFIG_MACH_PCM043=y
+CONFIG_MACH_MX35_3DS=y
+CONFIG_MACH_EUKREA_CPUIMX35=y
+CONFIG_MACH_VPR200=y
+CONFIG_MACH_IMX51_DT=y
CONFIG_MACH_MX51_3DS=y
CONFIG_MACH_EUKREA_CPUIMX51=y
CONFIG_MACH_EUKREA_CPUIMX51SD=y
CONFIG_MACH_MX51_EFIKAMX=y
CONFIG_MACH_MX51_EFIKASB=y
-CONFIG_MACH_MX53_EVK=y
-CONFIG_MACH_MX53_SMD=y
-CONFIG_MACH_MX53_LOCO=y
-CONFIG_MACH_MX53_ARD=y
+CONFIG_MACH_IMX53_DT=y
+CONFIG_SOC_IMX6Q=y
CONFIG_MXC_PWM=y
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
+CONFIG_SMP=y
CONFIG_VMSPLIT_2G=y
CONFIG_PREEMPT_VOLUNTARY=y
CONFIG_AEABI=y
@@ -49,7 +61,7 @@ CONFIG_IP_PNP_DHCP=y
# CONFIG_INET_XFRM_MODE_TUNNEL is not set
# CONFIG_INET_XFRM_MODE_BEET is not set
# CONFIG_INET_LRO is not set
-# CONFIG_IPV6 is not set
+CONFIG_IPV6=y
# CONFIG_WIRELESS is not set
CONFIG_DEVTMPFS=y
CONFIG_DEVTMPFS_MOUNT=y
@@ -68,24 +80,20 @@ CONFIG_SCSI_SCAN_ASYNC=y
CONFIG_ATA=y
CONFIG_PATA_IMX=y
CONFIG_NETDEVICES=y
-CONFIG_MII=m
-CONFIG_MARVELL_PHY=y
-CONFIG_DAVICOM_PHY=y
-CONFIG_QSEMI_PHY=y
-CONFIG_LXT_PHY=y
-CONFIG_CICADA_PHY=y
-CONFIG_VITESSE_PHY=y
-CONFIG_SMSC_PHY=y
-CONFIG_BROADCOM_PHY=y
-CONFIG_ICPLUS_PHY=y
-CONFIG_REALTEK_PHY=y
-CONFIG_NATIONAL_PHY=y
-CONFIG_STE10XP=y
-CONFIG_LSI_ET1011C_PHY=y
-CONFIG_MICREL_PHY=y
-CONFIG_NET_ETHERNET=y
-# CONFIG_NETDEV_1000 is not set
-# CONFIG_NETDEV_10000 is not set
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_CHELSIO is not set
+# CONFIG_NET_VENDOR_FARADAY is not set
+CONFIG_FEC=y
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_MICROCHIP is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+CONFIG_SMC91X=y
+CONFIG_SMC911X=y
+CONFIG_SMSC911X=y
+# CONFIG_NET_VENDOR_STMICRO is not set
# CONFIG_WLAN is not set
# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
CONFIG_INPUT_EVDEV=y
@@ -124,7 +132,6 @@ CONFIG_USB_EHCI_HCD=y
CONFIG_USB_EHCI_MXC=y
CONFIG_USB_STORAGE=y
CONFIG_MMC=y
-CONFIG_MMC_BLOCK=m
CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_PLTFM=y
CONFIG_MMC_SDHCI_ESDHC_IMX=y
@@ -133,6 +140,8 @@ CONFIG_LEDS_CLASS=y
CONFIG_RTC_CLASS=y
CONFIG_RTC_INTF_DEV_UIE_EMUL=y
CONFIG_RTC_MXC=y
+CONFIG_DMADEVICES=y
+CONFIG_IMX_SDMA=y
CONFIG_EXT2_FS=y
CONFIG_EXT2_FS_XATTR=y
CONFIG_EXT2_FS_POSIX_ACL=y
diff --git a/arch/arm/configs/mx3_defconfig b/arch/arm/configs/mx3_defconfig
deleted file mode 100644
index cb0717fbb03d..000000000000
--- a/arch/arm/configs/mx3_defconfig
+++ /dev/null
@@ -1,144 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-CONFIG_SYSVIPC=y
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_EXPERT=y
-CONFIG_SLAB=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_MODULE_FORCE_UNLOAD=y
-CONFIG_MODVERSIONS=y
-# CONFIG_BLK_DEV_BSG is not set
-CONFIG_ARCH_MXC=y
-CONFIG_MACH_MX31ADS_WM1133_EV1=y
-CONFIG_MACH_MX31LILLY=y
-CONFIG_MACH_MX31LITE=y
-CONFIG_MACH_PCM037=y
-CONFIG_MACH_PCM037_EET=y
-CONFIG_MACH_MX31_3DS=y
-CONFIG_MACH_MX31MOBOARD=y
-CONFIG_MACH_QONG=y
-CONFIG_MACH_ARMADILLO5X0=y
-CONFIG_MACH_KZM_ARM11_01=y
-CONFIG_MACH_PCM043=y
-CONFIG_MACH_MX35_3DS=y
-CONFIG_MACH_EUKREA_CPUIMX35=y
-CONFIG_MXC_IRQ_PRIOR=y
-CONFIG_MXC_PWM=y
-CONFIG_ARM_ERRATA_411920=y
-CONFIG_NO_HZ=y
-CONFIG_HIGH_RES_TIMERS=y
-CONFIG_PREEMPT=y
-CONFIG_AEABI=y
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="noinitrd console=ttymxc0,115200 root=/dev/mtdblock2 rw ip=off"
-CONFIG_VFP=y
-CONFIG_PM_DEBUG=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET_XFRM_MODE_BEET is not set
-# CONFIG_INET_LRO is not set
-# CONFIG_INET_DIAG is not set
-# CONFIG_IPV6 is not set
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-CONFIG_FW_LOADER=m
-CONFIG_MTD=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-CONFIG_MTD_CFI=y
-CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_NAND=y
-CONFIG_MTD_NAND_MXC=y
-CONFIG_MTD_UBI=y
-# CONFIG_BLK_DEV is not set
-CONFIG_MISC_DEVICES=y
-CONFIG_EEPROM_AT24=y
-CONFIG_NETDEVICES=y
-CONFIG_SMSC_PHY=y
-CONFIG_NET_ETHERNET=y
-CONFIG_SMSC911X=y
-CONFIG_DNET=y
-# CONFIG_NETDEV_1000 is not set
-# CONFIG_NETDEV_10000 is not set
-# CONFIG_INPUT_MOUSEDEV is not set
-# CONFIG_KEYBOARD_ATKBD is not set
-CONFIG_KEYBOARD_IMX=y
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO is not set
-# CONFIG_VT is not set
-# CONFIG_LEGACY_PTYS is not set
-CONFIG_SERIAL_8250=m
-CONFIG_SERIAL_8250_EXTENDED=y
-CONFIG_SERIAL_8250_SHARE_IRQ=y
-CONFIG_SERIAL_IMX=y
-CONFIG_SERIAL_IMX_CONSOLE=y
-# CONFIG_HW_RANDOM is not set
-CONFIG_I2C=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_I2C_IMX=y
-CONFIG_SPI=y
-CONFIG_W1=y
-CONFIG_W1_MASTER_MXC=y
-CONFIG_W1_SLAVE_THERM=y
-# CONFIG_HWMON is not set
-CONFIG_WATCHDOG=y
-CONFIG_IMX2_WDT=y
-CONFIG_MFD_WM8350_I2C=y
-CONFIG_REGULATOR=y
-CONFIG_REGULATOR_WM8350=y
-CONFIG_MEDIA_SUPPORT=y
-CONFIG_VIDEO_DEV=y
-# CONFIG_RC_CORE is not set
-# CONFIG_MEDIA_TUNER_CUSTOMISE is not set
-CONFIG_SOC_CAMERA=y
-CONFIG_SOC_CAMERA_MT9M001=y
-CONFIG_SOC_CAMERA_MT9M111=y
-CONFIG_SOC_CAMERA_MT9T031=y
-CONFIG_SOC_CAMERA_MT9V022=y
-CONFIG_SOC_CAMERA_TW9910=y
-CONFIG_SOC_CAMERA_OV772X=y
-CONFIG_VIDEO_MX3=y
-# CONFIG_RADIO_ADAPTERS is not set
-CONFIG_FB=y
-CONFIG_SOUND=y
-CONFIG_SND=y
-# CONFIG_SND_ARM is not set
-# CONFIG_SND_SPI is not set
-CONFIG_SND_SOC=y
-CONFIG_SND_IMX_SOC=y
-CONFIG_SND_MXC_SOC_WM1133_EV1=y
-CONFIG_SND_SOC_PHYCORE_AC97=y
-CONFIG_SND_SOC_EUKREA_TLV320=y
-CONFIG_USB=y
-CONFIG_USB_EHCI_HCD=y
-CONFIG_USB_EHCI_MXC=y
-CONFIG_USB_GADGET=m
-CONFIG_USB_FSL_USB2=m
-CONFIG_USB_G_SERIAL=m
-CONFIG_USB_ULPI=y
-CONFIG_MMC=y
-CONFIG_MMC_MXC=y
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_MXC=y
-CONFIG_DMADEVICES=y
-# CONFIG_DNOTIFY is not set
-CONFIG_TMPFS=y
-CONFIG_JFFS2_FS=y
-CONFIG_UBIFS_FS=y
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-CONFIG_NFS_V4=y
-CONFIG_ROOT_NFS=y
-# CONFIG_ENABLE_WARN_DEPRECATED is not set
-# CONFIG_ENABLE_MUST_CHECK is not set
-CONFIG_SYSCTL_SYSCALL_CHECK=y
-# CONFIG_CRYPTO_ANSI_CPRNG is not set
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index 0e6de366c648..09f357bcecde 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -22,6 +22,18 @@ config ARCH_MX25
config MACH_MX27
bool
+config ARCH_MX5
+ bool
+
+config ARCH_MX50
+ bool
+
+config ARCH_MX51
+ bool
+
+config ARCH_MX53
+ bool
+
config SOC_IMX1
bool
select ARCH_MX1
@@ -73,6 +85,32 @@ config SOC_IMX35
select MXC_AVIC
select SMP_ON_UP if SMP
+config SOC_IMX5
+ select CPU_V7
+ select ARM_L1_CACHE_SHIFT_6
+ select MXC_TZIC
+ select ARCH_MXC_IOMUX_V3
+ select ARCH_MXC_AUDMUX_V2
+ select ARCH_HAS_CPUFREQ
+ select ARCH_MX5
+ bool
+
+config SOC_IMX50
+ bool
+ select SOC_IMX5
+ select ARCH_MX50
+
+config SOC_IMX51
+ bool
+ select SOC_IMX5
+ select ARCH_MX5
+ select ARCH_MX51
+
+config SOC_IMX53
+ bool
+ select SOC_IMX5
+ select ARCH_MX5
+ select ARCH_MX53
if ARCH_IMX_V4_V5
@@ -592,6 +630,207 @@ config MACH_VPR200
Include support for VPR200 platform. This includes specific
configurations for the board and its peripherals.
+comment "i.MX5 platforms:"
+
+config MACH_MX50_RDP
+ bool "Support MX50 reference design platform"
+ depends on BROKEN
+ select SOC_IMX50
+ select IMX_HAVE_PLATFORM_IMX_I2C
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
+ select IMX_HAVE_PLATFORM_SPI_IMX
+ help
+ Include support for MX50 reference design platform (RDP) board. This
+ includes specific configurations for the board and its peripherals.
+
+comment "i.MX51 machines:"
+
+config MACH_IMX51_DT
+ bool "Support i.MX51 platforms from device tree"
+ select SOC_IMX51
+ select USE_OF
+ select MACH_MX51_BABBAGE
+ help
+ Include support for Freescale i.MX51 based platforms
+ using the device tree for discovery
+
+config MACH_MX51_BABBAGE
+ bool "Support MX51 BABBAGE platforms"
+ select SOC_IMX51
+ select IMX_HAVE_PLATFORM_FSL_USB2_UDC
+ select IMX_HAVE_PLATFORM_IMX2_WDT
+ select IMX_HAVE_PLATFORM_IMX_I2C
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_MXC_EHCI
+ select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
+ select IMX_HAVE_PLATFORM_SPI_IMX
+ help
+ Include support for MX51 Babbage platform, also known as MX51EVK in
+ u-boot. This includes specific configurations for the board and its
+ peripherals.
+
+config MACH_MX51_3DS
+ bool "Support MX51PDK (3DS)"
+ select SOC_IMX51
+ select IMX_HAVE_PLATFORM_IMX2_WDT
+ select IMX_HAVE_PLATFORM_IMX_KEYPAD
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
+ select IMX_HAVE_PLATFORM_SPI_IMX
+ select MXC_DEBUG_BOARD
+ help
+ Include support for MX51PDK (3DS) platform. This includes specific
+ configurations for the board and its peripherals.
+
+config MACH_EUKREA_CPUIMX51
+ bool "Support Eukrea CPUIMX51 module"
+ select SOC_IMX51
+ select IMX_HAVE_PLATFORM_FSL_USB2_UDC
+ select IMX_HAVE_PLATFORM_IMX_I2C
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_MXC_EHCI
+ select IMX_HAVE_PLATFORM_MXC_NAND
+ select IMX_HAVE_PLATFORM_SPI_IMX
+ help
+ Include support for Eukrea CPUIMX51 platform. This includes
+ specific configurations for the module and its peripherals.
+
+choice
+ prompt "Baseboard"
+ depends on MACH_EUKREA_CPUIMX51
+ default MACH_EUKREA_MBIMX51_BASEBOARD
+
+config MACH_EUKREA_MBIMX51_BASEBOARD
+ prompt "Eukrea MBIMX51 development board"
+ bool
+ select IMX_HAVE_PLATFORM_IMX_KEYPAD
+ select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
+ select LEDS_GPIO_REGISTER
+ help
+ This adds board specific devices that can be found on Eukrea's
+ MBIMX51 evaluation board.
+
+endchoice
+
+config MACH_EUKREA_CPUIMX51SD
+ bool "Support Eukrea CPUIMX51SD module"
+ select SOC_IMX51
+ select IMX_HAVE_PLATFORM_FSL_USB2_UDC
+ select IMX_HAVE_PLATFORM_IMX_I2C
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_MXC_EHCI
+ select IMX_HAVE_PLATFORM_MXC_NAND
+ select IMX_HAVE_PLATFORM_SPI_IMX
+ help
+ Include support for Eukrea CPUIMX51SD platform. This includes
+ specific configurations for the module and its peripherals.
+
+choice
+ prompt "Baseboard"
+ depends on MACH_EUKREA_CPUIMX51SD
+ default MACH_EUKREA_MBIMXSD51_BASEBOARD
+
+config MACH_EUKREA_MBIMXSD51_BASEBOARD
+ prompt "Eukrea MBIMXSD development board"
+ bool
+ select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
+ select LEDS_GPIO_REGISTER
+ help
+ This adds board specific devices that can be found on Eukrea's
+ MBIMXSD evaluation board.
+
+endchoice
+
+config MX51_EFIKA_COMMON
+ bool
+ select SOC_IMX51
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_MXC_EHCI
+ select IMX_HAVE_PLATFORM_PATA_IMX
+ select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
+ select IMX_HAVE_PLATFORM_SPI_IMX
+ select MXC_ULPI if USB_ULPI
+
+config MACH_MX51_EFIKAMX
+ bool "Support MX51 Genesi Efika MX nettop"
+ select LEDS_GPIO_REGISTER
+ select MX51_EFIKA_COMMON
+ help
+ Include support for Genesi Efika MX nettop. This includes specific
+ configurations for the board and its peripherals.
+
+config MACH_MX51_EFIKASB
+ bool "Support MX51 Genesi Efika Smartbook"
+ select LEDS_GPIO_REGISTER
+ select MX51_EFIKA_COMMON
+ help
+ Include support for Genesi Efika Smartbook. This includes specific
+ configurations for the board and its peripherals.
+
+comment "i.MX53 machines:"
+
+config MACH_IMX53_DT
+ bool "Support i.MX53 platforms from device tree"
+ select SOC_IMX53
+ select USE_OF
+ select MACH_MX53_ARD
+ select MACH_MX53_EVK
+ select MACH_MX53_LOCO
+ select MACH_MX53_SMD
+ help
+ Include support for Freescale i.MX53 based platforms
+ using the device tree for discovery
+
+config MACH_MX53_EVK
+ bool "Support MX53 EVK platforms"
+ select SOC_IMX53
+ select IMX_HAVE_PLATFORM_IMX2_WDT
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_IMX_I2C
+ select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
+ select IMX_HAVE_PLATFORM_SPI_IMX
+ select LEDS_GPIO_REGISTER
+ help
+ Include support for MX53 EVK platform. This includes specific
+ configurations for the board and its peripherals.
+
+config MACH_MX53_SMD
+ bool "Support MX53 SMD platforms"
+ select SOC_IMX53
+ select IMX_HAVE_PLATFORM_IMX2_WDT
+ select IMX_HAVE_PLATFORM_IMX_I2C
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
+ help
+ Include support for MX53 SMD platform. This includes specific
+ configurations for the board and its peripherals.
+
+config MACH_MX53_LOCO
+ bool "Support MX53 LOCO platforms"
+ select SOC_IMX53
+ select IMX_HAVE_PLATFORM_IMX2_WDT
+ select IMX_HAVE_PLATFORM_IMX_I2C
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
+ select IMX_HAVE_PLATFORM_GPIO_KEYS
+ select LEDS_GPIO_REGISTER
+ help
+ Include support for MX53 LOCO platform. This includes specific
+ configurations for the board and its peripherals.
+
+config MACH_MX53_ARD
+ bool "Support MX53 ARD platforms"
+ select SOC_IMX53
+ select IMX_HAVE_PLATFORM_IMX2_WDT
+ select IMX_HAVE_PLATFORM_IMX_I2C
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
+ select IMX_HAVE_PLATFORM_GPIO_KEYS
+ help
+ Include support for MX53 ARD platform. This includes specific
+ configurations for the board and its peripherals.
+
comment "i.MX6 family:"
config SOC_IMX6Q
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index f5920c24f7d7..55db9c488f2b 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -11,6 +11,8 @@ obj-$(CONFIG_SOC_IMX27) += clock-imx27.o mm-imx27.o ehci-imx27.o
obj-$(CONFIG_SOC_IMX31) += mm-imx3.o cpu-imx31.o clock-imx31.o iomux-imx31.o ehci-imx31.o
obj-$(CONFIG_SOC_IMX35) += mm-imx3.o cpu-imx35.o clock-imx35.o ehci-imx35.o
+obj-$(CONFIG_SOC_IMX5) += cpu-imx5.o mm-imx5.o clock-mx51-mx53.o ehci-imx5.o pm-imx5.o cpu_op-mx51.o
+
# Support for CMOS sensor interface
obj-$(CONFIG_MX1_VIDEO) += mx1-camera-fiq.o mx1-camera-fiq-ksym.o
@@ -75,3 +77,22 @@ obj-$(CONFIG_SOC_IMX6Q) += clock-imx6q.o mach-imx6q.o
ifeq ($(CONFIG_PM),y)
obj-$(CONFIG_SOC_IMX6Q) += pm-imx6q.o
endif
+
+# i.MX5 based machines
+obj-$(CONFIG_MACH_MX51_BABBAGE) += mach-mx51_babbage.o
+obj-$(CONFIG_MACH_MX51_3DS) += mach-mx51_3ds.o
+obj-$(CONFIG_MACH_MX53_EVK) += mach-mx53_evk.o
+obj-$(CONFIG_MACH_MX53_SMD) += mach-mx53_smd.o
+obj-$(CONFIG_MACH_MX53_LOCO) += mach-mx53_loco.o
+obj-$(CONFIG_MACH_MX53_ARD) += mach-mx53_ard.o
+obj-$(CONFIG_MACH_EUKREA_CPUIMX51) += mach-cpuimx51.o
+obj-$(CONFIG_MACH_EUKREA_MBIMX51_BASEBOARD) += eukrea_mbimx51-baseboard.o
+obj-$(CONFIG_MACH_EUKREA_CPUIMX51SD) += mach-cpuimx51sd.o
+obj-$(CONFIG_MACH_EUKREA_MBIMXSD51_BASEBOARD) += eukrea_mbimxsd-baseboard.o
+obj-$(CONFIG_MX51_EFIKA_COMMON) += mx51_efika.o
+obj-$(CONFIG_MACH_MX51_EFIKAMX) += mach-mx51_efikamx.o
+obj-$(CONFIG_MACH_MX51_EFIKASB) += mach-mx51_efikasb.o
+obj-$(CONFIG_MACH_MX50_RDP) += mach-mx50_rdp.o
+
+obj-$(CONFIG_MACH_IMX51_DT) += imx51-dt.o
+obj-$(CONFIG_MACH_IMX53_DT) += imx53-dt.o
diff --git a/arch/arm/mach-imx/Makefile.boot b/arch/arm/mach-imx/Makefile.boot
index 5f4d06af4912..6dfdbcc83afd 100644
--- a/arch/arm/mach-imx/Makefile.boot
+++ b/arch/arm/mach-imx/Makefile.boot
@@ -22,6 +22,18 @@ zreladdr-$(CONFIG_SOC_IMX35) += 0x80008000
params_phys-$(CONFIG_SOC_IMX35) := 0x80000100
initrd_phys-$(CONFIG_SOC_IMX35) := 0x80800000
+zreladdr-$(CONFIG_SOC_IMX50) += 0x70008000
+params_phys-$(CONFIG_SOC_IMX50) := 0x70000100
+initrd_phys-$(CONFIG_SOC_IMX50) := 0x70800000
+
+zreladdr-$(CONFIG_SOC_IMX51) += 0x90008000
+params_phys-$(CONFIG_SOC_IMX51) := 0x90000100
+initrd_phys-$(CONFIG_SOC_IMX51) := 0x90800000
+
+zreladdr-$(CONFIG_SOC_IMX53) += 0x70008000
+params_phys-$(CONFIG_SOC_IMX53) := 0x70000100
+initrd_phys-$(CONFIG_SOC_IMX53) := 0x70800000
+
zreladdr-$(CONFIG_SOC_IMX6Q) += 0x10008000
params_phys-$(CONFIG_SOC_IMX6Q) := 0x10000100
initrd_phys-$(CONFIG_SOC_IMX6Q) := 0x10800000
diff --git a/arch/arm/mach-mx5/clock-mx51-mx53.c b/arch/arm/mach-imx/clock-mx51-mx53.c
index 4cb276977190..08470504a088 100644
--- a/arch/arm/mach-mx5/clock-mx51-mx53.c
+++ b/arch/arm/mach-imx/clock-mx51-mx53.c
@@ -23,7 +23,7 @@
#include <mach/common.h>
#include <mach/clock.h>
-#include "crm_regs.h"
+#include "crm-regs-imx5.h"
/* External clock values passed-in by the board code */
static unsigned long external_high_reference, external_low_reference;
diff --git a/arch/arm/mach-mx5/cpu.c b/arch/arm/mach-imx/cpu-imx5.c
index 5e2e7a843860..5e2e7a843860 100644
--- a/arch/arm/mach-mx5/cpu.c
+++ b/arch/arm/mach-imx/cpu-imx5.c
diff --git a/arch/arm/mach-mx5/cpu_op-mx51.c b/arch/arm/mach-imx/cpu_op-mx51.c
index 9d34c3d4c024..9d34c3d4c024 100644
--- a/arch/arm/mach-mx5/cpu_op-mx51.c
+++ b/arch/arm/mach-imx/cpu_op-mx51.c
diff --git a/arch/arm/mach-mx5/cpu_op-mx51.h b/arch/arm/mach-imx/cpu_op-mx51.h
index 97477fecb469..97477fecb469 100644
--- a/arch/arm/mach-mx5/cpu_op-mx51.h
+++ b/arch/arm/mach-imx/cpu_op-mx51.h
diff --git a/arch/arm/mach-mx5/crm_regs.h b/arch/arm/mach-imx/crm-regs-imx5.h
index 5e11ba7daee2..5e11ba7daee2 100644
--- a/arch/arm/mach-mx5/crm_regs.h
+++ b/arch/arm/mach-imx/crm-regs-imx5.h
diff --git a/arch/arm/mach-mx5/devices-imx50.h b/arch/arm/mach-imx/devices-imx50.h
index 7216667eaafc..7216667eaafc 100644
--- a/arch/arm/mach-mx5/devices-imx50.h
+++ b/arch/arm/mach-imx/devices-imx50.h
diff --git a/arch/arm/mach-mx5/devices-imx51.h b/arch/arm/mach-imx/devices-imx51.h
index af488bc0e225..af488bc0e225 100644
--- a/arch/arm/mach-mx5/devices-imx51.h
+++ b/arch/arm/mach-imx/devices-imx51.h
diff --git a/arch/arm/mach-mx5/devices-imx53.h b/arch/arm/mach-imx/devices-imx53.h
index 6e1e5d1f8c3a..6e1e5d1f8c3a 100644
--- a/arch/arm/mach-mx5/devices-imx53.h
+++ b/arch/arm/mach-imx/devices-imx53.h
diff --git a/arch/arm/mach-mx5/efika.h b/arch/arm/mach-imx/efika.h
index 014aa985faae..014aa985faae 100644
--- a/arch/arm/mach-mx5/efika.h
+++ b/arch/arm/mach-imx/efika.h
diff --git a/arch/arm/mach-mx5/ehci.c b/arch/arm/mach-imx/ehci-imx5.c
index c17fa131728b..c17fa131728b 100644
--- a/arch/arm/mach-mx5/ehci.c
+++ b/arch/arm/mach-imx/ehci-imx5.c
diff --git a/arch/arm/mach-mx5/eukrea_mbimx51-baseboard.c b/arch/arm/mach-imx/eukrea_mbimx51-baseboard.c
index a6a3ab8f1b1c..a6a3ab8f1b1c 100644
--- a/arch/arm/mach-mx5/eukrea_mbimx51-baseboard.c
+++ b/arch/arm/mach-imx/eukrea_mbimx51-baseboard.c
diff --git a/arch/arm/mach-mx5/eukrea_mbimxsd-baseboard.c b/arch/arm/mach-imx/eukrea_mbimxsd-baseboard.c
index d817fc80b986..d817fc80b986 100644
--- a/arch/arm/mach-mx5/eukrea_mbimxsd-baseboard.c
+++ b/arch/arm/mach-imx/eukrea_mbimxsd-baseboard.c
diff --git a/arch/arm/mach-mx5/imx51-dt.c b/arch/arm/mach-imx/imx51-dt.c
index e6bad17b908c..e6bad17b908c 100644
--- a/arch/arm/mach-mx5/imx51-dt.c
+++ b/arch/arm/mach-imx/imx51-dt.c
diff --git a/arch/arm/mach-mx5/imx53-dt.c b/arch/arm/mach-imx/imx53-dt.c
index 05ebb3e68679..05ebb3e68679 100644
--- a/arch/arm/mach-mx5/imx53-dt.c
+++ b/arch/arm/mach-imx/imx53-dt.c
diff --git a/arch/arm/mach-mx5/board-cpuimx51.c b/arch/arm/mach-imx/mach-cpuimx51.c
index 944025da8333..944025da8333 100644
--- a/arch/arm/mach-mx5/board-cpuimx51.c
+++ b/arch/arm/mach-imx/mach-cpuimx51.c
diff --git a/arch/arm/mach-mx5/board-cpuimx51sd.c b/arch/arm/mach-imx/mach-cpuimx51sd.c
index 9fbe923c8b08..9fbe923c8b08 100644
--- a/arch/arm/mach-mx5/board-cpuimx51sd.c
+++ b/arch/arm/mach-imx/mach-cpuimx51sd.c
diff --git a/arch/arm/mach-mx5/board-mx50_rdp.c b/arch/arm/mach-imx/mach-mx50_rdp.c
index 42b66e8d9615..42b66e8d9615 100644
--- a/arch/arm/mach-mx5/board-mx50_rdp.c
+++ b/arch/arm/mach-imx/mach-mx50_rdp.c
diff --git a/arch/arm/mach-mx5/board-mx51_3ds.c b/arch/arm/mach-imx/mach-mx51_3ds.c
index 83eab4176ca4..83eab4176ca4 100644
--- a/arch/arm/mach-mx5/board-mx51_3ds.c
+++ b/arch/arm/mach-imx/mach-mx51_3ds.c
diff --git a/arch/arm/mach-mx5/board-mx51_babbage.c b/arch/arm/mach-imx/mach-mx51_babbage.c
index e4b822e9f719..e4b822e9f719 100644
--- a/arch/arm/mach-mx5/board-mx51_babbage.c
+++ b/arch/arm/mach-imx/mach-mx51_babbage.c
diff --git a/arch/arm/mach-mx5/board-mx51_efikamx.c b/arch/arm/mach-imx/mach-mx51_efikamx.c
index 3a5ed2dd885a..3a5ed2dd885a 100644
--- a/arch/arm/mach-mx5/board-mx51_efikamx.c
+++ b/arch/arm/mach-imx/mach-mx51_efikamx.c
diff --git a/arch/arm/mach-mx5/board-mx51_efikasb.c b/arch/arm/mach-imx/mach-mx51_efikasb.c
index ea5f65b0381a..ea5f65b0381a 100644
--- a/arch/arm/mach-mx5/board-mx51_efikasb.c
+++ b/arch/arm/mach-imx/mach-mx51_efikasb.c
diff --git a/arch/arm/mach-mx5/board-mx53_ard.c b/arch/arm/mach-imx/mach-mx53_ard.c
index 5f224f1c3eb6..08dfb7628d2d 100644
--- a/arch/arm/mach-mx5/board-mx53_ard.c
+++ b/arch/arm/mach-imx/mach-mx53_ard.c
@@ -32,7 +32,6 @@
#include <asm/mach/arch.h>
#include <asm/mach/time.h>
-#include "crm_regs.h"
#include "devices-imx53.h"
#define ARD_ETHERNET_INT_B IMX_GPIO_NR(2, 31)
diff --git a/arch/arm/mach-mx5/board-mx53_evk.c b/arch/arm/mach-imx/mach-mx53_evk.c
index d6ce137896d6..5a72188b9cdb 100644
--- a/arch/arm/mach-mx5/board-mx53_evk.c
+++ b/arch/arm/mach-imx/mach-mx53_evk.c
@@ -37,7 +37,6 @@
#define EVK_ECSPI1_CS1 IMX_GPIO_NR(3, 19)
#define MX53EVK_LED IMX_GPIO_NR(7, 7)
-#include "crm_regs.h"
#include "devices-imx53.h"
static iomux_v3_cfg_t mx53_evk_pads[] = {
diff --git a/arch/arm/mach-mx5/board-mx53_loco.c b/arch/arm/mach-imx/mach-mx53_loco.c
index fd8b524e1c58..37f67cac15a4 100644
--- a/arch/arm/mach-mx5/board-mx53_loco.c
+++ b/arch/arm/mach-imx/mach-mx53_loco.c
@@ -32,7 +32,6 @@
#include <asm/mach/arch.h>
#include <asm/mach/time.h>
-#include "crm_regs.h"
#include "devices-imx53.h"
#define MX53_LOCO_POWER IMX_GPIO_NR(1, 8)
diff --git a/arch/arm/mach-mx5/board-mx53_smd.c b/arch/arm/mach-imx/mach-mx53_smd.c
index 22c53c9b18aa..8e972c5c3e13 100644
--- a/arch/arm/mach-mx5/board-mx53_smd.c
+++ b/arch/arm/mach-imx/mach-mx53_smd.c
@@ -31,7 +31,6 @@
#include <asm/mach/arch.h>
#include <asm/mach/time.h>
-#include "crm_regs.h"
#include "devices-imx53.h"
#define SMD_FEC_PHY_RST IMX_GPIO_NR(7, 6)
diff --git a/arch/arm/mach-mx5/mm.c b/arch/arm/mach-imx/mm-imx5.c
index bc17dfea3817..bc17dfea3817 100644
--- a/arch/arm/mach-mx5/mm.c
+++ b/arch/arm/mach-imx/mm-imx5.c
diff --git a/arch/arm/mach-mx5/mx51_efika.c b/arch/arm/mach-imx/mx51_efika.c
index ec6ca91b299b..ec6ca91b299b 100644
--- a/arch/arm/mach-mx5/mx51_efika.c
+++ b/arch/arm/mach-imx/mx51_efika.c
diff --git a/arch/arm/mach-mx5/system.c b/arch/arm/mach-imx/pm-imx5.c
index 5eebfaad1226..6dc093448057 100644
--- a/arch/arm/mach-mx5/system.c
+++ b/arch/arm/mach-imx/pm-imx5.c
@@ -1,8 +1,6 @@
/*
- * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
- */
-
-/*
+ * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
* The code contained herein is licensed under the GNU General Public
* License. You may obtain a copy of the GNU General Public License
* Version 2 or later at the following locations:
@@ -10,14 +8,22 @@
* http://www.opensource.org/licenses/gpl-license.html
* http://www.gnu.org/copyleft/gpl.html
*/
-#include <linux/platform_device.h>
+#include <linux/suspend.h>
+#include <linux/clk.h>
#include <linux/io.h>
-#include <mach/hardware.h>
+#include <linux/err.h>
+#include <asm/cacheflush.h>
+#include <asm/tlbflush.h>
#include <mach/common.h>
-#include "crm_regs.h"
+#include <mach/hardware.h>
+#include "crm-regs-imx5.h"
+
+static struct clk *gpc_dvfs_clk;
-/* set cpu low power mode before WFI instruction. This function is called
- * mx5 because it can be used for mx50, mx51, and mx53.*/
+/*
+ * set cpu low power mode before WFI instruction. This function is called
+ * mx5 because it can be used for mx50, mx51, and mx53.
+ */
void mx5_cpu_lp_set(enum mxc_cpu_pwr_mode mode)
{
u32 plat_lpc, arm_srpgcr, ccm_clpcr;
@@ -80,3 +86,68 @@ void mx5_cpu_lp_set(enum mxc_cpu_pwr_mode mode)
__raw_writel(empgc1, MXC_SRPG_EMPGC1_SRPGCR);
}
}
+
+static int mx5_suspend_prepare(void)
+{
+ return clk_enable(gpc_dvfs_clk);
+}
+
+static int mx5_suspend_enter(suspend_state_t state)
+{
+ switch (state) {
+ case PM_SUSPEND_MEM:
+ mx5_cpu_lp_set(STOP_POWER_OFF);
+ break;
+ case PM_SUSPEND_STANDBY:
+ mx5_cpu_lp_set(WAIT_UNCLOCKED_POWER_OFF);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (state == PM_SUSPEND_MEM) {
+ local_flush_tlb_all();
+ flush_cache_all();
+
+ /*clear the EMPGC0/1 bits */
+ __raw_writel(0, MXC_SRPG_EMPGC0_SRPGCR);
+ __raw_writel(0, MXC_SRPG_EMPGC1_SRPGCR);
+ }
+ cpu_do_idle();
+ return 0;
+}
+
+static void mx5_suspend_finish(void)
+{
+ clk_disable(gpc_dvfs_clk);
+}
+
+static int mx5_pm_valid(suspend_state_t state)
+{
+ return (state > PM_SUSPEND_ON && state <= PM_SUSPEND_MAX);
+}
+
+static const struct platform_suspend_ops mx5_suspend_ops = {
+ .valid = mx5_pm_valid,
+ .prepare = mx5_suspend_prepare,
+ .enter = mx5_suspend_enter,
+ .finish = mx5_suspend_finish,
+};
+
+static int __init mx5_pm_init(void)
+{
+ if (!cpu_is_mx51() && !cpu_is_mx53())
+ return 0;
+
+ if (gpc_dvfs_clk == NULL)
+ gpc_dvfs_clk = clk_get(NULL, "gpc_dvfs");
+
+ if (!IS_ERR(gpc_dvfs_clk)) {
+ if (cpu_is_mx51())
+ suspend_set_ops(&mx5_suspend_ops);
+ } else
+ return -EPERM;
+
+ return 0;
+}
+device_initcall(mx5_pm_init);
diff --git a/arch/arm/mach-mx5/Kconfig b/arch/arm/mach-mx5/Kconfig
deleted file mode 100644
index af0c212e3c7b..000000000000
--- a/arch/arm/mach-mx5/Kconfig
+++ /dev/null
@@ -1,244 +0,0 @@
-if ARCH_MX5
-
-# ARCH_MX5/50/53 are left to mark places where prevent multi-soc in single
-# image. So for most time, SOC_IMX50/51/53 should be used.
-
-config ARCH_MX51
- bool
-
-config ARCH_MX50
- bool
-
-config ARCH_MX53
- bool
-
-config SOC_IMX50
- bool
- select CPU_V7
- select ARM_L1_CACHE_SHIFT_6
- select MXC_TZIC
- select ARCH_MXC_IOMUX_V3
- select ARCH_MXC_AUDMUX_V2
- select ARCH_HAS_CPUFREQ
- select ARCH_MX50
-
-config SOC_IMX51
- bool
- select CPU_V7
- select ARM_L1_CACHE_SHIFT_6
- select MXC_TZIC
- select ARCH_MXC_IOMUX_V3
- select ARCH_MXC_AUDMUX_V2
- select ARCH_HAS_CPUFREQ
- select ARCH_MX51
-
-config SOC_IMX53
- bool
- select CPU_V7
- select ARM_L1_CACHE_SHIFT_6
- select MXC_TZIC
- select ARCH_MXC_IOMUX_V3
- select ARCH_MX53
-
-#comment "i.MX50 machines:"
-
-config MACH_MX50_RDP
- bool "Support MX50 reference design platform"
- depends on BROKEN
- select SOC_IMX50
- select IMX_HAVE_PLATFORM_IMX_I2C
- select IMX_HAVE_PLATFORM_IMX_UART
- select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
- select IMX_HAVE_PLATFORM_SPI_IMX
- help
- Include support for MX50 reference design platform (RDP) board. This
- includes specific configurations for the board and its peripherals.
-
-comment "i.MX51 machines:"
-
-config MACH_IMX51_DT
- bool "Support i.MX51 platforms from device tree"
- select SOC_IMX51
- select USE_OF
- select MACH_MX51_BABBAGE
- help
- Include support for Freescale i.MX51 based platforms
- using the device tree for discovery
-
-config MACH_MX51_BABBAGE
- bool "Support MX51 BABBAGE platforms"
- select SOC_IMX51
- select IMX_HAVE_PLATFORM_FSL_USB2_UDC
- select IMX_HAVE_PLATFORM_IMX2_WDT
- select IMX_HAVE_PLATFORM_IMX_I2C
- select IMX_HAVE_PLATFORM_IMX_UART
- select IMX_HAVE_PLATFORM_MXC_EHCI
- select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
- select IMX_HAVE_PLATFORM_SPI_IMX
- help
- Include support for MX51 Babbage platform, also known as MX51EVK in
- u-boot. This includes specific configurations for the board and its
- peripherals.
-
-config MACH_MX51_3DS
- bool "Support MX51PDK (3DS)"
- select SOC_IMX51
- select IMX_HAVE_PLATFORM_IMX2_WDT
- select IMX_HAVE_PLATFORM_IMX_KEYPAD
- select IMX_HAVE_PLATFORM_IMX_UART
- select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
- select IMX_HAVE_PLATFORM_SPI_IMX
- select MXC_DEBUG_BOARD
- help
- Include support for MX51PDK (3DS) platform. This includes specific
- configurations for the board and its peripherals.
-
-config MACH_EUKREA_CPUIMX51
- bool "Support Eukrea CPUIMX51 module"
- select SOC_IMX51
- select IMX_HAVE_PLATFORM_FSL_USB2_UDC
- select IMX_HAVE_PLATFORM_IMX_I2C
- select IMX_HAVE_PLATFORM_IMX_UART
- select IMX_HAVE_PLATFORM_MXC_EHCI
- select IMX_HAVE_PLATFORM_MXC_NAND
- select IMX_HAVE_PLATFORM_SPI_IMX
- help
- Include support for Eukrea CPUIMX51 platform. This includes
- specific configurations for the module and its peripherals.
-
-choice
- prompt "Baseboard"
- depends on MACH_EUKREA_CPUIMX51
- default MACH_EUKREA_MBIMX51_BASEBOARD
-
-config MACH_EUKREA_MBIMX51_BASEBOARD
- prompt "Eukrea MBIMX51 development board"
- bool
- select IMX_HAVE_PLATFORM_IMX_KEYPAD
- select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
- select LEDS_GPIO_REGISTER
- help
- This adds board specific devices that can be found on Eukrea's
- MBIMX51 evaluation board.
-
-endchoice
-
-config MACH_EUKREA_CPUIMX51SD
- bool "Support Eukrea CPUIMX51SD module"
- select SOC_IMX51
- select IMX_HAVE_PLATFORM_FSL_USB2_UDC
- select IMX_HAVE_PLATFORM_IMX_I2C
- select IMX_HAVE_PLATFORM_IMX_UART
- select IMX_HAVE_PLATFORM_MXC_EHCI
- select IMX_HAVE_PLATFORM_MXC_NAND
- select IMX_HAVE_PLATFORM_SPI_IMX
- help
- Include support for Eukrea CPUIMX51SD platform. This includes
- specific configurations for the module and its peripherals.
-
-choice
- prompt "Baseboard"
- depends on MACH_EUKREA_CPUIMX51SD
- default MACH_EUKREA_MBIMXSD51_BASEBOARD
-
-config MACH_EUKREA_MBIMXSD51_BASEBOARD
- prompt "Eukrea MBIMXSD development board"
- bool
- select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
- select LEDS_GPIO_REGISTER
- help
- This adds board specific devices that can be found on Eukrea's
- MBIMXSD evaluation board.
-
-endchoice
-
-config MX51_EFIKA_COMMON
- bool
- select SOC_IMX51
- select IMX_HAVE_PLATFORM_IMX_UART
- select IMX_HAVE_PLATFORM_MXC_EHCI
- select IMX_HAVE_PLATFORM_PATA_IMX
- select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
- select IMX_HAVE_PLATFORM_SPI_IMX
- select MXC_ULPI if USB_ULPI
-
-config MACH_MX51_EFIKAMX
- bool "Support MX51 Genesi Efika MX nettop"
- select LEDS_GPIO_REGISTER
- select MX51_EFIKA_COMMON
- help
- Include support for Genesi Efika MX nettop. This includes specific
- configurations for the board and its peripherals.
-
-config MACH_MX51_EFIKASB
- bool "Support MX51 Genesi Efika Smartbook"
- select LEDS_GPIO_REGISTER
- select MX51_EFIKA_COMMON
- help
- Include support for Genesi Efika Smartbook. This includes specific
- configurations for the board and its peripherals.
-
-comment "i.MX53 machines:"
-
-config MACH_IMX53_DT
- bool "Support i.MX53 platforms from device tree"
- select SOC_IMX53
- select USE_OF
- select MACH_MX53_ARD
- select MACH_MX53_EVK
- select MACH_MX53_LOCO
- select MACH_MX53_SMD
- help
- Include support for Freescale i.MX53 based platforms
- using the device tree for discovery
-
-config MACH_MX53_EVK
- bool "Support MX53 EVK platforms"
- select SOC_IMX53
- select IMX_HAVE_PLATFORM_IMX2_WDT
- select IMX_HAVE_PLATFORM_IMX_UART
- select IMX_HAVE_PLATFORM_IMX_I2C
- select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
- select IMX_HAVE_PLATFORM_SPI_IMX
- select LEDS_GPIO_REGISTER
- help
- Include support for MX53 EVK platform. This includes specific
- configurations for the board and its peripherals.
-
-config MACH_MX53_SMD
- bool "Support MX53 SMD platforms"
- select SOC_IMX53
- select IMX_HAVE_PLATFORM_IMX2_WDT
- select IMX_HAVE_PLATFORM_IMX_I2C
- select IMX_HAVE_PLATFORM_IMX_UART
- select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
- help
- Include support for MX53 SMD platform. This includes specific
- configurations for the board and its peripherals.
-
-config MACH_MX53_LOCO
- bool "Support MX53 LOCO platforms"
- select SOC_IMX53
- select IMX_HAVE_PLATFORM_IMX2_WDT
- select IMX_HAVE_PLATFORM_IMX_I2C
- select IMX_HAVE_PLATFORM_IMX_UART
- select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
- select IMX_HAVE_PLATFORM_GPIO_KEYS
- select LEDS_GPIO_REGISTER
- help
- Include support for MX53 LOCO platform. This includes specific
- configurations for the board and its peripherals.
-
-config MACH_MX53_ARD
- bool "Support MX53 ARD platforms"
- select SOC_IMX53
- select IMX_HAVE_PLATFORM_IMX2_WDT
- select IMX_HAVE_PLATFORM_IMX_I2C
- select IMX_HAVE_PLATFORM_IMX_UART
- select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
- select IMX_HAVE_PLATFORM_GPIO_KEYS
- help
- Include support for MX53 ARD platform. This includes specific
- configurations for the board and its peripherals.
-
-endif
diff --git a/arch/arm/mach-mx5/Makefile b/arch/arm/mach-mx5/Makefile
deleted file mode 100644
index 0fc60807fa2b..000000000000
--- a/arch/arm/mach-mx5/Makefile
+++ /dev/null
@@ -1,26 +0,0 @@
-#
-# Makefile for the linux kernel.
-#
-
-# Object file lists.
-obj-y := cpu.o mm.o clock-mx51-mx53.o ehci.o system.o
-
-obj-$(CONFIG_PM) += pm-imx5.o
-obj-$(CONFIG_CPU_FREQ_IMX) += cpu_op-mx51.o
-obj-$(CONFIG_MACH_MX51_BABBAGE) += board-mx51_babbage.o
-obj-$(CONFIG_MACH_MX51_3DS) += board-mx51_3ds.o
-obj-$(CONFIG_MACH_MX53_EVK) += board-mx53_evk.o
-obj-$(CONFIG_MACH_MX53_SMD) += board-mx53_smd.o
-obj-$(CONFIG_MACH_MX53_LOCO) += board-mx53_loco.o
-obj-$(CONFIG_MACH_MX53_ARD) += board-mx53_ard.o
-obj-$(CONFIG_MACH_EUKREA_CPUIMX51) += board-cpuimx51.o
-obj-$(CONFIG_MACH_EUKREA_MBIMX51_BASEBOARD) += eukrea_mbimx51-baseboard.o
-obj-$(CONFIG_MACH_EUKREA_CPUIMX51SD) += board-cpuimx51sd.o
-obj-$(CONFIG_MACH_EUKREA_MBIMXSD51_BASEBOARD) += eukrea_mbimxsd-baseboard.o
-obj-$(CONFIG_MX51_EFIKA_COMMON) += mx51_efika.o
-obj-$(CONFIG_MACH_MX51_EFIKAMX) += board-mx51_efikamx.o
-obj-$(CONFIG_MACH_MX51_EFIKASB) += board-mx51_efikasb.o
-obj-$(CONFIG_MACH_MX50_RDP) += board-mx50_rdp.o
-
-obj-$(CONFIG_MACH_IMX51_DT) += imx51-dt.o
-obj-$(CONFIG_MACH_IMX53_DT) += imx53-dt.o
diff --git a/arch/arm/mach-mx5/Makefile.boot b/arch/arm/mach-mx5/Makefile.boot
deleted file mode 100644
index ca207ca305ec..000000000000
--- a/arch/arm/mach-mx5/Makefile.boot
+++ /dev/null
@@ -1,9 +0,0 @@
- zreladdr-$(CONFIG_ARCH_MX50) += 0x70008000
-params_phys-$(CONFIG_ARCH_MX50) := 0x70000100
-initrd_phys-$(CONFIG_ARCH_MX50) := 0x70800000
- zreladdr-$(CONFIG_ARCH_MX51) += 0x90008000
-params_phys-$(CONFIG_ARCH_MX51) := 0x90000100
-initrd_phys-$(CONFIG_ARCH_MX51) := 0x90800000
- zreladdr-$(CONFIG_ARCH_MX53) += 0x70008000
-params_phys-$(CONFIG_ARCH_MX53) := 0x70000100
-initrd_phys-$(CONFIG_ARCH_MX53) := 0x70800000
diff --git a/arch/arm/mach-mx5/pm-imx5.c b/arch/arm/mach-mx5/pm-imx5.c
deleted file mode 100644
index 98052fc852c7..000000000000
--- a/arch/arm/mach-mx5/pm-imx5.c
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
- *
- * The code contained herein is licensed under the GNU General Public
- * License. You may obtain a copy of the GNU General Public License
- * Version 2 or later at the following locations:
- *
- * http://www.opensource.org/licenses/gpl-license.html
- * http://www.gnu.org/copyleft/gpl.html
- */
-#include <linux/suspend.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/err.h>
-#include <asm/cacheflush.h>
-#include <asm/tlbflush.h>
-#include <mach/common.h>
-#include <mach/hardware.h>
-#include "crm_regs.h"
-
-static struct clk *gpc_dvfs_clk;
-
-static int mx5_suspend_prepare(void)
-{
- return clk_enable(gpc_dvfs_clk);
-}
-
-static int mx5_suspend_enter(suspend_state_t state)
-{
- switch (state) {
- case PM_SUSPEND_MEM:
- mx5_cpu_lp_set(STOP_POWER_OFF);
- break;
- case PM_SUSPEND_STANDBY:
- mx5_cpu_lp_set(WAIT_UNCLOCKED_POWER_OFF);
- break;
- default:
- return -EINVAL;
- }
-
- if (state == PM_SUSPEND_MEM) {
- local_flush_tlb_all();
- flush_cache_all();
-
- /*clear the EMPGC0/1 bits */
- __raw_writel(0, MXC_SRPG_EMPGC0_SRPGCR);
- __raw_writel(0, MXC_SRPG_EMPGC1_SRPGCR);
- }
- cpu_do_idle();
- return 0;
-}
-
-static void mx5_suspend_finish(void)
-{
- clk_disable(gpc_dvfs_clk);
-}
-
-static int mx5_pm_valid(suspend_state_t state)
-{
- return (state > PM_SUSPEND_ON && state <= PM_SUSPEND_MAX);
-}
-
-static const struct platform_suspend_ops mx5_suspend_ops = {
- .valid = mx5_pm_valid,
- .prepare = mx5_suspend_prepare,
- .enter = mx5_suspend_enter,
- .finish = mx5_suspend_finish,
-};
-
-static int __init mx5_pm_init(void)
-{
- if (gpc_dvfs_clk == NULL)
- gpc_dvfs_clk = clk_get(NULL, "gpc_dvfs");
-
- if (!IS_ERR(gpc_dvfs_clk)) {
- if (cpu_is_mx51())
- suspend_set_ops(&mx5_suspend_ops);
- } else
- return -EPERM;
-
- return 0;
-}
-device_initcall(mx5_pm_init);
diff --git a/arch/arm/plat-mxc/Kconfig b/arch/arm/plat-mxc/Kconfig
index b30708e28c1d..dcebb1230f7f 100644
--- a/arch/arm/plat-mxc/Kconfig
+++ b/arch/arm/plat-mxc/Kconfig
@@ -17,26 +17,17 @@ config ARCH_IMX_V4_V5
and ARMv5 SoCs
config ARCH_IMX_V6_V7
- bool "i.MX3, i.MX6"
+ bool "i.MX3, i.MX5, i.MX6"
select AUTO_ZRELADDR if !ZBOOT_ROM
select ARM_PATCH_PHYS_VIRT
select MIGHT_HAVE_CACHE_L2X0
help
- This enables support for systems based on the Freescale i.MX3 and i.MX6
- family.
-
-config ARCH_MX5
- bool "i.MX50, i.MX51, i.MX53"
- select AUTO_ZRELADDR if !ZBOOT_ROM
- select ARM_PATCH_PHYS_VIRT
- help
- This enables support for machines using Freescale's i.MX50 and i.MX53
- processors.
+ This enables support for systems based on the Freescale i.MX3, i.MX5
+ and i.MX6 family.
endchoice
source "arch/arm/mach-imx/Kconfig"
-source "arch/arm/mach-mx5/Kconfig"
endmenu
diff --git a/arch/m68k/atari/config.c b/arch/m68k/atari/config.c
index 4203d101363c..c4ac15c4f065 100644
--- a/arch/m68k/atari/config.c
+++ b/arch/m68k/atari/config.c
@@ -414,9 +414,9 @@ void __init config_atari(void)
* FDC val = 4 -> Supervisor only */
asm volatile ("\n"
" .chip 68030\n"
- " pmove %0@,%/tt1\n"
+ " pmove %0,%/tt1\n"
" .chip 68k"
- : : "a" (&tt1_val));
+ : : "m" (tt1_val));
} else {
asm volatile ("\n"
" .chip 68040\n"
@@ -569,10 +569,10 @@ static void atari_reset(void)
: "d0");
} else
asm volatile ("\n"
- " pmove %0@,%%tc\n"
+ " pmove %0,%%tc\n"
" jmp %1@"
: /* no outputs */
- : "a" (&tc_val), "a" (reset_addr));
+ : "m" (tc_val), "a" (reset_addr));
}
diff --git a/arch/m68k/include/asm/irq.h b/arch/m68k/include/asm/irq.h
index 0e89fa05de0e..c1155f0e22cc 100644
--- a/arch/m68k/include/asm/irq.h
+++ b/arch/m68k/include/asm/irq.h
@@ -50,19 +50,6 @@
#define IRQ_USER 8
-/*
- * various flags for request_irq() - the Amiga now uses the standard
- * mechanism like all other architectures - IRQF_DISABLED and
- * IRQF_SHARED are your friends.
- */
-#ifndef MACH_AMIGA_ONLY
-#define IRQ_FLG_LOCK (0x0001) /* handler is not replaceable */
-#define IRQ_FLG_REPLACE (0x0002) /* replace existing handler */
-#define IRQ_FLG_FAST (0x0004)
-#define IRQ_FLG_SLOW (0x0008)
-#define IRQ_FLG_STD (0x8000) /* internally used */
-#endif
-
struct irq_data;
struct irq_chip;
struct irq_desc;
diff --git a/arch/m68k/kernel/process_mm.c b/arch/m68k/kernel/process_mm.c
index 125f34e00bf0..099283ee1a8f 100644
--- a/arch/m68k/kernel/process_mm.c
+++ b/arch/m68k/kernel/process_mm.c
@@ -172,7 +172,7 @@ void flush_thread(void)
current->thread.fs = __USER_DS;
if (!FPU_IS_EMU)
- asm volatile ("frestore %0@" : : "a" (&zero) : "memory");
+ asm volatile("frestore %0": :"m" (zero));
}
/*
diff --git a/arch/m68k/kernel/process_no.c b/arch/m68k/kernel/process_no.c
index 69c1803fcf1b..5e1078cabe0e 100644
--- a/arch/m68k/kernel/process_no.c
+++ b/arch/m68k/kernel/process_no.c
@@ -163,8 +163,8 @@ void flush_thread(void)
#ifdef CONFIG_FPU
if (!FPU_IS_EMU)
asm volatile (".chip 68k/68881\n\t"
- "frestore %0@\n\t"
- ".chip 68k" : : "a" (&zero));
+ "frestore %0\n\t"
+ ".chip 68k" : : "m" (zero));
#endif
}
diff --git a/arch/m68k/kernel/traps.c b/arch/m68k/kernel/traps.c
index a76452ca964e..daaa9187654c 100644
--- a/arch/m68k/kernel/traps.c
+++ b/arch/m68k/kernel/traps.c
@@ -552,13 +552,13 @@ static inline void bus_error030 (struct frame *fp)
#ifdef DEBUG
asm volatile ("ptestr %3,%2@,#7,%0\n\t"
- "pmove %%psr,%1@"
- : "=a&" (desc)
- : "a" (&temp), "a" (addr), "d" (ssw));
+ "pmove %%psr,%1"
+ : "=a&" (desc), "=m" (temp)
+ : "a" (addr), "d" (ssw));
#else
asm volatile ("ptestr %2,%1@,#7\n\t"
- "pmove %%psr,%0@"
- : : "a" (&temp), "a" (addr), "d" (ssw));
+ "pmove %%psr,%0"
+ : "=m" (temp) : "a" (addr), "d" (ssw));
#endif
mmusr = temp;
@@ -605,20 +605,18 @@ static inline void bus_error030 (struct frame *fp)
!(ssw & RW) ? "write" : "read", addr,
fp->ptregs.pc, ssw);
asm volatile ("ptestr #1,%1@,#0\n\t"
- "pmove %%psr,%0@"
- : /* no outputs */
- : "a" (&temp), "a" (addr));
+ "pmove %%psr,%0"
+ : "=m" (temp)
+ : "a" (addr));
mmusr = temp;
printk ("level 0 mmusr is %#x\n", mmusr);
#if 0
- asm volatile ("pmove %%tt0,%0@"
- : /* no outputs */
- : "a" (&tlong));
+ asm volatile ("pmove %%tt0,%0"
+ : "=m" (tlong));
printk("tt0 is %#lx, ", tlong);
- asm volatile ("pmove %%tt1,%0@"
- : /* no outputs */
- : "a" (&tlong));
+ asm volatile ("pmove %%tt1,%0"
+ : "=m" (tlong));
printk("tt1 is %#lx\n", tlong);
#endif
#ifdef DEBUG
@@ -668,13 +666,13 @@ static inline void bus_error030 (struct frame *fp)
#ifdef DEBUG
asm volatile ("ptestr #1,%2@,#7,%0\n\t"
- "pmove %%psr,%1@"
- : "=a&" (desc)
- : "a" (&temp), "a" (addr));
+ "pmove %%psr,%1"
+ : "=a&" (desc), "=m" (temp)
+ : "a" (addr));
#else
asm volatile ("ptestr #1,%1@,#7\n\t"
- "pmove %%psr,%0@"
- : : "a" (&temp), "a" (addr));
+ "pmove %%psr,%0"
+ : "=m" (temp) : "a" (addr));
#endif
mmusr = temp;
diff --git a/arch/m68k/mm/cache.c b/arch/m68k/mm/cache.c
index 95d0bf66e2e2..3d84c1f2ffb2 100644
--- a/arch/m68k/mm/cache.c
+++ b/arch/m68k/mm/cache.c
@@ -52,9 +52,9 @@ static unsigned long virt_to_phys_slow(unsigned long vaddr)
unsigned long *descaddr;
asm volatile ("ptestr %3,%2@,#7,%0\n\t"
- "pmove %%psr,%1@"
- : "=a&" (descaddr)
- : "a" (&mmusr), "a" (vaddr), "d" (get_fs().seg));
+ "pmove %%psr,%1"
+ : "=a&" (descaddr), "=m" (mmusr)
+ : "a" (vaddr), "d" (get_fs().seg));
if (mmusr & (MMU_I|MMU_B|MMU_L))
return 0;
descaddr = phys_to_virt((unsigned long)descaddr);
diff --git a/arch/powerpc/boot/dts/fsl/mpc8536si-post.dtsi b/arch/powerpc/boot/dts/fsl/mpc8536si-post.dtsi
index 89af62637707..b37da56018b6 100644
--- a/arch/powerpc/boot/dts/fsl/mpc8536si-post.dtsi
+++ b/arch/powerpc/boot/dts/fsl/mpc8536si-post.dtsi
@@ -236,6 +236,10 @@
};
/include/ "pq3-esdhc-0.dtsi"
+ sdhc@2e000 {
+ compatible = "fsl,mpc8536-esdhc", "fsl,esdhc";
+ };
+
/include/ "pq3-sec3.0-0.dtsi"
/include/ "pq3-mpic.dtsi"
/include/ "pq3-mpic-timer-B.dtsi"
diff --git a/arch/powerpc/boot/dts/fsl/p1010si-post.dtsi b/arch/powerpc/boot/dts/fsl/p1010si-post.dtsi
index bd9e163c764b..a97d1263372c 100644
--- a/arch/powerpc/boot/dts/fsl/p1010si-post.dtsi
+++ b/arch/powerpc/boot/dts/fsl/p1010si-post.dtsi
@@ -158,7 +158,8 @@
/include/ "pq3-usb2-dr-0.dtsi"
/include/ "pq3-esdhc-0.dtsi"
sdhc@2e000 {
- fsl,sdhci-auto-cmd12;
+ compatible = "fsl,p1010-esdhc", "fsl,esdhc";
+ sdhci,auto-cmd12;
};
/include/ "pq3-sec4.4-0.dtsi"
diff --git a/arch/powerpc/boot/dts/fsl/p1020si-post.dtsi b/arch/powerpc/boot/dts/fsl/p1020si-post.dtsi
index fc924c5ffebe..5de5fc351314 100644
--- a/arch/powerpc/boot/dts/fsl/p1020si-post.dtsi
+++ b/arch/powerpc/boot/dts/fsl/p1020si-post.dtsi
@@ -145,6 +145,10 @@
/include/ "pq3-usb2-dr-1.dtsi"
/include/ "pq3-esdhc-0.dtsi"
+ sdhc@2e000 {
+ compatible = "fsl,p1020-esdhc", "fsl,esdhc";
+ sdhci,auto-cmd12;
+ };
/include/ "pq3-sec3.3-0.dtsi"
/include/ "pq3-mpic.dtsi"
diff --git a/arch/powerpc/boot/dts/fsl/p1022si-post.dtsi b/arch/powerpc/boot/dts/fsl/p1022si-post.dtsi
index 16239b199d0a..ff9ed1d87929 100644
--- a/arch/powerpc/boot/dts/fsl/p1022si-post.dtsi
+++ b/arch/powerpc/boot/dts/fsl/p1022si-post.dtsi
@@ -203,7 +203,8 @@
/include/ "pq3-esdhc-0.dtsi"
sdhc@2e000 {
- fsl,sdhci-auto-cmd12;
+ compatible = "fsl,p1022-esdhc", "fsl,esdhc";
+ sdhci,auto-cmd12;
};
/include/ "pq3-sec3.3-0.dtsi"
diff --git a/arch/powerpc/boot/dts/fsl/p2020si-post.dtsi b/arch/powerpc/boot/dts/fsl/p2020si-post.dtsi
index c041050561a7..332e9e75e6c2 100644
--- a/arch/powerpc/boot/dts/fsl/p2020si-post.dtsi
+++ b/arch/powerpc/boot/dts/fsl/p2020si-post.dtsi
@@ -182,6 +182,10 @@
/include/ "pq3-etsec1-1.dtsi"
/include/ "pq3-etsec1-2.dtsi"
/include/ "pq3-esdhc-0.dtsi"
+ sdhc@2e000 {
+ compatible = "fsl,p2020-esdhc", "fsl,esdhc";
+ };
+
/include/ "pq3-sec3.1-0.dtsi"
/include/ "pq3-mpic.dtsi"
/include/ "pq3-mpic-timer-B.dtsi"
diff --git a/arch/powerpc/boot/dts/p1020rdb.dtsi b/arch/powerpc/boot/dts/p1020rdb.dtsi
index b5bd86f4baf2..1fb7e0e0940f 100644
--- a/arch/powerpc/boot/dts/p1020rdb.dtsi
+++ b/arch/powerpc/boot/dts/p1020rdb.dtsi
@@ -1,7 +1,7 @@
/*
* P1020 RDB Device Tree Source stub (no addresses or top-level ranges)
*
- * Copyright 2011 Freescale Semiconductor Inc.
+ * Copyright 2011-2012 Freescale Semiconductor Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -190,17 +190,16 @@
usb@22000 {
phy_type = "ulpi";
+ dr_mode = "host";
};
- /* USB2 is shared with localbus, so it must be disabled
- by default. We can't put 'status = "disabled";' here
- since U-Boot doesn't clear the status property when
- it enables USB2. OTOH, U-Boot does create a new node
- when there isn't any. So, just comment it out.
+ /* USB2 is shared with localbus. It is used
+ only in case of SPI and SD boot after
+ appropriate device-tree fixup done by uboot */
usb@23000 {
phy_type = "ulpi";
+ dr_mode = "host";
};
- */
mdio@24000 {
phy0: ethernet-phy@0 {
diff --git a/arch/powerpc/boot/dts/p1021mds.dts b/arch/powerpc/boot/dts/p1021mds.dts
index d9540791e434..97116f198a37 100644
--- a/arch/powerpc/boot/dts/p1021mds.dts
+++ b/arch/powerpc/boot/dts/p1021mds.dts
@@ -1,7 +1,7 @@
/*
* P1021 MDS Device Tree Source
*
- * Copyright 2010 Freescale Semiconductor Inc.
+ * Copyright 2010,2012 Freescale Semiconductor Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -151,6 +151,7 @@
usb@22000 {
phy_type = "ulpi";
+ dr_mode = "host";
};
mdio@24000 {
diff --git a/arch/powerpc/boot/dts/p2020ds.dtsi b/arch/powerpc/boot/dts/p2020ds.dtsi
index c1cf6cef4dd6..d3b939c573b0 100644
--- a/arch/powerpc/boot/dts/p2020ds.dtsi
+++ b/arch/powerpc/boot/dts/p2020ds.dtsi
@@ -1,7 +1,7 @@
/*
* P2020DS Device Tree Source stub (no addresses or top-level ranges)
*
- * Copyright 2011 Freescale Semiconductor Inc.
+ * Copyright 2011-2012 Freescale Semiconductor Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -134,6 +134,7 @@
&board_soc {
usb@22000 {
phy_type = "ulpi";
+ dr_mode = "host";
};
mdio@24520 {
diff --git a/arch/powerpc/boot/dts/p2020rdb.dts b/arch/powerpc/boot/dts/p2020rdb.dts
index 26759a591712..eb8a6aa2bda5 100644
--- a/arch/powerpc/boot/dts/p2020rdb.dts
+++ b/arch/powerpc/boot/dts/p2020rdb.dts
@@ -1,7 +1,7 @@
/*
* P2020 RDB Device Tree Source
*
- * Copyright 2009-2011 Freescale Semiconductor Inc.
+ * Copyright 2009-2012 Freescale Semiconductor Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -197,6 +197,7 @@
usb@22000 {
phy_type = "ulpi";
+ dr_mode = "host";
};
mdio@24520 {
diff --git a/arch/powerpc/kernel/crash.c b/arch/powerpc/kernel/crash.c
index 28be3452e67a..abef75176c07 100644
--- a/arch/powerpc/kernel/crash.c
+++ b/arch/powerpc/kernel/crash.c
@@ -46,7 +46,6 @@
/* This keeps a track of which one is the crashing cpu. */
int crashing_cpu = -1;
-static atomic_t cpus_in_crash;
static int time_to_dump;
#define CRASH_HANDLER_MAX 3
@@ -66,6 +65,7 @@ static int handle_fault(struct pt_regs *regs)
#ifdef CONFIG_SMP
+static atomic_t cpus_in_crash;
void crash_ipi_callback(struct pt_regs *regs)
{
static cpumask_t cpus_state_saved = CPU_MASK_NONE;
diff --git a/arch/powerpc/kernel/legacy_serial.c b/arch/powerpc/kernel/legacy_serial.c
index 3fea3689527e..bedd12e1cfbc 100644
--- a/arch/powerpc/kernel/legacy_serial.c
+++ b/arch/powerpc/kernel/legacy_serial.c
@@ -442,8 +442,10 @@ static void __init fixup_port_irq(int index,
port->irq = virq;
+#ifdef CONFIG_SERIAL_8250_FSL
if (of_device_is_compatible(np, "fsl,ns16550"))
port->handle_irq = fsl8250_handle_irq;
+#endif
}
static void __init fixup_port_pio(int index,
diff --git a/arch/powerpc/platforms/85xx/p1022_ds.c b/arch/powerpc/platforms/85xx/p1022_ds.c
index bb3d84f4046f..b0984ada3f83 100644
--- a/arch/powerpc/platforms/85xx/p1022_ds.c
+++ b/arch/powerpc/platforms/85xx/p1022_ds.c
@@ -25,6 +25,7 @@
#include <sysdev/fsl_soc.h>
#include <sysdev/fsl_pci.h>
+#include <asm/udbg.h>
#include <asm/fsl_guts.h>
#include "smp.h"
diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c
index f31162cfdaa9..5e155dfc4320 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -204,11 +204,10 @@ static void __devinit pnv_ioda_offset_bus(struct pci_bus *bus,
pr_devel(" -> OBR %s [%x] +%016llx\n",
bus->self ? pci_name(bus->self) : "root", flags, offset);
- for (i = 0; i < 2; i++) {
- r = bus->resource[i];
+ pci_bus_for_each_resource(bus, r, i) {
if (r && (r->flags & flags)) {
- bus->resource[i]->start += offset;
- bus->resource[i]->end += offset;
+ r->start += offset;
+ r->end += offset;
}
}
list_for_each_entry(dev, &bus->devices, bus_list)
@@ -288,12 +287,17 @@ static void __devinit pnv_ioda_calc_bus(struct pci_bus *bus, unsigned int flags,
* assignment algorithm is going to be uber-trivial for now, we
* can try to be smarter later at filling out holes.
*/
- start = bus->self ? 0 : bus->resource[bres]->start;
-
- /* Don't hand out IO 0 */
- if ((flags & IORESOURCE_IO) && !bus->self)
- start += 0x1000;
-
+ if (bus->self) {
+ /* No offset for downstream bridges */
+ start = 0;
+ } else {
+ /* Offset from the root */
+ if (flags & IORESOURCE_IO)
+ /* Don't hand out IO 0 */
+ start = hose->io_resource.start + 0x1000;
+ else
+ start = hose->mem_resources[0].start;
+ }
while(!list_empty(&head)) {
w = list_first_entry(&head, struct resource_wrap, link);
list_del(&w->link);
@@ -321,13 +325,20 @@ static void __devinit pnv_ioda_calc_bus(struct pci_bus *bus, unsigned int flags,
empty:
/* Only setup P2P's, not the PHB itself */
if (bus->self) {
- WARN_ON(bus->resource[bres] == NULL);
- bus->resource[bres]->start = 0;
- bus->resource[bres]->flags = (*size) ? flags : 0;
- bus->resource[bres]->end = (*size) ? (*size - 1) : 0;
+ struct resource *res = bus->resource[bres];
+
+ if (WARN_ON(res == NULL))
+ return;
- /* Clear prefetch bus resources for now */
- bus->resource[2]->flags = 0;
+ /*
+ * FIXME: We should probably export and call
+ * pci_bridge_check_ranges() to properly re-initialize
+ * the PCI portion of the flags here, and to detect
+ * what the bridge actually supports.
+ */
+ res->start = 0;
+ res->flags = (*size) ? flags : 0;
+ res->end = (*size) ? (*size - 1) : 0;
}
pr_devel("<- CBR %s [%x] *size=%016llx *align=%016llx\n",
diff --git a/arch/powerpc/platforms/pseries/Kconfig b/arch/powerpc/platforms/pseries/Kconfig
index ae7b6d41fed3..31f22c1f657d 100644
--- a/arch/powerpc/platforms/pseries/Kconfig
+++ b/arch/powerpc/platforms/pseries/Kconfig
@@ -122,7 +122,7 @@ config DTL
Say N if you are unsure.
config PSERIES_IDLE
- tristate "Cpuidle driver for pSeries platforms"
+ bool "Cpuidle driver for pSeries platforms"
depends on CPU_IDLE
depends on PPC_PSERIES
default y
diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
index 3b61e8cf3421..30eb17ecad49 100644
--- a/arch/powerpc/sysdev/fsl_pci.c
+++ b/arch/powerpc/sysdev/fsl_pci.c
@@ -205,12 +205,12 @@ static void __init setup_pci_atmu(struct pci_controller *hose,
if (paddr_hi == paddr_lo) {
pr_err("%s: No outbound window space\n", name);
- return ;
+ goto out;
}
if (paddr_lo == 0) {
pr_err("%s: No space for inbound window\n", name);
- return ;
+ goto out;
}
/* setup PCSRBAR/PEXCSRBAR */
@@ -357,6 +357,7 @@ static void __init setup_pci_atmu(struct pci_controller *hose,
(u64)hose->dma_window_size);
}
+out:
iounmap(pci);
}
diff --git a/arch/s390/include/asm/kexec.h b/arch/s390/include/asm/kexec.h
index cf4e47b0948c..3f30dac804ea 100644
--- a/arch/s390/include/asm/kexec.h
+++ b/arch/s390/include/asm/kexec.h
@@ -42,6 +42,24 @@
/* The native architecture */
#define KEXEC_ARCH KEXEC_ARCH_S390
+/*
+ * Size for s390x ELF notes per CPU
+ *
+ * Seven notes plus zero note at the end: prstatus, fpregset, timer,
+ * tod_cmp, tod_reg, control regs, and prefix
+ */
+#define KEXEC_NOTE_BYTES \
+ (ALIGN(sizeof(struct elf_note), 4) * 8 + \
+ ALIGN(sizeof("CORE"), 4) * 7 + \
+ ALIGN(sizeof(struct elf_prstatus), 4) + \
+ ALIGN(sizeof(elf_fpregset_t), 4) + \
+ ALIGN(sizeof(u64), 4) + \
+ ALIGN(sizeof(u64), 4) + \
+ ALIGN(sizeof(u32), 4) + \
+ ALIGN(sizeof(u64) * 16, 4) + \
+ ALIGN(sizeof(u32), 4) \
+ )
+
/* Provide a dummy definition to avoid build failures. */
static inline void crash_setup_regs(struct pt_regs *newregs,
struct pt_regs *oldregs) { }
diff --git a/arch/score/kernel/entry.S b/arch/score/kernel/entry.S
index 577abba3fac6..83bb96079c43 100644
--- a/arch/score/kernel/entry.S
+++ b/arch/score/kernel/entry.S
@@ -408,7 +408,7 @@ ENTRY(handle_sys)
sw r9, [r0, PT_EPC]
cmpi.c r27, __NR_syscalls # check syscall number
- bgtu illegal_syscall
+ bgeu illegal_syscall
slli r8, r27, 2 # get syscall routine
la r11, sys_call_table
diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c
index 7b65f752c5f8..7c1b765ecc59 100644
--- a/arch/x86/net/bpf_jit_comp.c
+++ b/arch/x86/net/bpf_jit_comp.c
@@ -151,17 +151,18 @@ void bpf_jit_compile(struct sk_filter *fp)
cleanup_addr = proglen; /* epilogue address */
for (pass = 0; pass < 10; pass++) {
+ u8 seen_or_pass0 = (pass == 0) ? (SEEN_XREG | SEEN_DATAREF | SEEN_MEM) : seen;
/* no prologue/epilogue for trivial filters (RET something) */
proglen = 0;
prog = temp;
- if (seen) {
+ if (seen_or_pass0) {
EMIT4(0x55, 0x48, 0x89, 0xe5); /* push %rbp; mov %rsp,%rbp */
EMIT4(0x48, 0x83, 0xec, 96); /* subq $96,%rsp */
/* note : must save %rbx in case bpf_error is hit */
- if (seen & (SEEN_XREG | SEEN_DATAREF))
+ if (seen_or_pass0 & (SEEN_XREG | SEEN_DATAREF))
EMIT4(0x48, 0x89, 0x5d, 0xf8); /* mov %rbx, -8(%rbp) */
- if (seen & SEEN_XREG)
+ if (seen_or_pass0 & SEEN_XREG)
CLEAR_X(); /* make sure we dont leek kernel memory */
/*
@@ -170,7 +171,7 @@ void bpf_jit_compile(struct sk_filter *fp)
* r9 = skb->len - skb->data_len
* r8 = skb->data
*/
- if (seen & SEEN_DATAREF) {
+ if (seen_or_pass0 & SEEN_DATAREF) {
if (offsetof(struct sk_buff, len) <= 127)
/* mov off8(%rdi),%r9d */
EMIT4(0x44, 0x8b, 0x4f, offsetof(struct sk_buff, len));
@@ -260,9 +261,14 @@ void bpf_jit_compile(struct sk_filter *fp)
case BPF_S_ALU_DIV_X: /* A /= X; */
seen |= SEEN_XREG;
EMIT2(0x85, 0xdb); /* test %ebx,%ebx */
- if (pc_ret0 != -1)
- EMIT_COND_JMP(X86_JE, addrs[pc_ret0] - (addrs[i] - 4));
- else {
+ if (pc_ret0 > 0) {
+ /* addrs[pc_ret0 - 1] is start address of target
+ * (addrs[i] - 4) is the address following this jmp
+ * ("xor %edx,%edx; div %ebx" being 4 bytes long)
+ */
+ EMIT_COND_JMP(X86_JE, addrs[pc_ret0 - 1] -
+ (addrs[i] - 4));
+ } else {
EMIT_COND_JMP(X86_JNE, 2 + 5);
CLEAR_A();
EMIT1_off32(0xe9, cleanup_addr - (addrs[i] - 4)); /* jmp .+off32 */
@@ -335,12 +341,12 @@ void bpf_jit_compile(struct sk_filter *fp)
}
/* fallinto */
case BPF_S_RET_A:
- if (seen) {
+ if (seen_or_pass0) {
if (i != flen - 1) {
EMIT_JMP(cleanup_addr - addrs[i]);
break;
}
- if (seen & SEEN_XREG)
+ if (seen_or_pass0 & SEEN_XREG)
EMIT4(0x48, 0x8b, 0x5d, 0xf8); /* mov -8(%rbp),%rbx */
EMIT1(0xc9); /* leaveq */
}
@@ -483,8 +489,9 @@ common_load: seen |= SEEN_DATAREF;
goto common_load;
case BPF_S_LDX_B_MSH:
if ((int)K < 0) {
- if (pc_ret0 != -1) {
- EMIT_JMP(addrs[pc_ret0] - addrs[i]);
+ if (pc_ret0 > 0) {
+ /* addrs[pc_ret0 - 1] is the start address */
+ EMIT_JMP(addrs[pc_ret0 - 1] - addrs[i]);
break;
}
CLEAR_A();
@@ -599,13 +606,14 @@ cond_branch: f_offset = addrs[i + filter[i].jf] - addrs[i];
* use it to give the cleanup instruction(s) addr
*/
cleanup_addr = proglen - 1; /* ret */
- if (seen)
+ if (seen_or_pass0)
cleanup_addr -= 1; /* leaveq */
- if (seen & SEEN_XREG)
+ if (seen_or_pass0 & SEEN_XREG)
cleanup_addr -= 4; /* mov -8(%rbp),%rbx */
if (image) {
- WARN_ON(proglen != oldproglen);
+ if (proglen != oldproglen)
+ pr_err("bpb_jit_compile proglen=%u != oldproglen=%u\n", proglen, oldproglen);
break;
}
if (proglen == oldproglen) {
diff --git a/crypto/sha512_generic.c b/crypto/sha512_generic.c
index 9ed9f60316e5..88f160b77b1f 100644
--- a/crypto/sha512_generic.c
+++ b/crypto/sha512_generic.c
@@ -21,8 +21,6 @@
#include <linux/percpu.h>
#include <asm/byteorder.h>
-static DEFINE_PER_CPU(u64[80], msg_schedule);
-
static inline u64 Ch(u64 x, u64 y, u64 z)
{
return z ^ (x & (y ^ z));
@@ -80,7 +78,7 @@ static inline void LOAD_OP(int I, u64 *W, const u8 *input)
static inline void BLEND_OP(int I, u64 *W)
{
- W[I] = s1(W[I-2]) + W[I-7] + s0(W[I-15]) + W[I-16];
+ W[I % 16] += s1(W[(I-2) % 16]) + W[(I-7) % 16] + s0(W[(I-15) % 16]);
}
static void
@@ -89,38 +87,48 @@ sha512_transform(u64 *state, const u8 *input)
u64 a, b, c, d, e, f, g, h, t1, t2;
int i;
- u64 *W = get_cpu_var(msg_schedule);
+ u64 W[16];
/* load the input */
for (i = 0; i < 16; i++)
LOAD_OP(i, W, input);
- for (i = 16; i < 80; i++) {
- BLEND_OP(i, W);
- }
-
/* load the state into our registers */
a=state[0]; b=state[1]; c=state[2]; d=state[3];
e=state[4]; f=state[5]; g=state[6]; h=state[7];
- /* now iterate */
- for (i=0; i<80; i+=8) {
- t1 = h + e1(e) + Ch(e,f,g) + sha512_K[i ] + W[i ];
- t2 = e0(a) + Maj(a,b,c); d+=t1; h=t1+t2;
- t1 = g + e1(d) + Ch(d,e,f) + sha512_K[i+1] + W[i+1];
- t2 = e0(h) + Maj(h,a,b); c+=t1; g=t1+t2;
- t1 = f + e1(c) + Ch(c,d,e) + sha512_K[i+2] + W[i+2];
- t2 = e0(g) + Maj(g,h,a); b+=t1; f=t1+t2;
- t1 = e + e1(b) + Ch(b,c,d) + sha512_K[i+3] + W[i+3];
- t2 = e0(f) + Maj(f,g,h); a+=t1; e=t1+t2;
- t1 = d + e1(a) + Ch(a,b,c) + sha512_K[i+4] + W[i+4];
- t2 = e0(e) + Maj(e,f,g); h+=t1; d=t1+t2;
- t1 = c + e1(h) + Ch(h,a,b) + sha512_K[i+5] + W[i+5];
- t2 = e0(d) + Maj(d,e,f); g+=t1; c=t1+t2;
- t1 = b + e1(g) + Ch(g,h,a) + sha512_K[i+6] + W[i+6];
- t2 = e0(c) + Maj(c,d,e); f+=t1; b=t1+t2;
- t1 = a + e1(f) + Ch(f,g,h) + sha512_K[i+7] + W[i+7];
- t2 = e0(b) + Maj(b,c,d); e+=t1; a=t1+t2;
+#define SHA512_0_15(i, a, b, c, d, e, f, g, h) \
+ t1 = h + e1(e) + Ch(e, f, g) + sha512_K[i] + W[i]; \
+ t2 = e0(a) + Maj(a, b, c); \
+ d += t1; \
+ h = t1 + t2
+
+#define SHA512_16_79(i, a, b, c, d, e, f, g, h) \
+ BLEND_OP(i, W); \
+ t1 = h + e1(e) + Ch(e, f, g) + sha512_K[i] + W[(i)%16]; \
+ t2 = e0(a) + Maj(a, b, c); \
+ d += t1; \
+ h = t1 + t2
+
+ for (i = 0; i < 16; i += 8) {
+ SHA512_0_15(i, a, b, c, d, e, f, g, h);
+ SHA512_0_15(i + 1, h, a, b, c, d, e, f, g);
+ SHA512_0_15(i + 2, g, h, a, b, c, d, e, f);
+ SHA512_0_15(i + 3, f, g, h, a, b, c, d, e);
+ SHA512_0_15(i + 4, e, f, g, h, a, b, c, d);
+ SHA512_0_15(i + 5, d, e, f, g, h, a, b, c);
+ SHA512_0_15(i + 6, c, d, e, f, g, h, a, b);
+ SHA512_0_15(i + 7, b, c, d, e, f, g, h, a);
+ }
+ for (i = 16; i < 80; i += 8) {
+ SHA512_16_79(i, a, b, c, d, e, f, g, h);
+ SHA512_16_79(i + 1, h, a, b, c, d, e, f, g);
+ SHA512_16_79(i + 2, g, h, a, b, c, d, e, f);
+ SHA512_16_79(i + 3, f, g, h, a, b, c, d, e);
+ SHA512_16_79(i + 4, e, f, g, h, a, b, c, d);
+ SHA512_16_79(i + 5, d, e, f, g, h, a, b, c);
+ SHA512_16_79(i + 6, c, d, e, f, g, h, a, b);
+ SHA512_16_79(i + 7, b, c, d, e, f, g, h, a);
}
state[0] += a; state[1] += b; state[2] += c; state[3] += d;
@@ -128,8 +136,6 @@ sha512_transform(u64 *state, const u8 *input)
/* erase our data */
a = b = c = d = e = f = g = h = t1 = t2 = 0;
- memset(W, 0, sizeof(__get_cpu_var(msg_schedule)));
- put_cpu_var(msg_schedule);
}
static int
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index c07f44f05f9d..1567028d2038 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -19,7 +19,6 @@ obj-y += acpi.o \
# All the builtin files are in the "acpi." module_param namespace.
acpi-y += osl.o utils.o reboot.o
-acpi-y += atomicio.o
acpi-y += nvs.o
# sleep related files
diff --git a/drivers/acpi/apei/apei-base.c b/drivers/acpi/apei/apei-base.c
index e45350cb6ac8..e5d53b7ddc7e 100644
--- a/drivers/acpi/apei/apei-base.c
+++ b/drivers/acpi/apei/apei-base.c
@@ -596,33 +596,19 @@ int apei_read(u64 *val, struct acpi_generic_address *reg)
{
int rc;
u64 address;
- u32 tmp, width = reg->bit_width;
acpi_status status;
rc = apei_check_gar(reg, &address);
if (rc)
return rc;
- if (width == 64)
- width = 32; /* Break into two 32-bit transfers */
-
*val = 0;
switch(reg->space_id) {
case ACPI_ADR_SPACE_SYSTEM_MEMORY:
- status = acpi_os_read_memory((acpi_physical_address)
- address, &tmp, width);
+ status = acpi_os_read_memory64((acpi_physical_address)
+ address, val, reg->bit_width);
if (ACPI_FAILURE(status))
return -EIO;
- *val = tmp;
-
- if (reg->bit_width == 64) {
- /* Read the top 32 bits */
- status = acpi_os_read_memory((acpi_physical_address)
- (address + 4), &tmp, 32);
- if (ACPI_FAILURE(status))
- return -EIO;
- *val |= ((u64)tmp << 32);
- }
break;
case ACPI_ADR_SPACE_SYSTEM_IO:
status = acpi_os_read_port(address, (u32 *)val, reg->bit_width);
@@ -642,31 +628,18 @@ int apei_write(u64 val, struct acpi_generic_address *reg)
{
int rc;
u64 address;
- u32 width = reg->bit_width;
acpi_status status;
rc = apei_check_gar(reg, &address);
if (rc)
return rc;
- if (width == 64)
- width = 32; /* Break into two 32-bit transfers */
-
switch (reg->space_id) {
case ACPI_ADR_SPACE_SYSTEM_MEMORY:
- status = acpi_os_write_memory((acpi_physical_address)
- address, ACPI_LODWORD(val),
- width);
+ status = acpi_os_write_memory64((acpi_physical_address)
+ address, val, reg->bit_width);
if (ACPI_FAILURE(status))
return -EIO;
-
- if (reg->bit_width == 64) {
- status = acpi_os_write_memory((acpi_physical_address)
- (address + 4),
- ACPI_HIDWORD(val), 32);
- if (ACPI_FAILURE(status))
- return -EIO;
- }
break;
case ACPI_ADR_SPACE_SYSTEM_IO:
status = acpi_os_write_port(address, val, reg->bit_width);
diff --git a/drivers/acpi/apei/einj.c b/drivers/acpi/apei/einj.c
index 5b898d4dda99..4ca087dd5f4f 100644
--- a/drivers/acpi/apei/einj.c
+++ b/drivers/acpi/apei/einj.c
@@ -141,21 +141,6 @@ static DEFINE_MUTEX(einj_mutex);
static void *einj_param;
-#ifndef readq
-static inline __u64 readq(volatile void __iomem *addr)
-{
- return ((__u64)readl(addr+4) << 32) + readl(addr);
-}
-#endif
-
-#ifndef writeq
-static inline void writeq(__u64 val, volatile void __iomem *addr)
-{
- writel(val, addr);
- writel(val >> 32, addr+4);
-}
-#endif
-
static void einj_exec_ctx_init(struct apei_exec_context *ctx)
{
apei_exec_ctx_init(ctx, einj_ins_type, ARRAY_SIZE(einj_ins_type),
@@ -204,22 +189,21 @@ static int einj_timedout(u64 *t)
static void check_vendor_extension(u64 paddr,
struct set_error_type_with_address *v5param)
{
- int offset = readl(&v5param->vendor_extension);
+ int offset = v5param->vendor_extension;
struct vendor_error_type_extension *v;
u32 sbdf;
if (!offset)
return;
- v = ioremap(paddr + offset, sizeof(*v));
+ v = acpi_os_map_memory(paddr + offset, sizeof(*v));
if (!v)
return;
- sbdf = readl(&v->pcie_sbdf);
+ sbdf = v->pcie_sbdf;
sprintf(vendor_dev, "%x:%x:%x.%x vendor_id=%x device_id=%x rev_id=%x\n",
sbdf >> 24, (sbdf >> 16) & 0xff,
(sbdf >> 11) & 0x1f, (sbdf >> 8) & 0x7,
- readw(&v->vendor_id), readw(&v->device_id),
- readb(&v->rev_id));
- iounmap(v);
+ v->vendor_id, v->device_id, v->rev_id);
+ acpi_os_unmap_memory(v, sizeof(*v));
}
static void *einj_get_parameter_address(void)
@@ -247,7 +231,7 @@ static void *einj_get_parameter_address(void)
if (paddrv5) {
struct set_error_type_with_address *v5param;
- v5param = ioremap(paddrv5, sizeof(*v5param));
+ v5param = acpi_os_map_memory(paddrv5, sizeof(*v5param));
if (v5param) {
acpi5 = 1;
check_vendor_extension(paddrv5, v5param);
@@ -257,17 +241,17 @@ static void *einj_get_parameter_address(void)
if (paddrv4) {
struct einj_parameter *v4param;
- v4param = ioremap(paddrv4, sizeof(*v4param));
+ v4param = acpi_os_map_memory(paddrv4, sizeof(*v4param));
if (!v4param)
- return 0;
- if (readq(&v4param->reserved1) || readq(&v4param->reserved2)) {
- iounmap(v4param);
- return 0;
+ return NULL;
+ if (v4param->reserved1 || v4param->reserved2) {
+ acpi_os_unmap_memory(v4param, sizeof(*v4param));
+ return NULL;
}
return v4param;
}
- return 0;
+ return NULL;
}
/* do sanity check to trigger table */
@@ -276,7 +260,7 @@ static int einj_check_trigger_header(struct acpi_einj_trigger *trigger_tab)
if (trigger_tab->header_size != sizeof(struct acpi_einj_trigger))
return -EINVAL;
if (trigger_tab->table_size > PAGE_SIZE ||
- trigger_tab->table_size <= trigger_tab->header_size)
+ trigger_tab->table_size < trigger_tab->header_size)
return -EINVAL;
if (trigger_tab->entry_count !=
(trigger_tab->table_size - trigger_tab->header_size) /
@@ -340,6 +324,11 @@ static int __einj_error_trigger(u64 trigger_paddr, u32 type,
"The trigger error action table is invalid\n");
goto out_rel_header;
}
+
+ /* No action structures in the TRIGGER_ERROR table, nothing to do */
+ if (!trigger_tab->entry_count)
+ goto out_rel_header;
+
rc = -EIO;
table_size = trigger_tab->table_size;
r = request_mem_region(trigger_paddr + sizeof(*trigger_tab),
@@ -435,41 +424,41 @@ static int __einj_error_inject(u32 type, u64 param1, u64 param2)
if (acpi5) {
struct set_error_type_with_address *v5param = einj_param;
- writel(type, &v5param->type);
+ v5param->type = type;
if (type & 0x80000000) {
switch (vendor_flags) {
case SETWA_FLAGS_APICID:
- writel(param1, &v5param->apicid);
+ v5param->apicid = param1;
break;
case SETWA_FLAGS_MEM:
- writeq(param1, &v5param->memory_address);
- writeq(param2, &v5param->memory_address_range);
+ v5param->memory_address = param1;
+ v5param->memory_address_range = param2;
break;
case SETWA_FLAGS_PCIE_SBDF:
- writel(param1, &v5param->pcie_sbdf);
+ v5param->pcie_sbdf = param1;
break;
}
- writel(vendor_flags, &v5param->flags);
+ v5param->flags = vendor_flags;
} else {
switch (type) {
case ACPI_EINJ_PROCESSOR_CORRECTABLE:
case ACPI_EINJ_PROCESSOR_UNCORRECTABLE:
case ACPI_EINJ_PROCESSOR_FATAL:
- writel(param1, &v5param->apicid);
- writel(SETWA_FLAGS_APICID, &v5param->flags);
+ v5param->apicid = param1;
+ v5param->flags = SETWA_FLAGS_APICID;
break;
case ACPI_EINJ_MEMORY_CORRECTABLE:
case ACPI_EINJ_MEMORY_UNCORRECTABLE:
case ACPI_EINJ_MEMORY_FATAL:
- writeq(param1, &v5param->memory_address);
- writeq(param2, &v5param->memory_address_range);
- writel(SETWA_FLAGS_MEM, &v5param->flags);
+ v5param->memory_address = param1;
+ v5param->memory_address_range = param2;
+ v5param->flags = SETWA_FLAGS_MEM;
break;
case ACPI_EINJ_PCIX_CORRECTABLE:
case ACPI_EINJ_PCIX_UNCORRECTABLE:
case ACPI_EINJ_PCIX_FATAL:
- writel(param1, &v5param->pcie_sbdf);
- writel(SETWA_FLAGS_PCIE_SBDF, &v5param->flags);
+ v5param->pcie_sbdf = param1;
+ v5param->flags = SETWA_FLAGS_PCIE_SBDF;
break;
}
}
@@ -479,8 +468,8 @@ static int __einj_error_inject(u32 type, u64 param1, u64 param2)
return rc;
if (einj_param) {
struct einj_parameter *v4param = einj_param;
- writeq(param1, &v4param->param1);
- writeq(param2, &v4param->param2);
+ v4param->param1 = param1;
+ v4param->param2 = param2;
}
}
rc = apei_exec_run(&ctx, ACPI_EINJ_EXECUTE_OPERATION);
@@ -731,8 +720,13 @@ static int __init einj_init(void)
return 0;
err_unmap:
- if (einj_param)
- iounmap(einj_param);
+ if (einj_param) {
+ acpi_size size = (acpi5) ?
+ sizeof(struct set_error_type_with_address) :
+ sizeof(struct einj_parameter);
+
+ acpi_os_unmap_memory(einj_param, size);
+ }
apei_exec_post_unmap_gars(&ctx);
err_release:
apei_resources_release(&einj_resources);
@@ -748,8 +742,13 @@ static void __exit einj_exit(void)
{
struct apei_exec_context ctx;
- if (einj_param)
- iounmap(einj_param);
+ if (einj_param) {
+ acpi_size size = (acpi5) ?
+ sizeof(struct set_error_type_with_address) :
+ sizeof(struct einj_parameter);
+
+ acpi_os_unmap_memory(einj_param, size);
+ }
einj_exec_ctx_init(&ctx);
apei_exec_post_unmap_gars(&ctx);
apei_resources_release(&einj_resources);
diff --git a/drivers/acpi/atomicio.c b/drivers/acpi/atomicio.c
deleted file mode 100644
index d4a5b3d3657b..000000000000
--- a/drivers/acpi/atomicio.c
+++ /dev/null
@@ -1,422 +0,0 @@
-/*
- * atomicio.c - ACPI IO memory pre-mapping/post-unmapping, then
- * accessing in atomic context.
- *
- * This is used for NMI handler to access IO memory area, because
- * ioremap/iounmap can not be used in NMI handler. The IO memory area
- * is pre-mapped in process context and accessed in NMI handler.
- *
- * Copyright (C) 2009-2010, Intel Corp.
- * Author: Huang Ying <ying.huang@intel.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License version
- * 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/kernel.h>
-#include <linux/export.h>
-#include <linux/init.h>
-#include <linux/acpi.h>
-#include <linux/io.h>
-#include <linux/kref.h>
-#include <linux/rculist.h>
-#include <linux/interrupt.h>
-#include <linux/slab.h>
-#include <linux/mm.h>
-#include <linux/highmem.h>
-#include <acpi/atomicio.h>
-
-#define ACPI_PFX "ACPI: "
-
-static LIST_HEAD(acpi_iomaps);
-/*
- * Used for mutual exclusion between writers of acpi_iomaps list, for
- * synchronization between readers and writer, RCU is used.
- */
-static DEFINE_SPINLOCK(acpi_iomaps_lock);
-
-struct acpi_iomap {
- struct list_head list;
- void __iomem *vaddr;
- unsigned long size;
- phys_addr_t paddr;
- struct kref ref;
-};
-
-/* acpi_iomaps_lock or RCU read lock must be held before calling */
-static struct acpi_iomap *__acpi_find_iomap(phys_addr_t paddr,
- unsigned long size)
-{
- struct acpi_iomap *map;
-
- list_for_each_entry_rcu(map, &acpi_iomaps, list) {
- if (map->paddr + map->size >= paddr + size &&
- map->paddr <= paddr)
- return map;
- }
- return NULL;
-}
-
-/*
- * Atomic "ioremap" used by NMI handler, if the specified IO memory
- * area is not pre-mapped, NULL will be returned.
- *
- * acpi_iomaps_lock or RCU read lock must be held before calling
- */
-static void __iomem *__acpi_ioremap_fast(phys_addr_t paddr,
- unsigned long size)
-{
- struct acpi_iomap *map;
-
- map = __acpi_find_iomap(paddr, size/8);
- if (map)
- return map->vaddr + (paddr - map->paddr);
- else
- return NULL;
-}
-
-/* acpi_iomaps_lock must be held before calling */
-static void __iomem *__acpi_try_ioremap(phys_addr_t paddr,
- unsigned long size)
-{
- struct acpi_iomap *map;
-
- map = __acpi_find_iomap(paddr, size);
- if (map) {
- kref_get(&map->ref);
- return map->vaddr + (paddr - map->paddr);
- } else
- return NULL;
-}
-
-#ifndef CONFIG_IA64
-#define should_use_kmap(pfn) page_is_ram(pfn)
-#else
-/* ioremap will take care of cache attributes */
-#define should_use_kmap(pfn) 0
-#endif
-
-static void __iomem *acpi_map(phys_addr_t pg_off, unsigned long pg_sz)
-{
- unsigned long pfn;
-
- pfn = pg_off >> PAGE_SHIFT;
- if (should_use_kmap(pfn)) {
- if (pg_sz > PAGE_SIZE)
- return NULL;
- return (void __iomem __force *)kmap(pfn_to_page(pfn));
- } else
- return ioremap(pg_off, pg_sz);
-}
-
-static void acpi_unmap(phys_addr_t pg_off, void __iomem *vaddr)
-{
- unsigned long pfn;
-
- pfn = pg_off >> PAGE_SHIFT;
- if (page_is_ram(pfn))
- kunmap(pfn_to_page(pfn));
- else
- iounmap(vaddr);
-}
-
-/*
- * Used to pre-map the specified IO memory area. First try to find
- * whether the area is already pre-mapped, if it is, increase the
- * reference count (in __acpi_try_ioremap) and return; otherwise, do
- * the real ioremap, and add the mapping into acpi_iomaps list.
- */
-static void __iomem *acpi_pre_map(phys_addr_t paddr,
- unsigned long size)
-{
- void __iomem *vaddr;
- struct acpi_iomap *map;
- unsigned long pg_sz, flags;
- phys_addr_t pg_off;
-
- spin_lock_irqsave(&acpi_iomaps_lock, flags);
- vaddr = __acpi_try_ioremap(paddr, size);
- spin_unlock_irqrestore(&acpi_iomaps_lock, flags);
- if (vaddr)
- return vaddr;
-
- pg_off = paddr & PAGE_MASK;
- pg_sz = ((paddr + size + PAGE_SIZE - 1) & PAGE_MASK) - pg_off;
- vaddr = acpi_map(pg_off, pg_sz);
- if (!vaddr)
- return NULL;
- map = kmalloc(sizeof(*map), GFP_KERNEL);
- if (!map)
- goto err_unmap;
- INIT_LIST_HEAD(&map->list);
- map->paddr = pg_off;
- map->size = pg_sz;
- map->vaddr = vaddr;
- kref_init(&map->ref);
-
- spin_lock_irqsave(&acpi_iomaps_lock, flags);
- vaddr = __acpi_try_ioremap(paddr, size);
- if (vaddr) {
- spin_unlock_irqrestore(&acpi_iomaps_lock, flags);
- acpi_unmap(pg_off, map->vaddr);
- kfree(map);
- return vaddr;
- }
- list_add_tail_rcu(&map->list, &acpi_iomaps);
- spin_unlock_irqrestore(&acpi_iomaps_lock, flags);
-
- return map->vaddr + (paddr - map->paddr);
-err_unmap:
- acpi_unmap(pg_off, vaddr);
- return NULL;
-}
-
-/* acpi_iomaps_lock must be held before calling */
-static void __acpi_kref_del_iomap(struct kref *ref)
-{
- struct acpi_iomap *map;
-
- map = container_of(ref, struct acpi_iomap, ref);
- list_del_rcu(&map->list);
-}
-
-/*
- * Used to post-unmap the specified IO memory area. The iounmap is
- * done only if the reference count goes zero.
- */
-static void acpi_post_unmap(phys_addr_t paddr, unsigned long size)
-{
- struct acpi_iomap *map;
- unsigned long flags;
- int del;
-
- spin_lock_irqsave(&acpi_iomaps_lock, flags);
- map = __acpi_find_iomap(paddr, size);
- BUG_ON(!map);
- del = kref_put(&map->ref, __acpi_kref_del_iomap);
- spin_unlock_irqrestore(&acpi_iomaps_lock, flags);
-
- if (!del)
- return;
-
- synchronize_rcu();
- acpi_unmap(map->paddr, map->vaddr);
- kfree(map);
-}
-
-/* In NMI handler, should set silent = 1 */
-static int acpi_check_gar(struct acpi_generic_address *reg,
- u64 *paddr, int silent)
-{
- u32 width, space_id;
-
- width = reg->bit_width;
- space_id = reg->space_id;
- /* Handle possible alignment issues */
- memcpy(paddr, &reg->address, sizeof(*paddr));
- if (!*paddr) {
- if (!silent)
- pr_warning(FW_BUG ACPI_PFX
- "Invalid physical address in GAR [0x%llx/%u/%u]\n",
- *paddr, width, space_id);
- return -EINVAL;
- }
-
- if ((width != 8) && (width != 16) && (width != 32) && (width != 64)) {
- if (!silent)
- pr_warning(FW_BUG ACPI_PFX
- "Invalid bit width in GAR [0x%llx/%u/%u]\n",
- *paddr, width, space_id);
- return -EINVAL;
- }
-
- if (space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY &&
- space_id != ACPI_ADR_SPACE_SYSTEM_IO) {
- if (!silent)
- pr_warning(FW_BUG ACPI_PFX
- "Invalid address space type in GAR [0x%llx/%u/%u]\n",
- *paddr, width, space_id);
- return -EINVAL;
- }
-
- return 0;
-}
-
-/* Pre-map, working on GAR */
-int acpi_pre_map_gar(struct acpi_generic_address *reg)
-{
- u64 paddr;
- void __iomem *vaddr;
- int rc;
-
- if (reg->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY)
- return 0;
-
- rc = acpi_check_gar(reg, &paddr, 0);
- if (rc)
- return rc;
-
- vaddr = acpi_pre_map(paddr, reg->bit_width / 8);
- if (!vaddr)
- return -EIO;
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(acpi_pre_map_gar);
-
-/* Post-unmap, working on GAR */
-int acpi_post_unmap_gar(struct acpi_generic_address *reg)
-{
- u64 paddr;
- int rc;
-
- if (reg->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY)
- return 0;
-
- rc = acpi_check_gar(reg, &paddr, 0);
- if (rc)
- return rc;
-
- acpi_post_unmap(paddr, reg->bit_width / 8);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(acpi_post_unmap_gar);
-
-#ifdef readq
-static inline u64 read64(const volatile void __iomem *addr)
-{
- return readq(addr);
-}
-#else
-static inline u64 read64(const volatile void __iomem *addr)
-{
- u64 l, h;
- l = readl(addr);
- h = readl(addr+4);
- return l | (h << 32);
-}
-#endif
-
-/*
- * Can be used in atomic (including NMI) or process context. RCU read
- * lock can only be released after the IO memory area accessing.
- */
-static int acpi_atomic_read_mem(u64 paddr, u64 *val, u32 width)
-{
- void __iomem *addr;
-
- rcu_read_lock();
- addr = __acpi_ioremap_fast(paddr, width);
- switch (width) {
- case 8:
- *val = readb(addr);
- break;
- case 16:
- *val = readw(addr);
- break;
- case 32:
- *val = readl(addr);
- break;
- case 64:
- *val = read64(addr);
- break;
- default:
- return -EINVAL;
- }
- rcu_read_unlock();
-
- return 0;
-}
-
-#ifdef writeq
-static inline void write64(u64 val, volatile void __iomem *addr)
-{
- writeq(val, addr);
-}
-#else
-static inline void write64(u64 val, volatile void __iomem *addr)
-{
- writel(val, addr);
- writel(val>>32, addr+4);
-}
-#endif
-
-static int acpi_atomic_write_mem(u64 paddr, u64 val, u32 width)
-{
- void __iomem *addr;
-
- rcu_read_lock();
- addr = __acpi_ioremap_fast(paddr, width);
- switch (width) {
- case 8:
- writeb(val, addr);
- break;
- case 16:
- writew(val, addr);
- break;
- case 32:
- writel(val, addr);
- break;
- case 64:
- write64(val, addr);
- break;
- default:
- return -EINVAL;
- }
- rcu_read_unlock();
-
- return 0;
-}
-
-/* GAR accessing in atomic (including NMI) or process context */
-int acpi_atomic_read(u64 *val, struct acpi_generic_address *reg)
-{
- u64 paddr;
- int rc;
-
- rc = acpi_check_gar(reg, &paddr, 1);
- if (rc)
- return rc;
-
- *val = 0;
- switch (reg->space_id) {
- case ACPI_ADR_SPACE_SYSTEM_MEMORY:
- return acpi_atomic_read_mem(paddr, val, reg->bit_width);
- case ACPI_ADR_SPACE_SYSTEM_IO:
- return acpi_os_read_port(paddr, (u32 *)val, reg->bit_width);
- default:
- return -EINVAL;
- }
-}
-EXPORT_SYMBOL_GPL(acpi_atomic_read);
-
-int acpi_atomic_write(u64 val, struct acpi_generic_address *reg)
-{
- u64 paddr;
- int rc;
-
- rc = acpi_check_gar(reg, &paddr, 1);
- if (rc)
- return rc;
-
- switch (reg->space_id) {
- case ACPI_ADR_SPACE_SYSTEM_MEMORY:
- return acpi_atomic_write_mem(paddr, val, reg->bit_width);
- case ACPI_ADR_SPACE_SYSTEM_IO:
- return acpi_os_write_port(paddr, val, reg->bit_width);
- default:
- return -EINVAL;
- }
-}
-EXPORT_SYMBOL_GPL(acpi_atomic_write);
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index fcc12d842bcc..412a1e04a922 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -31,6 +31,7 @@
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/mm.h>
+#include <linux/highmem.h>
#include <linux/pci.h>
#include <linux/interrupt.h>
#include <linux/kmod.h>
@@ -321,6 +322,37 @@ acpi_map_lookup_virt(void __iomem *virt, acpi_size size)
return NULL;
}
+#ifndef CONFIG_IA64
+#define should_use_kmap(pfn) page_is_ram(pfn)
+#else
+/* ioremap will take care of cache attributes */
+#define should_use_kmap(pfn) 0
+#endif
+
+static void __iomem *acpi_map(acpi_physical_address pg_off, unsigned long pg_sz)
+{
+ unsigned long pfn;
+
+ pfn = pg_off >> PAGE_SHIFT;
+ if (should_use_kmap(pfn)) {
+ if (pg_sz > PAGE_SIZE)
+ return NULL;
+ return (void __iomem __force *)kmap(pfn_to_page(pfn));
+ } else
+ return acpi_os_ioremap(pg_off, pg_sz);
+}
+
+static void acpi_unmap(acpi_physical_address pg_off, void __iomem *vaddr)
+{
+ unsigned long pfn;
+
+ pfn = pg_off >> PAGE_SHIFT;
+ if (page_is_ram(pfn))
+ kunmap(pfn_to_page(pfn));
+ else
+ iounmap(vaddr);
+}
+
void __iomem *__init_refok
acpi_os_map_memory(acpi_physical_address phys, acpi_size size)
{
@@ -353,7 +385,7 @@ acpi_os_map_memory(acpi_physical_address phys, acpi_size size)
pg_off = round_down(phys, PAGE_SIZE);
pg_sz = round_up(phys + size, PAGE_SIZE) - pg_off;
- virt = acpi_os_ioremap(pg_off, pg_sz);
+ virt = acpi_map(pg_off, pg_sz);
if (!virt) {
mutex_unlock(&acpi_ioremap_lock);
kfree(map);
@@ -384,7 +416,7 @@ static void acpi_os_map_cleanup(struct acpi_ioremap *map)
{
if (!map->refcount) {
synchronize_rcu();
- iounmap(map->virt);
+ acpi_unmap(map->phys, map->virt);
kfree(map);
}
}
@@ -710,6 +742,67 @@ acpi_os_read_memory(acpi_physical_address phys_addr, u32 * value, u32 width)
return AE_OK;
}
+#ifdef readq
+static inline u64 read64(const volatile void __iomem *addr)
+{
+ return readq(addr);
+}
+#else
+static inline u64 read64(const volatile void __iomem *addr)
+{
+ u64 l, h;
+ l = readl(addr);
+ h = readl(addr+4);
+ return l | (h << 32);
+}
+#endif
+
+acpi_status
+acpi_os_read_memory64(acpi_physical_address phys_addr, u64 *value, u32 width)
+{
+ void __iomem *virt_addr;
+ unsigned int size = width / 8;
+ bool unmap = false;
+ u64 dummy;
+
+ rcu_read_lock();
+ virt_addr = acpi_map_vaddr_lookup(phys_addr, size);
+ if (!virt_addr) {
+ rcu_read_unlock();
+ virt_addr = acpi_os_ioremap(phys_addr, size);
+ if (!virt_addr)
+ return AE_BAD_ADDRESS;
+ unmap = true;
+ }
+
+ if (!value)
+ value = &dummy;
+
+ switch (width) {
+ case 8:
+ *(u8 *) value = readb(virt_addr);
+ break;
+ case 16:
+ *(u16 *) value = readw(virt_addr);
+ break;
+ case 32:
+ *(u32 *) value = readl(virt_addr);
+ break;
+ case 64:
+ *(u64 *) value = read64(virt_addr);
+ break;
+ default:
+ BUG();
+ }
+
+ if (unmap)
+ iounmap(virt_addr);
+ else
+ rcu_read_unlock();
+
+ return AE_OK;
+}
+
acpi_status
acpi_os_write_memory(acpi_physical_address phys_addr, u32 value, u32 width)
{
@@ -749,6 +842,61 @@ acpi_os_write_memory(acpi_physical_address phys_addr, u32 value, u32 width)
return AE_OK;
}
+#ifdef writeq
+static inline void write64(u64 val, volatile void __iomem *addr)
+{
+ writeq(val, addr);
+}
+#else
+static inline void write64(u64 val, volatile void __iomem *addr)
+{
+ writel(val, addr);
+ writel(val>>32, addr+4);
+}
+#endif
+
+acpi_status
+acpi_os_write_memory64(acpi_physical_address phys_addr, u64 value, u32 width)
+{
+ void __iomem *virt_addr;
+ unsigned int size = width / 8;
+ bool unmap = false;
+
+ rcu_read_lock();
+ virt_addr = acpi_map_vaddr_lookup(phys_addr, size);
+ if (!virt_addr) {
+ rcu_read_unlock();
+ virt_addr = acpi_os_ioremap(phys_addr, size);
+ if (!virt_addr)
+ return AE_BAD_ADDRESS;
+ unmap = true;
+ }
+
+ switch (width) {
+ case 8:
+ writeb(value, virt_addr);
+ break;
+ case 16:
+ writew(value, virt_addr);
+ break;
+ case 32:
+ writel(value, virt_addr);
+ break;
+ case 64:
+ write64(value, virt_addr);
+ break;
+ default:
+ BUG();
+ }
+
+ if (unmap)
+ iounmap(virt_addr);
+ else
+ rcu_read_unlock();
+
+ return AE_OK;
+}
+
acpi_status
acpi_os_read_pci_configuration(struct acpi_pci_id * pci_id, u32 reg,
u64 *value, u32 width)
diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c
index 0034ede38710..2b805d7ef317 100644
--- a/drivers/acpi/processor_driver.c
+++ b/drivers/acpi/processor_driver.c
@@ -84,7 +84,7 @@ static int acpi_processor_remove(struct acpi_device *device, int type);
static void acpi_processor_notify(struct acpi_device *device, u32 event);
static acpi_status acpi_processor_hotadd_init(struct acpi_processor *pr);
static int acpi_processor_handle_eject(struct acpi_processor *pr);
-
+static int acpi_processor_start(struct acpi_processor *pr);
static const struct acpi_device_id processor_device_ids[] = {
{ACPI_PROCESSOR_OBJECT_HID, 0},
@@ -423,10 +423,29 @@ static int acpi_cpu_soft_notify(struct notifier_block *nfb,
struct acpi_processor *pr = per_cpu(processors, cpu);
if (action == CPU_ONLINE && pr) {
- acpi_processor_ppc_has_changed(pr, 0);
- acpi_processor_hotplug(pr);
- acpi_processor_reevaluate_tstate(pr, action);
- acpi_processor_tstate_has_changed(pr);
+ /* CPU got physically hotplugged and onlined the first time:
+ * Initialize missing things
+ */
+ if (pr->flags.need_hotplug_init) {
+ struct cpuidle_driver *idle_driver =
+ cpuidle_get_driver();
+
+ printk(KERN_INFO "Will online and init hotplugged "
+ "CPU: %d\n", pr->id);
+ WARN(acpi_processor_start(pr), "Failed to start CPU:"
+ " %d\n", pr->id);
+ pr->flags.need_hotplug_init = 0;
+ if (idle_driver && !strcmp(idle_driver->name,
+ "intel_idle")) {
+ intel_idle_cpu_init(pr->id);
+ }
+ /* Normal CPU soft online event */
+ } else {
+ acpi_processor_ppc_has_changed(pr, 0);
+ acpi_processor_cst_has_changed(pr);
+ acpi_processor_reevaluate_tstate(pr, action);
+ acpi_processor_tstate_has_changed(pr);
+ }
}
if (action == CPU_DEAD && pr) {
/* invalidate the flag.throttling after one CPU is offline */
@@ -440,6 +459,71 @@ static struct notifier_block acpi_cpu_notifier =
.notifier_call = acpi_cpu_soft_notify,
};
+/*
+ * acpi_processor_start() is called by the cpu_hotplug_notifier func:
+ * acpi_cpu_soft_notify(). Getting it __cpuinit{data} is difficult, the
+ * root cause seem to be that acpi_processor_uninstall_hotplug_notify()
+ * is in the module_exit (__exit) func. Allowing acpi_processor_start()
+ * to not be in __cpuinit section, but being called from __cpuinit funcs
+ * via __ref looks like the right thing to do here.
+ */
+static __ref int acpi_processor_start(struct acpi_processor *pr)
+{
+ struct acpi_device *device = per_cpu(processor_device_array, pr->id);
+ int result = 0;
+
+#ifdef CONFIG_CPU_FREQ
+ acpi_processor_ppc_has_changed(pr, 0);
+#endif
+ acpi_processor_get_throttling_info(pr);
+ acpi_processor_get_limit_info(pr);
+
+ if (!cpuidle_get_driver() || cpuidle_get_driver() == &acpi_idle_driver)
+ acpi_processor_power_init(pr, device);
+
+ pr->cdev = thermal_cooling_device_register("Processor", device,
+ &processor_cooling_ops);
+ if (IS_ERR(pr->cdev)) {
+ result = PTR_ERR(pr->cdev);
+ goto err_power_exit;
+ }
+
+ dev_dbg(&device->dev, "registered as cooling_device%d\n",
+ pr->cdev->id);
+
+ result = sysfs_create_link(&device->dev.kobj,
+ &pr->cdev->device.kobj,
+ "thermal_cooling");
+ if (result) {
+ printk(KERN_ERR PREFIX "Create sysfs link\n");
+ goto err_thermal_unregister;
+ }
+ result = sysfs_create_link(&pr->cdev->device.kobj,
+ &device->dev.kobj,
+ "device");
+ if (result) {
+ printk(KERN_ERR PREFIX "Create sysfs link\n");
+ goto err_remove_sysfs_thermal;
+ }
+
+ return 0;
+
+err_remove_sysfs_thermal:
+ sysfs_remove_link(&device->dev.kobj, "thermal_cooling");
+err_thermal_unregister:
+ thermal_cooling_device_unregister(pr->cdev);
+err_power_exit:
+ acpi_processor_power_exit(pr, device);
+
+ return result;
+}
+
+/*
+ * Do not put anything in here which needs the core to be online.
+ * For example MSR access or setting up things which check for cpuinfo_x86
+ * (cpu_data(cpu)) values, like CPU feature flags, family, model, etc.
+ * Such things have to be put in and set up above in acpi_processor_start()
+ */
static int __cpuinit acpi_processor_add(struct acpi_device *device)
{
struct acpi_processor *pr = NULL;
@@ -495,48 +579,27 @@ static int __cpuinit acpi_processor_add(struct acpi_device *device)
goto err_free_cpumask;
}
-#ifdef CONFIG_CPU_FREQ
- acpi_processor_ppc_has_changed(pr, 0);
-#endif
- acpi_processor_get_throttling_info(pr);
- acpi_processor_get_limit_info(pr);
-
- if (!cpuidle_get_driver() || cpuidle_get_driver() == &acpi_idle_driver)
- acpi_processor_power_init(pr, device);
-
- pr->cdev = thermal_cooling_device_register("Processor", device,
- &processor_cooling_ops);
- if (IS_ERR(pr->cdev)) {
- result = PTR_ERR(pr->cdev);
- goto err_power_exit;
- }
+ /*
+ * Do not start hotplugged CPUs now, but when they
+ * are onlined the first time
+ */
+ if (pr->flags.need_hotplug_init)
+ return 0;
- dev_dbg(&device->dev, "registered as cooling_device%d\n",
- pr->cdev->id);
+ /*
+ * Do not start hotplugged CPUs now, but when they
+ * are onlined the first time
+ */
+ if (pr->flags.need_hotplug_init)
+ return 0;
- result = sysfs_create_link(&device->dev.kobj,
- &pr->cdev->device.kobj,
- "thermal_cooling");
- if (result) {
- printk(KERN_ERR PREFIX "Create sysfs link\n");
- goto err_thermal_unregister;
- }
- result = sysfs_create_link(&pr->cdev->device.kobj,
- &device->dev.kobj,
- "device");
- if (result) {
- printk(KERN_ERR PREFIX "Create sysfs link\n");
+ result = acpi_processor_start(pr);
+ if (result)
goto err_remove_sysfs;
- }
return 0;
err_remove_sysfs:
- sysfs_remove_link(&device->dev.kobj, "thermal_cooling");
-err_thermal_unregister:
- thermal_cooling_device_unregister(pr->cdev);
-err_power_exit:
- acpi_processor_power_exit(pr, device);
sysfs_remove_link(&device->dev.kobj, "sysdev");
err_free_cpumask:
free_cpumask_var(pr->throttling.shared_cpu_map);
@@ -735,6 +798,17 @@ static acpi_status acpi_processor_hotadd_init(struct acpi_processor *pr)
return AE_ERROR;
}
+ /* CPU got hot-plugged, but cpu_data is not initialized yet
+ * Set flag to delay cpu_idle/throttling initialization
+ * in:
+ * acpi_processor_add()
+ * acpi_processor_get_info()
+ * and do it when the CPU gets online the first time
+ * TBD: Cleanup above functions and try to do this more elegant.
+ */
+ printk(KERN_INFO "CPU %d got hotplugged\n", pr->id);
+ pr->flags.need_hotplug_init = 1;
+
return AE_OK;
}
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c
index 0a7ed69546ba..ca191ff97844 100644
--- a/drivers/acpi/sleep.c
+++ b/drivers/acpi/sleep.c
@@ -438,6 +438,14 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = {
},
{
.callback = init_nvs_nosave,
+ .ident = "Sony Vaio VPCCW29FX",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "VPCCW29FX"),
+ },
+ },
+ {
+ .callback = init_nvs_nosave,
.ident = "Averatec AV1020-ED2",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "AVERATEC"),
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index 99dc5921e1dd..40fb12288ce2 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -915,9 +915,10 @@ static BUS_ATTR(uevent, S_IWUSR, NULL, bus_uevent_store);
/**
* __bus_register - register a driver-core subsystem
- * @bus: bus.
+ * @bus: bus to register
+ * @key: lockdep class key
*
- * Once we have that, we registered the bus with the kobject
+ * Once we have that, we register the bus with the kobject
* infrastructure, then register the children subsystems it has:
* the devices and drivers that belong to the subsystem.
*/
@@ -1220,8 +1221,8 @@ static void system_root_device_release(struct device *dev)
}
/**
* subsys_system_register - register a subsystem at /sys/devices/system/
- * @subsys - system subsystem
- * @groups - default attributes for the root device
+ * @subsys: system subsystem
+ * @groups: default attributes for the root device
*
* All 'system' subsystems have a /sys/devices/system/<name> root device
* with the name of the subsystem. The root device can carry subsystem-
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
index 26ab358dac62..6c9387d646ec 100644
--- a/drivers/base/firmware_class.c
+++ b/drivers/base/firmware_class.c
@@ -525,8 +525,7 @@ static int _request_firmware(const struct firmware **firmware_p,
if (!firmware) {
dev_err(device, "%s: kmalloc(struct firmware) failed\n",
__func__);
- retval = -ENOMEM;
- goto out;
+ return -ENOMEM;
}
if (fw_get_builtin_firmware(firmware, name)) {
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index be10a4ff6609..65558034318f 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -284,6 +284,9 @@ int regmap_reinit_cache(struct regmap *map, const struct regmap_config *config)
map->precious_reg = config->precious_reg;
map->cache_type = config->cache_type;
+ map->cache_bypass = false;
+ map->cache_only = false;
+
ret = regcache_init(map, config);
mutex_unlock(&map->lock);
diff --git a/drivers/gpu/drm/drm_auth.c b/drivers/gpu/drm/drm_auth.c
index 3f46772f0cb2..ba23790450e9 100644
--- a/drivers/gpu/drm/drm_auth.c
+++ b/drivers/gpu/drm/drm_auth.c
@@ -101,7 +101,7 @@ static int drm_add_magic(struct drm_master *master, struct drm_file *priv,
* Searches and unlinks the entry in drm_device::magiclist with the magic
* number hash key, while holding the drm_device::struct_mutex lock.
*/
-static int drm_remove_magic(struct drm_master *master, drm_magic_t magic)
+int drm_remove_magic(struct drm_master *master, drm_magic_t magic)
{
struct drm_magic_entry *pt;
struct drm_hash_item *hash;
@@ -136,6 +136,8 @@ static int drm_remove_magic(struct drm_master *master, drm_magic_t magic)
* If there is a magic number in drm_file::magic then use it, otherwise
* searches an unique non-zero magic number and add it associating it with \p
* file_priv.
+ * This ioctl needs protection by the drm_global_mutex, which protects
+ * struct drm_file::magic and struct drm_magic_entry::priv.
*/
int drm_getmagic(struct drm_device *dev, void *data, struct drm_file *file_priv)
{
@@ -173,6 +175,8 @@ int drm_getmagic(struct drm_device *dev, void *data, struct drm_file *file_priv)
* \return zero if authentication successed, or a negative number otherwise.
*
* Checks if \p file_priv is associated with the magic number passed in \arg.
+ * This ioctl needs protection by the drm_global_mutex, which protects
+ * struct drm_file::magic and struct drm_magic_entry::priv.
*/
int drm_authmagic(struct drm_device *dev, void *data,
struct drm_file *file_priv)
diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c
index c00cf154cc0b..6263b0147598 100644
--- a/drivers/gpu/drm/drm_fops.c
+++ b/drivers/gpu/drm/drm_fops.c
@@ -487,6 +487,11 @@ int drm_release(struct inode *inode, struct file *filp)
(long)old_encode_dev(file_priv->minor->device),
dev->open_count);
+ /* Release any auth tokens that might point to this file_priv,
+ (do that under the drm_global_mutex) */
+ if (file_priv->magic)
+ (void) drm_remove_magic(file_priv->master, file_priv->magic);
+
/* if the master has gone away we can't do anything with the lock */
if (file_priv->minor->master)
drm_master_release(dev, filp);
diff --git a/drivers/gpu/drm/gma500/gtt.c b/drivers/gpu/drm/gma500/gtt.c
index e770bd190a5c..5d5330f667f1 100644
--- a/drivers/gpu/drm/gma500/gtt.c
+++ b/drivers/gpu/drm/gma500/gtt.c
@@ -20,6 +20,7 @@
*/
#include <drm/drmP.h>
+#include <linux/shmem_fs.h>
#include "psb_drv.h"
@@ -203,9 +204,7 @@ static int psb_gtt_attach_pages(struct gtt_range *gt)
gt->npage = pages;
for (i = 0; i < pages; i++) {
- /* FIXME: needs updating as per mail from Hugh Dickins */
- p = read_cache_page_gfp(mapping, i,
- __GFP_COLD | GFP_KERNEL);
+ p = shmem_read_mapping_page(mapping, i);
if (IS_ERR(p))
goto err;
gt->pages[i] = p;
diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c
index 724b41a2b9e9..ec54364ac828 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bo.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bo.c
@@ -812,6 +812,10 @@ nouveau_bo_move_ntfy(struct ttm_buffer_object *bo, struct ttm_mem_reg *new_mem)
struct nouveau_bo *nvbo = nouveau_bo(bo);
struct nouveau_vma *vma;
+ /* ttm can now (stupidly) pass the driver bos it didn't create... */
+ if (bo->destroy != nouveau_bo_del_ttm)
+ return;
+
list_for_each_entry(vma, &nvbo->vma_list, head) {
if (new_mem && new_mem->mem_type == TTM_PL_VRAM) {
nouveau_vm_map(vma, new_mem->mm_node);
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c
index 0fda830ef806..891935271d34 100644
--- a/drivers/gpu/drm/radeon/atombios_crtc.c
+++ b/drivers/gpu/drm/radeon/atombios_crtc.c
@@ -355,15 +355,12 @@ static void atombios_crtc_set_timing(struct drm_crtc *crtc,
atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
}
-static void atombios_disable_ss(struct drm_crtc *crtc)
+static void atombios_disable_ss(struct radeon_device *rdev, int pll_id)
{
- struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
- struct drm_device *dev = crtc->dev;
- struct radeon_device *rdev = dev->dev_private;
u32 ss_cntl;
if (ASIC_IS_DCE4(rdev)) {
- switch (radeon_crtc->pll_id) {
+ switch (pll_id) {
case ATOM_PPLL1:
ss_cntl = RREG32(EVERGREEN_P1PLL_SS_CNTL);
ss_cntl &= ~EVERGREEN_PxPLL_SS_EN;
@@ -379,7 +376,7 @@ static void atombios_disable_ss(struct drm_crtc *crtc)
return;
}
} else if (ASIC_IS_AVIVO(rdev)) {
- switch (radeon_crtc->pll_id) {
+ switch (pll_id) {
case ATOM_PPLL1:
ss_cntl = RREG32(AVIVO_P1PLL_INT_SS_CNTL);
ss_cntl &= ~1;
@@ -406,13 +403,11 @@ union atom_enable_ss {
ENABLE_SPREAD_SPECTRUM_ON_PPLL_V3 v3;
};
-static void atombios_crtc_program_ss(struct drm_crtc *crtc,
+static void atombios_crtc_program_ss(struct radeon_device *rdev,
int enable,
int pll_id,
struct radeon_atom_ss *ss)
{
- struct drm_device *dev = crtc->dev;
- struct radeon_device *rdev = dev->dev_private;
int index = GetIndexIntoMasterTable(COMMAND, EnableSpreadSpectrumOnPPLL);
union atom_enable_ss args;
@@ -479,7 +474,7 @@ static void atombios_crtc_program_ss(struct drm_crtc *crtc,
} else if (ASIC_IS_AVIVO(rdev)) {
if ((enable == ATOM_DISABLE) || (ss->percentage == 0) ||
(ss->type & ATOM_EXTERNAL_SS_MASK)) {
- atombios_disable_ss(crtc);
+ atombios_disable_ss(rdev, pll_id);
return;
}
args.lvds_ss_2.usSpreadSpectrumPercentage = cpu_to_le16(ss->percentage);
@@ -491,7 +486,7 @@ static void atombios_crtc_program_ss(struct drm_crtc *crtc,
} else {
if ((enable == ATOM_DISABLE) || (ss->percentage == 0) ||
(ss->type & ATOM_EXTERNAL_SS_MASK)) {
- atombios_disable_ss(crtc);
+ atombios_disable_ss(rdev, pll_id);
return;
}
args.lvds_ss.usSpreadSpectrumPercentage = cpu_to_le16(ss->percentage);
@@ -523,6 +518,7 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
int encoder_mode = 0;
u32 dp_clock = mode->clock;
int bpc = 8;
+ bool is_duallink = false;
/* reset the pll flags */
pll->flags = 0;
@@ -557,6 +553,7 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
if (connector && connector->display_info.bpc)
bpc = connector->display_info.bpc;
encoder_mode = atombios_get_encoder_mode(encoder);
+ is_duallink = radeon_dig_monitor_is_duallink(encoder, mode->clock);
if ((radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT | ATOM_DEVICE_DFP_SUPPORT)) ||
(radeon_encoder_get_dp_bridge_encoder_id(encoder) != ENCODER_OBJECT_ID_NONE)) {
if (connector) {
@@ -652,7 +649,7 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
if (dig->coherent_mode)
args.v3.sInput.ucDispPllConfig |=
DISPPLL_CONFIG_COHERENT_MODE;
- if (mode->clock > 165000)
+ if (is_duallink)
args.v3.sInput.ucDispPllConfig |=
DISPPLL_CONFIG_DUAL_LINK;
}
@@ -702,11 +699,9 @@ union set_pixel_clock {
/* on DCE5, make sure the voltage is high enough to support the
* required disp clk.
*/
-static void atombios_crtc_set_dcpll(struct drm_crtc *crtc,
+static void atombios_crtc_set_dcpll(struct radeon_device *rdev,
u32 dispclk)
{
- struct drm_device *dev = crtc->dev;
- struct radeon_device *rdev = dev->dev_private;
u8 frev, crev;
int index;
union set_pixel_clock args;
@@ -996,7 +991,7 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode
radeon_compute_pll_legacy(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div,
&ref_div, &post_div);
- atombios_crtc_program_ss(crtc, ATOM_DISABLE, radeon_crtc->pll_id, &ss);
+ atombios_crtc_program_ss(rdev, ATOM_DISABLE, radeon_crtc->pll_id, &ss);
atombios_crtc_program_pll(crtc, radeon_crtc->crtc_id, radeon_crtc->pll_id,
encoder_mode, radeon_encoder->encoder_id, mode->clock,
@@ -1019,7 +1014,7 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode
ss.step = step_size;
}
- atombios_crtc_program_ss(crtc, ATOM_ENABLE, radeon_crtc->pll_id, &ss);
+ atombios_crtc_program_ss(rdev, ATOM_ENABLE, radeon_crtc->pll_id, &ss);
}
}
@@ -1494,6 +1489,24 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc)
}
+void radeon_atom_dcpll_init(struct radeon_device *rdev)
+{
+ /* always set DCPLL */
+ if (ASIC_IS_DCE4(rdev)) {
+ struct radeon_atom_ss ss;
+ bool ss_enabled = radeon_atombios_get_asic_ss_info(rdev, &ss,
+ ASIC_INTERNAL_SS_ON_DCPLL,
+ rdev->clock.default_dispclk);
+ if (ss_enabled)
+ atombios_crtc_program_ss(rdev, ATOM_DISABLE, ATOM_DCPLL, &ss);
+ /* XXX: DCE5, make sure voltage, dispclk is high enough */
+ atombios_crtc_set_dcpll(rdev, rdev->clock.default_dispclk);
+ if (ss_enabled)
+ atombios_crtc_program_ss(rdev, ATOM_ENABLE, ATOM_DCPLL, &ss);
+ }
+
+}
+
int atombios_crtc_mode_set(struct drm_crtc *crtc,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode,
@@ -1515,19 +1528,6 @@ int atombios_crtc_mode_set(struct drm_crtc *crtc,
}
}
- /* always set DCPLL */
- if (ASIC_IS_DCE4(rdev)) {
- struct radeon_atom_ss ss;
- bool ss_enabled = radeon_atombios_get_asic_ss_info(rdev, &ss,
- ASIC_INTERNAL_SS_ON_DCPLL,
- rdev->clock.default_dispclk);
- if (ss_enabled)
- atombios_crtc_program_ss(crtc, ATOM_DISABLE, ATOM_DCPLL, &ss);
- /* XXX: DCE5, make sure voltage, dispclk is high enough */
- atombios_crtc_set_dcpll(crtc, rdev->clock.default_dispclk);
- if (ss_enabled)
- atombios_crtc_program_ss(crtc, ATOM_ENABLE, ATOM_DCPLL, &ss);
- }
atombios_crtc_set_pll(crtc, adjusted_mode);
if (ASIC_IS_DCE4(rdev))
diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c
index 6fb335a4fdda..a71557ce01dc 100644
--- a/drivers/gpu/drm/radeon/atombios_dp.c
+++ b/drivers/gpu/drm/radeon/atombios_dp.c
@@ -549,8 +549,8 @@ bool radeon_dp_getdpcd(struct radeon_connector *radeon_connector)
return false;
}
-static void radeon_dp_set_panel_mode(struct drm_encoder *encoder,
- struct drm_connector *connector)
+int radeon_dp_get_panel_mode(struct drm_encoder *encoder,
+ struct drm_connector *connector)
{
struct drm_device *dev = encoder->dev;
struct radeon_device *rdev = dev->dev_private;
@@ -558,7 +558,7 @@ static void radeon_dp_set_panel_mode(struct drm_encoder *encoder,
int panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE;
if (!ASIC_IS_DCE4(rdev))
- return;
+ return panel_mode;
if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) ==
ENCODER_OBJECT_ID_NUTMEG)
@@ -572,14 +572,7 @@ static void radeon_dp_set_panel_mode(struct drm_encoder *encoder,
panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE;
}
- atombios_dig_encoder_setup(encoder,
- ATOM_ENCODER_CMD_SETUP_PANEL_MODE,
- panel_mode);
-
- if ((connector->connector_type == DRM_MODE_CONNECTOR_eDP) &&
- (panel_mode == DP_PANEL_MODE_INTERNAL_DP2_MODE)) {
- radeon_write_dpcd_reg(radeon_connector, DP_EDP_CONFIGURATION_SET, 1);
- }
+ return panel_mode;
}
void radeon_dp_set_link_config(struct drm_connector *connector,
@@ -717,6 +710,8 @@ static void radeon_dp_set_tp(struct radeon_dp_link_train_info *dp_info, int tp)
static int radeon_dp_link_train_init(struct radeon_dp_link_train_info *dp_info)
{
+ struct radeon_encoder *radeon_encoder = to_radeon_encoder(dp_info->encoder);
+ struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
u8 tmp;
/* power up the sink */
@@ -732,7 +727,10 @@ static int radeon_dp_link_train_init(struct radeon_dp_link_train_info *dp_info)
radeon_write_dpcd_reg(dp_info->radeon_connector,
DP_DOWNSPREAD_CTRL, 0);
- radeon_dp_set_panel_mode(dp_info->encoder, dp_info->connector);
+ if ((dp_info->connector->connector_type == DRM_MODE_CONNECTOR_eDP) &&
+ (dig->panel_mode == DP_PANEL_MODE_INTERNAL_DP2_MODE)) {
+ radeon_write_dpcd_reg(dp_info->radeon_connector, DP_EDP_CONFIGURATION_SET, 1);
+ }
/* set the lane count on the sink */
tmp = dp_info->dp_lane_count;
diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c b/drivers/gpu/drm/radeon/atombios_encoders.c
index f1f06ca9f1f5..b88c4608731b 100644
--- a/drivers/gpu/drm/radeon/atombios_encoders.c
+++ b/drivers/gpu/drm/radeon/atombios_encoders.c
@@ -57,22 +57,6 @@ static inline bool radeon_encoder_is_digital(struct drm_encoder *encoder)
}
}
-static struct drm_connector *
-radeon_get_connector_for_encoder_init(struct drm_encoder *encoder)
-{
- struct drm_device *dev = encoder->dev;
- struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
- struct drm_connector *connector;
- struct radeon_connector *radeon_connector;
-
- list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
- radeon_connector = to_radeon_connector(connector);
- if (radeon_encoder->devices & radeon_connector->devices)
- return connector;
- }
- return NULL;
-}
-
static bool radeon_atom_mode_fixup(struct drm_encoder *encoder,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
@@ -253,7 +237,7 @@ atombios_dvo_setup(struct drm_encoder *encoder, int action)
/* R4xx, R5xx */
args.ext_tmds.sXTmdsEncoder.ucEnable = action;
- if (radeon_encoder->pixel_clock > 165000)
+ if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock))
args.ext_tmds.sXTmdsEncoder.ucMisc |= PANEL_ENCODER_MISC_DUAL;
args.ext_tmds.sXTmdsEncoder.ucMisc |= ATOM_PANEL_MISC_888RGB;
@@ -265,7 +249,7 @@ atombios_dvo_setup(struct drm_encoder *encoder, int action)
/* DFP1, CRT1, TV1 depending on the type of port */
args.dvo.sDVOEncoder.ucDeviceType = ATOM_DEVICE_DFP1_INDEX;
- if (radeon_encoder->pixel_clock > 165000)
+ if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock))
args.dvo.sDVOEncoder.usDevAttr.sDigAttrib.ucAttribute |= PANEL_ENCODER_MISC_DUAL;
break;
case 3:
@@ -349,7 +333,7 @@ atombios_digital_setup(struct drm_encoder *encoder, int action)
} else {
if (dig->linkb)
args.v1.ucMisc |= PANEL_ENCODER_MISC_TMDS_LINKB;
- if (radeon_encoder->pixel_clock > 165000)
+ if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock))
args.v1.ucMisc |= PANEL_ENCODER_MISC_DUAL;
/*if (pScrn->rgbBits == 8) */
args.v1.ucMisc |= ATOM_PANEL_MISC_888RGB;
@@ -388,7 +372,7 @@ atombios_digital_setup(struct drm_encoder *encoder, int action)
} else {
if (dig->linkb)
args.v2.ucMisc |= PANEL_ENCODER_MISC_TMDS_LINKB;
- if (radeon_encoder->pixel_clock > 165000)
+ if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock))
args.v2.ucMisc |= PANEL_ENCODER_MISC_DUAL;
}
break;
@@ -432,7 +416,7 @@ atombios_get_encoder_mode(struct drm_encoder *encoder)
switch (connector->connector_type) {
case DRM_MODE_CONNECTOR_DVII:
case DRM_MODE_CONNECTOR_HDMIB: /* HDMI-B is basically DL-DVI; analog works fine */
- if (drm_detect_monitor_audio(radeon_connector->edid) &&
+ if (drm_detect_hdmi_monitor(radeon_connector->edid) &&
radeon_audio)
return ATOM_ENCODER_MODE_HDMI;
else if (radeon_connector->use_digital)
@@ -443,7 +427,7 @@ atombios_get_encoder_mode(struct drm_encoder *encoder)
case DRM_MODE_CONNECTOR_DVID:
case DRM_MODE_CONNECTOR_HDMIA:
default:
- if (drm_detect_monitor_audio(radeon_connector->edid) &&
+ if (drm_detect_hdmi_monitor(radeon_connector->edid) &&
radeon_audio)
return ATOM_ENCODER_MODE_HDMI;
else
@@ -457,7 +441,7 @@ atombios_get_encoder_mode(struct drm_encoder *encoder)
if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) ||
(dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP))
return ATOM_ENCODER_MODE_DP;
- else if (drm_detect_monitor_audio(radeon_connector->edid) &&
+ else if (drm_detect_hdmi_monitor(radeon_connector->edid) &&
radeon_audio)
return ATOM_ENCODER_MODE_HDMI;
else
@@ -587,7 +571,7 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action, int panel_mo
if (ENCODER_MODE_IS_DP(args.v1.ucEncoderMode))
args.v1.ucLaneNum = dp_lane_count;
- else if (radeon_encoder->pixel_clock > 165000)
+ else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock))
args.v1.ucLaneNum = 8;
else
args.v1.ucLaneNum = 4;
@@ -622,7 +606,7 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action, int panel_mo
if (ENCODER_MODE_IS_DP(args.v1.ucEncoderMode))
args.v3.ucLaneNum = dp_lane_count;
- else if (radeon_encoder->pixel_clock > 165000)
+ else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock))
args.v3.ucLaneNum = 8;
else
args.v3.ucLaneNum = 4;
@@ -662,7 +646,7 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action, int panel_mo
if (ENCODER_MODE_IS_DP(args.v1.ucEncoderMode))
args.v4.ucLaneNum = dp_lane_count;
- else if (radeon_encoder->pixel_clock > 165000)
+ else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock))
args.v4.ucLaneNum = 8;
else
args.v4.ucLaneNum = 4;
@@ -806,7 +790,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
if (is_dp)
args.v1.usPixelClock =
cpu_to_le16(dp_clock / 10);
- else if (radeon_encoder->pixel_clock > 165000)
+ else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock))
args.v1.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10);
else
args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
@@ -821,7 +805,8 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
if ((rdev->flags & RADEON_IS_IGP) &&
(radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_UNIPHY)) {
- if (is_dp || (radeon_encoder->pixel_clock <= 165000)) {
+ if (is_dp ||
+ !radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) {
if (igp_lane_info & 0x1)
args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_3;
else if (igp_lane_info & 0x2)
@@ -848,7 +833,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {
if (dig->coherent_mode)
args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_COHERENT;
- if (radeon_encoder->pixel_clock > 165000)
+ if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock))
args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_8LANE_LINK;
}
break;
@@ -863,7 +848,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
if (is_dp)
args.v2.usPixelClock =
cpu_to_le16(dp_clock / 10);
- else if (radeon_encoder->pixel_clock > 165000)
+ else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock))
args.v2.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10);
else
args.v2.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
@@ -891,7 +876,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
} else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {
if (dig->coherent_mode)
args.v2.acConfig.fCoherentMode = 1;
- if (radeon_encoder->pixel_clock > 165000)
+ if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock))
args.v2.acConfig.fDualLinkConnector = 1;
}
break;
@@ -906,7 +891,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
if (is_dp)
args.v3.usPixelClock =
cpu_to_le16(dp_clock / 10);
- else if (radeon_encoder->pixel_clock > 165000)
+ else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock))
args.v3.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10);
else
args.v3.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
@@ -914,7 +899,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
if (is_dp)
args.v3.ucLaneNum = dp_lane_count;
- else if (radeon_encoder->pixel_clock > 165000)
+ else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock))
args.v3.ucLaneNum = 8;
else
args.v3.ucLaneNum = 4;
@@ -951,7 +936,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {
if (dig->coherent_mode)
args.v3.acConfig.fCoherentMode = 1;
- if (radeon_encoder->pixel_clock > 165000)
+ if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock))
args.v3.acConfig.fDualLinkConnector = 1;
}
break;
@@ -966,7 +951,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
if (is_dp)
args.v4.usPixelClock =
cpu_to_le16(dp_clock / 10);
- else if (radeon_encoder->pixel_clock > 165000)
+ else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock))
args.v4.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10);
else
args.v4.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
@@ -974,7 +959,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
if (is_dp)
args.v4.ucLaneNum = dp_lane_count;
- else if (radeon_encoder->pixel_clock > 165000)
+ else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock))
args.v4.ucLaneNum = 8;
else
args.v4.ucLaneNum = 4;
@@ -1014,7 +999,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {
if (dig->coherent_mode)
args.v4.acConfig.fCoherentMode = 1;
- if (radeon_encoder->pixel_clock > 165000)
+ if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock))
args.v4.acConfig.fDualLinkConnector = 1;
}
break;
@@ -1137,7 +1122,7 @@ atombios_external_encoder_setup(struct drm_encoder *encoder,
if (dp_clock == 270000)
args.v1.sDigEncoder.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ;
args.v1.sDigEncoder.ucLaneNum = dp_lane_count;
- } else if (radeon_encoder->pixel_clock > 165000)
+ } else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock))
args.v1.sDigEncoder.ucLaneNum = 8;
else
args.v1.sDigEncoder.ucLaneNum = 4;
@@ -1156,7 +1141,7 @@ atombios_external_encoder_setup(struct drm_encoder *encoder,
else if (dp_clock == 540000)
args.v3.sExtEncoder.ucConfig |= EXTERNAL_ENCODER_CONFIG_V3_DPLINKRATE_5_40GHZ;
args.v3.sExtEncoder.ucLaneNum = dp_lane_count;
- } else if (radeon_encoder->pixel_clock > 165000)
+ } else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock))
args.v3.sExtEncoder.ucLaneNum = 8;
else
args.v3.sExtEncoder.ucLaneNum = 4;
@@ -1341,7 +1326,8 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode)
switch (mode) {
case DRM_MODE_DPMS_ON:
/* some early dce3.2 boards have a bug in their transmitter control table */
- if ((rdev->family == CHIP_RV710) || (rdev->family == CHIP_RV730))
+ if ((rdev->family == CHIP_RV710) || (rdev->family == CHIP_RV730) ||
+ ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev))
atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0);
else
atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0);
@@ -1351,8 +1337,6 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode)
ATOM_TRANSMITTER_ACTION_POWER_ON);
radeon_dig_connector->edp_on = true;
}
- if (ASIC_IS_DCE4(rdev))
- atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_OFF, 0);
radeon_dp_link_train(encoder, connector);
if (ASIC_IS_DCE4(rdev))
atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_ON, 0);
@@ -1363,7 +1347,10 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode)
case DRM_MODE_DPMS_STANDBY:
case DRM_MODE_DPMS_SUSPEND:
case DRM_MODE_DPMS_OFF:
- atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT, 0, 0);
+ if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev))
+ atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0);
+ else
+ atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT, 0, 0);
if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector) {
if (ASIC_IS_DCE4(rdev))
atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_OFF, 0);
@@ -1810,7 +1797,21 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder,
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
- if (ASIC_IS_DCE4(rdev)) {
+ if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) {
+ struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
+ struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
+
+ if (!connector)
+ dig->panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE;
+ else
+ dig->panel_mode = radeon_dp_get_panel_mode(encoder, connector);
+
+ /* setup and enable the encoder */
+ atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_SETUP, 0);
+ atombios_dig_encoder_setup(encoder,
+ ATOM_ENCODER_CMD_SETUP_PANEL_MODE,
+ dig->panel_mode);
+ } else if (ASIC_IS_DCE4(rdev)) {
/* disable the transmitter */
atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0);
/* setup and enable the encoder */
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c
index 636660fca8c2..ae09fe82afbc 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -1455,6 +1455,7 @@ int evergreen_cp_resume(struct radeon_device *rdev)
#endif
WREG32(CP_RB_CNTL, tmp);
WREG32(CP_SEM_WAIT_TIMER, 0x0);
+ WREG32(CP_SEM_INCOMPLETE_TIMER_CNTL, 0x0);
/* Set the write pointer delay */
WREG32(CP_RB_WPTR_DELAY, 0);
diff --git a/drivers/gpu/drm/radeon/evergreend.h b/drivers/gpu/drm/radeon/evergreend.h
index b502216d42af..74713d42df29 100644
--- a/drivers/gpu/drm/radeon/evergreend.h
+++ b/drivers/gpu/drm/radeon/evergreend.h
@@ -108,6 +108,7 @@
#define CP_RB_WPTR_ADDR_HI 0xC11C
#define CP_RB_WPTR_DELAY 0x8704
#define CP_SEM_WAIT_TIMER 0x85BC
+#define CP_SEM_INCOMPLETE_TIMER_CNTL 0x85C8
#define CP_DEBUG 0xC1FC
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c
index 321137295400..db09065e68fd 100644
--- a/drivers/gpu/drm/radeon/ni.c
+++ b/drivers/gpu/drm/radeon/ni.c
@@ -1219,6 +1219,7 @@ int cayman_cp_resume(struct radeon_device *rdev)
RREG32(GRBM_SOFT_RESET);
WREG32(CP_SEM_WAIT_TIMER, 0x0);
+ WREG32(CP_SEM_INCOMPLETE_TIMER_CNTL, 0x0);
/* Set the write pointer delay */
WREG32(CP_RB_WPTR_DELAY, 0);
diff --git a/drivers/gpu/drm/radeon/nid.h b/drivers/gpu/drm/radeon/nid.h
index f9df2a645e79..9a7f3b6e02de 100644
--- a/drivers/gpu/drm/radeon/nid.h
+++ b/drivers/gpu/drm/radeon/nid.h
@@ -222,6 +222,7 @@
#define SCRATCH_UMSK 0x8540
#define SCRATCH_ADDR 0x8544
#define CP_SEM_WAIT_TIMER 0x85BC
+#define CP_SEM_INCOMPLETE_TIMER_CNTL 0x85C8
#define CP_COHER_CNTL2 0x85E8
#define CP_ME_CNTL 0x86D8
#define CP_ME_HALT (1 << 28)
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 73e05cb85eca..1668ec1ee770 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -157,6 +157,47 @@ bool radeon_get_bios(struct radeon_device *rdev);
/*
+ * Mutex which allows recursive locking from the same process.
+ */
+struct radeon_mutex {
+ struct mutex mutex;
+ struct task_struct *owner;
+ int level;
+};
+
+static inline void radeon_mutex_init(struct radeon_mutex *mutex)
+{
+ mutex_init(&mutex->mutex);
+ mutex->owner = NULL;
+ mutex->level = 0;
+}
+
+static inline void radeon_mutex_lock(struct radeon_mutex *mutex)
+{
+ if (mutex_trylock(&mutex->mutex)) {
+ /* The mutex was unlocked before, so it's ours now */
+ mutex->owner = current;
+ } else if (mutex->owner != current) {
+ /* Another process locked the mutex, take it */
+ mutex_lock(&mutex->mutex);
+ mutex->owner = current;
+ }
+ /* Otherwise the mutex was already locked by this process */
+
+ mutex->level++;
+}
+
+static inline void radeon_mutex_unlock(struct radeon_mutex *mutex)
+{
+ if (--mutex->level > 0)
+ return;
+
+ mutex->owner = NULL;
+ mutex_unlock(&mutex->mutex);
+}
+
+
+/*
* Dummy page
*/
struct radeon_dummy_page {
@@ -598,7 +639,7 @@ struct radeon_ib {
* mutex protects scheduled_ibs, ready, alloc_bm
*/
struct radeon_ib_pool {
- struct mutex mutex;
+ struct radeon_mutex mutex;
struct radeon_sa_manager sa_manager;
struct radeon_ib ibs[RADEON_IB_POOL_SIZE];
bool ready;
@@ -1355,47 +1396,6 @@ struct r600_vram_scratch {
/*
- * Mutex which allows recursive locking from the same process.
- */
-struct radeon_mutex {
- struct mutex mutex;
- struct task_struct *owner;
- int level;
-};
-
-static inline void radeon_mutex_init(struct radeon_mutex *mutex)
-{
- mutex_init(&mutex->mutex);
- mutex->owner = NULL;
- mutex->level = 0;
-}
-
-static inline void radeon_mutex_lock(struct radeon_mutex *mutex)
-{
- if (mutex_trylock(&mutex->mutex)) {
- /* The mutex was unlocked before, so it's ours now */
- mutex->owner = current;
- } else if (mutex->owner != current) {
- /* Another process locked the mutex, take it */
- mutex_lock(&mutex->mutex);
- mutex->owner = current;
- }
- /* Otherwise the mutex was already locked by this process */
-
- mutex->level++;
-}
-
-static inline void radeon_mutex_unlock(struct radeon_mutex *mutex)
-{
- if (--mutex->level > 0)
- return;
-
- mutex->owner = NULL;
- mutex_unlock(&mutex->mutex);
-}
-
-
-/*
* Core structure, functions and helpers.
*/
typedef uint32_t (*radeon_rreg_t)(struct radeon_device*, uint32_t);
diff --git a/drivers/gpu/drm/radeon/radeon_atpx_handler.c b/drivers/gpu/drm/radeon/radeon_atpx_handler.c
index 9d95792bea3e..13ac63ba6075 100644
--- a/drivers/gpu/drm/radeon/radeon_atpx_handler.c
+++ b/drivers/gpu/drm/radeon/radeon_atpx_handler.c
@@ -58,9 +58,9 @@ static int radeon_atrm_call(acpi_handle atrm_handle, uint8_t *bios,
}
obj = (union acpi_object *)buffer.pointer;
- memcpy(bios+offset, obj->buffer.pointer, len);
+ memcpy(bios+offset, obj->buffer.pointer, obj->buffer.length);
kfree(buffer.pointer);
- return len;
+ return obj->buffer.length;
}
bool radeon_atrm_supported(struct pci_dev *pdev)
diff --git a/drivers/gpu/drm/radeon/radeon_bios.c b/drivers/gpu/drm/radeon/radeon_bios.c
index 229a20f10e2b..501f4881e5aa 100644
--- a/drivers/gpu/drm/radeon/radeon_bios.c
+++ b/drivers/gpu/drm/radeon/radeon_bios.c
@@ -120,7 +120,7 @@ static bool radeon_atrm_get_bios(struct radeon_device *rdev)
ret = radeon_atrm_get_bios_chunk(rdev->bios,
(i * ATRM_BIOS_PAGE),
ATRM_BIOS_PAGE);
- if (ret <= 0)
+ if (ret < ATRM_BIOS_PAGE)
break;
}
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c
index 0afb13bd8dca..cec51a5b69dd 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -720,7 +720,7 @@ int radeon_device_init(struct radeon_device *rdev,
/* mutex initialization are all done here so we
* can recall function without having locking issues */
radeon_mutex_init(&rdev->cs_mutex);
- mutex_init(&rdev->ib_pool.mutex);
+ radeon_mutex_init(&rdev->ib_pool.mutex);
for (i = 0; i < RADEON_NUM_RINGS; ++i)
mutex_init(&rdev->ring[i].mutex);
mutex_init(&rdev->dc_hw_i2c_mutex);
@@ -959,9 +959,11 @@ int radeon_resume_kms(struct drm_device *dev)
radeon_fbdev_set_suspend(rdev, 0);
console_unlock();
- /* init dig PHYs */
- if (rdev->is_atom_bios)
+ /* init dig PHYs, disp eng pll */
+ if (rdev->is_atom_bios) {
radeon_atom_encoder_init(rdev);
+ radeon_atom_dcpll_init(rdev);
+ }
/* reset hpd state */
radeon_hpd_init(rdev);
/* blat the mode back in */
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c
index d3ffc18774a6..8c49fef1ce78 100644
--- a/drivers/gpu/drm/radeon/radeon_display.c
+++ b/drivers/gpu/drm/radeon/radeon_display.c
@@ -1305,9 +1305,11 @@ int radeon_modeset_init(struct radeon_device *rdev)
return ret;
}
- /* init dig PHYs */
- if (rdev->is_atom_bios)
+ /* init dig PHYs, disp eng pll */
+ if (rdev->is_atom_bios) {
radeon_atom_encoder_init(rdev);
+ radeon_atom_dcpll_init(rdev);
+ }
/* initialize hpd */
radeon_hpd_init(rdev);
diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c
index 4b27efa4405b..9419c51bcf50 100644
--- a/drivers/gpu/drm/radeon/radeon_encoders.c
+++ b/drivers/gpu/drm/radeon/radeon_encoders.c
@@ -202,6 +202,22 @@ radeon_get_connector_for_encoder(struct drm_encoder *encoder)
return NULL;
}
+struct drm_connector *
+radeon_get_connector_for_encoder_init(struct drm_encoder *encoder)
+{
+ struct drm_device *dev = encoder->dev;
+ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+ struct drm_connector *connector;
+ struct radeon_connector *radeon_connector;
+
+ list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+ radeon_connector = to_radeon_connector(connector);
+ if (radeon_encoder->devices & radeon_connector->devices)
+ return connector;
+ }
+ return NULL;
+}
+
struct drm_encoder *radeon_get_external_encoder(struct drm_encoder *encoder)
{
struct drm_device *dev = encoder->dev;
@@ -288,3 +304,64 @@ void radeon_panel_mode_fixup(struct drm_encoder *encoder,
}
+bool radeon_dig_monitor_is_duallink(struct drm_encoder *encoder,
+ u32 pixel_clock)
+{
+ struct drm_device *dev = encoder->dev;
+ struct radeon_device *rdev = dev->dev_private;
+ struct drm_connector *connector;
+ struct radeon_connector *radeon_connector;
+ struct radeon_connector_atom_dig *dig_connector;
+
+ connector = radeon_get_connector_for_encoder(encoder);
+ /* if we don't have an active device yet, just use one of
+ * the connectors tied to the encoder.
+ */
+ if (!connector)
+ connector = radeon_get_connector_for_encoder_init(encoder);
+ radeon_connector = to_radeon_connector(connector);
+
+ switch (connector->connector_type) {
+ case DRM_MODE_CONNECTOR_DVII:
+ case DRM_MODE_CONNECTOR_HDMIB:
+ if (radeon_connector->use_digital) {
+ /* HDMI 1.3 supports up to 340 Mhz over single link */
+ if (ASIC_IS_DCE3(rdev) && drm_detect_hdmi_monitor(radeon_connector->edid)) {
+ if (pixel_clock > 340000)
+ return true;
+ else
+ return false;
+ } else {
+ if (pixel_clock > 165000)
+ return true;
+ else
+ return false;
+ }
+ } else
+ return false;
+ case DRM_MODE_CONNECTOR_DVID:
+ case DRM_MODE_CONNECTOR_HDMIA:
+ case DRM_MODE_CONNECTOR_DisplayPort:
+ dig_connector = radeon_connector->con_priv;
+ if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) ||
+ (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP))
+ return false;
+ else {
+ /* HDMI 1.3 supports up to 340 Mhz over single link */
+ if (ASIC_IS_DCE3(rdev) && drm_detect_hdmi_monitor(radeon_connector->edid)) {
+ if (pixel_clock > 340000)
+ return true;
+ else
+ return false;
+ } else {
+ if (pixel_clock > 165000)
+ return true;
+ else
+ return false;
+ }
+ }
+ default:
+ return false;
+ }
+}
+
diff --git a/drivers/gpu/drm/radeon/radeon_irq_kms.c b/drivers/gpu/drm/radeon/radeon_irq_kms.c
index be38921bf761..66d5fe1c8174 100644
--- a/drivers/gpu/drm/radeon/radeon_irq_kms.c
+++ b/drivers/gpu/drm/radeon/radeon_irq_kms.c
@@ -138,6 +138,12 @@ static bool radeon_msi_ok(struct radeon_device *rdev)
/* Dell RS690 only seems to work with MSIs. */
if ((rdev->pdev->device == 0x791f) &&
(rdev->pdev->subsystem_vendor == 0x1028) &&
+ (rdev->pdev->subsystem_device == 0x01fc))
+ return true;
+
+ /* Dell RS690 only seems to work with MSIs. */
+ if ((rdev->pdev->device == 0x791f) &&
+ (rdev->pdev->subsystem_vendor == 0x1028) &&
(rdev->pdev->subsystem_device == 0x01fd))
return true;
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h
index 08ff857c8fd6..4330e3253573 100644
--- a/drivers/gpu/drm/radeon/radeon_mode.h
+++ b/drivers/gpu/drm/radeon/radeon_mode.h
@@ -362,6 +362,7 @@ struct radeon_encoder_atom_dig {
struct backlight_device *bl_dev;
int dpms_mode;
uint8_t backlight_level;
+ int panel_mode;
};
struct radeon_encoder_atom_dac {
@@ -466,6 +467,10 @@ radeon_atombios_get_tv_info(struct radeon_device *rdev);
extern struct drm_connector *
radeon_get_connector_for_encoder(struct drm_encoder *encoder);
+extern struct drm_connector *
+radeon_get_connector_for_encoder_init(struct drm_encoder *encoder);
+extern bool radeon_dig_monitor_is_duallink(struct drm_encoder *encoder,
+ u32 pixel_clock);
extern u16 radeon_encoder_get_dp_bridge_encoder_id(struct drm_encoder *encoder);
extern u16 radeon_connector_encoder_get_dp_bridge_encoder_id(struct drm_connector *connector);
@@ -482,8 +487,11 @@ extern void radeon_dp_link_train(struct drm_encoder *encoder,
extern bool radeon_dp_needs_link_train(struct radeon_connector *radeon_connector);
extern u8 radeon_dp_getsinktype(struct radeon_connector *radeon_connector);
extern bool radeon_dp_getdpcd(struct radeon_connector *radeon_connector);
+extern int radeon_dp_get_panel_mode(struct drm_encoder *encoder,
+ struct drm_connector *connector);
extern void atombios_dig_encoder_setup(struct drm_encoder *encoder, int action, int panel_mode);
extern void radeon_atom_encoder_init(struct radeon_device *rdev);
+extern void radeon_atom_dcpll_init(struct radeon_device *rdev);
extern void atombios_dig_transmitter_setup(struct drm_encoder *encoder,
int action, uint8_t lane_num,
uint8_t lane_set);
diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c
index e8bc70933d1b..30a4c5014c8b 100644
--- a/drivers/gpu/drm/radeon/radeon_ring.c
+++ b/drivers/gpu/drm/radeon/radeon_ring.c
@@ -109,12 +109,12 @@ int radeon_ib_get(struct radeon_device *rdev, int ring,
return r;
}
- mutex_lock(&rdev->ib_pool.mutex);
+ radeon_mutex_lock(&rdev->ib_pool.mutex);
idx = rdev->ib_pool.head_id;
retry:
if (cretry > 5) {
dev_err(rdev->dev, "failed to get an ib after 5 retry\n");
- mutex_unlock(&rdev->ib_pool.mutex);
+ radeon_mutex_unlock(&rdev->ib_pool.mutex);
radeon_fence_unref(&fence);
return -ENOMEM;
}
@@ -139,7 +139,7 @@ retry:
*/
rdev->ib_pool.head_id = (1 + idx);
rdev->ib_pool.head_id &= (RADEON_IB_POOL_SIZE - 1);
- mutex_unlock(&rdev->ib_pool.mutex);
+ radeon_mutex_unlock(&rdev->ib_pool.mutex);
return 0;
}
}
@@ -158,7 +158,7 @@ retry:
}
idx = (idx + 1) & (RADEON_IB_POOL_SIZE - 1);
}
- mutex_unlock(&rdev->ib_pool.mutex);
+ radeon_mutex_unlock(&rdev->ib_pool.mutex);
radeon_fence_unref(&fence);
return r;
}
@@ -171,12 +171,12 @@ void radeon_ib_free(struct radeon_device *rdev, struct radeon_ib **ib)
if (tmp == NULL) {
return;
}
- mutex_lock(&rdev->ib_pool.mutex);
+ radeon_mutex_lock(&rdev->ib_pool.mutex);
if (tmp->fence && !tmp->fence->emitted) {
radeon_sa_bo_free(rdev, &tmp->sa_bo);
radeon_fence_unref(&tmp->fence);
}
- mutex_unlock(&rdev->ib_pool.mutex);
+ radeon_mutex_unlock(&rdev->ib_pool.mutex);
}
int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib)
@@ -204,22 +204,25 @@ int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib)
int radeon_ib_pool_init(struct radeon_device *rdev)
{
+ struct radeon_sa_manager tmp;
int i, r;
- mutex_lock(&rdev->ib_pool.mutex);
- if (rdev->ib_pool.ready) {
- mutex_unlock(&rdev->ib_pool.mutex);
- return 0;
- }
-
- r = radeon_sa_bo_manager_init(rdev, &rdev->ib_pool.sa_manager,
+ r = radeon_sa_bo_manager_init(rdev, &tmp,
RADEON_IB_POOL_SIZE*64*1024,
RADEON_GEM_DOMAIN_GTT);
if (r) {
- mutex_unlock(&rdev->ib_pool.mutex);
return r;
}
+ radeon_mutex_lock(&rdev->ib_pool.mutex);
+ if (rdev->ib_pool.ready) {
+ radeon_mutex_unlock(&rdev->ib_pool.mutex);
+ radeon_sa_bo_manager_fini(rdev, &tmp);
+ return 0;
+ }
+
+ rdev->ib_pool.sa_manager = tmp;
+ INIT_LIST_HEAD(&rdev->ib_pool.sa_manager.sa_bo);
for (i = 0; i < RADEON_IB_POOL_SIZE; i++) {
rdev->ib_pool.ibs[i].fence = NULL;
rdev->ib_pool.ibs[i].idx = i;
@@ -236,7 +239,7 @@ int radeon_ib_pool_init(struct radeon_device *rdev)
if (radeon_debugfs_ring_init(rdev)) {
DRM_ERROR("Failed to register debugfs file for rings !\n");
}
- mutex_unlock(&rdev->ib_pool.mutex);
+ radeon_mutex_unlock(&rdev->ib_pool.mutex);
return 0;
}
@@ -244,7 +247,7 @@ void radeon_ib_pool_fini(struct radeon_device *rdev)
{
unsigned i;
- mutex_lock(&rdev->ib_pool.mutex);
+ radeon_mutex_lock(&rdev->ib_pool.mutex);
if (rdev->ib_pool.ready) {
for (i = 0; i < RADEON_IB_POOL_SIZE; i++) {
radeon_sa_bo_free(rdev, &rdev->ib_pool.ibs[i].sa_bo);
@@ -253,7 +256,7 @@ void radeon_ib_pool_fini(struct radeon_device *rdev)
radeon_sa_bo_manager_fini(rdev, &rdev->ib_pool.sa_manager);
rdev->ib_pool.ready = false;
}
- mutex_unlock(&rdev->ib_pool.mutex);
+ radeon_mutex_unlock(&rdev->ib_pool.mutex);
}
int radeon_ib_pool_start(struct radeon_device *rdev)
diff --git a/drivers/gpu/drm/sis/sis_drv.c b/drivers/gpu/drm/sis/sis_drv.c
index 06da063ece2e..573220cc5269 100644
--- a/drivers/gpu/drm/sis/sis_drv.c
+++ b/drivers/gpu/drm/sis/sis_drv.c
@@ -40,7 +40,6 @@ static struct pci_device_id pciidlist[] = {
static int sis_driver_load(struct drm_device *dev, unsigned long chipset)
{
drm_sis_private_t *dev_priv;
- int ret;
dev_priv = kzalloc(sizeof(drm_sis_private_t), GFP_KERNEL);
if (dev_priv == NULL)
@@ -50,7 +49,7 @@ static int sis_driver_load(struct drm_device *dev, unsigned long chipset)
dev_priv->chipset = chipset;
idr_init(&dev->object_name_idr);
- return ret;
+ return 0;
}
static int sis_driver_unload(struct drm_device *dev)
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c
index 2f0eab66ece6..7c3a57de8187 100644
--- a/drivers/gpu/drm/ttm/ttm_bo.c
+++ b/drivers/gpu/drm/ttm/ttm_bo.c
@@ -404,6 +404,9 @@ static int ttm_bo_handle_move_mem(struct ttm_buffer_object *bo,
}
}
+ if (bdev->driver->move_notify)
+ bdev->driver->move_notify(bo, mem);
+
if (!(old_man->flags & TTM_MEMTYPE_FLAG_FIXED) &&
!(new_man->flags & TTM_MEMTYPE_FLAG_FIXED))
ret = ttm_bo_move_ttm(bo, evict, no_wait_reserve, no_wait_gpu, mem);
@@ -413,11 +416,17 @@ static int ttm_bo_handle_move_mem(struct ttm_buffer_object *bo,
else
ret = ttm_bo_move_memcpy(bo, evict, no_wait_reserve, no_wait_gpu, mem);
- if (ret)
- goto out_err;
+ if (ret) {
+ if (bdev->driver->move_notify) {
+ struct ttm_mem_reg tmp_mem = *mem;
+ *mem = bo->mem;
+ bo->mem = tmp_mem;
+ bdev->driver->move_notify(bo, mem);
+ bo->mem = *mem;
+ }
- if (bdev->driver->move_notify)
- bdev->driver->move_notify(bo, mem);
+ goto out_err;
+ }
moved:
if (bo->evicted) {
diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c
index 20bce51c2e82..54ab97bae042 100644
--- a/drivers/idle/intel_idle.c
+++ b/drivers/idle/intel_idle.c
@@ -527,7 +527,7 @@ int intel_idle_cpu_init(int cpu)
return 0;
}
-
+EXPORT_SYMBOL_GPL(intel_idle_cpu_init);
static int __init intel_idle_init(void)
{
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index c957c344233f..9ca28fced2b9 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -403,6 +403,13 @@ config LEDS_MAX8997
This option enables support for on-chip LED drivers on
MAXIM MAX8997 PMIC.
+config LEDS_OT200
+ tristate "LED support for the Bachmann OT200"
+ depends on LEDS_CLASS && HAS_IOMEM
+ help
+ This option enables support for the LEDs on the Bachmann OT200.
+ Say Y to enable LEDs on the Bachmann OT200.
+
config LEDS_TRIGGERS
bool "LED Trigger support"
depends on LEDS_CLASS
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
index b8a9723477f0..1fc6875a8b20 100644
--- a/drivers/leds/Makefile
+++ b/drivers/leds/Makefile
@@ -28,6 +28,7 @@ obj-$(CONFIG_LEDS_LP5523) += leds-lp5523.o
obj-$(CONFIG_LEDS_TCA6507) += leds-tca6507.o
obj-$(CONFIG_LEDS_CLEVO_MAIL) += leds-clevo-mail.o
obj-$(CONFIG_LEDS_HP6XX) += leds-hp6xx.o
+obj-$(CONFIG_LEDS_OT200) += leds-ot200.o
obj-$(CONFIG_LEDS_FSG) += leds-fsg.o
obj-$(CONFIG_LEDS_PCA955X) += leds-pca955x.o
obj-$(CONFIG_LEDS_DA903X) += leds-da903x.o
diff --git a/drivers/leds/leds-ot200.c b/drivers/leds/leds-ot200.c
new file mode 100644
index 000000000000..c4646825a620
--- /dev/null
+++ b/drivers/leds/leds-ot200.c
@@ -0,0 +1,171 @@
+/*
+ * Bachmann ot200 leds driver.
+ *
+ * Author: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+ * Christian Gmeiner <christian.gmeiner@gmail.com>
+ *
+ * License: GPL as published by the FSF.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/leds.h>
+#include <linux/io.h>
+#include <linux/module.h>
+
+
+struct ot200_led {
+ struct led_classdev cdev;
+ const char *name;
+ unsigned long port;
+ u8 mask;
+};
+
+/*
+ * The device has three leds on the back panel (led_err, led_init and led_run)
+ * and can handle up to seven leds on the front panel.
+ */
+
+static struct ot200_led leds[] = {
+ {
+ .name = "led_run",
+ .port = 0x5a,
+ .mask = BIT(0),
+ },
+ {
+ .name = "led_init",
+ .port = 0x5a,
+ .mask = BIT(1),
+ },
+ {
+ .name = "led_err",
+ .port = 0x5a,
+ .mask = BIT(2),
+ },
+ {
+ .name = "led_1",
+ .port = 0x49,
+ .mask = BIT(7),
+ },
+ {
+ .name = "led_2",
+ .port = 0x49,
+ .mask = BIT(6),
+ },
+ {
+ .name = "led_3",
+ .port = 0x49,
+ .mask = BIT(5),
+ },
+ {
+ .name = "led_4",
+ .port = 0x49,
+ .mask = BIT(4),
+ },
+ {
+ .name = "led_5",
+ .port = 0x49,
+ .mask = BIT(3),
+ },
+ {
+ .name = "led_6",
+ .port = 0x49,
+ .mask = BIT(2),
+ },
+ {
+ .name = "led_7",
+ .port = 0x49,
+ .mask = BIT(1),
+ }
+};
+
+static DEFINE_SPINLOCK(value_lock);
+
+/*
+ * we need to store the current led states, as it is not
+ * possible to read the current led state via inb().
+ */
+static u8 leds_back;
+static u8 leds_front;
+
+static void ot200_led_brightness_set(struct led_classdev *led_cdev,
+ enum led_brightness value)
+{
+ struct ot200_led *led = container_of(led_cdev, struct ot200_led, cdev);
+ u8 *val;
+ unsigned long flags;
+
+ spin_lock_irqsave(&value_lock, flags);
+
+ if (led->port == 0x49)
+ val = &leds_front;
+ else if (led->port == 0x5a)
+ val = &leds_back;
+ else
+ BUG();
+
+ if (value == LED_OFF)
+ *val &= ~led->mask;
+ else
+ *val |= led->mask;
+
+ outb(*val, led->port);
+ spin_unlock_irqrestore(&value_lock, flags);
+}
+
+static int __devinit ot200_led_probe(struct platform_device *pdev)
+{
+ int i;
+ int ret;
+
+ for (i = 0; i < ARRAY_SIZE(leds); i++) {
+
+ leds[i].cdev.name = leds[i].name;
+ leds[i].cdev.brightness_set = ot200_led_brightness_set;
+
+ ret = led_classdev_register(&pdev->dev, &leds[i].cdev);
+ if (ret < 0)
+ goto err;
+ }
+
+ leds_front = 0; /* turn off all front leds */
+ leds_back = BIT(1); /* turn on init led */
+ outb(leds_front, 0x49);
+ outb(leds_back, 0x5a);
+
+ return 0;
+
+err:
+ for (i = i - 1; i >= 0; i--)
+ led_classdev_unregister(&leds[i].cdev);
+
+ return ret;
+}
+
+static int __devexit ot200_led_remove(struct platform_device *pdev)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(leds); i++)
+ led_classdev_unregister(&leds[i].cdev);
+
+ return 0;
+}
+
+static struct platform_driver ot200_led_driver = {
+ .probe = ot200_led_probe,
+ .remove = __devexit_p(ot200_led_remove),
+ .driver = {
+ .name = "leds-ot200",
+ .owner = THIS_MODULE,
+ },
+};
+
+module_platform_driver(ot200_led_driver);
+
+MODULE_AUTHOR("Sebastian A. Siewior <bigeasy@linutronix.de>");
+MODULE_DESCRIPTION("ot200 LED driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:leds-ot200");
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c
index 342626f4bc46..f820b26b9db3 100644
--- a/drivers/net/bonding/bond_alb.c
+++ b/drivers/net/bonding/bond_alb.c
@@ -909,16 +909,12 @@ static void alb_send_learning_packets(struct slave *slave, u8 mac_addr[])
}
}
-/* hw is a boolean parameter that determines whether we should try and
- * set the hw address of the device as well as the hw address of the
- * net_device
- */
-static int alb_set_slave_mac_addr(struct slave *slave, u8 addr[], int hw)
+static int alb_set_slave_mac_addr(struct slave *slave, u8 addr[])
{
struct net_device *dev = slave->dev;
struct sockaddr s_addr;
- if (!hw) {
+ if (slave->bond->params.mode == BOND_MODE_TLB) {
memcpy(dev->dev_addr, addr, dev->addr_len);
return 0;
}
@@ -948,8 +944,8 @@ static void alb_swap_mac_addr(struct bonding *bond, struct slave *slave1, struct
u8 tmp_mac_addr[ETH_ALEN];
memcpy(tmp_mac_addr, slave1->dev->dev_addr, ETH_ALEN);
- alb_set_slave_mac_addr(slave1, slave2->dev->dev_addr, bond->alb_info.rlb_enabled);
- alb_set_slave_mac_addr(slave2, tmp_mac_addr, bond->alb_info.rlb_enabled);
+ alb_set_slave_mac_addr(slave1, slave2->dev->dev_addr);
+ alb_set_slave_mac_addr(slave2, tmp_mac_addr);
}
@@ -1096,8 +1092,7 @@ static int alb_handle_addr_collision_on_attach(struct bonding *bond, struct slav
/* Try setting slave mac to bond address and fall-through
to code handling that situation below... */
- alb_set_slave_mac_addr(slave, bond->dev->dev_addr,
- bond->alb_info.rlb_enabled);
+ alb_set_slave_mac_addr(slave, bond->dev->dev_addr);
}
/* The slave's address is equal to the address of the bond.
@@ -1133,8 +1128,7 @@ static int alb_handle_addr_collision_on_attach(struct bonding *bond, struct slav
}
if (free_mac_slave) {
- alb_set_slave_mac_addr(slave, free_mac_slave->perm_hwaddr,
- bond->alb_info.rlb_enabled);
+ alb_set_slave_mac_addr(slave, free_mac_slave->perm_hwaddr);
pr_warning("%s: Warning: the hw address of slave %s is in use by the bond; giving it the hw address of %s\n",
bond->dev->name, slave->dev->name,
@@ -1491,8 +1485,7 @@ int bond_alb_init_slave(struct bonding *bond, struct slave *slave)
{
int res;
- res = alb_set_slave_mac_addr(slave, slave->perm_hwaddr,
- bond->alb_info.rlb_enabled);
+ res = alb_set_slave_mac_addr(slave, slave->perm_hwaddr);
if (res) {
return res;
}
@@ -1643,8 +1636,7 @@ void bond_alb_handle_active_change(struct bonding *bond, struct slave *new_slave
alb_swap_mac_addr(bond, swap_slave, new_slave);
} else {
/* set the new_slave to the bond mac address */
- alb_set_slave_mac_addr(new_slave, bond->dev->dev_addr,
- bond->alb_info.rlb_enabled);
+ alb_set_slave_mac_addr(new_slave, bond->dev->dev_addr);
}
if (swap_slave) {
@@ -1704,8 +1696,7 @@ int bond_alb_set_mac_address(struct net_device *bond_dev, void *addr)
alb_swap_mac_addr(bond, swap_slave, bond->curr_active_slave);
alb_fasten_mac_swap(bond, swap_slave, bond->curr_active_slave);
} else {
- alb_set_slave_mac_addr(bond->curr_active_slave, bond_dev->dev_addr,
- bond->alb_info.rlb_enabled);
+ alb_set_slave_mac_addr(bond->curr_active_slave, bond_dev->dev_addr);
read_lock(&bond->lock);
alb_send_learning_packets(bond->curr_active_slave, bond_dev->dev_addr);
diff --git a/drivers/net/dsa/mv88e6060.c b/drivers/net/dsa/mv88e6060.c
index 7fc4e81d4d43..325391d19bad 100644
--- a/drivers/net/dsa/mv88e6060.c
+++ b/drivers/net/dsa/mv88e6060.c
@@ -9,6 +9,7 @@
*/
#include <linux/list.h>
+#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/phy.h>
#include <net/dsa.h>
diff --git a/drivers/net/dsa/mv88e6123_61_65.c b/drivers/net/dsa/mv88e6123_61_65.c
index c0a458fc698f..c17c75b9f531 100644
--- a/drivers/net/dsa/mv88e6123_61_65.c
+++ b/drivers/net/dsa/mv88e6123_61_65.c
@@ -9,6 +9,7 @@
*/
#include <linux/list.h>
+#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/phy.h>
#include <net/dsa.h>
@@ -20,12 +21,25 @@ static char *mv88e6123_61_65_probe(struct mii_bus *bus, int sw_addr)
ret = __mv88e6xxx_reg_read(bus, sw_addr, REG_PORT(0), 0x03);
if (ret >= 0) {
- ret &= 0xfff0;
- if (ret == 0x1210)
+ if (ret == 0x1212)
+ return "Marvell 88E6123 (A1)";
+ if (ret == 0x1213)
+ return "Marvell 88E6123 (A2)";
+ if ((ret & 0xfff0) == 0x1210)
return "Marvell 88E6123";
- if (ret == 0x1610)
+
+ if (ret == 0x1612)
+ return "Marvell 88E6161 (A1)";
+ if (ret == 0x1613)
+ return "Marvell 88E6161 (A2)";
+ if ((ret & 0xfff0) == 0x1610)
return "Marvell 88E6161";
- if (ret == 0x1650)
+
+ if (ret == 0x1652)
+ return "Marvell 88E6165 (A1)";
+ if (ret == 0x1653)
+ return "Marvell 88e6165 (A2)";
+ if ((ret & 0xfff0) == 0x1650)
return "Marvell 88E6165";
}
diff --git a/drivers/net/dsa/mv88e6131.c b/drivers/net/dsa/mv88e6131.c
index e0eb68243834..55888b06d8b4 100644
--- a/drivers/net/dsa/mv88e6131.c
+++ b/drivers/net/dsa/mv88e6131.c
@@ -9,6 +9,7 @@
*/
#include <linux/list.h>
+#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/phy.h>
#include <net/dsa.h>
diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c
index 5467c040824a..a2c62c2f30ee 100644
--- a/drivers/net/dsa/mv88e6xxx.c
+++ b/drivers/net/dsa/mv88e6xxx.c
@@ -9,6 +9,7 @@
*/
#include <linux/list.h>
+#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/phy.h>
#include <net/dsa.h>
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
index 2b731b253598..03f3935fd8c2 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
@@ -3117,7 +3117,7 @@ static int bnx2x_alloc_fp_mem_at(struct bnx2x *bp, int index)
int rx_ring_size = 0;
#ifdef BCM_CNIC
- if (IS_MF_ISCSI_SD(bp)) {
+ if (!bp->rx_ring_size && IS_MF_ISCSI_SD(bp)) {
rx_ring_size = MIN_RX_SIZE_NONTPA;
bp->rx_ring_size = rx_ring_size;
} else
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
index f99c6e312a5d..31a8b38ab15e 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
@@ -1738,7 +1738,7 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode)
struct bnx2x_fp_txdata *txdata = &fp_tx->txdata[0];
u16 tx_start_idx, tx_idx;
u16 rx_start_idx, rx_idx;
- u16 pkt_prod, bd_prod, rx_comp_cons;
+ u16 pkt_prod, bd_prod;
struct sw_tx_bd *tx_buf;
struct eth_tx_start_bd *tx_start_bd;
struct eth_tx_parse_bd_e1x *pbd_e1x = NULL;
@@ -1873,8 +1873,7 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode)
if (rx_idx != rx_start_idx + num_pkts)
goto test_loopback_exit;
- rx_comp_cons = le16_to_cpu(fp_rx->rx_comp_cons);
- cqe = &fp_rx->rx_comp_ring[RCQ_BD(rx_comp_cons)];
+ cqe = &fp_rx->rx_comp_ring[RCQ_BD(fp_rx->rx_comp_cons)];
cqe_fp_flags = cqe->fast_path_cqe.type_error_flags;
cqe_fp_type = cqe_fp_flags & ETH_FAST_PATH_RX_CQE_TYPE;
if (!CQE_TYPE_FAST(cqe_fp_type) || (cqe_fp_flags & ETH_RX_ERROR_FALGS))
@@ -2121,18 +2120,16 @@ static int bnx2x_get_sset_count(struct net_device *dev, int stringset)
case ETH_SS_STATS:
if (is_multi(bp)) {
num_stats = bnx2x_num_stat_queues(bp) *
- BNX2X_NUM_Q_STATS;
- if (!IS_MF_MODE_STAT(bp))
- num_stats += BNX2X_NUM_STATS;
- } else {
- if (IS_MF_MODE_STAT(bp)) {
- num_stats = 0;
- for (i = 0; i < BNX2X_NUM_STATS; i++)
- if (IS_FUNC_STAT(i))
- num_stats++;
- } else
- num_stats = BNX2X_NUM_STATS;
- }
+ BNX2X_NUM_Q_STATS;
+ } else
+ num_stats = 0;
+ if (IS_MF_MODE_STAT(bp)) {
+ for (i = 0; i < BNX2X_NUM_STATS; i++)
+ if (IS_FUNC_STAT(i))
+ num_stats++;
+ } else
+ num_stats += BNX2X_NUM_STATS;
+
return num_stats;
case ETH_SS_TEST:
@@ -2151,8 +2148,8 @@ static void bnx2x_get_strings(struct net_device *dev, u32 stringset, u8 *buf)
switch (stringset) {
case ETH_SS_STATS:
+ k = 0;
if (is_multi(bp)) {
- k = 0;
for_each_eth_queue(bp, i) {
memset(queue_name, 0, sizeof(queue_name));
sprintf(queue_name, "%d", i);
@@ -2163,20 +2160,17 @@ static void bnx2x_get_strings(struct net_device *dev, u32 stringset, u8 *buf)
queue_name);
k += BNX2X_NUM_Q_STATS;
}
- if (IS_MF_MODE_STAT(bp))
- break;
- for (j = 0; j < BNX2X_NUM_STATS; j++)
- strcpy(buf + (k + j)*ETH_GSTRING_LEN,
- bnx2x_stats_arr[j].string);
- } else {
- for (i = 0, j = 0; i < BNX2X_NUM_STATS; i++) {
- if (IS_MF_MODE_STAT(bp) && IS_PORT_STAT(i))
- continue;
- strcpy(buf + j*ETH_GSTRING_LEN,
- bnx2x_stats_arr[i].string);
- j++;
- }
}
+
+
+ for (i = 0, j = 0; i < BNX2X_NUM_STATS; i++) {
+ if (IS_MF_MODE_STAT(bp) && IS_PORT_STAT(i))
+ continue;
+ strcpy(buf + (k + j)*ETH_GSTRING_LEN,
+ bnx2x_stats_arr[i].string);
+ j++;
+ }
+
break;
case ETH_SS_TEST:
@@ -2190,10 +2184,9 @@ static void bnx2x_get_ethtool_stats(struct net_device *dev,
{
struct bnx2x *bp = netdev_priv(dev);
u32 *hw_stats, *offset;
- int i, j, k;
+ int i, j, k = 0;
if (is_multi(bp)) {
- k = 0;
for_each_eth_queue(bp, i) {
hw_stats = (u32 *)&bp->fp[i].eth_q_stats;
for (j = 0; j < BNX2X_NUM_Q_STATS; j++) {
@@ -2214,46 +2207,28 @@ static void bnx2x_get_ethtool_stats(struct net_device *dev,
}
k += BNX2X_NUM_Q_STATS;
}
- if (IS_MF_MODE_STAT(bp))
- return;
- hw_stats = (u32 *)&bp->eth_stats;
- for (j = 0; j < BNX2X_NUM_STATS; j++) {
- if (bnx2x_stats_arr[j].size == 0) {
- /* skip this counter */
- buf[k + j] = 0;
- continue;
- }
- offset = (hw_stats + bnx2x_stats_arr[j].offset);
- if (bnx2x_stats_arr[j].size == 4) {
- /* 4-byte counter */
- buf[k + j] = (u64) *offset;
- continue;
- }
- /* 8-byte counter */
- buf[k + j] = HILO_U64(*offset, *(offset + 1));
+ }
+
+ hw_stats = (u32 *)&bp->eth_stats;
+ for (i = 0, j = 0; i < BNX2X_NUM_STATS; i++) {
+ if (IS_MF_MODE_STAT(bp) && IS_PORT_STAT(i))
+ continue;
+ if (bnx2x_stats_arr[i].size == 0) {
+ /* skip this counter */
+ buf[k + j] = 0;
+ j++;
+ continue;
}
- } else {
- hw_stats = (u32 *)&bp->eth_stats;
- for (i = 0, j = 0; i < BNX2X_NUM_STATS; i++) {
- if (IS_MF_MODE_STAT(bp) && IS_PORT_STAT(i))
- continue;
- if (bnx2x_stats_arr[i].size == 0) {
- /* skip this counter */
- buf[j] = 0;
- j++;
- continue;
- }
- offset = (hw_stats + bnx2x_stats_arr[i].offset);
- if (bnx2x_stats_arr[i].size == 4) {
- /* 4-byte counter */
- buf[j] = (u64) *offset;
- j++;
- continue;
- }
- /* 8-byte counter */
- buf[j] = HILO_U64(*offset, *(offset + 1));
+ offset = (hw_stats + bnx2x_stats_arr[i].offset);
+ if (bnx2x_stats_arr[i].size == 4) {
+ /* 4-byte counter */
+ buf[k + j] = (u64) *offset;
j++;
+ continue;
}
+ /* 8-byte counter */
+ buf[k + j] = HILO_U64(*offset, *(offset + 1));
+ j++;
}
}
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
index ffeaaa95ed96..1e3f978ee6da 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
@@ -941,7 +941,7 @@ void bnx2x_panic_dump(struct bnx2x *bp)
struct sw_rx_bd *sw_bd = &fp->rx_buf_ring[j];
BNX2X_ERR("fp%d: rx_bd[%x]=[%x:%x] sw_bd=[%p]\n",
- i, j, rx_bd[1], rx_bd[0], sw_bd->skb);
+ i, j, rx_bd[1], rx_bd[0], sw_bd->data);
}
start = RX_SGE(fp->rx_sge_prod);
@@ -10536,6 +10536,9 @@ static int __devinit bnx2x_init_dev(struct pci_dev *pdev,
{
struct bnx2x *bp;
int rc;
+ bool chip_is_e1x = (board_type == BCM57710 ||
+ board_type == BCM57711 ||
+ board_type == BCM57711E);
SET_NETDEV_DEV(dev, &pdev->dev);
bp = netdev_priv(dev);
@@ -10624,7 +10627,7 @@ static int __devinit bnx2x_init_dev(struct pci_dev *pdev,
REG_WR(bp, PXP2_REG_PGL_ADDR_90_F0, 0);
REG_WR(bp, PXP2_REG_PGL_ADDR_94_F0, 0);
- if (CHIP_IS_E1x(bp)) {
+ if (chip_is_e1x) {
REG_WR(bp, PXP2_REG_PGL_ADDR_88_F1, 0);
REG_WR(bp, PXP2_REG_PGL_ADDR_8C_F1, 0);
REG_WR(bp, PXP2_REG_PGL_ADDR_90_F1, 0);
@@ -10635,9 +10638,7 @@ static int __devinit bnx2x_init_dev(struct pci_dev *pdev,
* Enable internal target-read (in case we are probed after PF FLR).
* Must be done prior to any BAR read access. Only for 57712 and up
*/
- if (board_type != BCM57710 &&
- board_type != BCM57711 &&
- board_type != BCM57711E)
+ if (!chip_is_e1x)
REG_WR(bp, PGLUE_B_REG_INTERNAL_PFID_ENABLE_TARGET_READ, 1);
/* Reset the load counter */
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c
index 5ac616093f9f..cb6339c35571 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c
@@ -50,6 +50,7 @@ static inline void bnx2x_exe_queue_init(struct bnx2x *bp,
int exe_len,
union bnx2x_qable_obj *owner,
exe_q_validate validate,
+ exe_q_remove remove,
exe_q_optimize optimize,
exe_q_execute exec,
exe_q_get get)
@@ -66,6 +67,7 @@ static inline void bnx2x_exe_queue_init(struct bnx2x *bp,
/* Owner specific callbacks */
o->validate = validate;
+ o->remove = remove;
o->optimize = optimize;
o->execute = exec;
o->get = get;
@@ -1340,6 +1342,35 @@ static int bnx2x_validate_vlan_mac(struct bnx2x *bp,
}
}
+static int bnx2x_remove_vlan_mac(struct bnx2x *bp,
+ union bnx2x_qable_obj *qo,
+ struct bnx2x_exeq_elem *elem)
+{
+ int rc = 0;
+
+ /* If consumption wasn't required, nothing to do */
+ if (test_bit(BNX2X_DONT_CONSUME_CAM_CREDIT,
+ &elem->cmd_data.vlan_mac.vlan_mac_flags))
+ return 0;
+
+ switch (elem->cmd_data.vlan_mac.cmd) {
+ case BNX2X_VLAN_MAC_ADD:
+ case BNX2X_VLAN_MAC_MOVE:
+ rc = qo->vlan_mac.put_credit(&qo->vlan_mac);
+ break;
+ case BNX2X_VLAN_MAC_DEL:
+ rc = qo->vlan_mac.get_credit(&qo->vlan_mac);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (rc != true)
+ return -EINVAL;
+
+ return 0;
+}
+
/**
* bnx2x_wait_vlan_mac - passivly wait for 5 seconds until all work completes.
*
@@ -1801,8 +1832,14 @@ static int bnx2x_vlan_mac_del_all(struct bnx2x *bp,
list_for_each_entry_safe(exeq_pos, exeq_pos_n, &exeq->exe_queue, link) {
if (exeq_pos->cmd_data.vlan_mac.vlan_mac_flags ==
- *vlan_mac_flags)
+ *vlan_mac_flags) {
+ rc = exeq->remove(bp, exeq->owner, exeq_pos);
+ if (rc) {
+ BNX2X_ERR("Failed to remove command\n");
+ return rc;
+ }
list_del(&exeq_pos->link);
+ }
}
spin_unlock_bh(&exeq->lock);
@@ -1908,6 +1945,7 @@ void bnx2x_init_mac_obj(struct bnx2x *bp,
bnx2x_exe_queue_init(bp,
&mac_obj->exe_queue, 1, qable_obj,
bnx2x_validate_vlan_mac,
+ bnx2x_remove_vlan_mac,
bnx2x_optimize_vlan_mac,
bnx2x_execute_vlan_mac,
bnx2x_exeq_get_mac);
@@ -1924,6 +1962,7 @@ void bnx2x_init_mac_obj(struct bnx2x *bp,
bnx2x_exe_queue_init(bp,
&mac_obj->exe_queue, CLASSIFY_RULES_COUNT,
qable_obj, bnx2x_validate_vlan_mac,
+ bnx2x_remove_vlan_mac,
bnx2x_optimize_vlan_mac,
bnx2x_execute_vlan_mac,
bnx2x_exeq_get_mac);
@@ -1963,6 +2002,7 @@ void bnx2x_init_vlan_obj(struct bnx2x *bp,
bnx2x_exe_queue_init(bp,
&vlan_obj->exe_queue, CLASSIFY_RULES_COUNT,
qable_obj, bnx2x_validate_vlan_mac,
+ bnx2x_remove_vlan_mac,
bnx2x_optimize_vlan_mac,
bnx2x_execute_vlan_mac,
bnx2x_exeq_get_vlan);
@@ -2009,6 +2049,7 @@ void bnx2x_init_vlan_mac_obj(struct bnx2x *bp,
bnx2x_exe_queue_init(bp,
&vlan_mac_obj->exe_queue, 1, qable_obj,
bnx2x_validate_vlan_mac,
+ bnx2x_remove_vlan_mac,
bnx2x_optimize_vlan_mac,
bnx2x_execute_vlan_mac,
bnx2x_exeq_get_vlan_mac);
@@ -2025,6 +2066,7 @@ void bnx2x_init_vlan_mac_obj(struct bnx2x *bp,
&vlan_mac_obj->exe_queue,
CLASSIFY_RULES_COUNT,
qable_obj, bnx2x_validate_vlan_mac,
+ bnx2x_remove_vlan_mac,
bnx2x_optimize_vlan_mac,
bnx2x_execute_vlan_mac,
bnx2x_exeq_get_vlan_mac);
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h
index 992308ff82e8..66da39f0c84a 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h
@@ -161,6 +161,10 @@ typedef int (*exe_q_validate)(struct bnx2x *bp,
union bnx2x_qable_obj *o,
struct bnx2x_exeq_elem *elem);
+typedef int (*exe_q_remove)(struct bnx2x *bp,
+ union bnx2x_qable_obj *o,
+ struct bnx2x_exeq_elem *elem);
+
/**
* @return positive is entry was optimized, 0 - if not, negative
* in case of an error.
@@ -203,11 +207,18 @@ struct bnx2x_exe_queue_obj {
*/
exe_q_validate validate;
+ /**
+ * Called before removing pending commands, cleaning allocated
+ * resources (e.g., credits from validate)
+ */
+ exe_q_remove remove;
/**
* This will try to cancel the current pending commands list
* considering the new command.
*
+ * Returns the number of optimized commands or a negative error code
+ *
* Must run under exe_queue->lock
*/
exe_q_optimize optimize;
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index d529af99157d..a1f2e0fed78b 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -6667,14 +6667,9 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
iph = ip_hdr(skb);
tcp_opt_len = tcp_optlen(skb);
- if (skb_is_gso_v6(skb)) {
- hdr_len = skb_headlen(skb) - ETH_HLEN;
- } else {
- u32 ip_tcp_len;
-
- ip_tcp_len = ip_hdrlen(skb) + sizeof(struct tcphdr);
- hdr_len = ip_tcp_len + tcp_opt_len;
+ hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb) - ETH_HLEN;
+ if (!skb_is_gso_v6(skb)) {
iph->check = 0;
iph->tot_len = htons(mss + hdr_len);
}
diff --git a/drivers/net/ethernet/cisco/enic/enic.h b/drivers/net/ethernet/cisco/enic/enic.h
index fe0c29acdbe6..ee93a2087fe6 100644
--- a/drivers/net/ethernet/cisco/enic/enic.h
+++ b/drivers/net/ethernet/cisco/enic/enic.h
@@ -32,7 +32,7 @@
#define DRV_NAME "enic"
#define DRV_DESCRIPTION "Cisco VIC Ethernet NIC Driver"
-#define DRV_VERSION "2.1.1.28"
+#define DRV_VERSION "2.1.1.31"
#define DRV_COPYRIGHT "Copyright 2008-2011 Cisco Systems, Inc"
#define ENIC_BARS_MAX 6
diff --git a/drivers/net/ethernet/cisco/enic/enic_main.c b/drivers/net/ethernet/cisco/enic/enic_main.c
index 2fd9db4b1be5..ab3f67f980d8 100644
--- a/drivers/net/ethernet/cisco/enic/enic_main.c
+++ b/drivers/net/ethernet/cisco/enic/enic_main.c
@@ -57,11 +57,13 @@
#define PCI_DEVICE_ID_CISCO_VIC_ENET 0x0043 /* ethernet vnic */
#define PCI_DEVICE_ID_CISCO_VIC_ENET_DYN 0x0044 /* enet dynamic vnic */
+#define PCI_DEVICE_ID_CISCO_VIC_ENET_VF 0x0071 /* enet SRIOV VF */
/* Supported devices */
static DEFINE_PCI_DEVICE_TABLE(enic_id_table) = {
{ PCI_VDEVICE(CISCO, PCI_DEVICE_ID_CISCO_VIC_ENET) },
{ PCI_VDEVICE(CISCO, PCI_DEVICE_ID_CISCO_VIC_ENET_DYN) },
+ { PCI_VDEVICE(CISCO, PCI_DEVICE_ID_CISCO_VIC_ENET_VF) },
{ 0, } /* end of table */
};
@@ -132,6 +134,11 @@ int enic_sriov_enabled(struct enic *enic)
return (enic->priv_flags & ENIC_SRIOV_ENABLED) ? 1 : 0;
}
+static int enic_is_sriov_vf(struct enic *enic)
+{
+ return enic->pdev->device == PCI_DEVICE_ID_CISCO_VIC_ENET_VF;
+}
+
int enic_is_valid_vf(struct enic *enic, int vf)
{
#ifdef CONFIG_PCI_IOV
@@ -437,7 +444,7 @@ static void enic_mtu_check(struct enic *enic)
if (mtu && mtu != enic->port_mtu) {
enic->port_mtu = mtu;
- if (enic_is_dynamic(enic)) {
+ if (enic_is_dynamic(enic) || enic_is_sriov_vf(enic)) {
mtu = max_t(int, ENIC_MIN_MTU,
min_t(int, ENIC_MAX_MTU, mtu));
if (mtu != netdev->mtu)
@@ -849,7 +856,7 @@ static int enic_set_mac_addr(struct net_device *netdev, char *addr)
{
struct enic *enic = netdev_priv(netdev);
- if (enic_is_dynamic(enic)) {
+ if (enic_is_dynamic(enic) || enic_is_sriov_vf(enic)) {
if (!is_valid_ether_addr(addr) && !is_zero_ether_addr(addr))
return -EADDRNOTAVAIL;
} else {
@@ -1608,7 +1615,7 @@ static int enic_open(struct net_device *netdev)
for (i = 0; i < enic->rq_count; i++)
vnic_rq_enable(&enic->rq[i]);
- if (!enic_is_dynamic(enic))
+ if (!enic_is_dynamic(enic) && !enic_is_sriov_vf(enic))
enic_dev_add_station_addr(enic);
enic_set_rx_mode(netdev);
@@ -1659,7 +1666,7 @@ static int enic_stop(struct net_device *netdev)
netif_carrier_off(netdev);
netif_tx_disable(netdev);
- if (!enic_is_dynamic(enic))
+ if (!enic_is_dynamic(enic) && !enic_is_sriov_vf(enic))
enic_dev_del_station_addr(enic);
for (i = 0; i < enic->wq_count; i++) {
@@ -1696,7 +1703,7 @@ static int enic_change_mtu(struct net_device *netdev, int new_mtu)
if (new_mtu < ENIC_MIN_MTU || new_mtu > ENIC_MAX_MTU)
return -EINVAL;
- if (enic_is_dynamic(enic))
+ if (enic_is_dynamic(enic) || enic_is_sriov_vf(enic))
return -EOPNOTSUPP;
if (running)
@@ -2263,10 +2270,10 @@ static int __devinit enic_probe(struct pci_dev *pdev,
int using_dac = 0;
unsigned int i;
int err;
- int num_pps = 1;
#ifdef CONFIG_PCI_IOV
int pos = 0;
#endif
+ int num_pps = 1;
/* Allocate net device structure and initialize. Private
* instance data is initialized to zero.
@@ -2376,14 +2383,14 @@ static int __devinit enic_probe(struct pci_dev *pdev,
num_pps = enic->num_vfs;
}
}
-
#endif
+
/* Allocate structure for port profiles */
enic->pp = kcalloc(num_pps, sizeof(*enic->pp), GFP_KERNEL);
if (!enic->pp) {
pr_err("port profile alloc failed, aborting\n");
err = -ENOMEM;
- goto err_out_disable_sriov;
+ goto err_out_disable_sriov_pp;
}
/* Issue device open to get device in known state
@@ -2392,7 +2399,7 @@ static int __devinit enic_probe(struct pci_dev *pdev,
err = enic_dev_open(enic);
if (err) {
dev_err(dev, "vNIC dev open failed, aborting\n");
- goto err_out_free_pp;
+ goto err_out_disable_sriov;
}
/* Setup devcmd lock
@@ -2426,7 +2433,7 @@ static int __devinit enic_probe(struct pci_dev *pdev,
* called later by an upper layer.
*/
- if (!enic_is_dynamic(enic)) {
+ if (!enic_is_dynamic(enic) && !enic_is_sriov_vf(enic)) {
err = vnic_dev_init(enic->vdev, 0);
if (err) {
dev_err(dev, "vNIC dev init failed, aborting\n");
@@ -2460,8 +2467,7 @@ static int __devinit enic_probe(struct pci_dev *pdev,
(void)enic_change_mtu(netdev, enic->port_mtu);
#ifdef CONFIG_PCI_IOV
- if (enic_is_dynamic(enic) && pdev->is_virtfn &&
- is_zero_ether_addr(enic->mac_addr))
+ if (enic_is_sriov_vf(enic) && is_zero_ether_addr(enic->mac_addr))
random_ether_addr(enic->mac_addr);
#endif
@@ -2474,7 +2480,7 @@ static int __devinit enic_probe(struct pci_dev *pdev,
enic->tx_coalesce_usecs = enic->config.intr_timer_usec;
enic->rx_coalesce_usecs = enic->tx_coalesce_usecs;
- if (enic_is_dynamic(enic))
+ if (enic_is_dynamic(enic) || enic_is_sriov_vf(enic))
netdev->netdev_ops = &enic_netdev_dynamic_ops;
else
netdev->netdev_ops = &enic_netdev_ops;
@@ -2516,17 +2522,17 @@ err_out_dev_deinit:
enic_dev_deinit(enic);
err_out_dev_close:
vnic_dev_close(enic->vdev);
-err_out_free_pp:
- kfree(enic->pp);
err_out_disable_sriov:
+ kfree(enic->pp);
+err_out_disable_sriov_pp:
#ifdef CONFIG_PCI_IOV
if (enic_sriov_enabled(enic)) {
pci_disable_sriov(pdev);
enic->priv_flags &= ~ENIC_SRIOV_ENABLED;
}
err_out_vnic_unregister:
- vnic_dev_unregister(enic->vdev);
#endif
+ vnic_dev_unregister(enic->vdev);
err_out_iounmap:
enic_iounmap(enic);
err_out_release_regions:
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index a6bcdb5cd2be..e703d64434f8 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -1786,8 +1786,7 @@ static void be_rx_queues_destroy(struct be_adapter *adapter)
static u32 be_num_rxqs_want(struct be_adapter *adapter)
{
if ((adapter->function_caps & BE_FUNCTION_CAPS_RSS) &&
- !sriov_enabled(adapter) && be_physfn(adapter) &&
- !be_is_mc(adapter)) {
+ !sriov_enabled(adapter) && be_physfn(adapter)) {
return 1 + MAX_RSS_QS; /* one default non-RSS queue */
} else {
dev_warn(&adapter->pdev->dev,
diff --git a/drivers/net/ethernet/faraday/ftgmac100.c b/drivers/net/ethernet/faraday/ftgmac100.c
index fb5579a3b19d..47f85c337cf7 100644
--- a/drivers/net/ethernet/faraday/ftgmac100.c
+++ b/drivers/net/ethernet/faraday/ftgmac100.c
@@ -25,6 +25,7 @@
#include <linux/etherdevice.h>
#include <linux/ethtool.h>
#include <linux/init.h>
+#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/netdevice.h>
diff --git a/drivers/net/ethernet/faraday/ftmac100.c b/drivers/net/ethernet/faraday/ftmac100.c
index a127cb2476c7..bb336a0959c9 100644
--- a/drivers/net/ethernet/faraday/ftmac100.c
+++ b/drivers/net/ethernet/faraday/ftmac100.c
@@ -25,6 +25,7 @@
#include <linux/etherdevice.h>
#include <linux/ethtool.h>
#include <linux/init.h>
+#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/mii.h>
#include <linux/module.h>
diff --git a/drivers/net/ethernet/intel/igb/Makefile b/drivers/net/ethernet/intel/igb/Makefile
index c6e4621b6262..6565c463185c 100644
--- a/drivers/net/ethernet/intel/igb/Makefile
+++ b/drivers/net/ethernet/intel/igb/Makefile
@@ -1,7 +1,7 @@
################################################################################
#
# Intel 82575 PCI-Express Ethernet Linux driver
-# Copyright(c) 1999 - 2011 Intel Corporation.
+# Copyright(c) 1999 - 2012 Intel Corporation.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms and conditions of the GNU General Public License,
diff --git a/drivers/net/ethernet/intel/igb/e1000_82575.c b/drivers/net/ethernet/intel/igb/e1000_82575.c
index b8e20f037d0a..08bdc33715ee 100644
--- a/drivers/net/ethernet/intel/igb/e1000_82575.c
+++ b/drivers/net/ethernet/intel/igb/e1000_82575.c
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007-2011 Intel Corporation.
+ Copyright(c) 2007-2012 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
diff --git a/drivers/net/ethernet/intel/igb/e1000_82575.h b/drivers/net/ethernet/intel/igb/e1000_82575.h
index 08a757eb6608..b927d79ab536 100644
--- a/drivers/net/ethernet/intel/igb/e1000_82575.h
+++ b/drivers/net/ethernet/intel/igb/e1000_82575.h
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007-2011 Intel Corporation.
+ Copyright(c) 2007-2012 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
diff --git a/drivers/net/ethernet/intel/igb/e1000_defines.h b/drivers/net/ethernet/intel/igb/e1000_defines.h
index f5fc5725ea94..aed217449f0d 100644
--- a/drivers/net/ethernet/intel/igb/e1000_defines.h
+++ b/drivers/net/ethernet/intel/igb/e1000_defines.h
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007-2011 Intel Corporation.
+ Copyright(c) 2007-2012 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
diff --git a/drivers/net/ethernet/intel/igb/e1000_hw.h b/drivers/net/ethernet/intel/igb/e1000_hw.h
index 4519a1367170..f67cbd3fa307 100644
--- a/drivers/net/ethernet/intel/igb/e1000_hw.h
+++ b/drivers/net/ethernet/intel/igb/e1000_hw.h
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007-2011 Intel Corporation.
+ Copyright(c) 2007-2012 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
diff --git a/drivers/net/ethernet/intel/igb/e1000_mac.c b/drivers/net/ethernet/intel/igb/e1000_mac.c
index 73aac082c44d..f57338afd71f 100644
--- a/drivers/net/ethernet/intel/igb/e1000_mac.c
+++ b/drivers/net/ethernet/intel/igb/e1000_mac.c
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007-2011 Intel Corporation.
+ Copyright(c) 2007-2012 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@@ -151,7 +151,7 @@ void igb_clear_vfta_i350(struct e1000_hw *hw)
* Writes value at the given offset in the register array which stores
* the VLAN filter table.
**/
-void igb_write_vfta_i350(struct e1000_hw *hw, u32 offset, u32 value)
+static void igb_write_vfta_i350(struct e1000_hw *hw, u32 offset, u32 value)
{
int i;
diff --git a/drivers/net/ethernet/intel/igb/e1000_mac.h b/drivers/net/ethernet/intel/igb/e1000_mac.h
index e45996b4ea34..cbddc4e51e30 100644
--- a/drivers/net/ethernet/intel/igb/e1000_mac.h
+++ b/drivers/net/ethernet/intel/igb/e1000_mac.h
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007-2011 Intel Corporation.
+ Copyright(c) 2007-2012 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
diff --git a/drivers/net/ethernet/intel/igb/e1000_mbx.c b/drivers/net/ethernet/intel/igb/e1000_mbx.c
index 469d95eaa154..5988b8958baf 100644
--- a/drivers/net/ethernet/intel/igb/e1000_mbx.c
+++ b/drivers/net/ethernet/intel/igb/e1000_mbx.c
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007-2011 Intel Corporation.
+ Copyright(c) 2007-2012 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
diff --git a/drivers/net/ethernet/intel/igb/e1000_mbx.h b/drivers/net/ethernet/intel/igb/e1000_mbx.h
index eddb0f83dcea..dbcfa3d5caec 100644
--- a/drivers/net/ethernet/intel/igb/e1000_mbx.h
+++ b/drivers/net/ethernet/intel/igb/e1000_mbx.h
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007-2011 Intel Corporation.
+ Copyright(c) 2007-2012 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
diff --git a/drivers/net/ethernet/intel/igb/e1000_nvm.c b/drivers/net/ethernet/intel/igb/e1000_nvm.c
index 40407124e722..fa2c6ba62139 100644
--- a/drivers/net/ethernet/intel/igb/e1000_nvm.c
+++ b/drivers/net/ethernet/intel/igb/e1000_nvm.c
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007-2011 Intel Corporation.
+ Copyright(c) 2007-2012 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
diff --git a/drivers/net/ethernet/intel/igb/e1000_nvm.h b/drivers/net/ethernet/intel/igb/e1000_nvm.h
index a2a7ca9fa733..825b0228cac0 100644
--- a/drivers/net/ethernet/intel/igb/e1000_nvm.h
+++ b/drivers/net/ethernet/intel/igb/e1000_nvm.h
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2011 Intel Corporation.
+ Copyright(c) 2012 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
diff --git a/drivers/net/ethernet/intel/igb/e1000_phy.c b/drivers/net/ethernet/intel/igb/e1000_phy.c
index b17d7c20f817..789de5b83aad 100644
--- a/drivers/net/ethernet/intel/igb/e1000_phy.c
+++ b/drivers/net/ethernet/intel/igb/e1000_phy.c
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007-2011 Intel Corporation.
+ Copyright(c) 2007-2012 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
diff --git a/drivers/net/ethernet/intel/igb/e1000_phy.h b/drivers/net/ethernet/intel/igb/e1000_phy.h
index 8510797b9d81..4c32ac66ff39 100644
--- a/drivers/net/ethernet/intel/igb/e1000_phy.h
+++ b/drivers/net/ethernet/intel/igb/e1000_phy.h
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007-2011 Intel Corporation.
+ Copyright(c) 2007-2012 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
diff --git a/drivers/net/ethernet/intel/igb/e1000_regs.h b/drivers/net/ethernet/intel/igb/e1000_regs.h
index 0a860bc1198e..ccdf36d503fd 100644
--- a/drivers/net/ethernet/intel/igb/e1000_regs.h
+++ b/drivers/net/ethernet/intel/igb/e1000_regs.h
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007-2011 Intel Corporation.
+ Copyright(c) 2007-2012 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
diff --git a/drivers/net/ethernet/intel/igb/igb.h b/drivers/net/ethernet/intel/igb/igb.h
index 3d12e67eebb4..8e33bdd33eea 100644
--- a/drivers/net/ethernet/intel/igb/igb.h
+++ b/drivers/net/ethernet/intel/igb/igb.h
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007-2011 Intel Corporation.
+ Copyright(c) 2007-2012 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
diff --git a/drivers/net/ethernet/intel/igb/igb_ethtool.c b/drivers/net/ethernet/intel/igb/igb_ethtool.c
index 7998bf4d5946..aa399a8a8f0d 100644
--- a/drivers/net/ethernet/intel/igb/igb_ethtool.c
+++ b/drivers/net/ethernet/intel/igb/igb_ethtool.c
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007-2011 Intel Corporation.
+ Copyright(c) 2007-2012 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
index 01e5e89ef959..e91d73c8aa4e 100644
--- a/drivers/net/ethernet/intel/igb/igb_main.c
+++ b/drivers/net/ethernet/intel/igb/igb_main.c
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007-2011 Intel Corporation.
+ Copyright(c) 2007-2012 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@@ -68,7 +68,7 @@ char igb_driver_name[] = "igb";
char igb_driver_version[] = DRV_VERSION;
static const char igb_driver_string[] =
"Intel(R) Gigabit Ethernet Network Driver";
-static const char igb_copyright[] = "Copyright (c) 2007-2011 Intel Corporation.";
+static const char igb_copyright[] = "Copyright (c) 2007-2012 Intel Corporation.";
static const struct e1000_info *igb_info_tbl[] = {
[board_82575] = &e1000_82575_info,
@@ -4003,8 +4003,8 @@ set_itr_now:
}
}
-void igb_tx_ctxtdesc(struct igb_ring *tx_ring, u32 vlan_macip_lens,
- u32 type_tucmd, u32 mss_l4len_idx)
+static void igb_tx_ctxtdesc(struct igb_ring *tx_ring, u32 vlan_macip_lens,
+ u32 type_tucmd, u32 mss_l4len_idx)
{
struct e1000_adv_tx_context_desc *context_desc;
u16 i = tx_ring->next_to_use;
@@ -5623,7 +5623,7 @@ static irqreturn_t igb_intr(int irq, void *data)
return IRQ_HANDLED;
}
-void igb_ring_irq_enable(struct igb_q_vector *q_vector)
+static void igb_ring_irq_enable(struct igb_q_vector *q_vector)
{
struct igb_adapter *adapter = q_vector->adapter;
struct e1000_hw *hw = &adapter->hw;
diff --git a/drivers/net/ethernet/intel/igbvf/ethtool.c b/drivers/net/ethernet/intel/igbvf/ethtool.c
index 7b600a1f6366..2dba53446064 100644
--- a/drivers/net/ethernet/intel/igbvf/ethtool.c
+++ b/drivers/net/ethernet/intel/igbvf/ethtool.c
@@ -468,6 +468,5 @@ static const struct ethtool_ops igbvf_ethtool_ops = {
void igbvf_set_ethtool_ops(struct net_device *netdev)
{
- /* have to "undeclare" const on this struct to remove warnings */
- SET_ETHTOOL_OPS(netdev, (struct ethtool_ops *)&igbvf_ethtool_ops);
+ SET_ETHTOOL_OPS(netdev, &igbvf_ethtool_ops);
}
diff --git a/drivers/net/ethernet/intel/igbvf/netdev.c b/drivers/net/ethernet/intel/igbvf/netdev.c
index fd3da3076c2f..a4b20c865759 100644
--- a/drivers/net/ethernet/intel/igbvf/netdev.c
+++ b/drivers/net/ethernet/intel/igbvf/netdev.c
@@ -1194,11 +1194,6 @@ static int igbvf_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
struct igbvf_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw;
- igbvf_irq_disable(adapter);
-
- if (!test_bit(__IGBVF_DOWN, &adapter->state))
- igbvf_irq_enable(adapter);
-
if (hw->mac.ops.set_vfta(hw, vid, false)) {
dev_err(&adapter->pdev->dev,
"Failed to remove vlan id %d\n", vid);
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
index 802bfa0f62cc..775602ef90e5 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
@@ -161,19 +161,19 @@
/* Receive DMA Registers */
#define IXGBE_RDBAL(_i) (((_i) < 64) ? (0x01000 + ((_i) * 0x40)) : \
- (0x0D000 + ((_i - 64) * 0x40)))
+ (0x0D000 + (((_i) - 64) * 0x40)))
#define IXGBE_RDBAH(_i) (((_i) < 64) ? (0x01004 + ((_i) * 0x40)) : \
- (0x0D004 + ((_i - 64) * 0x40)))
+ (0x0D004 + (((_i) - 64) * 0x40)))
#define IXGBE_RDLEN(_i) (((_i) < 64) ? (0x01008 + ((_i) * 0x40)) : \
- (0x0D008 + ((_i - 64) * 0x40)))
+ (0x0D008 + (((_i) - 64) * 0x40)))
#define IXGBE_RDH(_i) (((_i) < 64) ? (0x01010 + ((_i) * 0x40)) : \
- (0x0D010 + ((_i - 64) * 0x40)))
+ (0x0D010 + (((_i) - 64) * 0x40)))
#define IXGBE_RDT(_i) (((_i) < 64) ? (0x01018 + ((_i) * 0x40)) : \
- (0x0D018 + ((_i - 64) * 0x40)))
+ (0x0D018 + (((_i) - 64) * 0x40)))
#define IXGBE_RXDCTL(_i) (((_i) < 64) ? (0x01028 + ((_i) * 0x40)) : \
- (0x0D028 + ((_i - 64) * 0x40)))
+ (0x0D028 + (((_i) - 64) * 0x40)))
#define IXGBE_RSCCTL(_i) (((_i) < 64) ? (0x0102C + ((_i) * 0x40)) : \
- (0x0D02C + ((_i - 64) * 0x40)))
+ (0x0D02C + (((_i) - 64) * 0x40)))
#define IXGBE_RSCDBU 0x03028
#define IXGBE_RDDCC 0x02F20
#define IXGBE_RXMEMWRAP 0x03190
@@ -186,7 +186,7 @@
*/
#define IXGBE_SRRCTL(_i) (((_i) <= 15) ? (0x02100 + ((_i) * 4)) : \
(((_i) < 64) ? (0x01014 + ((_i) * 0x40)) : \
- (0x0D014 + ((_i - 64) * 0x40))))
+ (0x0D014 + (((_i) - 64) * 0x40))))
/*
* Rx DCA Control Register:
* 00-15 : 0x02200 + n*4
@@ -195,7 +195,7 @@
*/
#define IXGBE_DCA_RXCTRL(_i) (((_i) <= 15) ? (0x02200 + ((_i) * 4)) : \
(((_i) < 64) ? (0x0100C + ((_i) * 0x40)) : \
- (0x0D00C + ((_i - 64) * 0x40))))
+ (0x0D00C + (((_i) - 64) * 0x40))))
#define IXGBE_RDRXCTL 0x02F00
#define IXGBE_RXPBSIZE(_i) (0x03C00 + ((_i) * 4))
/* 8 of these 0x03C00 - 0x03C1C */
@@ -344,9 +344,9 @@
#define IXGBE_WUPL 0x05900
#define IXGBE_WUPM 0x05A00 /* wake up pkt memory 0x5A00-0x5A7C */
-#define IXGBE_FHFT(_n) (0x09000 + (_n * 0x100)) /* Flex host filter table */
-#define IXGBE_FHFT_EXT(_n) (0x09800 + (_n * 0x100)) /* Ext Flexible Host
- * Filter Table */
+#define IXGBE_FHFT(_n) (0x09000 + ((_n) * 0x100)) /* Flex host filter table */
+#define IXGBE_FHFT_EXT(_n) (0x09800 + ((_n) * 0x100)) /* Ext Flexible Host
+ * Filter Table */
#define IXGBE_FLEXIBLE_FILTER_COUNT_MAX 4
#define IXGBE_EXT_FLEXIBLE_FILTER_COUNT_MAX 2
@@ -1485,7 +1485,7 @@ enum {
#define IXGBE_LED_BLINK_BASE 0x00000080
#define IXGBE_LED_MODE_MASK_BASE 0x0000000F
#define IXGBE_LED_OFFSET(_base, _i) (_base << (8 * (_i)))
-#define IXGBE_LED_MODE_SHIFT(_i) (8*(_i))
+#define IXGBE_LED_MODE_SHIFT(_i) (8 * (_i))
#define IXGBE_LED_IVRT(_i) IXGBE_LED_OFFSET(IXGBE_LED_IVRT_BASE, _i)
#define IXGBE_LED_BLINK(_i) IXGBE_LED_OFFSET(IXGBE_LED_BLINK_BASE, _i)
#define IXGBE_LED_MODE_MASK(_i) IXGBE_LED_OFFSET(IXGBE_LED_MODE_MASK_BASE, _i)
@@ -2068,9 +2068,9 @@ enum {
/* SR-IOV specific macros */
#define IXGBE_MBVFICR_INDEX(vf_number) (vf_number >> 4)
-#define IXGBE_MBVFICR(_i) (0x00710 + (_i * 4))
-#define IXGBE_VFLRE(_i) (((_i & 1) ? 0x001C0 : 0x00600))
-#define IXGBE_VFLREC(_i) (0x00700 + (_i * 4))
+#define IXGBE_MBVFICR(_i) (0x00710 + ((_i) * 4))
+#define IXGBE_VFLRE(_i) ((((_i) & 1) ? 0x001C0 : 0x00600))
+#define IXGBE_VFLREC(_i) (0x00700 + ((_i) * 4))
enum ixgbe_fdir_pballoc_type {
IXGBE_FDIR_PBALLOC_NONE = 0,
diff --git a/drivers/net/ethernet/intel/ixgbevf/ethtool.c b/drivers/net/ethernet/intel/ixgbevf/ethtool.c
index dc8e6511c640..c85700318147 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ethtool.c
+++ b/drivers/net/ethernet/intel/ixgbevf/ethtool.c
@@ -56,7 +56,8 @@ struct ixgbe_stats {
offsetof(struct ixgbevf_adapter, m), \
offsetof(struct ixgbevf_adapter, b), \
offsetof(struct ixgbevf_adapter, r)
-static struct ixgbe_stats ixgbe_gstrings_stats[] = {
+
+static const struct ixgbe_stats ixgbe_gstrings_stats[] = {
{"rx_packets", IXGBEVF_STAT(stats.vfgprc, stats.base_vfgprc,
stats.saved_reset_vfgprc)},
{"tx_packets", IXGBEVF_STAT(stats.vfgptc, stats.base_vfgptc,
@@ -671,7 +672,7 @@ static int ixgbevf_nway_reset(struct net_device *netdev)
return 0;
}
-static struct ethtool_ops ixgbevf_ethtool_ops = {
+static const struct ethtool_ops ixgbevf_ethtool_ops = {
.get_settings = ixgbevf_get_settings,
.get_drvinfo = ixgbevf_get_drvinfo,
.get_regs_len = ixgbevf_get_regs_len,
diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h b/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
index e6c9d1a927a9..9075c1d61039 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
+++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
@@ -279,12 +279,12 @@ enum ixgbevf_boards {
board_X540_vf,
};
-extern struct ixgbevf_info ixgbevf_82599_vf_info;
-extern struct ixgbevf_info ixgbevf_X540_vf_info;
-extern struct ixgbe_mbx_operations ixgbevf_mbx_ops;
+extern const struct ixgbevf_info ixgbevf_82599_vf_info;
+extern const struct ixgbevf_info ixgbevf_X540_vf_info;
+extern const struct ixgbe_mbx_operations ixgbevf_mbx_ops;
/* needed by ethtool.c */
-extern char ixgbevf_driver_name[];
+extern const char ixgbevf_driver_name[];
extern const char ixgbevf_driver_version[];
extern int ixgbevf_up(struct ixgbevf_adapter *adapter);
diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
index 891162d1610c..bed411bada21 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
+++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
@@ -53,7 +53,7 @@
#include "ixgbevf.h"
-char ixgbevf_driver_name[] = "ixgbevf";
+const char ixgbevf_driver_name[] = "ixgbevf";
static const char ixgbevf_driver_string[] =
"Intel(R) 10 Gigabit PCI Express Virtual Function Network Driver";
@@ -917,31 +917,34 @@ static irqreturn_t ixgbevf_msix_mbx(int irq, void *data)
struct ixgbe_hw *hw = &adapter->hw;
u32 eicr;
u32 msg;
+ bool got_ack = false;
eicr = IXGBE_READ_REG(hw, IXGBE_VTEICS);
IXGBE_WRITE_REG(hw, IXGBE_VTEICR, eicr);
- if (!hw->mbx.ops.check_for_ack(hw)) {
- /*
- * checking for the ack clears the PFACK bit. Place
- * it back in the v2p_mailbox cache so that anyone
- * polling for an ack will not miss it. Also
- * avoid the read below because the code to read
- * the mailbox will also clear the ack bit. This was
- * causing lost acks. Just cache the bit and exit
- * the IRQ handler.
- */
- hw->mbx.v2p_mailbox |= IXGBE_VFMAILBOX_PFACK;
- goto out;
- }
+ if (!hw->mbx.ops.check_for_ack(hw))
+ got_ack = true;
- /* Not an ack interrupt, go ahead and read the message */
- hw->mbx.ops.read(hw, &msg, 1);
+ if (!hw->mbx.ops.check_for_msg(hw)) {
+ hw->mbx.ops.read(hw, &msg, 1);
- if ((msg & IXGBE_MBVFICR_VFREQ_MASK) == IXGBE_PF_CONTROL_MSG)
- mod_timer(&adapter->watchdog_timer,
- round_jiffies(jiffies + 1));
+ if ((msg & IXGBE_MBVFICR_VFREQ_MASK) == IXGBE_PF_CONTROL_MSG)
+ mod_timer(&adapter->watchdog_timer,
+ round_jiffies(jiffies + 1));
+ if (msg & IXGBE_VT_MSGTYPE_NACK)
+ pr_warn("Last Request of type %2.2x to PF Nacked\n",
+ msg & 0xFF);
+ goto out;
+ }
+
+ /*
+ * checking for the ack clears the PFACK bit. Place
+ * it back in the v2p_mailbox cache so that anyone
+ * polling for an ack will not miss it
+ */
+ if (got_ack)
+ hw->mbx.v2p_mailbox |= IXGBE_VFMAILBOX_PFACK;
out:
return IRQ_HANDLED;
}
diff --git a/drivers/net/ethernet/intel/ixgbevf/mbx.c b/drivers/net/ethernet/intel/ixgbevf/mbx.c
index 930fa83f2568..13532d9ba72d 100644
--- a/drivers/net/ethernet/intel/ixgbevf/mbx.c
+++ b/drivers/net/ethernet/intel/ixgbevf/mbx.c
@@ -26,6 +26,7 @@
*******************************************************************************/
#include "mbx.h"
+#include "ixgbevf.h"
/**
* ixgbevf_poll_for_msg - Wait for message notification
@@ -328,7 +329,7 @@ static s32 ixgbevf_init_mbx_params_vf(struct ixgbe_hw *hw)
return 0;
}
-struct ixgbe_mbx_operations ixgbevf_mbx_ops = {
+const struct ixgbe_mbx_operations ixgbevf_mbx_ops = {
.init_params = ixgbevf_init_mbx_params_vf,
.read = ixgbevf_read_mbx_vf,
.write = ixgbevf_write_mbx_vf,
diff --git a/drivers/net/ethernet/intel/ixgbevf/vf.c b/drivers/net/ethernet/intel/ixgbevf/vf.c
index 21533e300367..d0138d7a31a1 100644
--- a/drivers/net/ethernet/intel/ixgbevf/vf.c
+++ b/drivers/net/ethernet/intel/ixgbevf/vf.c
@@ -26,6 +26,7 @@
*******************************************************************************/
#include "vf.h"
+#include "ixgbevf.h"
/**
* ixgbevf_start_hw_vf - Prepare hardware for Tx/Rx
@@ -401,7 +402,7 @@ static s32 ixgbevf_check_mac_link_vf(struct ixgbe_hw *hw,
return 0;
}
-static struct ixgbe_mac_operations ixgbevf_mac_ops = {
+static const struct ixgbe_mac_operations ixgbevf_mac_ops = {
.init_hw = ixgbevf_init_hw_vf,
.reset_hw = ixgbevf_reset_hw_vf,
.start_hw = ixgbevf_start_hw_vf,
@@ -415,12 +416,12 @@ static struct ixgbe_mac_operations ixgbevf_mac_ops = {
.set_vfta = ixgbevf_set_vfta_vf,
};
-struct ixgbevf_info ixgbevf_82599_vf_info = {
+const struct ixgbevf_info ixgbevf_82599_vf_info = {
.mac = ixgbe_mac_82599_vf,
.mac_ops = &ixgbevf_mac_ops,
};
-struct ixgbevf_info ixgbevf_X540_vf_info = {
+const struct ixgbevf_info ixgbevf_X540_vf_info = {
.mac = ixgbe_mac_X540_vf,
.mac_ops = &ixgbevf_mac_ops,
};
diff --git a/drivers/net/ethernet/intel/ixgbevf/vf.h b/drivers/net/ethernet/intel/ixgbevf/vf.h
index 10306b492ee6..d556619a9212 100644
--- a/drivers/net/ethernet/intel/ixgbevf/vf.h
+++ b/drivers/net/ethernet/intel/ixgbevf/vf.h
@@ -167,7 +167,7 @@ struct ixgbevf_hw_stats {
struct ixgbevf_info {
enum ixgbe_mac_type mac;
- struct ixgbe_mac_operations *mac_ops;
+ const struct ixgbe_mac_operations *mac_ops;
};
#endif /* __IXGBE_VF_H__ */
diff --git a/drivers/net/ethernet/marvell/mv643xx_eth.c b/drivers/net/ethernet/marvell/mv643xx_eth.c
index 9c049d2cb97d..9edecfa1f0f4 100644
--- a/drivers/net/ethernet/marvell/mv643xx_eth.c
+++ b/drivers/net/ethernet/marvell/mv643xx_eth.c
@@ -136,6 +136,8 @@ static char mv643xx_eth_driver_version[] = "1.4";
#define INT_MASK 0x0068
#define INT_MASK_EXT 0x006c
#define TX_FIFO_URGENT_THRESHOLD 0x0074
+#define RX_DISCARD_FRAME_CNT 0x0084
+#define RX_OVERRUN_FRAME_CNT 0x0088
#define TXQ_FIX_PRIO_CONF_MOVED 0x00dc
#define TX_BW_RATE_MOVED 0x00e0
#define TX_BW_MTU_MOVED 0x00e8
@@ -334,6 +336,9 @@ struct mib_counters {
u32 bad_crc_event;
u32 collision;
u32 late_collision;
+ /* Non MIB hardware counters */
+ u32 rx_discard;
+ u32 rx_overrun;
};
struct lro_counters {
@@ -1225,6 +1230,10 @@ static void mib_counters_clear(struct mv643xx_eth_private *mp)
for (i = 0; i < 0x80; i += 4)
mib_read(mp, i);
+
+ /* Clear non MIB hw counters also */
+ rdlp(mp, RX_DISCARD_FRAME_CNT);
+ rdlp(mp, RX_OVERRUN_FRAME_CNT);
}
static void mib_counters_update(struct mv643xx_eth_private *mp)
@@ -1262,6 +1271,9 @@ static void mib_counters_update(struct mv643xx_eth_private *mp)
p->bad_crc_event += mib_read(mp, 0x74);
p->collision += mib_read(mp, 0x78);
p->late_collision += mib_read(mp, 0x7c);
+ /* Non MIB hardware counters */
+ p->rx_discard += rdlp(mp, RX_DISCARD_FRAME_CNT);
+ p->rx_overrun += rdlp(mp, RX_OVERRUN_FRAME_CNT);
spin_unlock_bh(&mp->mib_counters_lock);
mod_timer(&mp->mib_counters_timer, jiffies + 30 * HZ);
@@ -1413,6 +1425,8 @@ static const struct mv643xx_eth_stats mv643xx_eth_stats[] = {
MIBSTAT(bad_crc_event),
MIBSTAT(collision),
MIBSTAT(late_collision),
+ MIBSTAT(rx_discard),
+ MIBSTAT(rx_overrun),
LROSTAT(lro_aggregated),
LROSTAT(lro_flushed),
LROSTAT(lro_no_desc),
diff --git a/drivers/net/ethernet/marvell/skge.c b/drivers/net/ethernet/marvell/skge.c
index 18a87a57fc0a..edb9bda55d55 100644
--- a/drivers/net/ethernet/marvell/skge.c
+++ b/drivers/net/ethernet/marvell/skge.c
@@ -931,17 +931,20 @@ static int skge_ring_alloc(struct skge_ring *ring, void *vaddr, u32 base)
}
/* Allocate and setup a new buffer for receiving */
-static void skge_rx_setup(struct skge_port *skge, struct skge_element *e,
- struct sk_buff *skb, unsigned int bufsize)
+static int skge_rx_setup(struct pci_dev *pdev,
+ struct skge_element *e,
+ struct sk_buff *skb, unsigned int bufsize)
{
struct skge_rx_desc *rd = e->desc;
- u64 map;
+ dma_addr_t map;
- map = pci_map_single(skge->hw->pdev, skb->data, bufsize,
+ map = pci_map_single(pdev, skb->data, bufsize,
PCI_DMA_FROMDEVICE);
+ if (pci_dma_mapping_error(pdev, map))
+ goto mapping_error;
- rd->dma_lo = map;
- rd->dma_hi = map >> 32;
+ rd->dma_lo = lower_32_bits(map);
+ rd->dma_hi = upper_32_bits(map);
e->skb = skb;
rd->csum1_start = ETH_HLEN;
rd->csum2_start = ETH_HLEN;
@@ -953,6 +956,13 @@ static void skge_rx_setup(struct skge_port *skge, struct skge_element *e,
rd->control = BMU_OWN | BMU_STF | BMU_IRQ_EOF | BMU_TCP_CHECK | bufsize;
dma_unmap_addr_set(e, mapaddr, map);
dma_unmap_len_set(e, maplen, bufsize);
+ return 0;
+
+mapping_error:
+ if (net_ratelimit())
+ dev_warn(&pdev->dev, "%s: rx mapping error\n",
+ skb->dev->name);
+ return -EIO;
}
/* Resume receiving using existing skb,
@@ -1014,7 +1024,11 @@ static int skge_rx_fill(struct net_device *dev)
return -ENOMEM;
skb_reserve(skb, NET_IP_ALIGN);
- skge_rx_setup(skge, e, skb, skge->rx_buf_size);
+ if (skge_rx_setup(skge->hw->pdev, e, skb, skge->rx_buf_size)) {
+ kfree_skb(skb);
+ return -ENOMEM;
+ }
+
} while ((e = e->next) != ring->start);
ring->to_clean = ring->start;
@@ -2576,6 +2590,7 @@ static int skge_up(struct net_device *dev)
}
/* Initialize MAC */
+ netif_carrier_off(dev);
spin_lock_bh(&hw->phy_lock);
if (is_genesis(hw))
genesis_mac_init(hw, port);
@@ -2728,7 +2743,7 @@ static netdev_tx_t skge_xmit_frame(struct sk_buff *skb,
struct skge_tx_desc *td;
int i;
u32 control, len;
- u64 map;
+ dma_addr_t map;
if (skb_padto(skb, ETH_ZLEN))
return NETDEV_TX_OK;
@@ -2742,11 +2757,14 @@ static netdev_tx_t skge_xmit_frame(struct sk_buff *skb,
e->skb = skb;
len = skb_headlen(skb);
map = pci_map_single(hw->pdev, skb->data, len, PCI_DMA_TODEVICE);
+ if (pci_dma_mapping_error(hw->pdev, map))
+ goto mapping_error;
+
dma_unmap_addr_set(e, mapaddr, map);
dma_unmap_len_set(e, maplen, len);
- td->dma_lo = map;
- td->dma_hi = map >> 32;
+ td->dma_lo = lower_32_bits(map);
+ td->dma_hi = upper_32_bits(map);
if (skb->ip_summed == CHECKSUM_PARTIAL) {
const int offset = skb_checksum_start_offset(skb);
@@ -2777,14 +2795,16 @@ static netdev_tx_t skge_xmit_frame(struct sk_buff *skb,
map = skb_frag_dma_map(&hw->pdev->dev, frag, 0,
skb_frag_size(frag), DMA_TO_DEVICE);
+ if (dma_mapping_error(&hw->pdev->dev, map))
+ goto mapping_unwind;
e = e->next;
e->skb = skb;
tf = e->desc;
BUG_ON(tf->control & BMU_OWN);
- tf->dma_lo = map;
- tf->dma_hi = (u64) map >> 32;
+ tf->dma_lo = lower_32_bits(map);
+ tf->dma_hi = upper_32_bits(map);
dma_unmap_addr_set(e, mapaddr, map);
dma_unmap_len_set(e, maplen, skb_frag_size(frag));
@@ -2797,6 +2817,8 @@ static netdev_tx_t skge_xmit_frame(struct sk_buff *skb,
td->control = BMU_OWN | BMU_SW | BMU_STF | control | len;
wmb();
+ netdev_sent_queue(dev, skb->len);
+
skge_write8(hw, Q_ADDR(txqaddr[skge->port], Q_CSR), CSR_START);
netif_printk(skge, tx_queued, KERN_DEBUG, skge->netdev,
@@ -2812,15 +2834,35 @@ static netdev_tx_t skge_xmit_frame(struct sk_buff *skb,
}
return NETDEV_TX_OK;
+
+mapping_unwind:
+ /* unroll any pages that were already mapped. */
+ if (e != skge->tx_ring.to_use) {
+ struct skge_element *u;
+
+ for (u = skge->tx_ring.to_use->next; u != e; u = u->next)
+ pci_unmap_page(hw->pdev, dma_unmap_addr(u, mapaddr),
+ dma_unmap_len(u, maplen),
+ PCI_DMA_TODEVICE);
+ e = skge->tx_ring.to_use;
+ }
+ /* undo the mapping for the skb header */
+ pci_unmap_single(hw->pdev, dma_unmap_addr(e, mapaddr),
+ dma_unmap_len(e, maplen),
+ PCI_DMA_TODEVICE);
+mapping_error:
+ /* mapping error causes error message and packet to be discarded. */
+ if (net_ratelimit())
+ dev_warn(&hw->pdev->dev, "%s: tx mapping error\n", dev->name);
+ dev_kfree_skb(skb);
+ return NETDEV_TX_OK;
}
/* Free resources associated with this reing element */
-static void skge_tx_free(struct skge_port *skge, struct skge_element *e,
- u32 control)
+static inline void skge_tx_unmap(struct pci_dev *pdev, struct skge_element *e,
+ u32 control)
{
- struct pci_dev *pdev = skge->hw->pdev;
-
/* skb header vs. fragment */
if (control & BMU_STF)
pci_unmap_single(pdev, dma_unmap_addr(e, mapaddr),
@@ -2830,13 +2872,6 @@ static void skge_tx_free(struct skge_port *skge, struct skge_element *e,
pci_unmap_page(pdev, dma_unmap_addr(e, mapaddr),
dma_unmap_len(e, maplen),
PCI_DMA_TODEVICE);
-
- if (control & BMU_EOF) {
- netif_printk(skge, tx_done, KERN_DEBUG, skge->netdev,
- "tx done slot %td\n", e - skge->tx_ring.start);
-
- dev_kfree_skb(e->skb);
- }
}
/* Free all buffers in transmit ring */
@@ -2847,10 +2882,15 @@ static void skge_tx_clean(struct net_device *dev)
for (e = skge->tx_ring.to_clean; e != skge->tx_ring.to_use; e = e->next) {
struct skge_tx_desc *td = e->desc;
- skge_tx_free(skge, e, td->control);
+
+ skge_tx_unmap(skge->hw->pdev, e, td->control);
+
+ if (td->control & BMU_EOF)
+ dev_kfree_skb(e->skb);
td->control = 0;
}
+ netdev_reset_queue(dev);
skge->tx_ring.to_clean = e;
}
@@ -3059,13 +3099,17 @@ static struct sk_buff *skge_rx_get(struct net_device *dev,
if (!nskb)
goto resubmit;
+ if (unlikely(skge_rx_setup(skge->hw->pdev, e, nskb, skge->rx_buf_size))) {
+ dev_kfree_skb(nskb);
+ goto resubmit;
+ }
+
pci_unmap_single(skge->hw->pdev,
dma_unmap_addr(e, mapaddr),
dma_unmap_len(e, maplen),
PCI_DMA_FROMDEVICE);
skb = e->skb;
prefetch(skb->data);
- skge_rx_setup(skge, e, nskb, skge->rx_buf_size);
}
skb_put(skb, len);
@@ -3111,6 +3155,7 @@ static void skge_tx_done(struct net_device *dev)
struct skge_port *skge = netdev_priv(dev);
struct skge_ring *ring = &skge->tx_ring;
struct skge_element *e;
+ unsigned int bytes_compl = 0, pkts_compl = 0;
skge_write8(skge->hw, Q_ADDR(txqaddr[skge->port], Q_CSR), CSR_IRQ_CL_F);
@@ -3120,8 +3165,20 @@ static void skge_tx_done(struct net_device *dev)
if (control & BMU_OWN)
break;
- skge_tx_free(skge, e, control);
+ skge_tx_unmap(skge->hw->pdev, e, control);
+
+ if (control & BMU_EOF) {
+ netif_printk(skge, tx_done, KERN_DEBUG, skge->netdev,
+ "tx done slot %td\n",
+ e - skge->tx_ring.start);
+
+ pkts_compl++;
+ bytes_compl += e->skb->len;
+
+ dev_kfree_skb(e->skb);
+ }
}
+ netdev_completed_queue(dev, pkts_compl, bytes_compl);
skge->tx_ring.to_clean = e;
/* Can run lockless until we need to synchronize to restart queue. */
diff --git a/drivers/net/ethernet/mellanox/mlx4/cmd.c b/drivers/net/ethernet/mellanox/mlx4/cmd.c
index 978f593094c0..405e6ac3faf6 100644
--- a/drivers/net/ethernet/mellanox/mlx4/cmd.c
+++ b/drivers/net/ethernet/mellanox/mlx4/cmd.c
@@ -1247,6 +1247,7 @@ static void mlx4_master_do_cmd(struct mlx4_dev *dev, int slave, u8 cmd,
u32 reply;
u32 slave_status = 0;
u8 is_going_down = 0;
+ int i;
slave_state[slave].comm_toggle ^= 1;
reply = (u32) slave_state[slave].comm_toggle << 31;
@@ -1258,6 +1259,10 @@ static void mlx4_master_do_cmd(struct mlx4_dev *dev, int slave, u8 cmd,
if (cmd == MLX4_COMM_CMD_RESET) {
mlx4_warn(dev, "Received reset from slave:%d\n", slave);
slave_state[slave].active = false;
+ for (i = 0; i < MLX4_EVENT_TYPES_NUM; ++i) {
+ slave_state[slave].event_eq[i].eqn = -1;
+ slave_state[slave].event_eq[i].token = 0;
+ }
/*check if we are in the middle of FLR process,
if so return "retry" status to the slave*/
if (MLX4_COMM_CMD_FLR == slave_state[slave].last_cmd) {
@@ -1452,7 +1457,7 @@ int mlx4_multi_func_init(struct mlx4_dev *dev)
{
struct mlx4_priv *priv = mlx4_priv(dev);
struct mlx4_slave_state *s_state;
- int i, err, port;
+ int i, j, err, port;
priv->mfunc.vhcr = dma_alloc_coherent(&(dev->pdev->dev), PAGE_SIZE,
&priv->mfunc.vhcr_dma,
@@ -1485,6 +1490,8 @@ int mlx4_multi_func_init(struct mlx4_dev *dev)
for (i = 0; i < dev->num_slaves; ++i) {
s_state = &priv->mfunc.master.slave_state[i];
s_state->last_cmd = MLX4_COMM_CMD_RESET;
+ for (j = 0; j < MLX4_EVENT_TYPES_NUM; ++j)
+ s_state->event_eq[j].eqn = -1;
__raw_writel((__force u32) 0,
&priv->mfunc.comm[i].slave_write);
__raw_writel((__force u32) 0,
diff --git a/drivers/net/ethernet/mellanox/mlx4/cq.c b/drivers/net/ethernet/mellanox/mlx4/cq.c
index 475f9d6af955..7e64033d7de3 100644
--- a/drivers/net/ethernet/mellanox/mlx4/cq.c
+++ b/drivers/net/ethernet/mellanox/mlx4/cq.c
@@ -96,7 +96,7 @@ void mlx4_cq_event(struct mlx4_dev *dev, u32 cqn, int event_type)
static int mlx4_SW2HW_CQ(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *mailbox,
int cq_num)
{
- return mlx4_cmd(dev, mailbox->dma | dev->caps.function, cq_num, 0,
+ return mlx4_cmd(dev, mailbox->dma, cq_num, 0,
MLX4_CMD_SW2HW_CQ, MLX4_CMD_TIME_CLASS_A,
MLX4_CMD_WRAPPED);
}
@@ -111,7 +111,7 @@ static int mlx4_MODIFY_CQ(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *mailbox
static int mlx4_HW2SW_CQ(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *mailbox,
int cq_num)
{
- return mlx4_cmd_box(dev, dev->caps.function, mailbox ? mailbox->dma : 0,
+ return mlx4_cmd_box(dev, 0, mailbox ? mailbox->dma : 0,
cq_num, mailbox ? 0 : 1, MLX4_CMD_HW2SW_CQ,
MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED);
}
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
index 7dbc6a230779..70346fd7f9c4 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
@@ -183,10 +183,11 @@ static int mlx4_en_set_wol(struct net_device *netdev,
static int mlx4_en_get_sset_count(struct net_device *dev, int sset)
{
struct mlx4_en_priv *priv = netdev_priv(dev);
+ int bit_count = hweight64(priv->stats_bitmap);
switch (sset) {
case ETH_SS_STATS:
- return NUM_ALL_STATS +
+ return (priv->stats_bitmap ? bit_count : NUM_ALL_STATS) +
(priv->tx_ring_num + priv->rx_ring_num) * 2;
case ETH_SS_TEST:
return MLX4_EN_NUM_SELF_TEST - !(priv->mdev->dev->caps.flags
@@ -201,14 +202,34 @@ static void mlx4_en_get_ethtool_stats(struct net_device *dev,
{
struct mlx4_en_priv *priv = netdev_priv(dev);
int index = 0;
- int i;
+ int i, j = 0;
spin_lock_bh(&priv->stats_lock);
- for (i = 0; i < NUM_MAIN_STATS; i++)
- data[index++] = ((unsigned long *) &priv->stats)[i];
- for (i = 0; i < NUM_PORT_STATS; i++)
- data[index++] = ((unsigned long *) &priv->port_stats)[i];
+ if (!(priv->stats_bitmap)) {
+ for (i = 0; i < NUM_MAIN_STATS; i++)
+ data[index++] =
+ ((unsigned long *) &priv->stats)[i];
+ for (i = 0; i < NUM_PORT_STATS; i++)
+ data[index++] =
+ ((unsigned long *) &priv->port_stats)[i];
+ for (i = 0; i < NUM_PKT_STATS; i++)
+ data[index++] =
+ ((unsigned long *) &priv->pkstats)[i];
+ } else {
+ for (i = 0; i < NUM_MAIN_STATS; i++) {
+ if ((priv->stats_bitmap >> j) & 1)
+ data[index++] =
+ ((unsigned long *) &priv->stats)[i];
+ j++;
+ }
+ for (i = 0; i < NUM_PORT_STATS; i++) {
+ if ((priv->stats_bitmap >> j) & 1)
+ data[index++] =
+ ((unsigned long *) &priv->port_stats)[i];
+ j++;
+ }
+ }
for (i = 0; i < priv->tx_ring_num; i++) {
data[index++] = priv->tx_ring[i].packets;
data[index++] = priv->tx_ring[i].bytes;
@@ -217,8 +238,6 @@ static void mlx4_en_get_ethtool_stats(struct net_device *dev,
data[index++] = priv->rx_ring[i].packets;
data[index++] = priv->rx_ring[i].bytes;
}
- for (i = 0; i < NUM_PKT_STATS; i++)
- data[index++] = ((unsigned long *) &priv->pkstats)[i];
spin_unlock_bh(&priv->stats_lock);
}
@@ -247,11 +266,29 @@ static void mlx4_en_get_strings(struct net_device *dev,
case ETH_SS_STATS:
/* Add main counters */
- for (i = 0; i < NUM_MAIN_STATS; i++)
- strcpy(data + (index++) * ETH_GSTRING_LEN, main_strings[i]);
- for (i = 0; i< NUM_PORT_STATS; i++)
- strcpy(data + (index++) * ETH_GSTRING_LEN,
- main_strings[i + NUM_MAIN_STATS]);
+ if (!priv->stats_bitmap) {
+ for (i = 0; i < NUM_MAIN_STATS; i++)
+ strcpy(data + (index++) * ETH_GSTRING_LEN,
+ main_strings[i]);
+ for (i = 0; i < NUM_PORT_STATS; i++)
+ strcpy(data + (index++) * ETH_GSTRING_LEN,
+ main_strings[i +
+ NUM_MAIN_STATS]);
+ for (i = 0; i < NUM_PKT_STATS; i++)
+ strcpy(data + (index++) * ETH_GSTRING_LEN,
+ main_strings[i +
+ NUM_MAIN_STATS +
+ NUM_PORT_STATS]);
+ } else
+ for (i = 0; i < NUM_MAIN_STATS + NUM_PORT_STATS; i++) {
+ if ((priv->stats_bitmap >> i) & 1) {
+ strcpy(data +
+ (index++) * ETH_GSTRING_LEN,
+ main_strings[i]);
+ }
+ if (!(priv->stats_bitmap >> i))
+ break;
+ }
for (i = 0; i < priv->tx_ring_num; i++) {
sprintf(data + (index++) * ETH_GSTRING_LEN,
"tx%d_packets", i);
@@ -264,9 +301,6 @@ static void mlx4_en_get_strings(struct net_device *dev,
sprintf(data + (index++) * ETH_GSTRING_LEN,
"rx%d_bytes", i);
}
- for (i = 0; i< NUM_PKT_STATS; i++)
- strcpy(data + (index++) * ETH_GSTRING_LEN,
- main_strings[i + NUM_MAIN_STATS + NUM_PORT_STATS]);
break;
}
}
@@ -479,6 +513,95 @@ static void mlx4_en_get_ringparam(struct net_device *dev,
param->tx_pending = priv->tx_ring[0].size;
}
+static u32 mlx4_en_get_rxfh_indir_size(struct net_device *dev)
+{
+ struct mlx4_en_priv *priv = netdev_priv(dev);
+
+ return priv->rx_ring_num;
+}
+
+static int mlx4_en_get_rxfh_indir(struct net_device *dev, u32 *ring_index)
+{
+ struct mlx4_en_priv *priv = netdev_priv(dev);
+ struct mlx4_en_rss_map *rss_map = &priv->rss_map;
+ int rss_rings;
+ size_t n = priv->rx_ring_num;
+ int err = 0;
+
+ rss_rings = priv->prof->rss_rings ?: priv->rx_ring_num;
+
+ while (n--) {
+ ring_index[n] = rss_map->qps[n % rss_rings].qpn -
+ rss_map->base_qpn;
+ }
+
+ return err;
+}
+
+static int mlx4_en_set_rxfh_indir(struct net_device *dev,
+ const u32 *ring_index)
+{
+ struct mlx4_en_priv *priv = netdev_priv(dev);
+ struct mlx4_en_dev *mdev = priv->mdev;
+ int port_up = 0;
+ int err = 0;
+ int i;
+ int rss_rings = 0;
+
+ /* Calculate RSS table size and make sure flows are spread evenly
+ * between rings
+ */
+ for (i = 0; i < priv->rx_ring_num; i++) {
+ if (i > 0 && !ring_index[i] && !rss_rings)
+ rss_rings = i;
+
+ if (ring_index[i] != (i % (rss_rings ?: priv->rx_ring_num)))
+ return -EINVAL;
+ }
+
+ if (!rss_rings)
+ rss_rings = priv->rx_ring_num;
+
+ /* RSS table size must be an order of 2 */
+ if (!is_power_of_2(rss_rings))
+ return -EINVAL;
+
+ mutex_lock(&mdev->state_lock);
+ if (priv->port_up) {
+ port_up = 1;
+ mlx4_en_stop_port(dev);
+ }
+
+ priv->prof->rss_rings = rss_rings;
+
+ if (port_up) {
+ err = mlx4_en_start_port(dev);
+ if (err)
+ en_err(priv, "Failed starting port\n");
+ }
+
+ mutex_unlock(&mdev->state_lock);
+ return err;
+}
+
+static int mlx4_en_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd,
+ u32 *rule_locs)
+{
+ struct mlx4_en_priv *priv = netdev_priv(dev);
+ int err = 0;
+
+ switch (cmd->cmd) {
+ case ETHTOOL_GRXRINGS:
+ cmd->data = priv->rx_ring_num;
+ break;
+ default:
+ err = -EOPNOTSUPP;
+ break;
+ }
+
+ return err;
+}
+
const struct ethtool_ops mlx4_en_ethtool_ops = {
.get_drvinfo = mlx4_en_get_drvinfo,
.get_settings = mlx4_en_get_settings,
@@ -498,6 +621,10 @@ const struct ethtool_ops mlx4_en_ethtool_ops = {
.set_pauseparam = mlx4_en_set_pauseparam,
.get_ringparam = mlx4_en_get_ringparam,
.set_ringparam = mlx4_en_set_ringparam,
+ .get_rxnfc = mlx4_en_get_rxnfc,
+ .get_rxfh_indir_size = mlx4_en_get_rxfh_indir_size,
+ .get_rxfh_indir = mlx4_en_get_rxfh_indir,
+ .set_rxfh_indir = mlx4_en_set_rxfh_indir,
};
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_main.c b/drivers/net/ethernet/mellanox/mlx4/en_main.c
index a06096fcc0b8..2097a7d3c5b8 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_main.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_main.c
@@ -62,10 +62,6 @@ static const char mlx4_en_version[] =
* Device scope module parameters
*/
-
-/* Enable RSS TCP traffic */
-MLX4_EN_PARM_INT(tcp_rss, 1,
- "Enable RSS for incomming TCP traffic or disabled (0)");
/* Enable RSS UDP traffic */
MLX4_EN_PARM_INT(udp_rss, 1,
"Enable RSS for incomming UDP traffic or disabled (0)");
@@ -104,7 +100,6 @@ static int mlx4_en_get_profile(struct mlx4_en_dev *mdev)
struct mlx4_en_profile *params = &mdev->profile;
int i;
- params->tcp_rss = tcp_rss;
params->udp_rss = udp_rss;
if (params->udp_rss && !(mdev->dev->caps.flags
& MLX4_DEV_CAP_FLAG_UDP_RSS)) {
@@ -120,6 +115,7 @@ static int mlx4_en_get_profile(struct mlx4_en_dev *mdev)
params->prof[i].rx_ring_size = MLX4_EN_DEF_RX_RING_SIZE;
params->prof[i].tx_ring_num = MLX4_EN_NUM_TX_RINGS +
(!!pfcrx) * MLX4_EN_NUM_PPP_RINGS;
+ params->prof[i].rss_rings = 0;
}
return 0;
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
index 72fa807b69ce..467ae5824875 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
@@ -702,6 +702,8 @@ int mlx4_en_start_port(struct net_device *dev)
/* Schedule multicast task to populate multicast list */
queue_work(mdev->workqueue, &priv->mcast_task);
+ mlx4_set_stats_bitmap(mdev->dev, &priv->stats_bitmap);
+
priv->port_up = true;
netif_tx_start_all_queues(dev);
return 0;
@@ -807,38 +809,50 @@ static void mlx4_en_restart(struct work_struct *work)
mutex_unlock(&mdev->state_lock);
}
-
-static int mlx4_en_open(struct net_device *dev)
+static void mlx4_en_clear_stats(struct net_device *dev)
{
struct mlx4_en_priv *priv = netdev_priv(dev);
struct mlx4_en_dev *mdev = priv->mdev;
int i;
- int err = 0;
-
- mutex_lock(&mdev->state_lock);
-
- if (!mdev->device_up) {
- en_err(priv, "Cannot open - device down/disabled\n");
- err = -EBUSY;
- goto out;
- }
- /* Reset HW statistics and performance counters */
if (mlx4_en_DUMP_ETH_STATS(mdev, priv->port, 1))
en_dbg(HW, priv, "Failed dumping statistics\n");
memset(&priv->stats, 0, sizeof(priv->stats));
memset(&priv->pstats, 0, sizeof(priv->pstats));
+ memset(&priv->pkstats, 0, sizeof(priv->pkstats));
+ memset(&priv->port_stats, 0, sizeof(priv->port_stats));
for (i = 0; i < priv->tx_ring_num; i++) {
priv->tx_ring[i].bytes = 0;
priv->tx_ring[i].packets = 0;
+ priv->tx_ring[i].tx_csum = 0;
}
for (i = 0; i < priv->rx_ring_num; i++) {
priv->rx_ring[i].bytes = 0;
priv->rx_ring[i].packets = 0;
+ priv->rx_ring[i].csum_ok = 0;
+ priv->rx_ring[i].csum_none = 0;
+ }
+}
+
+static int mlx4_en_open(struct net_device *dev)
+{
+ struct mlx4_en_priv *priv = netdev_priv(dev);
+ struct mlx4_en_dev *mdev = priv->mdev;
+ int err = 0;
+
+ mutex_lock(&mdev->state_lock);
+
+ if (!mdev->device_up) {
+ en_err(priv, "Cannot open - device down/disabled\n");
+ err = -EBUSY;
+ goto out;
}
+ /* Reset HW statistics and SW counters */
+ mlx4_en_clear_stats(dev);
+
err = mlx4_en_start_port(dev);
if (err)
en_err(priv, "Failed starting port:%d\n", priv->port);
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_rx.c b/drivers/net/ethernet/mellanox/mlx4/en_rx.c
index e8d6ad2dce0a..971d4b6b8dfe 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_rx.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_rx.c
@@ -853,6 +853,7 @@ int mlx4_en_config_rss_steer(struct mlx4_en_priv *priv)
struct mlx4_en_rss_map *rss_map = &priv->rss_map;
struct mlx4_qp_context context;
struct mlx4_rss_context *rss_context;
+ int rss_rings;
void *ptr;
u8 rss_mask = (MLX4_RSS_IPV4 | MLX4_RSS_TCP_IPV4 | MLX4_RSS_IPV6 |
MLX4_RSS_TCP_IPV6);
@@ -893,10 +894,15 @@ int mlx4_en_config_rss_steer(struct mlx4_en_priv *priv)
mlx4_en_fill_qp_context(priv, 0, 0, 0, 1, priv->base_qpn,
priv->rx_ring[0].cqn, &context);
+ if (!priv->prof->rss_rings || priv->prof->rss_rings > priv->rx_ring_num)
+ rss_rings = priv->rx_ring_num;
+ else
+ rss_rings = priv->prof->rss_rings;
+
ptr = ((void *) &context) + offsetof(struct mlx4_qp_context, pri_path)
+ MLX4_RSS_OFFSET_IN_QPC_PRI_PATH;
rss_context = ptr;
- rss_context->base_qpn = cpu_to_be32(ilog2(priv->rx_ring_num) << 24 |
+ rss_context->base_qpn = cpu_to_be32(ilog2(rss_rings) << 24 |
(rss_map->base_qpn));
rss_context->default_qpn = cpu_to_be32(rss_map->base_qpn);
if (priv->mdev->profile.udp_rss) {
diff --git a/drivers/net/ethernet/mellanox/mlx4/eq.c b/drivers/net/ethernet/mellanox/mlx4/eq.c
index 1e9b55eb7217..55d7bd4e210a 100644
--- a/drivers/net/ethernet/mellanox/mlx4/eq.c
+++ b/drivers/net/ethernet/mellanox/mlx4/eq.c
@@ -513,25 +513,22 @@ int mlx4_MAP_EQ_wrapper(struct mlx4_dev *dev, int slave,
{
struct mlx4_priv *priv = mlx4_priv(dev);
struct mlx4_slave_event_eq_info *event_eq =
- &priv->mfunc.master.slave_state[slave].event_eq;
+ priv->mfunc.master.slave_state[slave].event_eq;
u32 in_modifier = vhcr->in_modifier;
u32 eqn = in_modifier & 0x1FF;
u64 in_param = vhcr->in_param;
int err = 0;
+ int i;
if (slave == dev->caps.function)
err = mlx4_cmd(dev, in_param, (in_modifier & 0x80000000) | eqn,
0, MLX4_CMD_MAP_EQ, MLX4_CMD_TIME_CLASS_B,
MLX4_CMD_NATIVE);
- if (!err) {
- if (in_modifier >> 31) {
- /* unmap */
- event_eq->event_type &= ~in_param;
- } else {
- event_eq->eqn = eqn;
- event_eq->event_type = in_param;
- }
- }
+ if (!err)
+ for (i = 0; i < MLX4_EVENT_TYPES_NUM; ++i)
+ if (in_param & (1LL << i))
+ event_eq[i].eqn = in_modifier >> 31 ? -1 : eqn;
+
return err;
}
@@ -546,7 +543,7 @@ static int mlx4_MAP_EQ(struct mlx4_dev *dev, u64 event_mask, int unmap,
static int mlx4_SW2HW_EQ(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *mailbox,
int eq_num)
{
- return mlx4_cmd(dev, mailbox->dma | dev->caps.function, eq_num, 0,
+ return mlx4_cmd(dev, mailbox->dma, eq_num, 0,
MLX4_CMD_SW2HW_EQ, MLX4_CMD_TIME_CLASS_A,
MLX4_CMD_WRAPPED);
}
@@ -554,7 +551,7 @@ static int mlx4_SW2HW_EQ(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *mailbox,
static int mlx4_HW2SW_EQ(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *mailbox,
int eq_num)
{
- return mlx4_cmd_box(dev, dev->caps.function, mailbox->dma, eq_num,
+ return mlx4_cmd_box(dev, 0, mailbox->dma, eq_num,
0, MLX4_CMD_HW2SW_EQ, MLX4_CMD_TIME_CLASS_A,
MLX4_CMD_WRAPPED);
}
diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.c b/drivers/net/ethernet/mellanox/mlx4/fw.c
index a424a19280cc..8a21e10952ea 100644
--- a/drivers/net/ethernet/mellanox/mlx4/fw.c
+++ b/drivers/net/ethernet/mellanox/mlx4/fw.c
@@ -158,7 +158,6 @@ int mlx4_QUERY_FUNC_CAP_wrapper(struct mlx4_dev *dev, int slave,
#define QUERY_FUNC_CAP_FLAGS_OFFSET 0x0
#define QUERY_FUNC_CAP_NUM_PORTS_OFFSET 0x1
-#define QUERY_FUNC_CAP_FUNCTION_OFFSET 0x3
#define QUERY_FUNC_CAP_PF_BHVR_OFFSET 0x4
#define QUERY_FUNC_CAP_QP_QUOTA_OFFSET 0x10
#define QUERY_FUNC_CAP_CQ_QUOTA_OFFSET 0x14
@@ -182,9 +181,6 @@ int mlx4_QUERY_FUNC_CAP_wrapper(struct mlx4_dev *dev, int slave,
field = 1 << 7; /* enable only ethernet interface */
MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_FLAGS_OFFSET);
- field = slave;
- MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_FUNCTION_OFFSET);
-
field = dev->caps.num_ports;
MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_NUM_PORTS_OFFSET);
@@ -249,9 +245,6 @@ int mlx4_QUERY_FUNC_CAP(struct mlx4_dev *dev, struct mlx4_func_cap *func_cap)
goto out;
}
- MLX4_GET(field, outbox, QUERY_FUNC_CAP_FUNCTION_OFFSET);
- func_cap->function = field;
-
MLX4_GET(field, outbox, QUERY_FUNC_CAP_NUM_PORTS_OFFSET);
func_cap->num_ports = field;
diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.h b/drivers/net/ethernet/mellanox/mlx4/fw.h
index 119e0cc9fab3..e1a5fa56bcbc 100644
--- a/drivers/net/ethernet/mellanox/mlx4/fw.h
+++ b/drivers/net/ethernet/mellanox/mlx4/fw.h
@@ -119,7 +119,6 @@ struct mlx4_dev_cap {
};
struct mlx4_func_cap {
- u8 function;
u8 num_ports;
u8 flags;
u32 pf_context_behaviour;
diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c
index 6bb62c580e2d..678558b502fc 100644
--- a/drivers/net/ethernet/mellanox/mlx4/main.c
+++ b/drivers/net/ethernet/mellanox/mlx4/main.c
@@ -108,7 +108,7 @@ static struct mlx4_profile default_profile = {
.num_cq = 1 << 16,
.num_mcg = 1 << 13,
.num_mpt = 1 << 19,
- .num_mtt = 1 << 20,
+ .num_mtt = 1 << 20, /* It is really num mtt segements */
};
static int log_num_mac = 7;
@@ -471,7 +471,6 @@ static int mlx4_slave_cap(struct mlx4_dev *dev)
return -ENOSYS;
}
- dev->caps.function = func_cap.function;
dev->caps.num_ports = func_cap.num_ports;
dev->caps.num_qps = func_cap.qp_quota;
dev->caps.num_srqs = func_cap.srq_quota;
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/drivers/net/ethernet/mellanox/mlx4/mlx4.h
index a80121a2b519..c92269f8c057 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h
+++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h
@@ -388,9 +388,8 @@ struct mlx4_slave_eqe {
};
struct mlx4_slave_event_eq_info {
- u32 eqn;
+ int eqn;
u16 token;
- u64 event_type;
};
struct mlx4_profile {
@@ -449,6 +448,8 @@ struct mlx4_steer_index {
struct list_head duplicates;
};
+#define MLX4_EVENT_TYPES_NUM 64
+
struct mlx4_slave_state {
u8 comm_toggle;
u8 last_cmd;
@@ -461,7 +462,8 @@ struct mlx4_slave_state {
struct mlx4_slave_eqe eq[MLX4_MFUNC_MAX_EQES];
struct list_head mcast_filters[MLX4_MAX_PORTS + 1];
struct mlx4_vlan_fltr *vlan_filter[MLX4_MAX_PORTS + 1];
- struct mlx4_slave_event_eq_info event_eq;
+ /* event type to eq number lookup */
+ struct mlx4_slave_event_eq_info event_eq[MLX4_EVENT_TYPES_NUM];
u16 eq_pi;
u16 eq_ci;
spinlock_t lock;
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
index f2a8e65f5f88..35f08840813c 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
+++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
@@ -325,11 +325,11 @@ struct mlx4_en_port_profile {
u8 rx_ppp;
u8 tx_pause;
u8 tx_ppp;
+ int rss_rings;
};
struct mlx4_en_profile {
int rss_xor;
- int tcp_rss;
int udp_rss;
u8 rss_mask;
u32 active_ports;
@@ -476,6 +476,7 @@ struct mlx4_en_priv {
struct mlx4_en_perf_stats pstats;
struct mlx4_en_pkt_stats pkstats;
struct mlx4_en_port_stats port_stats;
+ u64 stats_bitmap;
char *mc_addrs;
int mc_addrs_cnt;
struct mlx4_en_stat_out_mbox hw_stats;
diff --git a/drivers/net/ethernet/mellanox/mlx4/mr.c b/drivers/net/ethernet/mellanox/mlx4/mr.c
index 01df5567e16e..8deeef98280c 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mr.c
+++ b/drivers/net/ethernet/mellanox/mlx4/mr.c
@@ -291,7 +291,7 @@ static u32 key_to_hw_index(u32 key)
static int mlx4_SW2HW_MPT(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *mailbox,
int mpt_index)
{
- return mlx4_cmd(dev, mailbox->dma | dev->caps.function , mpt_index,
+ return mlx4_cmd(dev, mailbox->dma, mpt_index,
0, MLX4_CMD_SW2HW_MPT, MLX4_CMD_TIME_CLASS_B,
MLX4_CMD_WRAPPED);
}
diff --git a/drivers/net/ethernet/mellanox/mlx4/pd.c b/drivers/net/ethernet/mellanox/mlx4/pd.c
index 5c9a54df17ab..db4746d0dca7 100644
--- a/drivers/net/ethernet/mellanox/mlx4/pd.c
+++ b/drivers/net/ethernet/mellanox/mlx4/pd.c
@@ -52,8 +52,7 @@ int mlx4_pd_alloc(struct mlx4_dev *dev, u32 *pdn)
*pdn = mlx4_bitmap_alloc(&priv->pd_bitmap);
if (*pdn == -1)
return -ENOMEM;
- if (mlx4_is_mfunc(dev))
- *pdn |= (dev->caps.function + 1) << NOT_MASKED_PD_BITS;
+
return 0;
}
EXPORT_SYMBOL_GPL(mlx4_pd_alloc);
diff --git a/drivers/net/ethernet/mellanox/mlx4/port.c b/drivers/net/ethernet/mellanox/mlx4/port.c
index 88b52e547524..f44ae555bf43 100644
--- a/drivers/net/ethernet/mellanox/mlx4/port.c
+++ b/drivers/net/ethernet/mellanox/mlx4/port.c
@@ -44,6 +44,11 @@
#define MLX4_VLAN_VALID (1u << 31)
#define MLX4_VLAN_MASK 0xfff
+#define MLX4_STATS_TRAFFIC_COUNTERS_MASK 0xfULL
+#define MLX4_STATS_TRAFFIC_DROPS_MASK 0xc0ULL
+#define MLX4_STATS_ERROR_COUNTERS_MASK 0x1ffc30ULL
+#define MLX4_STATS_PORT_COUNTERS_MASK 0x1fe00000ULL
+
void mlx4_init_mac_table(struct mlx4_dev *dev, struct mlx4_mac_table *table)
{
int i;
@@ -898,6 +903,24 @@ int mlx4_DUMP_ETH_STATS_wrapper(struct mlx4_dev *dev, int slave,
struct mlx4_cmd_mailbox *outbox,
struct mlx4_cmd_info *cmd)
{
+ if (slave != dev->caps.function)
+ return 0;
return mlx4_common_dump_eth_stats(dev, slave,
vhcr->in_modifier, outbox);
}
+
+void mlx4_set_stats_bitmap(struct mlx4_dev *dev, u64 *stats_bitmap)
+{
+ if (!mlx4_is_mfunc(dev)) {
+ *stats_bitmap = 0;
+ return;
+ }
+
+ *stats_bitmap = (MLX4_STATS_TRAFFIC_COUNTERS_MASK |
+ MLX4_STATS_TRAFFIC_DROPS_MASK |
+ MLX4_STATS_PORT_COUNTERS_MASK);
+
+ if (mlx4_is_master(dev))
+ *stats_bitmap |= MLX4_STATS_ERROR_COUNTERS_MASK;
+}
+EXPORT_SYMBOL(mlx4_set_stats_bitmap);
diff --git a/drivers/net/ethernet/mellanox/mlx4/profile.c b/drivers/net/ethernet/mellanox/mlx4/profile.c
index 66f91ca7a7c6..1129677daa62 100644
--- a/drivers/net/ethernet/mellanox/mlx4/profile.c
+++ b/drivers/net/ethernet/mellanox/mlx4/profile.c
@@ -110,7 +110,7 @@ u64 mlx4_make_profile(struct mlx4_dev *dev,
profile[MLX4_RES_EQ].num = min_t(unsigned, dev_cap->max_eqs, MAX_MSIX);
profile[MLX4_RES_DMPT].num = request->num_mpt;
profile[MLX4_RES_CMPT].num = MLX4_NUM_CMPTS;
- profile[MLX4_RES_MTT].num = request->num_mtt;
+ profile[MLX4_RES_MTT].num = request->num_mtt * (1 << log_mtts_per_seg);
profile[MLX4_RES_MCG].num = request->num_mcg;
for (i = 0; i < MLX4_RES_NUM; ++i) {
diff --git a/drivers/net/ethernet/mellanox/mlx4/qp.c b/drivers/net/ethernet/mellanox/mlx4/qp.c
index 6b03ac8b9002..738f950a1ce5 100644
--- a/drivers/net/ethernet/mellanox/mlx4/qp.c
+++ b/drivers/net/ethernet/mellanox/mlx4/qp.c
@@ -162,7 +162,7 @@ static int __mlx4_qp_modify(struct mlx4_dev *dev, struct mlx4_mtt *mtt,
((struct mlx4_qp_context *) (mailbox->buf + 8))->local_qpn =
cpu_to_be32(qp->qpn);
- ret = mlx4_cmd(dev, mailbox->dma | dev->caps.function,
+ ret = mlx4_cmd(dev, mailbox->dma,
qp->qpn | (!!sqd_event << 31),
new_state == MLX4_QP_STATE_RST ? 2 : 0,
op[cur_state][new_state], MLX4_CMD_TIME_CLASS_C, native);
diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
index ed20751a057d..dcd819bfb2f0 100644
--- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
+++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
@@ -1561,11 +1561,6 @@ static int mr_get_mtt_size(struct mlx4_mpt_entry *mpt)
return be32_to_cpu(mpt->mtt_sz);
}
-static int mr_get_pdn(struct mlx4_mpt_entry *mpt)
-{
- return be32_to_cpu(mpt->pd_flags) & 0xffffff;
-}
-
static int qp_get_mtt_addr(struct mlx4_qp_context *qpc)
{
return be32_to_cpu(qpc->mtt_base_addr_l) & 0xfffffff8;
@@ -1602,16 +1597,6 @@ static int qp_get_mtt_size(struct mlx4_qp_context *qpc)
return total_pages;
}
-static int qp_get_pdn(struct mlx4_qp_context *qpc)
-{
- return be32_to_cpu(qpc->pd) & 0xffffff;
-}
-
-static int pdn2slave(int pdn)
-{
- return (pdn >> NOT_MASKED_PD_BITS) - 1;
-}
-
static int check_mtt_range(struct mlx4_dev *dev, int slave, int start,
int size, struct res_mtt *mtt)
{
@@ -1656,11 +1641,6 @@ int mlx4_SW2HW_MPT_wrapper(struct mlx4_dev *dev, int slave,
mpt->mtt = mtt;
}
- if (pdn2slave(mr_get_pdn(inbox->buf)) != slave) {
- err = -EPERM;
- goto ex_put;
- }
-
err = mlx4_DMA_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
if (err)
goto ex_put;
@@ -1792,11 +1772,6 @@ int mlx4_RST2INIT_QP_wrapper(struct mlx4_dev *dev, int slave,
if (err)
goto ex_put_mtt;
- if (pdn2slave(qp_get_pdn(qpc)) != slave) {
- err = -EPERM;
- goto ex_put_mtt;
- }
-
err = get_res(dev, slave, rcqn, RES_CQ, &rcq);
if (err)
goto ex_put_mtt;
@@ -2048,10 +2023,10 @@ int mlx4_GEN_EQE(struct mlx4_dev *dev, int slave, struct mlx4_eqe *eqe)
if (!priv->mfunc.master.slave_state)
return -EINVAL;
- event_eq = &priv->mfunc.master.slave_state[slave].event_eq;
+ event_eq = &priv->mfunc.master.slave_state[slave].event_eq[eqe->type];
/* Create the event only if the slave is registered */
- if ((event_eq->event_type & (1 << eqe->type)) == 0)
+ if (event_eq->eqn < 0)
return 0;
mutex_lock(&priv->mfunc.master.gen_eqe_mutex[slave]);
@@ -2289,11 +2264,6 @@ ex_put:
return err;
}
-static int srq_get_pdn(struct mlx4_srq_context *srqc)
-{
- return be32_to_cpu(srqc->pd) & 0xffffff;
-}
-
static int srq_get_mtt_size(struct mlx4_srq_context *srqc)
{
int log_srq_size = (be32_to_cpu(srqc->state_logsize_srqn) >> 24) & 0xf;
@@ -2333,11 +2303,6 @@ int mlx4_SW2HW_SRQ_wrapper(struct mlx4_dev *dev, int slave,
if (err)
goto ex_put_mtt;
- if (pdn2slave(srq_get_pdn(srqc)) != slave) {
- err = -EPERM;
- goto ex_put_mtt;
- }
-
err = mlx4_DMA_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
if (err)
goto ex_put_mtt;
diff --git a/drivers/net/ethernet/mellanox/mlx4/srq.c b/drivers/net/ethernet/mellanox/mlx4/srq.c
index 2823fffc6383..feda6c00829f 100644
--- a/drivers/net/ethernet/mellanox/mlx4/srq.c
+++ b/drivers/net/ethernet/mellanox/mlx4/srq.c
@@ -67,7 +67,7 @@ void mlx4_srq_event(struct mlx4_dev *dev, u32 srqn, int event_type)
static int mlx4_SW2HW_SRQ(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *mailbox,
int srq_num)
{
- return mlx4_cmd(dev, mailbox->dma | dev->caps.function, srq_num, 0,
+ return mlx4_cmd(dev, mailbox->dma, srq_num, 0,
MLX4_CMD_SW2HW_SRQ, MLX4_CMD_TIME_CLASS_A,
MLX4_CMD_WRAPPED);
}
diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
index 964e9c0948bc..3ead111111e1 100644
--- a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
+++ b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
@@ -1745,6 +1745,12 @@ int pch_gbe_up(struct pch_gbe_adapter *adapter)
struct pch_gbe_rx_ring *rx_ring = adapter->rx_ring;
int err;
+ /* Ensure we have a valid MAC */
+ if (!is_valid_ether_addr(adapter->hw.mac.addr)) {
+ pr_err("Error: Invalid MAC address\n");
+ return -EINVAL;
+ }
+
/* hardware has been reset, we need to reload some things */
pch_gbe_set_multi(netdev);
@@ -2468,9 +2474,14 @@ static int pch_gbe_probe(struct pci_dev *pdev,
memcpy(netdev->dev_addr, adapter->hw.mac.addr, netdev->addr_len);
if (!is_valid_ether_addr(netdev->dev_addr)) {
- dev_err(&pdev->dev, "Invalid MAC Address\n");
- ret = -EIO;
- goto err_free_adapter;
+ /*
+ * If the MAC is invalid (or just missing), display a warning
+ * but do not abort setting up the device. pch_gbe_up will
+ * prevent the interface from being brought up until a valid MAC
+ * is set.
+ */
+ dev_err(&pdev->dev, "Invalid MAC address, "
+ "interface disabled.\n");
}
setup_timer(&adapter->watchdog_timer, pch_gbe_watchdog,
(unsigned long)adapter);
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
index da4a1042523a..73195329aa46 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
@@ -154,7 +154,7 @@ int stmmac_mdio_register(struct net_device *ndev)
else
irqlist = priv->mii_irq;
- new_bus->name = "STMMAC MII Bus";
+ new_bus->name = "stmmac";
new_bus->read = &stmmac_mdio_read;
new_bus->write = &stmmac_mdio_write;
new_bus->reset = &stmmac_mdio_reset;
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
index 54a819a36487..c796de9eed72 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
@@ -170,9 +170,9 @@ static int stmmac_pci_resume(struct pci_dev *pdev)
#define STMMAC_DEVICE_ID 0x1108
static DEFINE_PCI_DEVICE_TABLE(stmmac_id_table) = {
- {
- PCI_DEVICE(STMMAC_VENDOR_ID, STMMAC_DEVICE_ID)}, {
- }
+ {PCI_DEVICE(STMMAC_VENDOR_ID, STMMAC_DEVICE_ID)},
+ {PCI_DEVICE(PCI_VENDOR_ID_STMICRO, PCI_DEVICE_ID_STMICRO_MAC)},
+ {}
};
MODULE_DEVICE_TABLE(pci, stmmac_id_table);
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index 462d05f05e84..1a1ca6cfc74a 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -68,11 +68,11 @@ static void do_set_multicast(struct work_struct *w)
nvdev = hv_get_drvdata(ndevctx->device_ctx);
if (nvdev == NULL)
- return;
+ goto out;
rdev = nvdev->extension;
if (rdev == NULL)
- return;
+ goto out;
if (net->flags & IFF_PROMISC)
rndis_filter_set_packet_filter(rdev,
@@ -83,6 +83,7 @@ static void do_set_multicast(struct work_struct *w)
NDIS_PACKET_TYPE_ALL_MULTICAST |
NDIS_PACKET_TYPE_DIRECTED);
+out:
kfree(w);
}
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index f2f820c4b40a..9ea99217f116 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -173,6 +173,7 @@ static rx_handler_result_t macvlan_handle_frame(struct sk_buff **pskb)
skb = ip_check_defrag(skb, IP_DEFRAG_MACVLAN);
if (!skb)
return RX_HANDLER_CONSUMED;
+ eth = eth_hdr(skb);
src = macvlan_hash_lookup(port, eth->h_source);
if (!src)
/* frame comes from an external address */
diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
index 88cc5db9affd..8985cc62cf41 100644
--- a/drivers/net/phy/mdio_bus.c
+++ b/drivers/net/phy/mdio_bus.c
@@ -38,12 +38,11 @@
/**
* mdiobus_alloc_size - allocate a mii_bus structure
+ * @size: extra amount of memory to allocate for private storage.
+ * If non-zero, then bus->priv is points to that memory.
*
* Description: called by a bus driver to allocate an mii_bus
* structure to fill in.
- *
- * 'size' is an an extra amount of memory to allocate for private storage.
- * If non-zero, then bus->priv is points to that memory.
*/
struct mii_bus *mdiobus_alloc_size(size_t size)
{
diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c
index ed2a862b835d..6b678f38e5ce 100644
--- a/drivers/net/team/team.c
+++ b/drivers/net/team/team.c
@@ -92,9 +92,9 @@ struct team_option *__team_find_option(struct team *team, const char *opt_name)
return NULL;
}
-int team_options_register(struct team *team,
- const struct team_option *option,
- size_t option_count)
+int __team_options_register(struct team *team,
+ const struct team_option *option,
+ size_t option_count)
{
int i;
struct team_option **dst_opts;
@@ -116,8 +116,11 @@ int team_options_register(struct team *team,
}
}
- for (i = 0; i < option_count; i++)
+ for (i = 0; i < option_count; i++) {
+ dst_opts[i]->changed = true;
+ dst_opts[i]->removed = false;
list_add_tail(&dst_opts[i]->list, &team->option_list);
+ }
kfree(dst_opts);
return 0;
@@ -130,10 +133,22 @@ rollback:
return err;
}
-EXPORT_SYMBOL(team_options_register);
+static void __team_options_mark_removed(struct team *team,
+ const struct team_option *option,
+ size_t option_count)
+{
+ int i;
+
+ for (i = 0; i < option_count; i++, option++) {
+ struct team_option *del_opt;
-static void __team_options_change_check(struct team *team,
- struct team_option *changed_option);
+ del_opt = __team_find_option(team, option->name);
+ if (del_opt) {
+ del_opt->changed = true;
+ del_opt->removed = true;
+ }
+ }
+}
static void __team_options_unregister(struct team *team,
const struct team_option *option,
@@ -152,12 +167,29 @@ static void __team_options_unregister(struct team *team,
}
}
+static void __team_options_change_check(struct team *team);
+
+int team_options_register(struct team *team,
+ const struct team_option *option,
+ size_t option_count)
+{
+ int err;
+
+ err = __team_options_register(team, option, option_count);
+ if (err)
+ return err;
+ __team_options_change_check(team);
+ return 0;
+}
+EXPORT_SYMBOL(team_options_register);
+
void team_options_unregister(struct team *team,
const struct team_option *option,
size_t option_count)
{
+ __team_options_mark_removed(team, option, option_count);
+ __team_options_change_check(team);
__team_options_unregister(team, option, option_count);
- __team_options_change_check(team, NULL);
}
EXPORT_SYMBOL(team_options_unregister);
@@ -176,7 +208,8 @@ static int team_option_set(struct team *team, struct team_option *option,
if (err)
return err;
- __team_options_change_check(team, option);
+ option->changed = true;
+ __team_options_change_check(team);
return err;
}
@@ -653,6 +686,7 @@ static int team_port_del(struct team *team, struct net_device *port_dev)
return -ENOENT;
}
+ port->removed = true;
__team_port_change_check(port, false);
team_port_list_del_port(team, port);
team_adjust_ops(team);
@@ -1200,10 +1234,9 @@ err_fill:
return err;
}
-static int team_nl_fill_options_get_changed(struct sk_buff *skb,
- u32 pid, u32 seq, int flags,
- struct team *team,
- struct team_option *changed_option)
+static int team_nl_fill_options_get(struct sk_buff *skb,
+ u32 pid, u32 seq, int flags,
+ struct team *team, bool fillall)
{
struct nlattr *option_list;
void *hdr;
@@ -1223,12 +1256,19 @@ static int team_nl_fill_options_get_changed(struct sk_buff *skb,
struct nlattr *option_item;
long arg;
+ /* Include only changed options if fill all mode is not on */
+ if (!fillall && !option->changed)
+ continue;
option_item = nla_nest_start(skb, TEAM_ATTR_ITEM_OPTION);
if (!option_item)
goto nla_put_failure;
NLA_PUT_STRING(skb, TEAM_ATTR_OPTION_NAME, option->name);
- if (option == changed_option)
+ if (option->changed) {
NLA_PUT_FLAG(skb, TEAM_ATTR_OPTION_CHANGED);
+ option->changed = false;
+ }
+ if (option->removed)
+ NLA_PUT_FLAG(skb, TEAM_ATTR_OPTION_REMOVED);
switch (option->type) {
case TEAM_OPTION_TYPE_U32:
NLA_PUT_U8(skb, TEAM_ATTR_OPTION_TYPE, NLA_U32);
@@ -1255,13 +1295,13 @@ nla_put_failure:
return -EMSGSIZE;
}
-static int team_nl_fill_options_get(struct sk_buff *skb,
- struct genl_info *info, int flags,
- struct team *team)
+static int team_nl_fill_options_get_all(struct sk_buff *skb,
+ struct genl_info *info, int flags,
+ struct team *team)
{
- return team_nl_fill_options_get_changed(skb, info->snd_pid,
- info->snd_seq, NLM_F_ACK,
- team, NULL);
+ return team_nl_fill_options_get(skb, info->snd_pid,
+ info->snd_seq, NLM_F_ACK,
+ team, true);
}
static int team_nl_cmd_options_get(struct sk_buff *skb, struct genl_info *info)
@@ -1273,7 +1313,7 @@ static int team_nl_cmd_options_get(struct sk_buff *skb, struct genl_info *info)
if (!team)
return -EINVAL;
- err = team_nl_send_generic(info, team, team_nl_fill_options_get);
+ err = team_nl_send_generic(info, team, team_nl_fill_options_get_all);
team_nl_team_put(team);
@@ -1365,10 +1405,10 @@ team_put:
return err;
}
-static int team_nl_fill_port_list_get_changed(struct sk_buff *skb,
- u32 pid, u32 seq, int flags,
- struct team *team,
- struct team_port *changed_port)
+static int team_nl_fill_port_list_get(struct sk_buff *skb,
+ u32 pid, u32 seq, int flags,
+ struct team *team,
+ bool fillall)
{
struct nlattr *port_list;
void *hdr;
@@ -1387,12 +1427,19 @@ static int team_nl_fill_port_list_get_changed(struct sk_buff *skb,
list_for_each_entry(port, &team->port_list, list) {
struct nlattr *port_item;
+ /* Include only changed ports if fill all mode is not on */
+ if (!fillall && !port->changed)
+ continue;
port_item = nla_nest_start(skb, TEAM_ATTR_ITEM_PORT);
if (!port_item)
goto nla_put_failure;
NLA_PUT_U32(skb, TEAM_ATTR_PORT_IFINDEX, port->dev->ifindex);
- if (port == changed_port)
+ if (port->changed) {
NLA_PUT_FLAG(skb, TEAM_ATTR_PORT_CHANGED);
+ port->changed = false;
+ }
+ if (port->removed)
+ NLA_PUT_FLAG(skb, TEAM_ATTR_PORT_REMOVED);
if (port->linkup)
NLA_PUT_FLAG(skb, TEAM_ATTR_PORT_LINKUP);
NLA_PUT_U32(skb, TEAM_ATTR_PORT_SPEED, port->speed);
@@ -1408,13 +1455,13 @@ nla_put_failure:
return -EMSGSIZE;
}
-static int team_nl_fill_port_list_get(struct sk_buff *skb,
- struct genl_info *info, int flags,
- struct team *team)
+static int team_nl_fill_port_list_get_all(struct sk_buff *skb,
+ struct genl_info *info, int flags,
+ struct team *team)
{
- return team_nl_fill_port_list_get_changed(skb, info->snd_pid,
- info->snd_seq, NLM_F_ACK,
- team, NULL);
+ return team_nl_fill_port_list_get(skb, info->snd_pid,
+ info->snd_seq, NLM_F_ACK,
+ team, true);
}
static int team_nl_cmd_port_list_get(struct sk_buff *skb,
@@ -1427,7 +1474,7 @@ static int team_nl_cmd_port_list_get(struct sk_buff *skb,
if (!team)
return -EINVAL;
- err = team_nl_send_generic(info, team, team_nl_fill_port_list_get);
+ err = team_nl_send_generic(info, team, team_nl_fill_port_list_get_all);
team_nl_team_put(team);
@@ -1464,8 +1511,7 @@ static struct genl_multicast_group team_change_event_mcgrp = {
.name = TEAM_GENL_CHANGE_EVENT_MC_GRP_NAME,
};
-static int team_nl_send_event_options_get(struct team *team,
- struct team_option *changed_option)
+static int team_nl_send_event_options_get(struct team *team)
{
struct sk_buff *skb;
int err;
@@ -1475,8 +1521,7 @@ static int team_nl_send_event_options_get(struct team *team,
if (!skb)
return -ENOMEM;
- err = team_nl_fill_options_get_changed(skb, 0, 0, 0, team,
- changed_option);
+ err = team_nl_fill_options_get(skb, 0, 0, 0, team, false);
if (err < 0)
goto err_fill;
@@ -1489,18 +1534,17 @@ err_fill:
return err;
}
-static int team_nl_send_event_port_list_get(struct team_port *port)
+static int team_nl_send_event_port_list_get(struct team *team)
{
struct sk_buff *skb;
int err;
- struct net *net = dev_net(port->team->dev);
+ struct net *net = dev_net(team->dev);
skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
if (!skb)
return -ENOMEM;
- err = team_nl_fill_port_list_get_changed(skb, 0, 0, 0,
- port->team, port);
+ err = team_nl_fill_port_list_get(skb, 0, 0, 0, team, false);
if (err < 0)
goto err_fill;
@@ -1544,12 +1588,11 @@ static void team_nl_fini(void)
* Change checkers
******************/
-static void __team_options_change_check(struct team *team,
- struct team_option *changed_option)
+static void __team_options_change_check(struct team *team)
{
int err;
- err = team_nl_send_event_options_get(team, changed_option);
+ err = team_nl_send_event_options_get(team);
if (err)
netdev_warn(team->dev, "Failed to send options change via netlink\n");
}
@@ -1559,9 +1602,10 @@ static void __team_port_change_check(struct team_port *port, bool linkup)
{
int err;
- if (port->linkup == linkup)
+ if (!port->removed && port->linkup == linkup)
return;
+ port->changed = true;
port->linkup = linkup;
if (linkup) {
struct ethtool_cmd ecmd;
@@ -1577,7 +1621,7 @@ static void __team_port_change_check(struct team_port *port, bool linkup)
port->duplex = 0;
send_event:
- err = team_nl_send_event_port_list_get(port);
+ err = team_nl_send_event_port_list_get(port->team);
if (err)
netdev_warn(port->team->dev, "Failed to send port change of device %s via netlink\n",
port->dev->name);
diff --git a/drivers/net/wireless/b43/Kconfig b/drivers/net/wireless/b43/Kconfig
index b97a40ed5fff..3876c7ea54f4 100644
--- a/drivers/net/wireless/b43/Kconfig
+++ b/drivers/net/wireless/b43/Kconfig
@@ -31,6 +31,12 @@ config B43_BCMA
depends on B43 && BCMA
default y
+config B43_BCMA_EXTRA
+ bool "Hardware support that overlaps with the brcmsmac driver"
+ depends on B43_BCMA
+ default n if BRCMSMAC || BRCMSMAC_MODULE
+ default y
+
config B43_SSB
bool
depends on B43 && SSB
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index b91f28ef1032..23ffb1b9a86f 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -116,8 +116,10 @@ MODULE_PARM_DESC(pio, "Use PIO accesses by default: 0=DMA, 1=PIO");
#ifdef CONFIG_B43_BCMA
static const struct bcma_device_id b43_bcma_tbl[] = {
BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x11, BCMA_ANY_CLASS),
+#ifdef CONFIG_B43_BCMA_EXTRA
BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x17, BCMA_ANY_CLASS),
BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x18, BCMA_ANY_CLASS),
+#endif
BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x1D, BCMA_ANY_CLASS),
BCMA_CORETABLE_END
};
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c
index f7ed34034f88..f6affc6fd12a 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
@@ -7981,13 +7981,21 @@ int brcms_c_get_curband(struct brcms_c_info *wlc)
void brcms_c_wait_for_tx_completion(struct brcms_c_info *wlc, bool drop)
{
+ int timeout = 20;
+
/* flush packet queue when requested */
if (drop)
brcmu_pktq_flush(&wlc->pkt_queue->q, false, NULL, NULL);
/* wait for queue and DMA fifos to run dry */
- while (!pktq_empty(&wlc->pkt_queue->q) || brcms_txpktpendtot(wlc) > 0)
+ while (!pktq_empty(&wlc->pkt_queue->q) || brcms_txpktpendtot(wlc) > 0) {
brcms_msleep(wlc->wl, 1);
+
+ if (--timeout == 0)
+ break;
+ }
+
+ WARN_ON_ONCE(timeout == 0);
}
void brcms_c_set_beacon_listen_interval(struct brcms_c_info *wlc, u8 interval)
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 97fff785e97e..af295bb21d62 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -2802,7 +2802,7 @@ pci_intx(struct pci_dev *pdev, int enable)
/**
* pci_intx_mask_supported - probe for INTx masking support
- * @pdev: the PCI device to operate on
+ * @dev: the PCI device to operate on
*
* Check if the device dev support INTx masking via the config space
* command word.
@@ -2884,7 +2884,7 @@ done:
/**
* pci_check_and_mask_intx - mask INTx on pending interrupt
- * @pdev: the PCI device to operate on
+ * @dev: the PCI device to operate on
*
* Check if the device dev has its INTx line asserted, mask it and
* return true in that case. False is returned if not interrupt was
@@ -2898,7 +2898,7 @@ EXPORT_SYMBOL_GPL(pci_check_and_mask_intx);
/**
* pci_check_and_mask_intx - unmask INTx of no interrupt is pending
- * @pdev: the PCI device to operate on
+ * @dev: the PCI device to operate on
*
* Check if the device dev has its INTx line asserted, unmask it if not
* and return true. False is returned and the mask remains active if
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index ca86f39a0fdc..e9a83f84adaf 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -2731,6 +2731,8 @@ static void rdev_init_debugfs(struct regulator_dev *rdev)
* @dev: struct device for the regulator
* @init_data: platform provided init data, passed through by driver
* @driver_data: private regulator data
+ * @of_node: OpenFirmware node to parse for device tree bindings (may be
+ * NULL).
*
* Called by regulator drivers to register a regulator.
* Returns 0 on success.
diff --git a/drivers/scsi/mac_esp.c b/drivers/scsi/mac_esp.c
index 4ceeace80453..70eb1f79b1ba 100644
--- a/drivers/scsi/mac_esp.c
+++ b/drivers/scsi/mac_esp.c
@@ -565,8 +565,7 @@ static int __devinit esp_mac_probe(struct platform_device *dev)
esp_chips[dev->id] = esp;
mb();
if (esp_chips[!dev->id] == NULL) {
- err = request_irq(host->irq, mac_scsi_esp_intr, 0,
- "Mac ESP", NULL);
+ err = request_irq(host->irq, mac_scsi_esp_intr, 0, "ESP", NULL);
if (err < 0) {
esp_chips[dev->id] = NULL;
goto fail_free_priv;
diff --git a/drivers/scsi/mac_scsi.c b/drivers/scsi/mac_scsi.c
index ea2bde206f7f..2bccfbe5661e 100644
--- a/drivers/scsi/mac_scsi.c
+++ b/drivers/scsi/mac_scsi.c
@@ -339,9 +339,6 @@ static void mac_scsi_reset_boot(struct Scsi_Host *instance)
printk(KERN_INFO "Macintosh SCSI: resetting the SCSI bus..." );
- /* switch off SCSI IRQ - catch an interrupt without IRQ bit set else */
- disable_irq(IRQ_MAC_SCSI);
-
/* get in phase */
NCR5380_write( TARGET_COMMAND_REG,
PHASE_SR_TO_TCR( NCR5380_read(STATUS_REG) ));
@@ -357,9 +354,6 @@ static void mac_scsi_reset_boot(struct Scsi_Host *instance)
for( end = jiffies + AFTER_RESET_DELAY; time_before(jiffies, end); )
barrier();
- /* switch on SCSI IRQ again */
- enable_irq(IRQ_MAC_SCSI);
-
printk(KERN_INFO " done\n" );
}
#endif
diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
index dd9a5743fa99..220ce7e31cf5 100644
--- a/drivers/thermal/thermal_sys.c
+++ b/drivers/thermal/thermal_sys.c
@@ -1304,7 +1304,7 @@ static struct genl_multicast_group thermal_event_mcgrp = {
.name = THERMAL_GENL_MCAST_GROUP_NAME,
};
-int generate_netlink_event(u32 orig, enum events event)
+int thermal_generate_netlink_event(u32 orig, enum events event)
{
struct sk_buff *skb;
struct nlattr *attr;
@@ -1363,7 +1363,7 @@ int generate_netlink_event(u32 orig, enum events event)
return result;
}
-EXPORT_SYMBOL(generate_netlink_event);
+EXPORT_SYMBOL(thermal_generate_netlink_event);
static int genetlink_init(void)
{
diff --git a/drivers/video/backlight/adp8860_bl.c b/drivers/video/backlight/adp8860_bl.c
index 66bc74d9ce2a..378276c9d3cf 100644
--- a/drivers/video/backlight/adp8860_bl.c
+++ b/drivers/video/backlight/adp8860_bl.c
@@ -146,7 +146,7 @@ static int adp8860_set_bits(struct i2c_client *client, int reg, uint8_t bit_mask
ret = adp8860_read(client, reg, &reg_val);
- if (!ret && ((reg_val & bit_mask) == 0)) {
+ if (!ret && ((reg_val & bit_mask) != bit_mask)) {
reg_val |= bit_mask;
ret = adp8860_write(client, reg, reg_val);
}
diff --git a/drivers/video/backlight/adp8870_bl.c b/drivers/video/backlight/adp8870_bl.c
index 6c68a6899e87..6735059376d6 100644
--- a/drivers/video/backlight/adp8870_bl.c
+++ b/drivers/video/backlight/adp8870_bl.c
@@ -160,7 +160,7 @@ static int adp8870_set_bits(struct i2c_client *client, int reg, uint8_t bit_mask
ret = adp8870_read(client, reg, &reg_val);
- if (!ret && ((reg_val & bit_mask) == 0)) {
+ if (!ret && ((reg_val & bit_mask) != bit_mask)) {
reg_val |= bit_mask;
ret = adp8870_write(client, reg, reg_val);
}
diff --git a/drivers/video/backlight/l4f00242t03.c b/drivers/video/backlight/l4f00242t03.c
index 4f5d1c4cb6ab..27d1d7a29c77 100644
--- a/drivers/video/backlight/l4f00242t03.c
+++ b/drivers/video/backlight/l4f00242t03.c
@@ -190,6 +190,7 @@ static int __devinit l4f00242t03_probe(struct spi_device *spi)
priv->io_reg = regulator_get(&spi->dev, "vdd");
if (IS_ERR(priv->io_reg)) {
+ ret = PTR_ERR(priv->io_reg);
dev_err(&spi->dev, "%s: Unable to get the IO regulator\n",
__func__);
goto err3;
@@ -197,6 +198,7 @@ static int __devinit l4f00242t03_probe(struct spi_device *spi)
priv->core_reg = regulator_get(&spi->dev, "vcore");
if (IS_ERR(priv->core_reg)) {
+ ret = PTR_ERR(priv->core_reg);
dev_err(&spi->dev, "%s: Unable to get the core regulator\n",
__func__);
goto err4;
diff --git a/drivers/video/macfb.c b/drivers/video/macfb.c
index 43207cc6cc19..fe01add3700e 100644
--- a/drivers/video/macfb.c
+++ b/drivers/video/macfb.c
@@ -592,12 +592,12 @@ static int __init macfb_init(void)
if (!fb_info.screen_base)
return -ENODEV;
- printk("macfb: framebuffer at 0x%08lx, mapped to 0x%p, size %dk\n",
- macfb_fix.smem_start, fb_info.screen_base,
- macfb_fix.smem_len / 1024);
- printk("macfb: mode is %dx%dx%d, linelength=%d\n",
- macfb_defined.xres, macfb_defined.yres,
- macfb_defined.bits_per_pixel, macfb_fix.line_length);
+ pr_info("macfb: framebuffer at 0x%08lx, mapped to 0x%p, size %dk\n",
+ macfb_fix.smem_start, fb_info.screen_base,
+ macfb_fix.smem_len / 1024);
+ pr_info("macfb: mode is %dx%dx%d, linelength=%d\n",
+ macfb_defined.xres, macfb_defined.yres,
+ macfb_defined.bits_per_pixel, macfb_fix.line_length);
/* Fill in the available video resolution */
macfb_defined.xres_virtual = macfb_defined.xres;
@@ -613,14 +613,10 @@ static int __init macfb_init(void)
switch (macfb_defined.bits_per_pixel) {
case 1:
- /*
- * XXX: I think this will catch any program that tries
- * to do FBIO_PUTCMAP when the visual is monochrome.
- */
macfb_defined.red.length = macfb_defined.bits_per_pixel;
macfb_defined.green.length = macfb_defined.bits_per_pixel;
macfb_defined.blue.length = macfb_defined.bits_per_pixel;
- video_cmap_len = 0;
+ video_cmap_len = 2;
macfb_fix.visual = FB_VISUAL_MONO01;
break;
case 2:
@@ -660,11 +656,10 @@ static int __init macfb_init(void)
macfb_fix.visual = FB_VISUAL_TRUECOLOR;
break;
default:
- video_cmap_len = 0;
- macfb_fix.visual = FB_VISUAL_MONO01;
- printk("macfb: unknown or unsupported bit depth: %d\n",
+ pr_err("macfb: unknown or unsupported bit depth: %d\n",
macfb_defined.bits_per_pixel);
- break;
+ err = -EINVAL;
+ goto fail_unmap;
}
/*
@@ -734,8 +729,8 @@ static int __init macfb_init(void)
case MAC_MODEL_Q950:
strcpy(macfb_fix.id, "DAFB");
macfb_setpalette = dafb_setpalette;
- macfb_defined.activate = FB_ACTIVATE_NOW;
dafb_cmap_regs = ioremap(DAFB_BASE, 0x1000);
+ macfb_defined.activate = FB_ACTIVATE_NOW;
break;
/*
@@ -744,8 +739,8 @@ static int __init macfb_init(void)
case MAC_MODEL_LCII:
strcpy(macfb_fix.id, "V8");
macfb_setpalette = v8_brazil_setpalette;
- macfb_defined.activate = FB_ACTIVATE_NOW;
v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000);
+ macfb_defined.activate = FB_ACTIVATE_NOW;
break;
/*
@@ -758,8 +753,8 @@ static int __init macfb_init(void)
case MAC_MODEL_P600:
strcpy(macfb_fix.id, "Brazil");
macfb_setpalette = v8_brazil_setpalette;
- macfb_defined.activate = FB_ACTIVATE_NOW;
v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000);
+ macfb_defined.activate = FB_ACTIVATE_NOW;
break;
/*
@@ -773,10 +768,10 @@ static int __init macfb_init(void)
case MAC_MODEL_P520:
case MAC_MODEL_P550:
case MAC_MODEL_P460:
- macfb_setpalette = v8_brazil_setpalette;
- macfb_defined.activate = FB_ACTIVATE_NOW;
strcpy(macfb_fix.id, "Sonora");
+ macfb_setpalette = v8_brazil_setpalette;
v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000);
+ macfb_defined.activate = FB_ACTIVATE_NOW;
break;
/*
@@ -786,10 +781,10 @@ static int __init macfb_init(void)
*/
case MAC_MODEL_IICI:
case MAC_MODEL_IISI:
- macfb_setpalette = rbv_setpalette;
- macfb_defined.activate = FB_ACTIVATE_NOW;
strcpy(macfb_fix.id, "RBV");
+ macfb_setpalette = rbv_setpalette;
rbv_cmap_regs = ioremap(DAC_BASE, 0x1000);
+ macfb_defined.activate = FB_ACTIVATE_NOW;
break;
/*
@@ -797,10 +792,10 @@ static int __init macfb_init(void)
*/
case MAC_MODEL_Q840:
case MAC_MODEL_C660:
- macfb_setpalette = civic_setpalette;
- macfb_defined.activate = FB_ACTIVATE_NOW;
strcpy(macfb_fix.id, "Civic");
+ macfb_setpalette = civic_setpalette;
civic_cmap_regs = ioremap(CIVIC_BASE, 0x1000);
+ macfb_defined.activate = FB_ACTIVATE_NOW;
break;
@@ -809,26 +804,26 @@ static int __init macfb_init(void)
* We think this may be like the LC II
*/
case MAC_MODEL_LC:
+ strcpy(macfb_fix.id, "LC");
if (vidtest) {
macfb_setpalette = v8_brazil_setpalette;
- macfb_defined.activate = FB_ACTIVATE_NOW;
v8_brazil_cmap_regs =
ioremap(DAC_BASE, 0x1000);
+ macfb_defined.activate = FB_ACTIVATE_NOW;
}
- strcpy(macfb_fix.id, "LC");
break;
/*
* We think this may be like the LC II
*/
case MAC_MODEL_CCL:
+ strcpy(macfb_fix.id, "Color Classic");
if (vidtest) {
macfb_setpalette = v8_brazil_setpalette;
- macfb_defined.activate = FB_ACTIVATE_NOW;
v8_brazil_cmap_regs =
ioremap(DAC_BASE, 0x1000);
+ macfb_defined.activate = FB_ACTIVATE_NOW;
}
- strcpy(macfb_fix.id, "Color Classic");
break;
/*
@@ -893,10 +888,10 @@ static int __init macfb_init(void)
case MAC_MODEL_PB270C:
case MAC_MODEL_PB280:
case MAC_MODEL_PB280C:
- macfb_setpalette = csc_setpalette;
- macfb_defined.activate = FB_ACTIVATE_NOW;
strcpy(macfb_fix.id, "CSC");
+ macfb_setpalette = csc_setpalette;
csc_cmap_regs = ioremap(CSC_BASE, 0x1000);
+ macfb_defined.activate = FB_ACTIVATE_NOW;
break;
default:
@@ -918,8 +913,9 @@ static int __init macfb_init(void)
if (err)
goto fail_dealloc;
- printk("fb%d: %s frame buffer device\n",
- fb_info.node, fb_info.fix.id);
+ pr_info("fb%d: %s frame buffer device\n",
+ fb_info.node, fb_info.fix.id);
+
return 0;
fail_dealloc:
diff --git a/fs/cifs/Kconfig b/fs/cifs/Kconfig
index f66cc1625150..0554b00a7b33 100644
--- a/fs/cifs/Kconfig
+++ b/fs/cifs/Kconfig
@@ -140,7 +140,6 @@ config CIFS_DFS_UPCALL
config CIFS_FSCACHE
bool "Provide CIFS client caching support (EXPERIMENTAL)"
- depends on EXPERIMENTAL
depends on CIFS=m && FSCACHE || CIFS=y && FSCACHE=y
help
Makes CIFS FS-Cache capable. Say Y here if you want your CIFS data
@@ -149,7 +148,7 @@ config CIFS_FSCACHE
config CIFS_ACL
bool "Provide CIFS ACL support (EXPERIMENTAL)"
- depends on EXPERIMENTAL && CIFS_XATTR && KEYS
+ depends on CIFS_XATTR && KEYS
help
Allows to fetch CIFS/NTFS ACL from the server. The DACL blob
is handed over to the application/caller.
diff --git a/fs/cifs/cifs_debug.c b/fs/cifs/cifs_debug.c
index 84e8c0724704..24b3dfc05282 100644
--- a/fs/cifs/cifs_debug.c
+++ b/fs/cifs/cifs_debug.c
@@ -676,14 +676,23 @@ static ssize_t cifs_multiuser_mount_proc_write(struct file *file,
{
char c;
int rc;
+ static bool warned;
rc = get_user(c, buffer);
if (rc)
return rc;
if (c == '0' || c == 'n' || c == 'N')
multiuser_mount = 0;
- else if (c == '1' || c == 'y' || c == 'Y')
+ else if (c == '1' || c == 'y' || c == 'Y') {
multiuser_mount = 1;
+ if (!warned) {
+ warned = true;
+ printk(KERN_WARNING "CIFS VFS: The legacy multiuser "
+ "mount code is scheduled to be deprecated in "
+ "3.5. Please switch to using the multiuser "
+ "mount option.");
+ }
+ }
return count;
}
diff --git a/fs/cifs/cifs_spnego.c b/fs/cifs/cifs_spnego.c
index 2272fd5fe5b7..e622863b292f 100644
--- a/fs/cifs/cifs_spnego.c
+++ b/fs/cifs/cifs_spnego.c
@@ -113,9 +113,11 @@ cifs_get_spnego_key(struct cifs_ses *sesInfo)
MAX_MECH_STR_LEN +
UID_KEY_LEN + (sizeof(uid_t) * 2) +
CREDUID_KEY_LEN + (sizeof(uid_t) * 2) +
- USER_KEY_LEN + strlen(sesInfo->user_name) +
PID_KEY_LEN + (sizeof(pid_t) * 2) + 1;
+ if (sesInfo->user_name)
+ desc_len += USER_KEY_LEN + strlen(sesInfo->user_name);
+
spnego_key = ERR_PTR(-ENOMEM);
description = kzalloc(desc_len, GFP_KERNEL);
if (description == NULL)
@@ -152,8 +154,10 @@ cifs_get_spnego_key(struct cifs_ses *sesInfo)
dp = description + strlen(description);
sprintf(dp, ";creduid=0x%x", sesInfo->cred_uid);
- dp = description + strlen(description);
- sprintf(dp, ";user=%s", sesInfo->user_name);
+ if (sesInfo->user_name) {
+ dp = description + strlen(description);
+ sprintf(dp, ";user=%s", sesInfo->user_name);
+ }
dp = description + strlen(description);
sprintf(dp, ";pid=0x%x", current->pid);
diff --git a/fs/cifs/cifs_unicode.c b/fs/cifs/cifs_unicode.c
index 1b2e180b018d..fbb9da951843 100644
--- a/fs/cifs/cifs_unicode.c
+++ b/fs/cifs/cifs_unicode.c
@@ -27,17 +27,17 @@
#include "cifs_debug.h"
/*
- * cifs_ucs2_bytes - how long will a string be after conversion?
- * @ucs - pointer to input string
+ * cifs_utf16_bytes - how long will a string be after conversion?
+ * @utf16 - pointer to input string
* @maxbytes - don't go past this many bytes of input string
* @codepage - destination codepage
*
- * Walk a ucs2le string and return the number of bytes that the string will
+ * Walk a utf16le string and return the number of bytes that the string will
* be after being converted to the given charset, not including any null
* termination required. Don't walk past maxbytes in the source buffer.
*/
int
-cifs_ucs2_bytes(const __le16 *from, int maxbytes,
+cifs_utf16_bytes(const __le16 *from, int maxbytes,
const struct nls_table *codepage)
{
int i;
@@ -122,7 +122,7 @@ cp_convert:
}
/*
- * cifs_from_ucs2 - convert utf16le string to local charset
+ * cifs_from_utf16 - convert utf16le string to local charset
* @to - destination buffer
* @from - source buffer
* @tolen - destination buffer size (in bytes)
@@ -130,7 +130,7 @@ cp_convert:
* @codepage - codepage to which characters should be converted
* @mapchar - should characters be remapped according to the mapchars option?
*
- * Convert a little-endian ucs2le string (as sent by the server) to a string
+ * Convert a little-endian utf16le string (as sent by the server) to a string
* in the provided codepage. The tolen and fromlen parameters are to ensure
* that the code doesn't walk off of the end of the buffer (which is always
* a danger if the alignment of the source buffer is off). The destination
@@ -139,12 +139,12 @@ cp_convert:
* null terminator).
*
* Note that some windows versions actually send multiword UTF-16 characters
- * instead of straight UCS-2. The linux nls routines however aren't able to
+ * instead of straight UTF16-2. The linux nls routines however aren't able to
* deal with those characters properly. In the event that we get some of
* those characters, they won't be translated properly.
*/
int
-cifs_from_ucs2(char *to, const __le16 *from, int tolen, int fromlen,
+cifs_from_utf16(char *to, const __le16 *from, int tolen, int fromlen,
const struct nls_table *codepage, bool mapchar)
{
int i, charlen, safelen;
@@ -190,13 +190,13 @@ cifs_from_ucs2(char *to, const __le16 *from, int tolen, int fromlen,
}
/*
- * NAME: cifs_strtoUCS()
+ * NAME: cifs_strtoUTF16()
*
* FUNCTION: Convert character string to unicode string
*
*/
int
-cifs_strtoUCS(__le16 *to, const char *from, int len,
+cifs_strtoUTF16(__le16 *to, const char *from, int len,
const struct nls_table *codepage)
{
int charlen;
@@ -206,7 +206,7 @@ cifs_strtoUCS(__le16 *to, const char *from, int len,
for (i = 0; len && *from; i++, from += charlen, len -= charlen) {
charlen = codepage->char2uni(from, len, &wchar_to);
if (charlen < 1) {
- cERROR(1, "strtoUCS: char2uni of 0x%x returned %d",
+ cERROR(1, "strtoUTF16: char2uni of 0x%x returned %d",
*from, charlen);
/* A question mark */
wchar_to = 0x003f;
@@ -220,7 +220,8 @@ cifs_strtoUCS(__le16 *to, const char *from, int len,
}
/*
- * cifs_strndup_from_ucs - copy a string from wire format to the local codepage
+ * cifs_strndup_from_utf16 - copy a string from wire format to the local
+ * codepage
* @src - source string
* @maxlen - don't walk past this many bytes in the source string
* @is_unicode - is this a unicode string?
@@ -231,19 +232,19 @@ cifs_strtoUCS(__le16 *to, const char *from, int len,
* error.
*/
char *
-cifs_strndup_from_ucs(const char *src, const int maxlen, const bool is_unicode,
- const struct nls_table *codepage)
+cifs_strndup_from_utf16(const char *src, const int maxlen,
+ const bool is_unicode, const struct nls_table *codepage)
{
int len;
char *dst;
if (is_unicode) {
- len = cifs_ucs2_bytes((__le16 *) src, maxlen, codepage);
+ len = cifs_utf16_bytes((__le16 *) src, maxlen, codepage);
len += nls_nullsize(codepage);
dst = kmalloc(len, GFP_KERNEL);
if (!dst)
return NULL;
- cifs_from_ucs2(dst, (__le16 *) src, len, maxlen, codepage,
+ cifs_from_utf16(dst, (__le16 *) src, len, maxlen, codepage,
false);
} else {
len = strnlen(src, maxlen);
@@ -264,7 +265,7 @@ cifs_strndup_from_ucs(const char *src, const int maxlen, const bool is_unicode,
* names are little endian 16 bit Unicode on the wire
*/
int
-cifsConvertToUCS(__le16 *target, const char *source, int srclen,
+cifsConvertToUTF16(__le16 *target, const char *source, int srclen,
const struct nls_table *cp, int mapChars)
{
int i, j, charlen;
@@ -273,7 +274,7 @@ cifsConvertToUCS(__le16 *target, const char *source, int srclen,
wchar_t tmp;
if (!mapChars)
- return cifs_strtoUCS(target, source, PATH_MAX, cp);
+ return cifs_strtoUTF16(target, source, PATH_MAX, cp);
for (i = 0, j = 0; i < srclen; j++) {
src_char = source[i];
@@ -281,7 +282,7 @@ cifsConvertToUCS(__le16 *target, const char *source, int srclen,
switch (src_char) {
case 0:
put_unaligned(0, &target[j]);
- goto ctoUCS_out;
+ goto ctoUTF16_out;
case ':':
dst_char = cpu_to_le16(UNI_COLON);
break;
@@ -326,7 +327,7 @@ cifsConvertToUCS(__le16 *target, const char *source, int srclen,
put_unaligned(dst_char, &target[j]);
}
-ctoUCS_out:
+ctoUTF16_out:
return i;
}
diff --git a/fs/cifs/cifs_unicode.h b/fs/cifs/cifs_unicode.h
index 6d02fd560566..a513a546700b 100644
--- a/fs/cifs/cifs_unicode.h
+++ b/fs/cifs/cifs_unicode.h
@@ -74,16 +74,16 @@ extern const struct UniCaseRange CifsUniLowerRange[];
#endif /* UNIUPR_NOLOWER */
#ifdef __KERNEL__
-int cifs_from_ucs2(char *to, const __le16 *from, int tolen, int fromlen,
- const struct nls_table *codepage, bool mapchar);
-int cifs_ucs2_bytes(const __le16 *from, int maxbytes,
- const struct nls_table *codepage);
-int cifs_strtoUCS(__le16 *, const char *, int, const struct nls_table *);
-char *cifs_strndup_from_ucs(const char *src, const int maxlen,
- const bool is_unicode,
- const struct nls_table *codepage);
-extern int cifsConvertToUCS(__le16 *target, const char *source, int maxlen,
- const struct nls_table *cp, int mapChars);
+int cifs_from_utf16(char *to, const __le16 *from, int tolen, int fromlen,
+ const struct nls_table *codepage, bool mapchar);
+int cifs_utf16_bytes(const __le16 *from, int maxbytes,
+ const struct nls_table *codepage);
+int cifs_strtoUTF16(__le16 *, const char *, int, const struct nls_table *);
+char *cifs_strndup_from_utf16(const char *src, const int maxlen,
+ const bool is_unicode,
+ const struct nls_table *codepage);
+extern int cifsConvertToUTF16(__le16 *target, const char *source, int maxlen,
+ const struct nls_table *cp, int mapChars);
#endif
diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c
index 72ddf23ef6f7..c1b254487388 100644
--- a/fs/cifs/cifsacl.c
+++ b/fs/cifs/cifsacl.c
@@ -909,6 +909,8 @@ static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl,
umode_t group_mask = S_IRWXG;
umode_t other_mask = S_IRWXU | S_IRWXG | S_IRWXO;
+ if (num_aces > ULONG_MAX / sizeof(struct cifs_ace *))
+ return;
ppace = kmalloc(num_aces * sizeof(struct cifs_ace *),
GFP_KERNEL);
if (!ppace) {
diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c
index 5d9b9acc5fce..63c460e503b6 100644
--- a/fs/cifs/cifsencrypt.c
+++ b/fs/cifs/cifsencrypt.c
@@ -327,7 +327,7 @@ build_avpair_blob(struct cifs_ses *ses, const struct nls_table *nls_cp)
attrptr->type = cpu_to_le16(NTLMSSP_AV_NB_DOMAIN_NAME);
attrptr->length = cpu_to_le16(2 * dlen);
blobptr = (unsigned char *)attrptr + sizeof(struct ntlmssp2_name);
- cifs_strtoUCS((__le16 *)blobptr, ses->domainName, dlen, nls_cp);
+ cifs_strtoUTF16((__le16 *)blobptr, ses->domainName, dlen, nls_cp);
return 0;
}
@@ -376,7 +376,7 @@ find_domain_name(struct cifs_ses *ses, const struct nls_table *nls_cp)
kmalloc(attrsize + 1, GFP_KERNEL);
if (!ses->domainName)
return -ENOMEM;
- cifs_from_ucs2(ses->domainName,
+ cifs_from_utf16(ses->domainName,
(__le16 *)blobptr, attrsize, attrsize,
nls_cp, false);
break;
@@ -420,15 +420,20 @@ static int calc_ntlmv2_hash(struct cifs_ses *ses, char *ntlmv2_hash,
}
/* convert ses->user_name to unicode and uppercase */
- len = strlen(ses->user_name);
+ len = ses->user_name ? strlen(ses->user_name) : 0;
user = kmalloc(2 + (len * 2), GFP_KERNEL);
if (user == NULL) {
cERROR(1, "calc_ntlmv2_hash: user mem alloc failure\n");
rc = -ENOMEM;
return rc;
}
- len = cifs_strtoUCS((__le16 *)user, ses->user_name, len, nls_cp);
- UniStrupr(user);
+
+ if (len) {
+ len = cifs_strtoUTF16((__le16 *)user, ses->user_name, len, nls_cp);
+ UniStrupr(user);
+ } else {
+ memset(user, '\0', 2);
+ }
rc = crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash,
(char *)user, 2 * len);
@@ -448,8 +453,8 @@ static int calc_ntlmv2_hash(struct cifs_ses *ses, char *ntlmv2_hash,
rc = -ENOMEM;
return rc;
}
- len = cifs_strtoUCS((__le16 *)domain, ses->domainName, len,
- nls_cp);
+ len = cifs_strtoUTF16((__le16 *)domain, ses->domainName, len,
+ nls_cp);
rc =
crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash,
(char *)domain, 2 * len);
@@ -468,7 +473,7 @@ static int calc_ntlmv2_hash(struct cifs_ses *ses, char *ntlmv2_hash,
rc = -ENOMEM;
return rc;
}
- len = cifs_strtoUCS((__le16 *)server, ses->serverName, len,
+ len = cifs_strtoUTF16((__le16 *)server, ses->serverName, len,
nls_cp);
rc =
crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash,
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index ba53c1c6c6cc..76e7d8b6da17 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -879,6 +879,8 @@ require use of the stronger protocol */
#define CIFSSEC_MASK 0xB70B7 /* current flags supported if weak */
#endif /* UPCALL */
#else /* do not allow weak pw hash */
+#define CIFSSEC_MUST_LANMAN 0
+#define CIFSSEC_MUST_PLNTXT 0
#ifdef CONFIG_CIFS_UPCALL
#define CIFSSEC_MASK 0x8F08F /* flags supported if no weak allowed */
#else
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index 6600aa2d2ef3..8b7794c31591 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -821,8 +821,8 @@ PsxDelete:
if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
name_len =
- cifsConvertToUCS((__le16 *) pSMB->FileName, fileName,
- PATH_MAX, nls_codepage, remap);
+ cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
+ PATH_MAX, nls_codepage, remap);
name_len++; /* trailing null */
name_len *= 2;
} else { /* BB add path length overrun check */
@@ -893,8 +893,8 @@ DelFileRetry:
if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
name_len =
- cifsConvertToUCS((__le16 *) pSMB->fileName, fileName,
- PATH_MAX, nls_codepage, remap);
+ cifsConvertToUTF16((__le16 *) pSMB->fileName, fileName,
+ PATH_MAX, nls_codepage, remap);
name_len++; /* trailing null */
name_len *= 2;
} else { /* BB improve check for buffer overruns BB */
@@ -938,8 +938,8 @@ RmDirRetry:
return rc;
if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
- name_len = cifsConvertToUCS((__le16 *) pSMB->DirName, dirName,
- PATH_MAX, nls_codepage, remap);
+ name_len = cifsConvertToUTF16((__le16 *) pSMB->DirName, dirName,
+ PATH_MAX, nls_codepage, remap);
name_len++; /* trailing null */
name_len *= 2;
} else { /* BB improve check for buffer overruns BB */
@@ -981,8 +981,8 @@ MkDirRetry:
return rc;
if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
- name_len = cifsConvertToUCS((__le16 *) pSMB->DirName, name,
- PATH_MAX, nls_codepage, remap);
+ name_len = cifsConvertToUTF16((__le16 *) pSMB->DirName, name,
+ PATH_MAX, nls_codepage, remap);
name_len++; /* trailing null */
name_len *= 2;
} else { /* BB improve check for buffer overruns BB */
@@ -1030,8 +1030,8 @@ PsxCreat:
if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
name_len =
- cifsConvertToUCS((__le16 *) pSMB->FileName, name,
- PATH_MAX, nls_codepage, remap);
+ cifsConvertToUTF16((__le16 *) pSMB->FileName, name,
+ PATH_MAX, nls_codepage, remap);
name_len++; /* trailing null */
name_len *= 2;
} else { /* BB improve the check for buffer overruns BB */
@@ -1197,8 +1197,8 @@ OldOpenRetry:
if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
count = 1; /* account for one byte pad to word boundary */
name_len =
- cifsConvertToUCS((__le16 *) (pSMB->fileName + 1),
- fileName, PATH_MAX, nls_codepage, remap);
+ cifsConvertToUTF16((__le16 *) (pSMB->fileName + 1),
+ fileName, PATH_MAX, nls_codepage, remap);
name_len++; /* trailing null */
name_len *= 2;
} else { /* BB improve check for buffer overruns BB */
@@ -1304,8 +1304,8 @@ openRetry:
if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
count = 1; /* account for one byte pad to word boundary */
name_len =
- cifsConvertToUCS((__le16 *) (pSMB->fileName + 1),
- fileName, PATH_MAX, nls_codepage, remap);
+ cifsConvertToUTF16((__le16 *) (pSMB->fileName + 1),
+ fileName, PATH_MAX, nls_codepage, remap);
name_len++; /* trailing null */
name_len *= 2;
pSMB->NameLength = cpu_to_le16(name_len);
@@ -2649,16 +2649,16 @@ renameRetry:
if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
name_len =
- cifsConvertToUCS((__le16 *) pSMB->OldFileName, fromName,
- PATH_MAX, nls_codepage, remap);
+ cifsConvertToUTF16((__le16 *) pSMB->OldFileName, fromName,
+ PATH_MAX, nls_codepage, remap);
name_len++; /* trailing null */
name_len *= 2;
pSMB->OldFileName[name_len] = 0x04; /* pad */
/* protocol requires ASCII signature byte on Unicode string */
pSMB->OldFileName[name_len + 1] = 0x00;
name_len2 =
- cifsConvertToUCS((__le16 *)&pSMB->OldFileName[name_len + 2],
- toName, PATH_MAX, nls_codepage, remap);
+ cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
+ toName, PATH_MAX, nls_codepage, remap);
name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
name_len2 *= 2; /* convert to bytes */
} else { /* BB improve the check for buffer overruns BB */
@@ -2738,10 +2738,12 @@ int CIFSSMBRenameOpenFile(const int xid, struct cifs_tcon *pTcon,
/* unicode only call */
if (target_name == NULL) {
sprintf(dummy_string, "cifs%x", pSMB->hdr.Mid);
- len_of_str = cifsConvertToUCS((__le16 *)rename_info->target_name,
+ len_of_str =
+ cifsConvertToUTF16((__le16 *)rename_info->target_name,
dummy_string, 24, nls_codepage, remap);
} else {
- len_of_str = cifsConvertToUCS((__le16 *)rename_info->target_name,
+ len_of_str =
+ cifsConvertToUTF16((__le16 *)rename_info->target_name,
target_name, PATH_MAX, nls_codepage,
remap);
}
@@ -2795,17 +2797,17 @@ copyRetry:
pSMB->Flags = cpu_to_le16(flags & COPY_TREE);
if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
- name_len = cifsConvertToUCS((__le16 *) pSMB->OldFileName,
- fromName, PATH_MAX, nls_codepage,
- remap);
+ name_len = cifsConvertToUTF16((__le16 *) pSMB->OldFileName,
+ fromName, PATH_MAX, nls_codepage,
+ remap);
name_len++; /* trailing null */
name_len *= 2;
pSMB->OldFileName[name_len] = 0x04; /* pad */
/* protocol requires ASCII signature byte on Unicode string */
pSMB->OldFileName[name_len + 1] = 0x00;
name_len2 =
- cifsConvertToUCS((__le16 *)&pSMB->OldFileName[name_len + 2],
- toName, PATH_MAX, nls_codepage, remap);
+ cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
+ toName, PATH_MAX, nls_codepage, remap);
name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
name_len2 *= 2; /* convert to bytes */
} else { /* BB improve the check for buffer overruns BB */
@@ -2861,9 +2863,9 @@ createSymLinkRetry:
if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
name_len =
- cifs_strtoUCS((__le16 *) pSMB->FileName, fromName, PATH_MAX
- /* find define for this maxpathcomponent */
- , nls_codepage);
+ cifs_strtoUTF16((__le16 *) pSMB->FileName, fromName,
+ /* find define for this maxpathcomponent */
+ PATH_MAX, nls_codepage);
name_len++; /* trailing null */
name_len *= 2;
@@ -2885,9 +2887,9 @@ createSymLinkRetry:
data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
name_len_target =
- cifs_strtoUCS((__le16 *) data_offset, toName, PATH_MAX
- /* find define for this maxpathcomponent */
- , nls_codepage);
+ cifs_strtoUTF16((__le16 *) data_offset, toName, PATH_MAX
+ /* find define for this maxpathcomponent */
+ , nls_codepage);
name_len_target++; /* trailing null */
name_len_target *= 2;
} else { /* BB improve the check for buffer overruns BB */
@@ -2949,8 +2951,8 @@ createHardLinkRetry:
return rc;
if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
- name_len = cifsConvertToUCS((__le16 *) pSMB->FileName, toName,
- PATH_MAX, nls_codepage, remap);
+ name_len = cifsConvertToUTF16((__le16 *) pSMB->FileName, toName,
+ PATH_MAX, nls_codepage, remap);
name_len++; /* trailing null */
name_len *= 2;
@@ -2972,8 +2974,8 @@ createHardLinkRetry:
data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
name_len_target =
- cifsConvertToUCS((__le16 *) data_offset, fromName, PATH_MAX,
- nls_codepage, remap);
+ cifsConvertToUTF16((__le16 *) data_offset, fromName,
+ PATH_MAX, nls_codepage, remap);
name_len_target++; /* trailing null */
name_len_target *= 2;
} else { /* BB improve the check for buffer overruns BB */
@@ -3042,8 +3044,8 @@ winCreateHardLinkRetry:
if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
name_len =
- cifsConvertToUCS((__le16 *) pSMB->OldFileName, fromName,
- PATH_MAX, nls_codepage, remap);
+ cifsConvertToUTF16((__le16 *) pSMB->OldFileName, fromName,
+ PATH_MAX, nls_codepage, remap);
name_len++; /* trailing null */
name_len *= 2;
@@ -3051,8 +3053,8 @@ winCreateHardLinkRetry:
pSMB->OldFileName[name_len] = 0x04;
pSMB->OldFileName[name_len + 1] = 0x00; /* pad */
name_len2 =
- cifsConvertToUCS((__le16 *)&pSMB->OldFileName[name_len + 2],
- toName, PATH_MAX, nls_codepage, remap);
+ cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
+ toName, PATH_MAX, nls_codepage, remap);
name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
name_len2 *= 2; /* convert to bytes */
} else { /* BB improve the check for buffer overruns BB */
@@ -3108,8 +3110,8 @@ querySymLinkRetry:
if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
name_len =
- cifs_strtoUCS((__le16 *) pSMB->FileName, searchName,
- PATH_MAX, nls_codepage);
+ cifs_strtoUTF16((__le16 *) pSMB->FileName, searchName,
+ PATH_MAX, nls_codepage);
name_len++; /* trailing null */
name_len *= 2;
} else { /* BB improve the check for buffer overruns BB */
@@ -3166,8 +3168,8 @@ querySymLinkRetry:
is_unicode = false;
/* BB FIXME investigate remapping reserved chars here */
- *symlinkinfo = cifs_strndup_from_ucs(data_start, count,
- is_unicode, nls_codepage);
+ *symlinkinfo = cifs_strndup_from_utf16(data_start,
+ count, is_unicode, nls_codepage);
if (!*symlinkinfo)
rc = -ENOMEM;
}
@@ -3450,8 +3452,9 @@ queryAclRetry:
if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
name_len =
- cifsConvertToUCS((__le16 *) pSMB->FileName, searchName,
- PATH_MAX, nls_codepage, remap);
+ cifsConvertToUTF16((__le16 *) pSMB->FileName,
+ searchName, PATH_MAX, nls_codepage,
+ remap);
name_len++; /* trailing null */
name_len *= 2;
pSMB->FileName[name_len] = 0;
@@ -3537,8 +3540,8 @@ setAclRetry:
return rc;
if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
name_len =
- cifsConvertToUCS((__le16 *) pSMB->FileName, fileName,
- PATH_MAX, nls_codepage, remap);
+ cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
+ PATH_MAX, nls_codepage, remap);
name_len++; /* trailing null */
name_len *= 2;
} else { /* BB improve the check for buffer overruns BB */
@@ -3948,8 +3951,9 @@ QInfRetry:
if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
name_len =
- cifsConvertToUCS((__le16 *) pSMB->FileName, searchName,
- PATH_MAX, nls_codepage, remap);
+ cifsConvertToUTF16((__le16 *) pSMB->FileName,
+ searchName, PATH_MAX, nls_codepage,
+ remap);
name_len++; /* trailing null */
name_len *= 2;
} else {
@@ -4086,8 +4090,8 @@ QPathInfoRetry:
if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
name_len =
- cifsConvertToUCS((__le16 *) pSMB->FileName, searchName,
- PATH_MAX, nls_codepage, remap);
+ cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
+ PATH_MAX, nls_codepage, remap);
name_len++; /* trailing null */
name_len *= 2;
} else { /* BB improve the check for buffer overruns BB */
@@ -4255,8 +4259,8 @@ UnixQPathInfoRetry:
if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
name_len =
- cifsConvertToUCS((__le16 *) pSMB->FileName, searchName,
- PATH_MAX, nls_codepage, remap);
+ cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
+ PATH_MAX, nls_codepage, remap);
name_len++; /* trailing null */
name_len *= 2;
} else { /* BB improve the check for buffer overruns BB */
@@ -4344,8 +4348,8 @@ findFirstRetry:
if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
name_len =
- cifsConvertToUCS((__le16 *) pSMB->FileName, searchName,
- PATH_MAX, nls_codepage, remap);
+ cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
+ PATH_MAX, nls_codepage, remap);
/* We can not add the asterik earlier in case
it got remapped to 0xF03A as if it were part of the
directory name instead of a wildcard */
@@ -4656,8 +4660,9 @@ GetInodeNumberRetry:
if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
name_len =
- cifsConvertToUCS((__le16 *) pSMB->FileName, searchName,
- PATH_MAX, nls_codepage, remap);
+ cifsConvertToUTF16((__le16 *) pSMB->FileName,
+ searchName, PATH_MAX, nls_codepage,
+ remap);
name_len++; /* trailing null */
name_len *= 2;
} else { /* BB improve the check for buffer overruns BB */
@@ -4794,9 +4799,9 @@ parse_DFS_referrals(TRANSACTION2_GET_DFS_REFER_RSP *pSMBr,
rc = -ENOMEM;
goto parse_DFS_referrals_exit;
}
- cifsConvertToUCS((__le16 *) tmp, searchName,
- PATH_MAX, nls_codepage, remap);
- node->path_consumed = cifs_ucs2_bytes(tmp,
+ cifsConvertToUTF16((__le16 *) tmp, searchName,
+ PATH_MAX, nls_codepage, remap);
+ node->path_consumed = cifs_utf16_bytes(tmp,
le16_to_cpu(pSMBr->PathConsumed),
nls_codepage);
kfree(tmp);
@@ -4809,8 +4814,8 @@ parse_DFS_referrals(TRANSACTION2_GET_DFS_REFER_RSP *pSMBr,
/* copy DfsPath */
temp = (char *)ref + le16_to_cpu(ref->DfsPathOffset);
max_len = data_end - temp;
- node->path_name = cifs_strndup_from_ucs(temp, max_len,
- is_unicode, nls_codepage);
+ node->path_name = cifs_strndup_from_utf16(temp, max_len,
+ is_unicode, nls_codepage);
if (!node->path_name) {
rc = -ENOMEM;
goto parse_DFS_referrals_exit;
@@ -4819,8 +4824,8 @@ parse_DFS_referrals(TRANSACTION2_GET_DFS_REFER_RSP *pSMBr,
/* copy link target UNC */
temp = (char *)ref + le16_to_cpu(ref->NetworkAddressOffset);
max_len = data_end - temp;
- node->node_name = cifs_strndup_from_ucs(temp, max_len,
- is_unicode, nls_codepage);
+ node->node_name = cifs_strndup_from_utf16(temp, max_len,
+ is_unicode, nls_codepage);
if (!node->node_name)
rc = -ENOMEM;
}
@@ -4873,8 +4878,9 @@ getDFSRetry:
if (ses->capabilities & CAP_UNICODE) {
pSMB->hdr.Flags2 |= SMBFLG2_UNICODE;
name_len =
- cifsConvertToUCS((__le16 *) pSMB->RequestFileName,
- searchName, PATH_MAX, nls_codepage, remap);
+ cifsConvertToUTF16((__le16 *) pSMB->RequestFileName,
+ searchName, PATH_MAX, nls_codepage,
+ remap);
name_len++; /* trailing null */
name_len *= 2;
} else { /* BB improve the check for buffer overruns BB */
@@ -5506,8 +5512,8 @@ SetEOFRetry:
if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
name_len =
- cifsConvertToUCS((__le16 *) pSMB->FileName, fileName,
- PATH_MAX, nls_codepage, remap);
+ cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
+ PATH_MAX, nls_codepage, remap);
name_len++; /* trailing null */
name_len *= 2;
} else { /* BB improve the check for buffer overruns BB */
@@ -5796,8 +5802,8 @@ SetTimesRetry:
if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
name_len =
- cifsConvertToUCS((__le16 *) pSMB->FileName, fileName,
- PATH_MAX, nls_codepage, remap);
+ cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
+ PATH_MAX, nls_codepage, remap);
name_len++; /* trailing null */
name_len *= 2;
} else { /* BB improve the check for buffer overruns BB */
@@ -5877,8 +5883,8 @@ SetAttrLgcyRetry:
if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
name_len =
- ConvertToUCS((__le16 *) pSMB->fileName, fileName,
- PATH_MAX, nls_codepage);
+ ConvertToUTF16((__le16 *) pSMB->fileName, fileName,
+ PATH_MAX, nls_codepage);
name_len++; /* trailing null */
name_len *= 2;
} else { /* BB improve the check for buffer overruns BB */
@@ -6030,8 +6036,8 @@ setPermsRetry:
if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
name_len =
- cifsConvertToUCS((__le16 *) pSMB->FileName, fileName,
- PATH_MAX, nls_codepage, remap);
+ cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
+ PATH_MAX, nls_codepage, remap);
name_len++; /* trailing null */
name_len *= 2;
} else { /* BB improve the check for buffer overruns BB */
@@ -6123,8 +6129,8 @@ QAllEAsRetry:
if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
list_len =
- cifsConvertToUCS((__le16 *) pSMB->FileName, searchName,
- PATH_MAX, nls_codepage, remap);
+ cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
+ PATH_MAX, nls_codepage, remap);
list_len++; /* trailing null */
list_len *= 2;
} else { /* BB improve the check for buffer overruns BB */
@@ -6301,8 +6307,8 @@ SetEARetry:
if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
name_len =
- cifsConvertToUCS((__le16 *) pSMB->FileName, fileName,
- PATH_MAX, nls_codepage, remap);
+ cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
+ PATH_MAX, nls_codepage, remap);
name_len++; /* trailing null */
name_len *= 2;
} else { /* BB improve the check for buffer overruns BB */
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 4666780f315d..986709a8d903 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -38,6 +38,7 @@
#include <asm/processor.h>
#include <linux/inet.h>
#include <linux/module.h>
+#include <keys/user-type.h>
#include <net/ipv6.h>
#include "cifspdu.h"
#include "cifsglob.h"
@@ -225,74 +226,90 @@ static int check2ndT2(struct smb_hdr *pSMB)
static int coalesce_t2(struct smb_hdr *psecond, struct smb_hdr *pTargetSMB)
{
- struct smb_t2_rsp *pSMB2 = (struct smb_t2_rsp *)psecond;
+ struct smb_t2_rsp *pSMBs = (struct smb_t2_rsp *)psecond;
struct smb_t2_rsp *pSMBt = (struct smb_t2_rsp *)pTargetSMB;
- char *data_area_of_target;
- char *data_area_of_buf2;
+ char *data_area_of_tgt;
+ char *data_area_of_src;
int remaining;
- unsigned int byte_count, total_in_buf;
- __u16 total_data_size, total_in_buf2;
+ unsigned int byte_count, total_in_tgt;
+ __u16 tgt_total_cnt, src_total_cnt, total_in_src;
- total_data_size = get_unaligned_le16(&pSMBt->t2_rsp.TotalDataCount);
+ src_total_cnt = get_unaligned_le16(&pSMBs->t2_rsp.TotalDataCount);
+ tgt_total_cnt = get_unaligned_le16(&pSMBt->t2_rsp.TotalDataCount);
- if (total_data_size !=
- get_unaligned_le16(&pSMB2->t2_rsp.TotalDataCount))
- cFYI(1, "total data size of primary and secondary t2 differ");
+ if (tgt_total_cnt != src_total_cnt)
+ cFYI(1, "total data count of primary and secondary t2 differ "
+ "source=%hu target=%hu", src_total_cnt, tgt_total_cnt);
- total_in_buf = get_unaligned_le16(&pSMBt->t2_rsp.DataCount);
+ total_in_tgt = get_unaligned_le16(&pSMBt->t2_rsp.DataCount);
- remaining = total_data_size - total_in_buf;
+ remaining = tgt_total_cnt - total_in_tgt;
- if (remaining < 0)
+ if (remaining < 0) {
+ cFYI(1, "Server sent too much data. tgt_total_cnt=%hu "
+ "total_in_tgt=%hu", tgt_total_cnt, total_in_tgt);
return -EPROTO;
+ }
- if (remaining == 0) /* nothing to do, ignore */
+ if (remaining == 0) {
+ /* nothing to do, ignore */
+ cFYI(1, "no more data remains");
return 0;
+ }
- total_in_buf2 = get_unaligned_le16(&pSMB2->t2_rsp.DataCount);
- if (remaining < total_in_buf2) {
+ total_in_src = get_unaligned_le16(&pSMBs->t2_rsp.DataCount);
+ if (remaining < total_in_src)
cFYI(1, "transact2 2nd response contains too much data");
- }
/* find end of first SMB data area */
- data_area_of_target = (char *)&pSMBt->hdr.Protocol +
+ data_area_of_tgt = (char *)&pSMBt->hdr.Protocol +
get_unaligned_le16(&pSMBt->t2_rsp.DataOffset);
- /* validate target area */
- data_area_of_buf2 = (char *)&pSMB2->hdr.Protocol +
- get_unaligned_le16(&pSMB2->t2_rsp.DataOffset);
+ /* validate target area */
+ data_area_of_src = (char *)&pSMBs->hdr.Protocol +
+ get_unaligned_le16(&pSMBs->t2_rsp.DataOffset);
- data_area_of_target += total_in_buf;
+ data_area_of_tgt += total_in_tgt;
- /* copy second buffer into end of first buffer */
- total_in_buf += total_in_buf2;
+ total_in_tgt += total_in_src;
/* is the result too big for the field? */
- if (total_in_buf > USHRT_MAX)
+ if (total_in_tgt > USHRT_MAX) {
+ cFYI(1, "coalesced DataCount too large (%u)", total_in_tgt);
return -EPROTO;
- put_unaligned_le16(total_in_buf, &pSMBt->t2_rsp.DataCount);
+ }
+ put_unaligned_le16(total_in_tgt, &pSMBt->t2_rsp.DataCount);
/* fix up the BCC */
byte_count = get_bcc(pTargetSMB);
- byte_count += total_in_buf2;
+ byte_count += total_in_src;
/* is the result too big for the field? */
- if (byte_count > USHRT_MAX)
+ if (byte_count > USHRT_MAX) {
+ cFYI(1, "coalesced BCC too large (%u)", byte_count);
return -EPROTO;
+ }
put_bcc(byte_count, pTargetSMB);
byte_count = be32_to_cpu(pTargetSMB->smb_buf_length);
- byte_count += total_in_buf2;
+ byte_count += total_in_src;
/* don't allow buffer to overflow */
- if (byte_count > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4)
+ if (byte_count > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) {
+ cFYI(1, "coalesced BCC exceeds buffer size (%u)", byte_count);
return -ENOBUFS;
+ }
pTargetSMB->smb_buf_length = cpu_to_be32(byte_count);
- memcpy(data_area_of_target, data_area_of_buf2, total_in_buf2);
+ /* copy second buffer into end of first buffer */
+ memcpy(data_area_of_tgt, data_area_of_src, total_in_src);
- if (remaining == total_in_buf2) {
- cFYI(1, "found the last secondary response");
- return 0; /* we are done */
- } else /* more responses to go */
+ if (remaining != total_in_src) {
+ /* more responses to go */
+ cFYI(1, "waiting for more secondary responses");
return 1;
+ }
+
+ /* we are done */
+ cFYI(1, "found the last secondary response");
+ return 0;
}
static void
@@ -1578,11 +1595,14 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
}
}
- if (vol->multiuser && !(vol->secFlg & CIFSSEC_MAY_KRB5)) {
- cERROR(1, "Multiuser mounts currently require krb5 "
- "authentication!");
+#ifndef CONFIG_KEYS
+ /* Muliuser mounts require CONFIG_KEYS support */
+ if (vol->multiuser) {
+ cERROR(1, "Multiuser mounts require kernels with "
+ "CONFIG_KEYS enabled.");
goto cifs_parse_mount_err;
}
+#endif
if (vol->UNCip == NULL)
vol->UNCip = &vol->UNC[2];
@@ -1981,10 +2001,16 @@ static int match_session(struct cifs_ses *ses, struct smb_vol *vol)
return 0;
break;
default:
+ /* NULL username means anonymous session */
+ if (ses->user_name == NULL) {
+ if (!vol->nullauth)
+ return 0;
+ break;
+ }
+
/* anything else takes username/password */
- if (ses->user_name == NULL)
- return 0;
- if (strncmp(ses->user_name, vol->username,
+ if (strncmp(ses->user_name,
+ vol->username ? vol->username : "",
MAX_USERNAME_SIZE))
return 0;
if (strlen(vol->username) != 0 &&
@@ -2039,6 +2065,132 @@ cifs_put_smb_ses(struct cifs_ses *ses)
cifs_put_tcp_session(server);
}
+#ifdef CONFIG_KEYS
+
+/* strlen("cifs:a:") + INET6_ADDRSTRLEN + 1 */
+#define CIFSCREDS_DESC_SIZE (7 + INET6_ADDRSTRLEN + 1)
+
+/* Populate username and pw fields from keyring if possible */
+static int
+cifs_set_cifscreds(struct smb_vol *vol, struct cifs_ses *ses)
+{
+ int rc = 0;
+ char *desc, *delim, *payload;
+ ssize_t len;
+ struct key *key;
+ struct TCP_Server_Info *server = ses->server;
+ struct sockaddr_in *sa;
+ struct sockaddr_in6 *sa6;
+ struct user_key_payload *upayload;
+
+ desc = kmalloc(CIFSCREDS_DESC_SIZE, GFP_KERNEL);
+ if (!desc)
+ return -ENOMEM;
+
+ /* try to find an address key first */
+ switch (server->dstaddr.ss_family) {
+ case AF_INET:
+ sa = (struct sockaddr_in *)&server->dstaddr;
+ sprintf(desc, "cifs:a:%pI4", &sa->sin_addr.s_addr);
+ break;
+ case AF_INET6:
+ sa6 = (struct sockaddr_in6 *)&server->dstaddr;
+ sprintf(desc, "cifs:a:%pI6c", &sa6->sin6_addr.s6_addr);
+ break;
+ default:
+ cFYI(1, "Bad ss_family (%hu)", server->dstaddr.ss_family);
+ rc = -EINVAL;
+ goto out_err;
+ }
+
+ cFYI(1, "%s: desc=%s", __func__, desc);
+ key = request_key(&key_type_logon, desc, "");
+ if (IS_ERR(key)) {
+ if (!ses->domainName) {
+ cFYI(1, "domainName is NULL");
+ rc = PTR_ERR(key);
+ goto out_err;
+ }
+
+ /* didn't work, try to find a domain key */
+ sprintf(desc, "cifs:d:%s", ses->domainName);
+ cFYI(1, "%s: desc=%s", __func__, desc);
+ key = request_key(&key_type_logon, desc, "");
+ if (IS_ERR(key)) {
+ rc = PTR_ERR(key);
+ goto out_err;
+ }
+ }
+
+ down_read(&key->sem);
+ upayload = key->payload.data;
+ if (IS_ERR_OR_NULL(upayload)) {
+ rc = PTR_ERR(key);
+ goto out_key_put;
+ }
+
+ /* find first : in payload */
+ payload = (char *)upayload->data;
+ delim = strnchr(payload, upayload->datalen, ':');
+ cFYI(1, "payload=%s", payload);
+ if (!delim) {
+ cFYI(1, "Unable to find ':' in payload (datalen=%d)",
+ upayload->datalen);
+ rc = -EINVAL;
+ goto out_key_put;
+ }
+
+ len = delim - payload;
+ if (len > MAX_USERNAME_SIZE || len <= 0) {
+ cFYI(1, "Bad value from username search (len=%ld)", len);
+ rc = -EINVAL;
+ goto out_key_put;
+ }
+
+ vol->username = kstrndup(payload, len, GFP_KERNEL);
+ if (!vol->username) {
+ cFYI(1, "Unable to allocate %ld bytes for username", len);
+ rc = -ENOMEM;
+ goto out_key_put;
+ }
+ cFYI(1, "%s: username=%s", __func__, vol->username);
+
+ len = key->datalen - (len + 1);
+ if (len > MAX_PASSWORD_SIZE || len <= 0) {
+ cFYI(1, "Bad len for password search (len=%ld)", len);
+ rc = -EINVAL;
+ kfree(vol->username);
+ vol->username = NULL;
+ goto out_key_put;
+ }
+
+ ++delim;
+ vol->password = kstrndup(delim, len, GFP_KERNEL);
+ if (!vol->password) {
+ cFYI(1, "Unable to allocate %ld bytes for password", len);
+ rc = -ENOMEM;
+ kfree(vol->username);
+ vol->username = NULL;
+ goto out_key_put;
+ }
+
+out_key_put:
+ up_read(&key->sem);
+ key_put(key);
+out_err:
+ kfree(desc);
+ cFYI(1, "%s: returning %d", __func__, rc);
+ return rc;
+}
+#else /* ! CONFIG_KEYS */
+static inline int
+cifs_set_cifscreds(struct smb_vol *vol __attribute__((unused)),
+ struct cifs_ses *ses __attribute__((unused)))
+{
+ return -ENOSYS;
+}
+#endif /* CONFIG_KEYS */
+
static bool warned_on_ntlm; /* globals init to false automatically */
static struct cifs_ses *
@@ -2914,18 +3066,33 @@ void cifs_setup_cifs_sb(struct smb_vol *pvolume_info,
#define CIFS_DEFAULT_IOSIZE (1024 * 1024)
/*
- * Windows only supports a max of 60k reads. Default to that when posix
- * extensions aren't in force.
+ * Windows only supports a max of 60kb reads and 65535 byte writes. Default to
+ * those values when posix extensions aren't in force. In actuality here, we
+ * use 65536 to allow for a write that is a multiple of 4k. Most servers seem
+ * to be ok with the extra byte even though Windows doesn't send writes that
+ * are that large.
+ *
+ * Citation:
+ *
+ * http://blogs.msdn.com/b/openspecification/archive/2009/04/10/smb-maximum-transmit-buffer-size-and-performance-tuning.aspx
*/
#define CIFS_DEFAULT_NON_POSIX_RSIZE (60 * 1024)
+#define CIFS_DEFAULT_NON_POSIX_WSIZE (65536)
static unsigned int
cifs_negotiate_wsize(struct cifs_tcon *tcon, struct smb_vol *pvolume_info)
{
__u64 unix_cap = le64_to_cpu(tcon->fsUnixInfo.Capability);
struct TCP_Server_Info *server = tcon->ses->server;
- unsigned int wsize = pvolume_info->wsize ? pvolume_info->wsize :
- CIFS_DEFAULT_IOSIZE;
+ unsigned int wsize;
+
+ /* start with specified wsize, or default */
+ if (pvolume_info->wsize)
+ wsize = pvolume_info->wsize;
+ else if (tcon->unix_ext && (unix_cap & CIFS_UNIX_LARGE_WRITE_CAP))
+ wsize = CIFS_DEFAULT_IOSIZE;
+ else
+ wsize = CIFS_DEFAULT_NON_POSIX_WSIZE;
/* can server support 24-bit write sizes? (via UNIX extensions) */
if (!tcon->unix_ext || !(unix_cap & CIFS_UNIX_LARGE_WRITE_CAP))
@@ -3136,10 +3303,9 @@ cifs_setup_volume_info(struct smb_vol *volume_info, char *mount_data,
return -EINVAL;
if (volume_info->nullauth) {
- cFYI(1, "null user");
- volume_info->username = kzalloc(1, GFP_KERNEL);
- if (volume_info->username == NULL)
- return -ENOMEM;
+ cFYI(1, "Anonymous login");
+ kfree(volume_info->username);
+ volume_info->username = NULL;
} else if (volume_info->username) {
/* BB fixme parse for domain name here */
cFYI(1, "Username: %s", volume_info->username);
@@ -3478,7 +3644,7 @@ CIFSTCon(unsigned int xid, struct cifs_ses *ses,
if (ses->capabilities & CAP_UNICODE) {
smb_buffer->Flags2 |= SMBFLG2_UNICODE;
length =
- cifs_strtoUCS((__le16 *) bcc_ptr, tree,
+ cifs_strtoUTF16((__le16 *) bcc_ptr, tree,
6 /* max utf8 char length in bytes */ *
(/* server len*/ + 256 /* share len */), nls_codepage);
bcc_ptr += 2 * length; /* convert num 16 bit words to bytes */
@@ -3533,7 +3699,7 @@ CIFSTCon(unsigned int xid, struct cifs_ses *ses,
/* mostly informational -- no need to fail on error here */
kfree(tcon->nativeFileSystem);
- tcon->nativeFileSystem = cifs_strndup_from_ucs(bcc_ptr,
+ tcon->nativeFileSystem = cifs_strndup_from_utf16(bcc_ptr,
bytes_left, is_unicode,
nls_codepage);
@@ -3657,16 +3823,38 @@ int cifs_setup_session(unsigned int xid, struct cifs_ses *ses,
return rc;
}
+static int
+cifs_set_vol_auth(struct smb_vol *vol, struct cifs_ses *ses)
+{
+ switch (ses->server->secType) {
+ case Kerberos:
+ vol->secFlg = CIFSSEC_MUST_KRB5;
+ return 0;
+ case NTLMv2:
+ vol->secFlg = CIFSSEC_MUST_NTLMV2;
+ break;
+ case NTLM:
+ vol->secFlg = CIFSSEC_MUST_NTLM;
+ break;
+ case RawNTLMSSP:
+ vol->secFlg = CIFSSEC_MUST_NTLMSSP;
+ break;
+ case LANMAN:
+ vol->secFlg = CIFSSEC_MUST_LANMAN;
+ break;
+ }
+
+ return cifs_set_cifscreds(vol, ses);
+}
+
static struct cifs_tcon *
cifs_construct_tcon(struct cifs_sb_info *cifs_sb, uid_t fsuid)
{
+ int rc;
struct cifs_tcon *master_tcon = cifs_sb_master_tcon(cifs_sb);
struct cifs_ses *ses;
struct cifs_tcon *tcon = NULL;
struct smb_vol *vol_info;
- char username[28]; /* big enough for "krb50x" + hex of ULONG_MAX 6+16 */
- /* We used to have this as MAX_USERNAME which is */
- /* way too big now (256 instead of 32) */
vol_info = kzalloc(sizeof(*vol_info), GFP_KERNEL);
if (vol_info == NULL) {
@@ -3674,8 +3862,6 @@ cifs_construct_tcon(struct cifs_sb_info *cifs_sb, uid_t fsuid)
goto out;
}
- snprintf(username, sizeof(username), "krb50x%x", fsuid);
- vol_info->username = username;
vol_info->local_nls = cifs_sb->local_nls;
vol_info->linux_uid = fsuid;
vol_info->cred_uid = fsuid;
@@ -3685,8 +3871,11 @@ cifs_construct_tcon(struct cifs_sb_info *cifs_sb, uid_t fsuid)
vol_info->local_lease = master_tcon->local_lease;
vol_info->no_linux_ext = !master_tcon->unix_ext;
- /* FIXME: allow for other secFlg settings */
- vol_info->secFlg = CIFSSEC_MUST_KRB5;
+ rc = cifs_set_vol_auth(vol_info, master_tcon->ses);
+ if (rc) {
+ tcon = ERR_PTR(rc);
+ goto out;
+ }
/* get a reference for the same TCP session */
spin_lock(&cifs_tcp_ses_lock);
@@ -3709,6 +3898,8 @@ cifs_construct_tcon(struct cifs_sb_info *cifs_sb, uid_t fsuid)
if (ses->capabilities & CAP_UNIX)
reset_cifs_unix_caps(0, tcon, NULL, vol_info);
out:
+ kfree(vol_info->username);
+ kfree(vol_info->password);
kfree(vol_info);
return tcon;
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c
index a090bbe6ee29..e2bbc683e018 100644
--- a/fs/cifs/readdir.c
+++ b/fs/cifs/readdir.c
@@ -647,10 +647,11 @@ static int cifs_filldir(char *find_entry, struct file *file, filldir_t filldir,
name.name = scratch_buf;
name.len =
- cifs_from_ucs2((char *)name.name, (__le16 *)de.name,
- UNICODE_NAME_MAX,
- min(de.namelen, (size_t)max_len), nlt,
- cifs_sb->mnt_cifs_flags &
+ cifs_from_utf16((char *)name.name, (__le16 *)de.name,
+ UNICODE_NAME_MAX,
+ min_t(size_t, de.namelen,
+ (size_t)max_len), nlt,
+ cifs_sb->mnt_cifs_flags &
CIFS_MOUNT_MAP_SPECIAL_CHR);
name.len -= nls_nullsize(nlt);
} else {
diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c
index 4ec3ee9d72cc..d85efad5765f 100644
--- a/fs/cifs/sess.c
+++ b/fs/cifs/sess.c
@@ -167,16 +167,16 @@ unicode_oslm_strings(char **pbcc_area, const struct nls_table *nls_cp)
int bytes_ret = 0;
/* Copy OS version */
- bytes_ret = cifs_strtoUCS((__le16 *)bcc_ptr, "Linux version ", 32,
- nls_cp);
+ bytes_ret = cifs_strtoUTF16((__le16 *)bcc_ptr, "Linux version ", 32,
+ nls_cp);
bcc_ptr += 2 * bytes_ret;
- bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, init_utsname()->release,
- 32, nls_cp);
+ bytes_ret = cifs_strtoUTF16((__le16 *) bcc_ptr, init_utsname()->release,
+ 32, nls_cp);
bcc_ptr += 2 * bytes_ret;
bcc_ptr += 2; /* trailing null */
- bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
- 32, nls_cp);
+ bytes_ret = cifs_strtoUTF16((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
+ 32, nls_cp);
bcc_ptr += 2 * bytes_ret;
bcc_ptr += 2; /* trailing null */
@@ -197,8 +197,8 @@ static void unicode_domain_string(char **pbcc_area, struct cifs_ses *ses,
*(bcc_ptr+1) = 0;
bytes_ret = 0;
} else
- bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, ses->domainName,
- 256, nls_cp);
+ bytes_ret = cifs_strtoUTF16((__le16 *) bcc_ptr, ses->domainName,
+ 256, nls_cp);
bcc_ptr += 2 * bytes_ret;
bcc_ptr += 2; /* account for null terminator */
@@ -226,8 +226,8 @@ static void unicode_ssetup_strings(char **pbcc_area, struct cifs_ses *ses,
*bcc_ptr = 0;
*(bcc_ptr+1) = 0;
} else {
- bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, ses->user_name,
- MAX_USERNAME_SIZE, nls_cp);
+ bytes_ret = cifs_strtoUTF16((__le16 *) bcc_ptr, ses->user_name,
+ MAX_USERNAME_SIZE, nls_cp);
}
bcc_ptr += 2 * bytes_ret;
bcc_ptr += 2; /* account for null termination */
@@ -287,7 +287,7 @@ decode_unicode_ssetup(char **pbcc_area, int bleft, struct cifs_ses *ses,
cFYI(1, "bleft %d", bleft);
kfree(ses->serverOS);
- ses->serverOS = cifs_strndup_from_ucs(data, bleft, true, nls_cp);
+ ses->serverOS = cifs_strndup_from_utf16(data, bleft, true, nls_cp);
cFYI(1, "serverOS=%s", ses->serverOS);
len = (UniStrnlen((wchar_t *) data, bleft / 2) * 2) + 2;
data += len;
@@ -296,7 +296,7 @@ decode_unicode_ssetup(char **pbcc_area, int bleft, struct cifs_ses *ses,
return;
kfree(ses->serverNOS);
- ses->serverNOS = cifs_strndup_from_ucs(data, bleft, true, nls_cp);
+ ses->serverNOS = cifs_strndup_from_utf16(data, bleft, true, nls_cp);
cFYI(1, "serverNOS=%s", ses->serverNOS);
len = (UniStrnlen((wchar_t *) data, bleft / 2) * 2) + 2;
data += len;
@@ -305,7 +305,7 @@ decode_unicode_ssetup(char **pbcc_area, int bleft, struct cifs_ses *ses,
return;
kfree(ses->serverDomain);
- ses->serverDomain = cifs_strndup_from_ucs(data, bleft, true, nls_cp);
+ ses->serverDomain = cifs_strndup_from_utf16(data, bleft, true, nls_cp);
cFYI(1, "serverDomain=%s", ses->serverDomain);
return;
@@ -502,8 +502,8 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer,
tmp += 2;
} else {
int len;
- len = cifs_strtoUCS((__le16 *)tmp, ses->domainName,
- MAX_USERNAME_SIZE, nls_cp);
+ len = cifs_strtoUTF16((__le16 *)tmp, ses->domainName,
+ MAX_USERNAME_SIZE, nls_cp);
len *= 2; /* unicode is 2 bytes each */
sec_blob->DomainName.BufferOffset = cpu_to_le32(tmp - pbuffer);
sec_blob->DomainName.Length = cpu_to_le16(len);
@@ -518,8 +518,8 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer,
tmp += 2;
} else {
int len;
- len = cifs_strtoUCS((__le16 *)tmp, ses->user_name,
- MAX_USERNAME_SIZE, nls_cp);
+ len = cifs_strtoUTF16((__le16 *)tmp, ses->user_name,
+ MAX_USERNAME_SIZE, nls_cp);
len *= 2; /* unicode is 2 bytes each */
sec_blob->UserName.BufferOffset = cpu_to_le32(tmp - pbuffer);
sec_blob->UserName.Length = cpu_to_le16(len);
diff --git a/fs/cifs/smbencrypt.c b/fs/cifs/smbencrypt.c
index 80d850881938..d5cd9aa7eacc 100644
--- a/fs/cifs/smbencrypt.c
+++ b/fs/cifs/smbencrypt.c
@@ -213,7 +213,7 @@ E_md4hash(const unsigned char *passwd, unsigned char *p16,
/* Password cannot be longer than 128 characters */
if (passwd) /* Password must be converted to NT unicode */
- len = cifs_strtoUCS(wpwd, passwd, 128, codepage);
+ len = cifs_strtoUTF16(wpwd, passwd, 128, codepage);
else {
len = 0;
*wpwd = 0; /* Ensure string is null terminated */
diff --git a/fs/debugfs/file.c b/fs/debugfs/file.c
index f65d4455c5e5..ef023eef0464 100644
--- a/fs/debugfs/file.c
+++ b/fs/debugfs/file.c
@@ -540,7 +540,7 @@ EXPORT_SYMBOL_GPL(debugfs_create_blob);
* debugfs_print_regs32 - use seq_print to describe a set of registers
* @s: the seq_file structure being used to generate output
* @regs: an array if struct debugfs_reg32 structures
- * @mregs: the length of the above array
+ * @nregs: the length of the above array
* @base: the base address to be used in reading the registers
* @prefix: a string to be prefixed to every output line
*
diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c
index 2a834255c75d..63ab24510649 100644
--- a/fs/ecryptfs/crypto.c
+++ b/fs/ecryptfs/crypto.c
@@ -417,17 +417,6 @@ static int ecryptfs_encrypt_extent(struct page *enc_extent_page,
(unsigned long long)(extent_base + extent_offset), rc);
goto out;
}
- if (unlikely(ecryptfs_verbosity > 0)) {
- ecryptfs_printk(KERN_DEBUG, "Encrypting extent "
- "with iv:\n");
- ecryptfs_dump_hex(extent_iv, crypt_stat->iv_bytes);
- ecryptfs_printk(KERN_DEBUG, "First 8 bytes before "
- "encryption:\n");
- ecryptfs_dump_hex((char *)
- (page_address(page)
- + (extent_offset * crypt_stat->extent_size)),
- 8);
- }
rc = ecryptfs_encrypt_page_offset(crypt_stat, enc_extent_page, 0,
page, (extent_offset
* crypt_stat->extent_size),
@@ -440,14 +429,6 @@ static int ecryptfs_encrypt_extent(struct page *enc_extent_page,
goto out;
}
rc = 0;
- if (unlikely(ecryptfs_verbosity > 0)) {
- ecryptfs_printk(KERN_DEBUG, "Encrypt extent [0x%.16llx]; "
- "rc = [%d]\n",
- (unsigned long long)(extent_base + extent_offset), rc);
- ecryptfs_printk(KERN_DEBUG, "First 8 bytes after "
- "encryption:\n");
- ecryptfs_dump_hex((char *)(page_address(enc_extent_page)), 8);
- }
out:
return rc;
}
@@ -543,17 +524,6 @@ static int ecryptfs_decrypt_extent(struct page *page,
(unsigned long long)(extent_base + extent_offset), rc);
goto out;
}
- if (unlikely(ecryptfs_verbosity > 0)) {
- ecryptfs_printk(KERN_DEBUG, "Decrypting extent "
- "with iv:\n");
- ecryptfs_dump_hex(extent_iv, crypt_stat->iv_bytes);
- ecryptfs_printk(KERN_DEBUG, "First 8 bytes before "
- "decryption:\n");
- ecryptfs_dump_hex((char *)
- (page_address(enc_extent_page)
- + (extent_offset * crypt_stat->extent_size)),
- 8);
- }
rc = ecryptfs_decrypt_page_offset(crypt_stat, page,
(extent_offset
* crypt_stat->extent_size),
@@ -567,16 +537,6 @@ static int ecryptfs_decrypt_extent(struct page *page,
goto out;
}
rc = 0;
- if (unlikely(ecryptfs_verbosity > 0)) {
- ecryptfs_printk(KERN_DEBUG, "Decrypt extent [0x%.16llx]; "
- "rc = [%d]\n",
- (unsigned long long)(extent_base + extent_offset), rc);
- ecryptfs_printk(KERN_DEBUG, "First 8 bytes after "
- "decryption:\n");
- ecryptfs_dump_hex((char *)(page_address(page)
- + (extent_offset
- * crypt_stat->extent_size)), 8);
- }
out:
return rc;
}
@@ -1590,8 +1550,8 @@ int ecryptfs_read_and_validate_xattr_region(struct dentry *dentry,
*/
int ecryptfs_read_metadata(struct dentry *ecryptfs_dentry)
{
- int rc = 0;
- char *page_virt = NULL;
+ int rc;
+ char *page_virt;
struct inode *ecryptfs_inode = ecryptfs_dentry->d_inode;
struct ecryptfs_crypt_stat *crypt_stat =
&ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat;
@@ -1616,11 +1576,13 @@ int ecryptfs_read_metadata(struct dentry *ecryptfs_dentry)
ecryptfs_dentry,
ECRYPTFS_VALIDATE_HEADER_SIZE);
if (rc) {
+ /* metadata is not in the file header, so try xattrs */
memset(page_virt, 0, PAGE_CACHE_SIZE);
rc = ecryptfs_read_xattr_region(page_virt, ecryptfs_inode);
if (rc) {
printk(KERN_DEBUG "Valid eCryptfs headers not found in "
- "file header region or xattr region\n");
+ "file header region or xattr region, inode %lu\n",
+ ecryptfs_inode->i_ino);
rc = -EINVAL;
goto out;
}
@@ -1629,7 +1591,8 @@ int ecryptfs_read_metadata(struct dentry *ecryptfs_dentry)
ECRYPTFS_DONT_VALIDATE_HEADER_SIZE);
if (rc) {
printk(KERN_DEBUG "Valid eCryptfs headers not found in "
- "file xattr region either\n");
+ "file xattr region either, inode %lu\n",
+ ecryptfs_inode->i_ino);
rc = -EINVAL;
}
if (crypt_stat->mount_crypt_stat->flags
@@ -1640,7 +1603,8 @@ int ecryptfs_read_metadata(struct dentry *ecryptfs_dentry)
"crypto metadata only in the extended attribute "
"region, but eCryptfs was mounted without "
"xattr support enabled. eCryptfs will not treat "
- "this like an encrypted file.\n");
+ "this like an encrypted file, inode %lu\n",
+ ecryptfs_inode->i_ino);
rc = -EINVAL;
}
}
diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h
index a9f29b12fbf2..a2362df58ae8 100644
--- a/fs/ecryptfs/ecryptfs_kernel.h
+++ b/fs/ecryptfs/ecryptfs_kernel.h
@@ -151,6 +151,11 @@ ecryptfs_get_key_payload_data(struct key *key)
* dentry name */
#define ECRYPTFS_TAG_73_PACKET_TYPE 0x49 /* FEK-encrypted filename as
* metadata */
+#define ECRYPTFS_MIN_PKT_LEN_SIZE 1 /* Min size to specify packet length */
+#define ECRYPTFS_MAX_PKT_LEN_SIZE 2 /* Pass at least this many bytes to
+ * ecryptfs_parse_packet_length() and
+ * ecryptfs_write_packet_length()
+ */
/* Constraint: ECRYPTFS_FILENAME_MIN_RANDOM_PREPEND_BYTES >=
* ECRYPTFS_MAX_IV_BYTES */
#define ECRYPTFS_FILENAME_MIN_RANDOM_PREPEND_BYTES 16
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c
index 19a8ca4ab1dd..19892d7d2ed1 100644
--- a/fs/ecryptfs/inode.c
+++ b/fs/ecryptfs/inode.c
@@ -822,18 +822,6 @@ static int truncate_upper(struct dentry *dentry, struct iattr *ia,
size_t num_zeros = (PAGE_CACHE_SIZE
- (ia->ia_size & ~PAGE_CACHE_MASK));
-
- /*
- * XXX(truncate) this should really happen at the begginning
- * of ->setattr. But the code is too messy to that as part
- * of a larger patch. ecryptfs is also totally missing out
- * on the inode_change_ok check at the beginning of
- * ->setattr while would include this.
- */
- rc = inode_newsize_ok(inode, ia->ia_size);
- if (rc)
- goto out;
-
if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED)) {
truncate_setsize(inode, ia->ia_size);
lower_ia->ia_size = ia->ia_size;
@@ -883,6 +871,28 @@ out:
return rc;
}
+static int ecryptfs_inode_newsize_ok(struct inode *inode, loff_t offset)
+{
+ struct ecryptfs_crypt_stat *crypt_stat;
+ loff_t lower_oldsize, lower_newsize;
+
+ crypt_stat = &ecryptfs_inode_to_private(inode)->crypt_stat;
+ lower_oldsize = upper_size_to_lower_size(crypt_stat,
+ i_size_read(inode));
+ lower_newsize = upper_size_to_lower_size(crypt_stat, offset);
+ if (lower_newsize > lower_oldsize) {
+ /*
+ * The eCryptfs inode and the new *lower* size are mixed here
+ * because we may not have the lower i_mutex held and/or it may
+ * not be appropriate to call inode_newsize_ok() with inodes
+ * from other filesystems.
+ */
+ return inode_newsize_ok(inode, lower_newsize);
+ }
+
+ return 0;
+}
+
/**
* ecryptfs_truncate
* @dentry: The ecryptfs layer dentry
@@ -899,6 +909,10 @@ int ecryptfs_truncate(struct dentry *dentry, loff_t new_length)
struct iattr lower_ia = { .ia_valid = 0 };
int rc;
+ rc = ecryptfs_inode_newsize_ok(dentry->d_inode, new_length);
+ if (rc)
+ return rc;
+
rc = truncate_upper(dentry, &ia, &lower_ia);
if (!rc && lower_ia.ia_valid & ATTR_SIZE) {
struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry);
@@ -978,6 +992,16 @@ static int ecryptfs_setattr(struct dentry *dentry, struct iattr *ia)
}
}
mutex_unlock(&crypt_stat->cs_mutex);
+
+ rc = inode_change_ok(inode, ia);
+ if (rc)
+ goto out;
+ if (ia->ia_valid & ATTR_SIZE) {
+ rc = ecryptfs_inode_newsize_ok(inode, ia->ia_size);
+ if (rc)
+ goto out;
+ }
+
if (S_ISREG(inode->i_mode)) {
rc = filemap_write_and_wait(inode->i_mapping);
if (rc)
diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c
index ac1ad48c2376..8e3b943e330f 100644
--- a/fs/ecryptfs/keystore.c
+++ b/fs/ecryptfs/keystore.c
@@ -109,7 +109,7 @@ int ecryptfs_parse_packet_length(unsigned char *data, size_t *size,
(*size) += ((unsigned char)(data[1]) + 192);
(*length_size) = 2;
} else if (data[0] == 255) {
- /* Five-byte length; we're not supposed to see this */
+ /* If support is added, adjust ECRYPTFS_MAX_PKT_LEN_SIZE */
ecryptfs_printk(KERN_ERR, "Five-byte packet length not "
"supported\n");
rc = -EINVAL;
@@ -126,7 +126,7 @@ out:
/**
* ecryptfs_write_packet_length
* @dest: The byte array target into which to write the length. Must
- * have at least 5 bytes allocated.
+ * have at least ECRYPTFS_MAX_PKT_LEN_SIZE bytes allocated.
* @size: The length to write.
* @packet_size_length: The number of bytes used to encode the packet
* length is written to this address.
@@ -146,6 +146,7 @@ int ecryptfs_write_packet_length(char *dest, size_t size,
dest[1] = ((size - 192) % 256);
(*packet_size_length) = 2;
} else {
+ /* If support is added, adjust ECRYPTFS_MAX_PKT_LEN_SIZE */
rc = -EINVAL;
ecryptfs_printk(KERN_WARNING,
"Unsupported packet size: [%zd]\n", size);
diff --git a/fs/ecryptfs/miscdev.c b/fs/ecryptfs/miscdev.c
index 940a82e63dc3..349209dc6a91 100644
--- a/fs/ecryptfs/miscdev.c
+++ b/fs/ecryptfs/miscdev.c
@@ -218,6 +218,29 @@ out_unlock:
return rc;
}
+/*
+ * miscdevfs packet format:
+ * Octet 0: Type
+ * Octets 1-4: network byte order msg_ctx->counter
+ * Octets 5-N0: Size of struct ecryptfs_message to follow
+ * Octets N0-N1: struct ecryptfs_message (including data)
+ *
+ * Octets 5-N1 not written if the packet type does not include a message
+ */
+#define PKT_TYPE_SIZE 1
+#define PKT_CTR_SIZE 4
+#define MIN_NON_MSG_PKT_SIZE (PKT_TYPE_SIZE + PKT_CTR_SIZE)
+#define MIN_MSG_PKT_SIZE (PKT_TYPE_SIZE + PKT_CTR_SIZE \
+ + ECRYPTFS_MIN_PKT_LEN_SIZE)
+/* 4 + ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES comes from tag 65 packet format */
+#define MAX_MSG_PKT_SIZE (PKT_TYPE_SIZE + PKT_CTR_SIZE \
+ + ECRYPTFS_MAX_PKT_LEN_SIZE \
+ + sizeof(struct ecryptfs_message) \
+ + 4 + ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES)
+#define PKT_TYPE_OFFSET 0
+#define PKT_CTR_OFFSET PKT_TYPE_SIZE
+#define PKT_LEN_OFFSET (PKT_TYPE_SIZE + PKT_CTR_SIZE)
+
/**
* ecryptfs_miscdev_read - format and send message from queue
* @file: fs/ecryptfs/euid miscdevfs handle (ignored)
@@ -237,7 +260,7 @@ ecryptfs_miscdev_read(struct file *file, char __user *buf, size_t count,
struct ecryptfs_daemon *daemon;
struct ecryptfs_msg_ctx *msg_ctx;
size_t packet_length_size;
- char packet_length[3];
+ char packet_length[ECRYPTFS_MAX_PKT_LEN_SIZE];
size_t i;
size_t total_length;
uid_t euid = current_euid();
@@ -305,15 +328,8 @@ check_list:
packet_length_size = 0;
msg_ctx->msg_size = 0;
}
- /* miscdevfs packet format:
- * Octet 0: Type
- * Octets 1-4: network byte order msg_ctx->counter
- * Octets 5-N0: Size of struct ecryptfs_message to follow
- * Octets N0-N1: struct ecryptfs_message (including data)
- *
- * Octets 5-N1 not written if the packet type does not
- * include a message */
- total_length = (1 + 4 + packet_length_size + msg_ctx->msg_size);
+ total_length = (PKT_TYPE_SIZE + PKT_CTR_SIZE + packet_length_size
+ + msg_ctx->msg_size);
if (count < total_length) {
rc = 0;
printk(KERN_WARNING "%s: Only given user buffer of "
@@ -324,9 +340,10 @@ check_list:
rc = -EFAULT;
if (put_user(msg_ctx->type, buf))
goto out_unlock_msg_ctx;
- if (put_user(cpu_to_be32(msg_ctx->counter), (__be32 __user *)(buf + 1)))
+ if (put_user(cpu_to_be32(msg_ctx->counter),
+ (__be32 __user *)(&buf[PKT_CTR_OFFSET])))
goto out_unlock_msg_ctx;
- i = 5;
+ i = PKT_TYPE_SIZE + PKT_CTR_SIZE;
if (msg_ctx->msg) {
if (copy_to_user(&buf[i], packet_length, packet_length_size))
goto out_unlock_msg_ctx;
@@ -391,12 +408,6 @@ out:
* @count: Amount of data in @buf
* @ppos: Pointer to offset in file (ignored)
*
- * miscdevfs packet format:
- * Octet 0: Type
- * Octets 1-4: network byte order msg_ctx->counter (0's for non-response)
- * Octets 5-N0: Size of struct ecryptfs_message to follow
- * Octets N0-N1: struct ecryptfs_message (including data)
- *
* Returns the number of bytes read from @buf
*/
static ssize_t
@@ -405,60 +416,78 @@ ecryptfs_miscdev_write(struct file *file, const char __user *buf,
{
__be32 counter_nbo;
u32 seq;
- size_t packet_size, packet_size_length, i;
- ssize_t sz = 0;
+ size_t packet_size, packet_size_length;
char *data;
uid_t euid = current_euid();
- int rc;
+ unsigned char packet_size_peek[ECRYPTFS_MAX_PKT_LEN_SIZE];
+ ssize_t rc;
- if (count == 0)
- goto out;
+ if (count == 0) {
+ return 0;
+ } else if (count == MIN_NON_MSG_PKT_SIZE) {
+ /* Likely a harmless MSG_HELO or MSG_QUIT - no packet length */
+ goto memdup;
+ } else if (count < MIN_MSG_PKT_SIZE || count > MAX_MSG_PKT_SIZE) {
+ printk(KERN_WARNING "%s: Acceptable packet size range is "
+ "[%d-%lu], but amount of data written is [%zu].",
+ __func__, MIN_MSG_PKT_SIZE, MAX_MSG_PKT_SIZE, count);
+ return -EINVAL;
+ }
+
+ if (copy_from_user(packet_size_peek, &buf[PKT_LEN_OFFSET],
+ sizeof(packet_size_peek))) {
+ printk(KERN_WARNING "%s: Error while inspecting packet size\n",
+ __func__);
+ return -EFAULT;
+ }
+ rc = ecryptfs_parse_packet_length(packet_size_peek, &packet_size,
+ &packet_size_length);
+ if (rc) {
+ printk(KERN_WARNING "%s: Error parsing packet length; "
+ "rc = [%zd]\n", __func__, rc);
+ return rc;
+ }
+
+ if ((PKT_TYPE_SIZE + PKT_CTR_SIZE + packet_size_length + packet_size)
+ != count) {
+ printk(KERN_WARNING "%s: Invalid packet size [%zu]\n", __func__,
+ packet_size);
+ return -EINVAL;
+ }
+
+memdup:
data = memdup_user(buf, count);
if (IS_ERR(data)) {
printk(KERN_ERR "%s: memdup_user returned error [%ld]\n",
__func__, PTR_ERR(data));
- goto out;
+ return PTR_ERR(data);
}
- sz = count;
- i = 0;
- switch (data[i++]) {
+ switch (data[PKT_TYPE_OFFSET]) {
case ECRYPTFS_MSG_RESPONSE:
- if (count < (1 + 4 + 1 + sizeof(struct ecryptfs_message))) {
+ if (count < (MIN_MSG_PKT_SIZE
+ + sizeof(struct ecryptfs_message))) {
printk(KERN_WARNING "%s: Minimum acceptable packet "
"size is [%zd], but amount of data written is "
"only [%zd]. Discarding response packet.\n",
__func__,
- (1 + 4 + 1 + sizeof(struct ecryptfs_message)),
- count);
+ (MIN_MSG_PKT_SIZE
+ + sizeof(struct ecryptfs_message)), count);
+ rc = -EINVAL;
goto out_free;
}
- memcpy(&counter_nbo, &data[i], 4);
+ memcpy(&counter_nbo, &data[PKT_CTR_OFFSET], PKT_CTR_SIZE);
seq = be32_to_cpu(counter_nbo);
- i += 4;
- rc = ecryptfs_parse_packet_length(&data[i], &packet_size,
- &packet_size_length);
+ rc = ecryptfs_miscdev_response(
+ &data[PKT_LEN_OFFSET + packet_size_length],
+ packet_size, euid, current_user_ns(),
+ task_pid(current), seq);
if (rc) {
- printk(KERN_WARNING "%s: Error parsing packet length; "
- "rc = [%d]\n", __func__, rc);
- goto out_free;
- }
- i += packet_size_length;
- if ((1 + 4 + packet_size_length + packet_size) != count) {
- printk(KERN_WARNING "%s: (1 + packet_size_length([%zd])"
- " + packet_size([%zd]))([%zd]) != "
- "count([%zd]). Invalid packet format.\n",
- __func__, packet_size_length, packet_size,
- (1 + packet_size_length + packet_size), count);
- goto out_free;
- }
- rc = ecryptfs_miscdev_response(&data[i], packet_size,
- euid, current_user_ns(),
- task_pid(current), seq);
- if (rc)
printk(KERN_WARNING "%s: Failed to deliver miscdev "
- "response to requesting operation; rc = [%d]\n",
+ "response to requesting operation; rc = [%zd]\n",
__func__, rc);
+ goto out_free;
+ }
break;
case ECRYPTFS_MSG_HELO:
case ECRYPTFS_MSG_QUIT:
@@ -467,12 +496,13 @@ ecryptfs_miscdev_write(struct file *file, const char __user *buf,
ecryptfs_printk(KERN_WARNING, "Dropping miscdev "
"message of unrecognized type [%d]\n",
data[0]);
- break;
+ rc = -EINVAL;
+ goto out_free;
}
+ rc = count;
out_free:
kfree(data);
-out:
- return sz;
+ return rc;
}
diff --git a/fs/ecryptfs/mmap.c b/fs/ecryptfs/mmap.c
index 6a44148c5fb9..10ec695ccd68 100644
--- a/fs/ecryptfs/mmap.c
+++ b/fs/ecryptfs/mmap.c
@@ -57,6 +57,10 @@ struct page *ecryptfs_get_locked_page(struct inode *inode, loff_t index)
* @page: Page that is locked before this call is made
*
* Returns zero on success; non-zero otherwise
+ *
+ * This is where we encrypt the data and pass the encrypted data to
+ * the lower filesystem. In OpenPGP-compatible mode, we operate on
+ * entire underlying packets.
*/
static int ecryptfs_writepage(struct page *page, struct writeback_control *wbc)
{
@@ -481,10 +485,6 @@ int ecryptfs_write_inode_size_to_metadata(struct inode *ecryptfs_inode)
* @copied: The amount of data copied
* @page: The eCryptfs page
* @fsdata: The fsdata (unused)
- *
- * This is where we encrypt the data and pass the encrypted data to
- * the lower filesystem. In OpenPGP-compatible mode, we operate on
- * entire underlying packets.
*/
static int ecryptfs_write_end(struct file *file,
struct address_space *mapping,
diff --git a/fs/ecryptfs/read_write.c b/fs/ecryptfs/read_write.c
index 3745f7c2b9c2..5c0106f75775 100644
--- a/fs/ecryptfs/read_write.c
+++ b/fs/ecryptfs/read_write.c
@@ -130,13 +130,18 @@ int ecryptfs_write(struct inode *ecryptfs_inode, char *data, loff_t offset,
pgoff_t ecryptfs_page_idx = (pos >> PAGE_CACHE_SHIFT);
size_t start_offset_in_page = (pos & ~PAGE_CACHE_MASK);
size_t num_bytes = (PAGE_CACHE_SIZE - start_offset_in_page);
- size_t total_remaining_bytes = ((offset + size) - pos);
+ loff_t total_remaining_bytes = ((offset + size) - pos);
+
+ if (fatal_signal_pending(current)) {
+ rc = -EINTR;
+ break;
+ }
if (num_bytes > total_remaining_bytes)
num_bytes = total_remaining_bytes;
if (pos < offset) {
/* remaining zeros to write, up to destination offset */
- size_t total_remaining_zeros = (offset - pos);
+ loff_t total_remaining_zeros = (offset - pos);
if (num_bytes > total_remaining_zeros)
num_bytes = total_remaining_zeros;
@@ -193,15 +198,19 @@ int ecryptfs_write(struct inode *ecryptfs_inode, char *data, loff_t offset,
}
pos += num_bytes;
}
- if ((offset + size) > ecryptfs_file_size) {
- i_size_write(ecryptfs_inode, (offset + size));
+ if (pos > ecryptfs_file_size) {
+ i_size_write(ecryptfs_inode, pos);
if (crypt_stat->flags & ECRYPTFS_ENCRYPTED) {
- rc = ecryptfs_write_inode_size_to_metadata(
+ int rc2;
+
+ rc2 = ecryptfs_write_inode_size_to_metadata(
ecryptfs_inode);
- if (rc) {
+ if (rc2) {
printk(KERN_ERR "Problem with "
"ecryptfs_write_inode_size_to_metadata; "
- "rc = [%d]\n", rc);
+ "rc = [%d]\n", rc2);
+ if (!rc)
+ rc = rc2;
goto out;
}
}
@@ -273,76 +282,3 @@ int ecryptfs_read_lower_page_segment(struct page *page_for_ecryptfs,
flush_dcache_page(page_for_ecryptfs);
return rc;
}
-
-#if 0
-/**
- * ecryptfs_read
- * @data: The virtual address into which to write the data read (and
- * possibly decrypted) from the lower file
- * @offset: The offset in the decrypted view of the file from which to
- * read into @data
- * @size: The number of bytes to read into @data
- * @ecryptfs_file: The eCryptfs file from which to read
- *
- * Read an arbitrary amount of data from an arbitrary location in the
- * eCryptfs page cache. This is done on an extent-by-extent basis;
- * individual extents are decrypted and read from the lower page
- * cache (via VFS reads). This function takes care of all the
- * address translation to locations in the lower filesystem.
- *
- * Returns zero on success; non-zero otherwise
- */
-int ecryptfs_read(char *data, loff_t offset, size_t size,
- struct file *ecryptfs_file)
-{
- struct inode *ecryptfs_inode = ecryptfs_file->f_dentry->d_inode;
- struct page *ecryptfs_page;
- char *ecryptfs_page_virt;
- loff_t ecryptfs_file_size = i_size_read(ecryptfs_inode);
- loff_t data_offset = 0;
- loff_t pos;
- int rc = 0;
-
- if ((offset + size) > ecryptfs_file_size) {
- rc = -EINVAL;
- printk(KERN_ERR "%s: Attempt to read data past the end of the "
- "file; offset = [%lld]; size = [%td]; "
- "ecryptfs_file_size = [%lld]\n",
- __func__, offset, size, ecryptfs_file_size);
- goto out;
- }
- pos = offset;
- while (pos < (offset + size)) {
- pgoff_t ecryptfs_page_idx = (pos >> PAGE_CACHE_SHIFT);
- size_t start_offset_in_page = (pos & ~PAGE_CACHE_MASK);
- size_t num_bytes = (PAGE_CACHE_SIZE - start_offset_in_page);
- size_t total_remaining_bytes = ((offset + size) - pos);
-
- if (num_bytes > total_remaining_bytes)
- num_bytes = total_remaining_bytes;
- ecryptfs_page = ecryptfs_get_locked_page(ecryptfs_inode,
- ecryptfs_page_idx);
- if (IS_ERR(ecryptfs_page)) {
- rc = PTR_ERR(ecryptfs_page);
- printk(KERN_ERR "%s: Error getting page at "
- "index [%ld] from eCryptfs inode "
- "mapping; rc = [%d]\n", __func__,
- ecryptfs_page_idx, rc);
- goto out;
- }
- ecryptfs_page_virt = kmap_atomic(ecryptfs_page, KM_USER0);
- memcpy((data + data_offset),
- ((char *)ecryptfs_page_virt + start_offset_in_page),
- num_bytes);
- kunmap_atomic(ecryptfs_page_virt, KM_USER0);
- flush_dcache_page(ecryptfs_page);
- SetPageUptodate(ecryptfs_page);
- unlock_page(ecryptfs_page);
- page_cache_release(ecryptfs_page);
- pos += num_bytes;
- data_offset += num_bytes;
- }
-out:
- return rc;
-}
-#endif /* 0 */
diff --git a/fs/ext2/ioctl.c b/fs/ext2/ioctl.c
index 1089f760c847..2de655f5d625 100644
--- a/fs/ext2/ioctl.c
+++ b/fs/ext2/ioctl.c
@@ -77,10 +77,11 @@ long ext2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
flags = flags & EXT2_FL_USER_MODIFIABLE;
flags |= oldflags & ~EXT2_FL_USER_MODIFIABLE;
ei->i_flags = flags;
- mutex_unlock(&inode->i_mutex);
ext2_set_inode_flags(inode);
inode->i_ctime = CURRENT_TIME_SEC;
+ mutex_unlock(&inode->i_mutex);
+
mark_inode_dirty(inode);
setflags_out:
mnt_drop_write_file(filp);
@@ -88,20 +89,29 @@ setflags_out:
}
case EXT2_IOC_GETVERSION:
return put_user(inode->i_generation, (int __user *) arg);
- case EXT2_IOC_SETVERSION:
+ case EXT2_IOC_SETVERSION: {
+ __u32 generation;
+
if (!inode_owner_or_capable(inode))
return -EPERM;
ret = mnt_want_write_file(filp);
if (ret)
return ret;
- if (get_user(inode->i_generation, (int __user *) arg)) {
+ if (get_user(generation, (int __user *) arg)) {
ret = -EFAULT;
- } else {
- inode->i_ctime = CURRENT_TIME_SEC;
- mark_inode_dirty(inode);
+ goto setversion_out;
}
+
+ mutex_lock(&inode->i_mutex);
+ inode->i_ctime = CURRENT_TIME_SEC;
+ inode->i_generation = generation;
+ mutex_unlock(&inode->i_mutex);
+
+ mark_inode_dirty(inode);
+setversion_out:
mnt_drop_write_file(filp);
return ret;
+ }
case EXT2_IOC_GETRSVSZ:
if (test_opt(inode->i_sb, RESERVATION)
&& S_ISREG(inode->i_mode)
diff --git a/fs/jbd/checkpoint.c b/fs/jbd/checkpoint.c
index 5d1a00a5041b..05f0754f2b46 100644
--- a/fs/jbd/checkpoint.c
+++ b/fs/jbd/checkpoint.c
@@ -453,8 +453,6 @@ out:
*
* Return <0 on error, 0 on success, 1 if there was nothing to clean up.
*
- * Called with the journal lock held.
- *
* This is the only part of the journaling code which really needs to be
* aware of transaction aborts. Checkpointing involves writing to the
* main filesystem area rather than to the journal, so it can proceed
@@ -472,13 +470,14 @@ int cleanup_journal_tail(journal_t *journal)
if (is_journal_aborted(journal))
return 1;
- /* OK, work out the oldest transaction remaining in the log, and
+ /*
+ * OK, work out the oldest transaction remaining in the log, and
* the log block it starts at.
*
* If the log is now empty, we need to work out which is the
* next transaction ID we will write, and where it will
- * start. */
-
+ * start.
+ */
spin_lock(&journal->j_state_lock);
spin_lock(&journal->j_list_lock);
transaction = journal->j_checkpoint_transactions;
@@ -504,7 +503,25 @@ int cleanup_journal_tail(journal_t *journal)
spin_unlock(&journal->j_state_lock);
return 1;
}
+ spin_unlock(&journal->j_state_lock);
+
+ /*
+ * We need to make sure that any blocks that were recently written out
+ * --- perhaps by log_do_checkpoint() --- are flushed out before we
+ * drop the transactions from the journal. It's unlikely this will be
+ * necessary, especially with an appropriately sized journal, but we
+ * need this to guarantee correctness. Fortunately
+ * cleanup_journal_tail() doesn't get called all that often.
+ */
+ if (journal->j_flags & JFS_BARRIER)
+ blkdev_issue_flush(journal->j_fs_dev, GFP_KERNEL, NULL);
+ spin_lock(&journal->j_state_lock);
+ if (!tid_gt(first_tid, journal->j_tail_sequence)) {
+ spin_unlock(&journal->j_state_lock);
+ /* Someone else cleaned up journal so return 0 */
+ return 0;
+ }
/* OK, update the superblock to recover the freed space.
* Physical blocks come first: have we wrapped beyond the end of
* the log? */
diff --git a/fs/jbd/recovery.c b/fs/jbd/recovery.c
index 5b43e96788e6..008bf062fd26 100644
--- a/fs/jbd/recovery.c
+++ b/fs/jbd/recovery.c
@@ -20,6 +20,7 @@
#include <linux/fs.h>
#include <linux/jbd.h>
#include <linux/errno.h>
+#include <linux/blkdev.h>
#endif
/*
@@ -263,6 +264,9 @@ int journal_recover(journal_t *journal)
err2 = sync_blockdev(journal->j_fs_dev);
if (!err)
err = err2;
+ /* Flush disk caches to get replayed data on the permanent storage */
+ if (journal->j_flags & JFS_BARRIER)
+ blkdev_issue_flush(journal->j_fs_dev, GFP_KERNEL, NULL);
return err;
}
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
index e418c5abdb0e..7dcd2a250495 100644
--- a/fs/proc/task_mmu.c
+++ b/fs/proc/task_mmu.c
@@ -518,6 +518,9 @@ static int clear_refs_pte_range(pmd_t *pmd, unsigned long addr,
if (!page)
continue;
+ if (PageReserved(page))
+ continue;
+
/* Clear accessed and referenced bits. */
ptep_test_and_clear_young(vma, addr, pte);
ClearPageReferenced(page);
diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
index 5ec59b20cf76..46741970371b 100644
--- a/fs/quota/dquot.c
+++ b/fs/quota/dquot.c
@@ -2125,6 +2125,8 @@ static int vfs_load_quota_inode(struct inode *inode, int type, int format_id,
mutex_unlock(&dqopt->dqio_mutex);
goto out_file_init;
}
+ if (dqopt->flags & DQUOT_QUOTA_SYS_FILE)
+ dqopt->info[type].dqi_flags |= DQF_SYS_FILE;
mutex_unlock(&dqopt->dqio_mutex);
spin_lock(&dq_state_lock);
dqopt->flags |= dquot_state_flag(flags, type);
@@ -2464,7 +2466,7 @@ int dquot_get_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii)
spin_lock(&dq_data_lock);
ii->dqi_bgrace = mi->dqi_bgrace;
ii->dqi_igrace = mi->dqi_igrace;
- ii->dqi_flags = mi->dqi_flags & DQF_MASK;
+ ii->dqi_flags = mi->dqi_flags & DQF_GETINFO_MASK;
ii->dqi_valid = IIF_ALL;
spin_unlock(&dq_data_lock);
mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex);
@@ -2490,8 +2492,8 @@ int dquot_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii)
if (ii->dqi_valid & IIF_IGRACE)
mi->dqi_igrace = ii->dqi_igrace;
if (ii->dqi_valid & IIF_FLAGS)
- mi->dqi_flags = (mi->dqi_flags & ~DQF_MASK) |
- (ii->dqi_flags & DQF_MASK);
+ mi->dqi_flags = (mi->dqi_flags & ~DQF_SETINFO_MASK) |
+ (ii->dqi_flags & DQF_SETINFO_MASK);
spin_unlock(&dq_data_lock);
mark_info_dirty(sb, type);
/* Force write to disk */
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c
index 0cf52da9d246..ebdb88840a47 100644
--- a/fs/xfs/xfs_vnodeops.c
+++ b/fs/xfs/xfs_vnodeops.c
@@ -131,7 +131,8 @@ xfs_readlink(
__func__, (unsigned long long) ip->i_ino,
(long long) pathlen);
ASSERT(0);
- return XFS_ERROR(EFSCORRUPTED);
+ error = XFS_ERROR(EFSCORRUPTED);
+ goto out;
}
diff --git a/include/acpi/acpiosxf.h b/include/acpi/acpiosxf.h
index 2fe8639b3ae7..7c9aebe8a7aa 100644
--- a/include/acpi/acpiosxf.h
+++ b/include/acpi/acpiosxf.h
@@ -218,9 +218,13 @@ acpi_status acpi_os_write_port(acpi_io_address address, u32 value, u32 width);
*/
acpi_status
acpi_os_read_memory(acpi_physical_address address, u32 * value, u32 width);
+acpi_status
+acpi_os_read_memory64(acpi_physical_address address, u64 *value, u32 width);
acpi_status
acpi_os_write_memory(acpi_physical_address address, u32 value, u32 width);
+acpi_status
+acpi_os_write_memory64(acpi_physical_address address, u64 value, u32 width);
/*
* Platform and hardware-independent PCI configuration space access
diff --git a/include/acpi/atomicio.h b/include/acpi/atomicio.h
deleted file mode 100644
index 8b9fb4b0b9ce..000000000000
--- a/include/acpi/atomicio.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifndef ACPI_ATOMIC_IO_H
-#define ACPI_ATOMIC_IO_H
-
-int acpi_pre_map_gar(struct acpi_generic_address *reg);
-int acpi_post_unmap_gar(struct acpi_generic_address *reg);
-
-int acpi_atomic_read(u64 *val, struct acpi_generic_address *reg);
-int acpi_atomic_write(u64 val, struct acpi_generic_address *reg);
-
-#endif
diff --git a/include/acpi/processor.h b/include/acpi/processor.h
index 610f6fb1bbc2..8cf7e98a2c7b 100644
--- a/include/acpi/processor.h
+++ b/include/acpi/processor.h
@@ -195,6 +195,7 @@ struct acpi_processor_flags {
u8 has_cst:1;
u8 power_setup_done:1;
u8 bm_rld_set:1;
+ u8 need_hotplug_init:1;
};
struct acpi_processor {
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index 76caa67c22e2..92f0981b5fb8 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -1328,6 +1328,7 @@ extern int drm_getmagic(struct drm_device *dev, void *data,
struct drm_file *file_priv);
extern int drm_authmagic(struct drm_device *dev, void *data,
struct drm_file *file_priv);
+extern int drm_remove_magic(struct drm_master *master, drm_magic_t magic);
/* Cache management (drm_cache.c) */
void drm_clflush_pages(struct page *pages[], unsigned long num_pages);
diff --git a/include/keys/user-type.h b/include/keys/user-type.h
index c37c34275a44..bc9ec1d7698c 100644
--- a/include/keys/user-type.h
+++ b/include/keys/user-type.h
@@ -17,7 +17,7 @@
/*****************************************************************************/
/*
- * the payload for a key of type "user"
+ * the payload for a key of type "user" or "logon"
* - once filled in and attached to a key:
* - the payload struct is invariant may not be changed, only replaced
* - the payload must be read with RCU procedures or with the key semaphore
@@ -33,6 +33,7 @@ struct user_key_payload {
};
extern struct key_type key_type_user;
+extern struct key_type key_type_logon;
extern int user_instantiate(struct key *key, const void *data, size_t datalen);
extern int user_update(struct key *key, const void *data, size_t datalen);
diff --git a/include/linux/device.h b/include/linux/device.h
index 5b3adb8f9588..b63fb393aa58 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -279,11 +279,11 @@ struct device *driver_find_device(struct device_driver *drv,
/**
* struct subsys_interface - interfaces to device functions
- * @name name of the device function
- * @subsystem subsytem of the devices to attach to
- * @node the list of functions registered at the subsystem
- * @add device hookup to device function handler
- * @remove device hookup to device function handler
+ * @name: name of the device function
+ * @subsys: subsytem of the devices to attach to
+ * @node: the list of functions registered at the subsystem
+ * @add_dev: device hookup to device function handler
+ * @remove_dev: device hookup to device function handler
*
* Simple interfaces attached to a subsystem. Multiple interfaces can
* attach to a subsystem and its devices. Unlike drivers, they do not
@@ -612,6 +612,7 @@ struct device_dma_parameters {
* @archdata: For arch-specific additions.
* @of_node: Associated device tree node.
* @devt: For creating the sysfs "dev".
+ * @id: device instance
* @devres_lock: Spinlock to protect the resource of the device.
* @devres_head: The resources list of the device.
* @knode_class: The node used to add the device to the class list.
@@ -1003,6 +1004,10 @@ extern long sysfs_deprecated;
* Each module may only use this macro once, and calling it replaces
* module_init() and module_exit().
*
+ * @__driver: driver name
+ * @__register: register function for this driver type
+ * @__unregister: unregister function for this driver type
+ *
* Use this macro to construct bus specific macros for registering
* drivers, and do not use it on its own.
*/
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 0244082d42c5..386da09f229d 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -396,6 +396,7 @@ struct inodes_stat_t {
#include <linux/rculist_bl.h>
#include <linux/atomic.h>
#include <linux/shrinker.h>
+#include <linux/migrate_mode.h>
#include <asm/byteorder.h>
@@ -526,7 +527,6 @@ enum positive_aop_returns {
struct page;
struct address_space;
struct writeback_control;
-enum migrate_mode;
struct iov_iter {
const struct iovec *iov;
diff --git a/include/linux/if_team.h b/include/linux/if_team.h
index 828181fbad5d..58404b0c5010 100644
--- a/include/linux/if_team.h
+++ b/include/linux/if_team.h
@@ -46,6 +46,10 @@ struct team_port {
u32 speed;
u8 duplex;
+ /* Custom gennetlink interface related flags */
+ bool changed;
+ bool removed;
+
struct rcu_head rcu;
};
@@ -72,6 +76,10 @@ struct team_option {
enum team_option_type type;
int (*getter)(struct team *team, void *arg);
int (*setter)(struct team *team, void *arg);
+
+ /* Custom gennetlink interface related flags */
+ bool changed;
+ bool removed;
};
struct team_mode {
@@ -207,6 +215,7 @@ enum {
TEAM_ATTR_OPTION_CHANGED, /* flag */
TEAM_ATTR_OPTION_TYPE, /* u8 */
TEAM_ATTR_OPTION_DATA, /* dynamic */
+ TEAM_ATTR_OPTION_REMOVED, /* flag */
__TEAM_ATTR_OPTION_MAX,
TEAM_ATTR_OPTION_MAX = __TEAM_ATTR_OPTION_MAX - 1,
@@ -227,6 +236,7 @@ enum {
TEAM_ATTR_PORT_LINKUP, /* flag */
TEAM_ATTR_PORT_SPEED, /* u32 */
TEAM_ATTR_PORT_DUPLEX, /* u8 */
+ TEAM_ATTR_PORT_REMOVED, /* flag */
__TEAM_ATTR_PORT_MAX,
TEAM_ATTR_PORT_MAX = __TEAM_ATTR_PORT_MAX - 1,
diff --git a/include/linux/kexec.h b/include/linux/kexec.h
index 2fa0901219d4..0d7d6a1b172f 100644
--- a/include/linux/kexec.h
+++ b/include/linux/kexec.h
@@ -50,9 +50,11 @@
* note header. For kdump, the code in vmcore.c runs in the context
* of the second kernel to combine them into one note.
*/
+#ifndef KEXEC_NOTE_BYTES
#define KEXEC_NOTE_BYTES ( (KEXEC_NOTE_HEAD_BYTES * 2) + \
KEXEC_CORE_NOTE_NAME_BYTES + \
KEXEC_CORE_NOTE_DESC_BYTES )
+#endif
/*
* This structure is used to hold the arguments that are used when loading
diff --git a/include/linux/migrate.h b/include/linux/migrate.h
index eaf867412f7a..05ed2828a553 100644
--- a/include/linux/migrate.h
+++ b/include/linux/migrate.h
@@ -3,22 +3,10 @@
#include <linux/mm.h>
#include <linux/mempolicy.h>
+#include <linux/migrate_mode.h>
typedef struct page *new_page_t(struct page *, unsigned long private, int **);
-/*
- * MIGRATE_ASYNC means never block
- * MIGRATE_SYNC_LIGHT in the current implementation means to allow blocking
- * on most operations but not ->writepage as the potential stall time
- * is too significant
- * MIGRATE_SYNC will block when migrating pages
- */
-enum migrate_mode {
- MIGRATE_ASYNC,
- MIGRATE_SYNC_LIGHT,
- MIGRATE_SYNC,
-};
-
#ifdef CONFIG_MIGRATION
#define PAGE_MIGRATION 1
diff --git a/include/linux/migrate_mode.h b/include/linux/migrate_mode.h
new file mode 100644
index 000000000000..ebf3d89a3919
--- /dev/null
+++ b/include/linux/migrate_mode.h
@@ -0,0 +1,16 @@
+#ifndef MIGRATE_MODE_H_INCLUDED
+#define MIGRATE_MODE_H_INCLUDED
+/*
+ * MIGRATE_ASYNC means never block
+ * MIGRATE_SYNC_LIGHT in the current implementation means to allow blocking
+ * on most operations but not ->writepage as the potential stall time
+ * is too significant
+ * MIGRATE_SYNC will block when migrating pages
+ */
+enum migrate_mode {
+ MIGRATE_ASYNC,
+ MIGRATE_SYNC_LIGHT,
+ MIGRATE_SYNC,
+};
+
+#endif /* MIGRATE_MODE_H_INCLUDED */
diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h
index 5c4fe8e5bfe5..aea61905499b 100644
--- a/include/linux/mlx4/device.h
+++ b/include/linux/mlx4/device.h
@@ -621,6 +621,7 @@ void mlx4_unregister_mac(struct mlx4_dev *dev, u8 port, u64 mac);
int mlx4_replace_mac(struct mlx4_dev *dev, u8 port, int qpn, u64 new_mac);
int mlx4_get_eth_qp(struct mlx4_dev *dev, u8 port, u64 mac, int *qpn);
void mlx4_put_eth_qp(struct mlx4_dev *dev, u8 port, u64 mac, int qpn);
+void mlx4_set_stats_bitmap(struct mlx4_dev *dev, u64 *stats_bitmap);
int mlx4_find_cached_vlan(struct mlx4_dev *dev, u8 port, u16 vid, int *idx);
int mlx4_register_vlan(struct mlx4_dev *dev, u8 port, u16 vlan, int *index);
diff --git a/include/linux/quota.h b/include/linux/quota.h
index cb7855699037..c09fa042b5ea 100644
--- a/include/linux/quota.h
+++ b/include/linux/quota.h
@@ -230,7 +230,11 @@ struct mem_dqinfo {
struct super_block;
#define DQF_MASK 0xffff /* Mask for format specific flags */
-#define DQF_INFO_DIRTY_B 16
+#define DQF_GETINFO_MASK 0x1ffff /* Mask for flags passed to userspace */
+#define DQF_SETINFO_MASK 0xffff /* Mask for flags modifiable from userspace */
+#define DQF_SYS_FILE_B 16
+#define DQF_SYS_FILE (1 << DQF_SYS_FILE_B) /* Quota file stored as system file */
+#define DQF_INFO_DIRTY_B 31
#define DQF_INFO_DIRTY (1 << DQF_INFO_DIRTY_B) /* Is info dirty? */
extern void mark_info_dirty(struct super_block *sb, int type);
diff --git a/include/linux/res_counter.h b/include/linux/res_counter.h
index c9d625ca659e..da81af086eaf 100644
--- a/include/linux/res_counter.h
+++ b/include/linux/res_counter.h
@@ -109,12 +109,18 @@ void res_counter_init(struct res_counter *counter, struct res_counter *parent);
*
* returns 0 on success and <0 if the counter->usage will exceed the
* counter->limit _locked call expects the counter->lock to be taken
+ *
+ * charge_nofail works the same, except that it charges the resource
+ * counter unconditionally, and returns < 0 if the after the current
+ * charge we are over limit.
*/
int __must_check res_counter_charge_locked(struct res_counter *counter,
unsigned long val);
int __must_check res_counter_charge(struct res_counter *counter,
unsigned long val, struct res_counter **limit_fail_at);
+int __must_check res_counter_charge_nofail(struct res_counter *counter,
+ unsigned long val, struct res_counter **limit_fail_at);
/*
* uncharge - tell that some portion of the resource is released
@@ -142,7 +148,10 @@ static inline unsigned long long res_counter_margin(struct res_counter *cnt)
unsigned long flags;
spin_lock_irqsave(&cnt->lock, flags);
- margin = cnt->limit - cnt->usage;
+ if (cnt->limit > cnt->usage)
+ margin = cnt->limit - cnt->usage;
+ else
+ margin = 0;
spin_unlock_irqrestore(&cnt->lock, flags);
return margin;
}
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 4032ec1cf836..2234985a5e65 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -2088,9 +2088,9 @@ extern int sched_setscheduler_nocheck(struct task_struct *, int,
extern struct task_struct *idle_task(int cpu);
/**
* is_idle_task - is the specified task an idle task?
- * @tsk: the task in question.
+ * @p: the task in question.
*/
-static inline bool is_idle_task(struct task_struct *p)
+static inline bool is_idle_task(const struct task_struct *p)
{
return p->pid == 0;
}
diff --git a/include/linux/shmem_fs.h b/include/linux/shmem_fs.h
index e4c711c6f321..79ab2555b3b0 100644
--- a/include/linux/shmem_fs.h
+++ b/include/linux/shmem_fs.h
@@ -48,6 +48,7 @@ extern struct file *shmem_file_setup(const char *name,
loff_t size, unsigned long flags);
extern int shmem_zero_setup(struct vm_area_struct *);
extern int shmem_lock(struct file *file, int lock, struct user_struct *user);
+extern void shmem_unlock_mapping(struct address_space *mapping);
extern struct page *shmem_read_mapping_page_gfp(struct address_space *mapping,
pgoff_t index, gfp_t gfp_mask);
extern void shmem_truncate_range(struct inode *inode, loff_t start, loff_t end);
diff --git a/include/linux/snmp.h b/include/linux/snmp.h
index e16557a357e5..c1241c428179 100644
--- a/include/linux/snmp.h
+++ b/include/linux/snmp.h
@@ -192,7 +192,6 @@ enum
LINUX_MIB_TCPPARTIALUNDO, /* TCPPartialUndo */
LINUX_MIB_TCPDSACKUNDO, /* TCPDSACKUndo */
LINUX_MIB_TCPLOSSUNDO, /* TCPLossUndo */
- LINUX_MIB_TCPLOSS, /* TCPLoss */
LINUX_MIB_TCPLOSTRETRANSMIT, /* TCPLostRetransmit */
LINUX_MIB_TCPRENOFAILURES, /* TCPRenoFailures */
LINUX_MIB_TCPSACKFAILURES, /* TCPSackFailures */
diff --git a/include/linux/suspend.h b/include/linux/suspend.h
index 95040cc33107..91784a4f8608 100644
--- a/include/linux/suspend.h
+++ b/include/linux/suspend.h
@@ -357,14 +357,29 @@ extern bool pm_save_wakeup_count(unsigned int count);
static inline void lock_system_sleep(void)
{
- freezer_do_not_count();
+ current->flags |= PF_FREEZER_SKIP;
mutex_lock(&pm_mutex);
}
static inline void unlock_system_sleep(void)
{
+ /*
+ * Don't use freezer_count() because we don't want the call to
+ * try_to_freeze() here.
+ *
+ * Reason:
+ * Fundamentally, we just don't need it, because freezing condition
+ * doesn't come into effect until we release the pm_mutex lock,
+ * since the freezer always works with pm_mutex held.
+ *
+ * More importantly, in the case of hibernation,
+ * unlock_system_sleep() gets called in snapshot_read() and
+ * snapshot_write() when the freezing condition is still in effect.
+ * Which means, if we use try_to_freeze() here, it would make them
+ * enter the refrigerator, thus causing hibernation to lockup.
+ */
+ current->flags &= ~PF_FREEZER_SKIP;
mutex_unlock(&pm_mutex);
- freezer_count();
}
#else /* !CONFIG_PM_SLEEP */
diff --git a/include/linux/swap.h b/include/linux/swap.h
index 06061a7f8e69..3e60228e7299 100644
--- a/include/linux/swap.h
+++ b/include/linux/swap.h
@@ -273,7 +273,7 @@ static inline int zone_reclaim(struct zone *z, gfp_t mask, unsigned int order)
#endif
extern int page_evictable(struct page *page, struct vm_area_struct *vma);
-extern void scan_mapping_unevictable_pages(struct address_space *);
+extern void check_move_unevictable_pages(struct page **, int nr_pages);
extern unsigned long scan_unevictable_pages;
extern int scan_unevictable_handler(struct ctl_table *, int,
diff --git a/include/linux/thermal.h b/include/linux/thermal.h
index 47b4a27e6e97..796f1ff0388c 100644
--- a/include/linux/thermal.h
+++ b/include/linux/thermal.h
@@ -152,9 +152,9 @@ struct thermal_cooling_device *thermal_cooling_device_register(char *, void *,
void thermal_cooling_device_unregister(struct thermal_cooling_device *);
#ifdef CONFIG_NET
-extern int generate_netlink_event(u32 orig, enum events event);
+extern int thermal_generate_netlink_event(u32 orig, enum events event);
#else
-static inline int generate_netlink_event(u32 orig, enum events event)
+static inline int thermal_generate_netlink_event(u32 orig, enum events event)
{
return 0;
}
diff --git a/include/linux/usb.h b/include/linux/usb.h
index 27a4e16d2bf1..69d845739bc2 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -1073,6 +1073,7 @@ typedef void (*usb_complete_t)(struct urb *);
* which the host controller driver should use in preference to the
* transfer_buffer.
* @sg: scatter gather buffer list
+ * @num_mapped_sgs: (internal) number of mapped sg entries
* @num_sgs: number of entries in the sg list
* @transfer_buffer_length: How big is transfer_buffer. The transfer may
* be broken up into chunks according to the current maximum packet
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 5b2fed5eebf2..00596e816b4d 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -1388,6 +1388,6 @@ struct hci_inquiry_req {
};
#define IREQ_CACHE_FLUSH 0x0001
-extern int enable_hs;
+extern bool enable_hs;
#endif /* __HCI_H */
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 15f4be7d768e..a067d30ce73e 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1140,6 +1140,7 @@ struct cfg80211_disassoc_request {
* @bssid: Fixed BSSID requested, maybe be %NULL, if set do not
* search for IBSSs with a different BSSID.
* @channel: The channel to use if no IBSS can be found to join.
+ * @channel_type: channel type (HT mode)
* @channel_fixed: The channel should be fixed -- do not search for
* IBSSs to join on other channels.
* @ie: information element(s) to include in the beacon
@@ -1978,6 +1979,11 @@ struct wiphy_wowlan_support {
* configured as RX antennas. Antenna configuration commands will be
* rejected unless this or @available_antennas_tx is set.
*
+ * @probe_resp_offload:
+ * Bitmap of supported protocols for probe response offloading.
+ * See &enum nl80211_probe_resp_offload_support_attr. Only valid
+ * when the wiphy flag @WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD is set.
+ *
* @max_remain_on_channel_duration: Maximum time a remain-on-channel operation
* may request, if implemented.
*
diff --git a/include/net/netprio_cgroup.h b/include/net/netprio_cgroup.h
index e503b87c4c1b..7b2d43139c8e 100644
--- a/include/net/netprio_cgroup.h
+++ b/include/net/netprio_cgroup.h
@@ -13,7 +13,6 @@
#ifndef _NETPRIO_CGROUP_H
#define _NETPRIO_CGROUP_H
-#include <linux/module.h>
#include <linux/cgroup.h>
#include <linux/hardirq.h>
#include <linux/rcupdate.h>
diff --git a/include/net/sock.h b/include/net/sock.h
index bb972d254dff..4c69ac165e6b 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -226,6 +226,7 @@ struct cg_proto;
* @sk_ack_backlog: current listen backlog
* @sk_max_ack_backlog: listen backlog set in listen()
* @sk_priority: %SO_PRIORITY setting
+ * @sk_cgrp_prioidx: socket group's priority map index
* @sk_type: socket type (%SOCK_STREAM, etc)
* @sk_protocol: which protocol this socket belongs in this network family
* @sk_peer_pid: &struct pid for this socket's peer
@@ -921,7 +922,7 @@ inline void sk_refcnt_debug_release(const struct sock *sk)
#define sk_refcnt_debug_release(sk) do { } while (0)
#endif /* SOCK_REFCNT_DEBUG */
-#ifdef CONFIG_CGROUP_MEM_RES_CTLR_KMEM
+#if defined(CONFIG_CGROUP_MEM_RES_CTLR_KMEM) && defined(CONFIG_NET)
extern struct jump_label_key memcg_socket_limit_enabled;
static inline struct cg_proto *parent_cg_proto(struct proto *proto,
struct cg_proto *cg_proto)
@@ -1007,9 +1008,8 @@ static inline void memcg_memory_allocated_add(struct cg_proto *prot,
struct res_counter *fail;
int ret;
- ret = res_counter_charge(prot->memory_allocated,
- amt << PAGE_SHIFT, &fail);
-
+ ret = res_counter_charge_nofail(prot->memory_allocated,
+ amt << PAGE_SHIFT, &fail);
if (ret < 0)
*parent_status = OVER_LIMIT;
}
@@ -1053,12 +1053,11 @@ sk_memory_allocated_add(struct sock *sk, int amt, int *parent_status)
}
static inline void
-sk_memory_allocated_sub(struct sock *sk, int amt, int parent_status)
+sk_memory_allocated_sub(struct sock *sk, int amt)
{
struct proto *prot = sk->sk_prot;
- if (mem_cgroup_sockets_enabled && sk->sk_cgrp &&
- parent_status != OVER_LIMIT) /* Otherwise was uncharged already */
+ if (mem_cgroup_sockets_enabled && sk->sk_cgrp)
memcg_memory_allocated_sub(sk->sk_cgrp, amt);
atomic_long_sub(amt, prot->memory_allocated);
diff --git a/ipc/mqueue.c b/ipc/mqueue.c
index 9b7c8ab7d75c..86ee272de210 100644
--- a/ipc/mqueue.c
+++ b/ipc/mqueue.c
@@ -128,7 +128,6 @@ static struct inode *mqueue_get_inode(struct super_block *sb,
if (S_ISREG(mode)) {
struct mqueue_inode_info *info;
- struct task_struct *p = current;
unsigned long mq_bytes, mq_msg_tblsz;
inode->i_fop = &mqueue_file_operations;
@@ -159,7 +158,7 @@ static struct inode *mqueue_get_inode(struct super_block *sb,
spin_lock(&mq_lock);
if (u->mq_bytes + mq_bytes < u->mq_bytes ||
- u->mq_bytes + mq_bytes > task_rlimit(p, RLIMIT_MSGQUEUE)) {
+ u->mq_bytes + mq_bytes > rlimit(RLIMIT_MSGQUEUE)) {
spin_unlock(&mq_lock);
/* mqueue_evict_inode() releases info->messages */
ret = -EMFILE;
diff --git a/ipc/shm.c b/ipc/shm.c
index 02ecf2c078fc..b76be5bda6c2 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -870,9 +870,7 @@ SYSCALL_DEFINE3(shmctl, int, shmid, int, cmd, struct shmid_ds __user *, buf)
case SHM_LOCK:
case SHM_UNLOCK:
{
- struct file *uninitialized_var(shm_file);
-
- lru_add_drain_all(); /* drain pagevecs to lru lists */
+ struct file *shm_file;
shp = shm_lock_check(ns, shmid);
if (IS_ERR(shp)) {
@@ -895,22 +893,31 @@ SYSCALL_DEFINE3(shmctl, int, shmid, int, cmd, struct shmid_ds __user *, buf)
err = security_shm_shmctl(shp, cmd);
if (err)
goto out_unlock;
-
- if(cmd==SHM_LOCK) {
+
+ shm_file = shp->shm_file;
+ if (is_file_hugepages(shm_file))
+ goto out_unlock;
+
+ if (cmd == SHM_LOCK) {
struct user_struct *user = current_user();
- if (!is_file_hugepages(shp->shm_file)) {
- err = shmem_lock(shp->shm_file, 1, user);
- if (!err && !(shp->shm_perm.mode & SHM_LOCKED)){
- shp->shm_perm.mode |= SHM_LOCKED;
- shp->mlock_user = user;
- }
+ err = shmem_lock(shm_file, 1, user);
+ if (!err && !(shp->shm_perm.mode & SHM_LOCKED)) {
+ shp->shm_perm.mode |= SHM_LOCKED;
+ shp->mlock_user = user;
}
- } else if (!is_file_hugepages(shp->shm_file)) {
- shmem_lock(shp->shm_file, 0, shp->mlock_user);
- shp->shm_perm.mode &= ~SHM_LOCKED;
- shp->mlock_user = NULL;
+ goto out_unlock;
}
+
+ /* SHM_UNLOCK */
+ if (!(shp->shm_perm.mode & SHM_LOCKED))
+ goto out_unlock;
+ shmem_lock(shm_file, 0, shp->mlock_user);
+ shp->shm_perm.mode &= ~SHM_LOCKED;
+ shp->mlock_user = NULL;
+ get_file(shm_file);
shm_unlock(shp);
+ shmem_unlock_mapping(shm_file->f_mapping);
+ fput(shm_file);
goto out;
}
case IPC_RMID:
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index caaea6e944f8..af1de0f34eae 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -1863,11 +1863,12 @@ void __audit_syscall_entry(int arch, int major,
/**
* audit_syscall_exit - deallocate audit context after a system call
- * @pt_regs: syscall registers
+ * @success: success value of the syscall
+ * @return_code: return value of the syscall
*
* Tear down after system call. If the audit context has been marked as
* auditable (either because of the AUDIT_RECORD_CONTEXT state from
- * filtering, or because some other part of the kernel write an audit
+ * filtering, or because some other part of the kernel wrote an audit
* message), then write out the syscall information. In call cases,
* free the names stored from getname().
*/
diff --git a/kernel/kprobes.c b/kernel/kprobes.c
index 95dd7212e610..29f5b65bee29 100644
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
@@ -1077,6 +1077,7 @@ void __kprobes kprobe_flush_task(struct task_struct *tk)
/* Early boot. kretprobe_table_locks not yet initialized. */
return;
+ INIT_HLIST_HEAD(&empty_rp);
hash = hash_ptr(tk, KPROBE_HASH_BITS);
head = &kretprobe_inst_table[hash];
kretprobe_table_lock(hash, &flags);
@@ -1085,7 +1086,6 @@ void __kprobes kprobe_flush_task(struct task_struct *tk)
recycle_rp_inst(ri, &empty_rp);
}
kretprobe_table_unlock(hash, &flags);
- INIT_HLIST_HEAD(&empty_rp);
hlist_for_each_entry_safe(ri, node, tmp, &empty_rp, hlist) {
hlist_del(&ri->hlist);
kfree(ri);
diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c
index 1cf88900ec4f..6a768e537001 100644
--- a/kernel/power/snapshot.c
+++ b/kernel/power/snapshot.c
@@ -812,7 +812,8 @@ unsigned int snapshot_additional_pages(struct zone *zone)
unsigned int res;
res = DIV_ROUND_UP(zone->spanned_pages, BM_BITS_PER_BLOCK);
- res += DIV_ROUND_UP(res * sizeof(struct bm_block), PAGE_SIZE);
+ res += DIV_ROUND_UP(res * sizeof(struct bm_block),
+ LINKED_PAGE_DATA_SIZE);
return 2 * res;
}
diff --git a/kernel/rcutorture.c b/kernel/rcutorture.c
index 88f17b8a3b1d..a58ac285fc69 100644
--- a/kernel/rcutorture.c
+++ b/kernel/rcutorture.c
@@ -56,8 +56,8 @@ static int nreaders = -1; /* # reader threads, defaults to 2*ncpus */
static int nfakewriters = 4; /* # fake writer threads */
static int stat_interval; /* Interval between stats, in seconds. */
/* Defaults to "only at end of test". */
-static int verbose; /* Print more debug info. */
-static int test_no_idle_hz; /* Test RCU's support for tickless idle CPUs. */
+static bool verbose; /* Print more debug info. */
+static bool test_no_idle_hz; /* Test RCU's support for tickless idle CPUs. */
static int shuffle_interval = 3; /* Interval between shuffles (in sec)*/
static int stutter = 5; /* Start/stop testing interval (in sec) */
static int irqreader = 1; /* RCU readers from irq (timers). */
@@ -1399,7 +1399,7 @@ rcu_torture_shutdown(void *arg)
* Execute random CPU-hotplug operations at the interval specified
* by the onoff_interval.
*/
-static int
+static int __cpuinit
rcu_torture_onoff(void *arg)
{
int cpu;
@@ -1447,7 +1447,7 @@ rcu_torture_onoff(void *arg)
return 0;
}
-static int
+static int __cpuinit
rcu_torture_onoff_init(void)
{
if (onoff_interval <= 0)
diff --git a/kernel/res_counter.c b/kernel/res_counter.c
index 6d269cce7aa1..d508363858b3 100644
--- a/kernel/res_counter.c
+++ b/kernel/res_counter.c
@@ -66,6 +66,31 @@ done:
return ret;
}
+int res_counter_charge_nofail(struct res_counter *counter, unsigned long val,
+ struct res_counter **limit_fail_at)
+{
+ int ret, r;
+ unsigned long flags;
+ struct res_counter *c;
+
+ r = ret = 0;
+ *limit_fail_at = NULL;
+ local_irq_save(flags);
+ for (c = counter; c != NULL; c = c->parent) {
+ spin_lock(&c->lock);
+ r = res_counter_charge_locked(c, val);
+ if (r)
+ c->usage += val;
+ spin_unlock(&c->lock);
+ if (r < 0 && ret == 0) {
+ *limit_fail_at = c;
+ ret = r;
+ }
+ }
+ local_irq_restore(flags);
+
+ return ret;
+}
void res_counter_uncharge_locked(struct res_counter *counter, unsigned long val)
{
if (WARN_ON(counter->usage < val))
diff --git a/kernel/sched/cpupri.c b/kernel/sched/cpupri.c
index b0d798eaf130..d72586fdf660 100644
--- a/kernel/sched/cpupri.c
+++ b/kernel/sched/cpupri.c
@@ -129,7 +129,7 @@ int cpupri_find(struct cpupri *cp, struct task_struct *p,
* cpupri_set - update the cpu priority setting
* @cp: The cpupri context
* @cpu: The target cpu
- * @pri: The priority (INVALID-RT99) to assign to this CPU
+ * @newpri: The priority (INVALID-RT99) to assign to this CPU
*
* Note: Assumes cpu_rq(cpu)->lock is locked
*
@@ -200,7 +200,6 @@ void cpupri_set(struct cpupri *cp, int cpu, int newpri)
/**
* cpupri_init - initialize the cpupri structure
* @cp: The cpupri context
- * @bootmem: true if allocations need to use bootmem
*
* Returns: -ENOMEM if memory fails.
*/
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index ea8c3a4cd2ae..5f34bd8dda34 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -2508,6 +2508,7 @@ static int hugetlb_no_page(struct mm_struct *mm, struct vm_area_struct *vma,
{
struct hstate *h = hstate_vma(vma);
int ret = VM_FAULT_SIGBUS;
+ int anon_rmap = 0;
pgoff_t idx;
unsigned long size;
struct page *page;
@@ -2562,14 +2563,13 @@ retry:
spin_lock(&inode->i_lock);
inode->i_blocks += blocks_per_huge_page(h);
spin_unlock(&inode->i_lock);
- page_dup_rmap(page);
} else {
lock_page(page);
if (unlikely(anon_vma_prepare(vma))) {
ret = VM_FAULT_OOM;
goto backout_unlocked;
}
- hugepage_add_new_anon_rmap(page, vma, address);
+ anon_rmap = 1;
}
} else {
/*
@@ -2582,7 +2582,6 @@ retry:
VM_FAULT_SET_HINDEX(h - hstates);
goto backout_unlocked;
}
- page_dup_rmap(page);
}
/*
@@ -2606,6 +2605,10 @@ retry:
if (!huge_pte_none(huge_ptep_get(ptep)))
goto backout;
+ if (anon_rmap)
+ hugepage_add_new_anon_rmap(page, vma, address);
+ else
+ page_dup_rmap(page);
new_pte = make_huge_pte(vma, page, ((vma->vm_flags & VM_WRITE)
&& (vma->vm_flags & VM_SHARED)));
set_huge_pte_at(mm, address, ptep, new_pte);
diff --git a/mm/memblock.c b/mm/memblock.c
index 2f55f19b7c86..77b5f227e1d8 100644
--- a/mm/memblock.c
+++ b/mm/memblock.c
@@ -106,14 +106,17 @@ phys_addr_t __init_memblock memblock_find_in_range_node(phys_addr_t start,
if (end == MEMBLOCK_ALLOC_ACCESSIBLE)
end = memblock.current_limit;
- /* adjust @start to avoid underflow and allocating the first page */
- start = max3(start, size, (phys_addr_t)PAGE_SIZE);
+ /* avoid allocating the first page */
+ start = max_t(phys_addr_t, start, PAGE_SIZE);
end = max(start, end);
for_each_free_mem_range_reverse(i, nid, &this_start, &this_end, NULL) {
this_start = clamp(this_start, start, end);
this_end = clamp(this_end, start, end);
+ if (this_end < size)
+ continue;
+
cand = round_down(this_end - size, align);
if (cand >= this_start)
return cand;
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 3dbff4dcde35..556859fec4ef 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -379,7 +379,7 @@ static void mem_cgroup_put(struct mem_cgroup *memcg);
static bool mem_cgroup_is_root(struct mem_cgroup *memcg);
void sock_update_memcg(struct sock *sk)
{
- if (static_branch(&memcg_socket_limit_enabled)) {
+ if (mem_cgroup_sockets_enabled) {
struct mem_cgroup *memcg;
BUG_ON(!sk->sk_prot->proto_cgroup);
@@ -411,7 +411,7 @@ EXPORT_SYMBOL(sock_update_memcg);
void sock_release_memcg(struct sock *sk)
{
- if (static_branch(&memcg_socket_limit_enabled) && sk->sk_cgrp) {
+ if (mem_cgroup_sockets_enabled && sk->sk_cgrp) {
struct mem_cgroup *memcg;
WARN_ON(!sk->sk_cgrp->memcg);
memcg = sk->sk_cgrp->memcg;
@@ -3247,7 +3247,7 @@ int mem_cgroup_prepare_migration(struct page *page,
ctype = MEM_CGROUP_CHARGE_TYPE_CACHE;
else
ctype = MEM_CGROUP_CHARGE_TYPE_SHMEM;
- __mem_cgroup_commit_charge(memcg, page, 1, pc, ctype);
+ __mem_cgroup_commit_charge(memcg, newpage, 1, pc, ctype);
return ret;
}
diff --git a/mm/memory.c b/mm/memory.c
index 5e30583c2605..fa2f04e0337c 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -878,15 +878,24 @@ copy_one_pte(struct mm_struct *dst_mm, struct mm_struct *src_mm,
}
if (likely(!non_swap_entry(entry)))
rss[MM_SWAPENTS]++;
- else if (is_write_migration_entry(entry) &&
- is_cow_mapping(vm_flags)) {
- /*
- * COW mappings require pages in both parent
- * and child to be set to read.
- */
- make_migration_entry_read(&entry);
- pte = swp_entry_to_pte(entry);
- set_pte_at(src_mm, addr, src_pte, pte);
+ else if (is_migration_entry(entry)) {
+ page = migration_entry_to_page(entry);
+
+ if (PageAnon(page))
+ rss[MM_ANONPAGES]++;
+ else
+ rss[MM_FILEPAGES]++;
+
+ if (is_write_migration_entry(entry) &&
+ is_cow_mapping(vm_flags)) {
+ /*
+ * COW mappings require pages in both
+ * parent and child to be set to read.
+ */
+ make_migration_entry_read(&entry);
+ pte = swp_entry_to_pte(entry);
+ set_pte_at(src_mm, addr, src_pte, pte);
+ }
}
}
goto out_set_pte;
@@ -1191,6 +1200,16 @@ again:
if (!non_swap_entry(entry))
rss[MM_SWAPENTS]--;
+ else if (is_migration_entry(entry)) {
+ struct page *page;
+
+ page = migration_entry_to_page(entry);
+
+ if (PageAnon(page))
+ rss[MM_ANONPAGES]--;
+ else
+ rss[MM_FILEPAGES]--;
+ }
if (unlikely(!free_swap_and_cache(entry)))
print_bad_pte(vma, addr, ptent, NULL);
}
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 0027d8f4a1bb..d2186ecb36f7 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -5413,7 +5413,25 @@ __count_immobile_pages(struct zone *zone, struct page *page, int count)
bool is_pageblock_removable_nolock(struct page *page)
{
- struct zone *zone = page_zone(page);
+ struct zone *zone;
+ unsigned long pfn;
+
+ /*
+ * We have to be careful here because we are iterating over memory
+ * sections which are not zone aware so we might end up outside of
+ * the zone but still within the section.
+ * We have to take care about the node as well. If the node is offline
+ * its NODE_DATA will be NULL - see page_zone.
+ */
+ if (!node_online(page_to_nid(page)))
+ return false;
+
+ zone = page_zone(page);
+ pfn = page_to_pfn(page);
+ if (zone->zone_start_pfn > pfn ||
+ zone->zone_start_pfn + zone->spanned_pages <= pfn)
+ return false;
+
return __count_immobile_pages(zone, page, 0);
}
diff --git a/mm/shmem.c b/mm/shmem.c
index feead1943d92..269d049294ab 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -379,7 +379,7 @@ static int shmem_free_swap(struct address_space *mapping,
/*
* Pagevec may contain swap entries, so shuffle up pages before releasing.
*/
-static void shmem_pagevec_release(struct pagevec *pvec)
+static void shmem_deswap_pagevec(struct pagevec *pvec)
{
int i, j;
@@ -389,7 +389,36 @@ static void shmem_pagevec_release(struct pagevec *pvec)
pvec->pages[j++] = page;
}
pvec->nr = j;
- pagevec_release(pvec);
+}
+
+/*
+ * SysV IPC SHM_UNLOCK restore Unevictable pages to their evictable lists.
+ */
+void shmem_unlock_mapping(struct address_space *mapping)
+{
+ struct pagevec pvec;
+ pgoff_t indices[PAGEVEC_SIZE];
+ pgoff_t index = 0;
+
+ pagevec_init(&pvec, 0);
+ /*
+ * Minor point, but we might as well stop if someone else SHM_LOCKs it.
+ */
+ while (!mapping_unevictable(mapping)) {
+ /*
+ * Avoid pagevec_lookup(): find_get_pages() returns 0 as if it
+ * has finished, if it hits a row of PAGEVEC_SIZE swap entries.
+ */
+ pvec.nr = shmem_find_get_pages_and_swap(mapping, index,
+ PAGEVEC_SIZE, pvec.pages, indices);
+ if (!pvec.nr)
+ break;
+ index = indices[pvec.nr - 1] + 1;
+ shmem_deswap_pagevec(&pvec);
+ check_move_unevictable_pages(pvec.pages, pvec.nr);
+ pagevec_release(&pvec);
+ cond_resched();
+ }
}
/*
@@ -440,7 +469,8 @@ void shmem_truncate_range(struct inode *inode, loff_t lstart, loff_t lend)
}
unlock_page(page);
}
- shmem_pagevec_release(&pvec);
+ shmem_deswap_pagevec(&pvec);
+ pagevec_release(&pvec);
mem_cgroup_uncharge_end();
cond_resched();
index++;
@@ -470,7 +500,8 @@ void shmem_truncate_range(struct inode *inode, loff_t lstart, loff_t lend)
continue;
}
if (index == start && indices[0] > end) {
- shmem_pagevec_release(&pvec);
+ shmem_deswap_pagevec(&pvec);
+ pagevec_release(&pvec);
break;
}
mem_cgroup_uncharge_start();
@@ -494,7 +525,8 @@ void shmem_truncate_range(struct inode *inode, loff_t lstart, loff_t lend)
}
unlock_page(page);
}
- shmem_pagevec_release(&pvec);
+ shmem_deswap_pagevec(&pvec);
+ pagevec_release(&pvec);
mem_cgroup_uncharge_end();
index++;
}
@@ -1068,13 +1100,6 @@ int shmem_lock(struct file *file, int lock, struct user_struct *user)
user_shm_unlock(inode->i_size, user);
info->flags &= ~VM_LOCKED;
mapping_clear_unevictable(file->f_mapping);
- /*
- * Ensure that a racing putback_lru_page() can see
- * the pages of this mapping are evictable when we
- * skip them due to !PageLRU during the scan.
- */
- smp_mb__after_clear_bit();
- scan_mapping_unevictable_pages(file->f_mapping);
}
retval = 0;
@@ -2445,6 +2470,10 @@ int shmem_lock(struct file *file, int lock, struct user_struct *user)
return 0;
}
+void shmem_unlock_mapping(struct address_space *mapping)
+{
+}
+
void shmem_truncate_range(struct inode *inode, loff_t lstart, loff_t lend)
{
truncate_inode_pages_range(inode->i_mapping, lstart, lend);
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 2880396f7953..c52b23552659 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -26,7 +26,6 @@
#include <linux/buffer_head.h> /* for try_to_release_page(),
buffer_heads_over_limit */
#include <linux/mm_inline.h>
-#include <linux/pagevec.h>
#include <linux/backing-dev.h>
#include <linux/rmap.h>
#include <linux/topology.h>
@@ -661,7 +660,7 @@ redo:
* When racing with an mlock or AS_UNEVICTABLE clearing
* (page is unlocked) make sure that if the other thread
* does not observe our setting of PG_lru and fails
- * isolation/check_move_unevictable_page,
+ * isolation/check_move_unevictable_pages,
* we see PG_mlocked/AS_UNEVICTABLE cleared below and move
* the page back to the evictable list.
*
@@ -3499,100 +3498,61 @@ int page_evictable(struct page *page, struct vm_area_struct *vma)
return 1;
}
+#ifdef CONFIG_SHMEM
/**
- * check_move_unevictable_page - check page for evictability and move to appropriate zone lru list
- * @page: page to check evictability and move to appropriate lru list
- * @zone: zone page is in
+ * check_move_unevictable_pages - check pages for evictability and move to appropriate zone lru list
+ * @pages: array of pages to check
+ * @nr_pages: number of pages to check
*
- * Checks a page for evictability and moves the page to the appropriate
- * zone lru list.
+ * Checks pages for evictability and moves them to the appropriate lru list.
*
- * Restrictions: zone->lru_lock must be held, page must be on LRU and must
- * have PageUnevictable set.
+ * This function is only used for SysV IPC SHM_UNLOCK.
*/
-static void check_move_unevictable_page(struct page *page, struct zone *zone)
+void check_move_unevictable_pages(struct page **pages, int nr_pages)
{
struct lruvec *lruvec;
+ struct zone *zone = NULL;
+ int pgscanned = 0;
+ int pgrescued = 0;
+ int i;
- VM_BUG_ON(PageActive(page));
-retry:
- ClearPageUnevictable(page);
- if (page_evictable(page, NULL)) {
- enum lru_list l = page_lru_base_type(page);
-
- __dec_zone_state(zone, NR_UNEVICTABLE);
- lruvec = mem_cgroup_lru_move_lists(zone, page,
- LRU_UNEVICTABLE, l);
- list_move(&page->lru, &lruvec->lists[l]);
- __inc_zone_state(zone, NR_INACTIVE_ANON + l);
- __count_vm_event(UNEVICTABLE_PGRESCUED);
- } else {
- /*
- * rotate unevictable list
- */
- SetPageUnevictable(page);
- lruvec = mem_cgroup_lru_move_lists(zone, page, LRU_UNEVICTABLE,
- LRU_UNEVICTABLE);
- list_move(&page->lru, &lruvec->lists[LRU_UNEVICTABLE]);
- if (page_evictable(page, NULL))
- goto retry;
- }
-}
-
-/**
- * scan_mapping_unevictable_pages - scan an address space for evictable pages
- * @mapping: struct address_space to scan for evictable pages
- *
- * Scan all pages in mapping. Check unevictable pages for
- * evictability and move them to the appropriate zone lru list.
- */
-void scan_mapping_unevictable_pages(struct address_space *mapping)
-{
- pgoff_t next = 0;
- pgoff_t end = (i_size_read(mapping->host) + PAGE_CACHE_SIZE - 1) >>
- PAGE_CACHE_SHIFT;
- struct zone *zone;
- struct pagevec pvec;
-
- if (mapping->nrpages == 0)
- return;
-
- pagevec_init(&pvec, 0);
- while (next < end &&
- pagevec_lookup(&pvec, mapping, next, PAGEVEC_SIZE)) {
- int i;
- int pg_scanned = 0;
-
- zone = NULL;
-
- for (i = 0; i < pagevec_count(&pvec); i++) {
- struct page *page = pvec.pages[i];
- pgoff_t page_index = page->index;
- struct zone *pagezone = page_zone(page);
+ for (i = 0; i < nr_pages; i++) {
+ struct page *page = pages[i];
+ struct zone *pagezone;
- pg_scanned++;
- if (page_index > next)
- next = page_index;
- next++;
+ pgscanned++;
+ pagezone = page_zone(page);
+ if (pagezone != zone) {
+ if (zone)
+ spin_unlock_irq(&zone->lru_lock);
+ zone = pagezone;
+ spin_lock_irq(&zone->lru_lock);
+ }
- if (pagezone != zone) {
- if (zone)
- spin_unlock_irq(&zone->lru_lock);
- zone = pagezone;
- spin_lock_irq(&zone->lru_lock);
- }
+ if (!PageLRU(page) || !PageUnevictable(page))
+ continue;
- if (PageLRU(page) && PageUnevictable(page))
- check_move_unevictable_page(page, zone);
+ if (page_evictable(page, NULL)) {
+ enum lru_list lru = page_lru_base_type(page);
+
+ VM_BUG_ON(PageActive(page));
+ ClearPageUnevictable(page);
+ __dec_zone_state(zone, NR_UNEVICTABLE);
+ lruvec = mem_cgroup_lru_move_lists(zone, page,
+ LRU_UNEVICTABLE, lru);
+ list_move(&page->lru, &lruvec->lists[lru]);
+ __inc_zone_state(zone, NR_INACTIVE_ANON + lru);
+ pgrescued++;
}
- if (zone)
- spin_unlock_irq(&zone->lru_lock);
- pagevec_release(&pvec);
-
- count_vm_events(UNEVICTABLE_PGSCANNED, pg_scanned);
}
+ if (zone) {
+ __count_vm_events(UNEVICTABLE_PGRESCUED, pgrescued);
+ __count_vm_events(UNEVICTABLE_PGSCANNED, pgscanned);
+ spin_unlock_irq(&zone->lru_lock);
+ }
}
+#endif /* CONFIG_SHMEM */
static void warn_scan_unevictable_pages(void)
{
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 845da3ee56a0..9de93714213a 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -55,7 +55,7 @@
#define AUTO_OFF_TIMEOUT 2000
-int enable_hs;
+bool enable_hs;
static void hci_rx_work(struct work_struct *work);
static void hci_cmd_work(struct work_struct *work);
diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index 921aa2b4b415..369b41894527 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -1311,6 +1311,7 @@ int dev_ethtool(struct net *net, struct ifreq *ifr)
case ETHTOOL_GRXCSUM:
case ETHTOOL_GTXCSUM:
case ETHTOOL_GSG:
+ case ETHTOOL_GSSET_INFO:
case ETHTOOL_GSTRINGS:
case ETHTOOL_GTSO:
case ETHTOOL_GPERMADDR:
diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c
index 0985b9b14b80..a225089df5b6 100644
--- a/net/core/flow_dissector.c
+++ b/net/core/flow_dissector.c
@@ -1,4 +1,5 @@
#include <linux/skbuff.h>
+#include <linux/export.h>
#include <linux/ip.h>
#include <linux/ipv6.h>
#include <linux/if_vlan.h>
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index 65f80c7b1656..4d8ce93cd503 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -767,8 +767,8 @@ done:
return i;
}
-static unsigned long num_arg(const char __user * user_buffer,
- unsigned long maxlen, unsigned long *num)
+static long num_arg(const char __user *user_buffer, unsigned long maxlen,
+ unsigned long *num)
{
int i;
*num = 0;
diff --git a/net/core/sock.c b/net/core/sock.c
index 5c5af9988f94..3e81fd2e3c75 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -1827,7 +1827,7 @@ suppress_allocation:
/* Alas. Undo changes. */
sk->sk_forward_alloc -= amt * SK_MEM_QUANTUM;
- sk_memory_allocated_sub(sk, amt, parent_status);
+ sk_memory_allocated_sub(sk, amt);
return 0;
}
@@ -1840,7 +1840,7 @@ EXPORT_SYMBOL(__sk_mem_schedule);
void __sk_mem_reclaim(struct sock *sk)
{
sk_memory_allocated_sub(sk,
- sk->sk_forward_alloc >> SK_MEM_QUANTUM_SHIFT, 0);
+ sk->sk_forward_alloc >> SK_MEM_QUANTUM_SHIFT);
sk->sk_forward_alloc &= SK_MEM_QUANTUM - 1;
if (sk_under_memory_pressure(sk) &&
diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c
index 3569d8ecaeac..6afc807ee2ad 100644
--- a/net/ipv4/proc.c
+++ b/net/ipv4/proc.c
@@ -216,7 +216,6 @@ static const struct snmp_mib snmp4_net_list[] = {
SNMP_MIB_ITEM("TCPPartialUndo", LINUX_MIB_TCPPARTIALUNDO),
SNMP_MIB_ITEM("TCPDSACKUndo", LINUX_MIB_TCPDSACKUNDO),
SNMP_MIB_ITEM("TCPLossUndo", LINUX_MIB_TCPLOSSUNDO),
- SNMP_MIB_ITEM("TCPLoss", LINUX_MIB_TCPLOSS),
SNMP_MIB_ITEM("TCPLostRetransmit", LINUX_MIB_TCPLOSTRETRANSMIT),
SNMP_MIB_ITEM("TCPRenoFailures", LINUX_MIB_TCPRENOFAILURES),
SNMP_MIB_ITEM("TCPSackFailures", LINUX_MIB_TCPSACKFAILURES),
diff --git a/net/ipv4/tcp_bic.c b/net/ipv4/tcp_bic.c
index 6187eb4d1dcf..f45e1c242440 100644
--- a/net/ipv4/tcp_bic.c
+++ b/net/ipv4/tcp_bic.c
@@ -63,7 +63,6 @@ static inline void bictcp_reset(struct bictcp *ca)
{
ca->cnt = 0;
ca->last_max_cwnd = 0;
- ca->loss_cwnd = 0;
ca->last_cwnd = 0;
ca->last_time = 0;
ca->epoch_start = 0;
@@ -72,7 +71,11 @@ static inline void bictcp_reset(struct bictcp *ca)
static void bictcp_init(struct sock *sk)
{
- bictcp_reset(inet_csk_ca(sk));
+ struct bictcp *ca = inet_csk_ca(sk);
+
+ bictcp_reset(ca);
+ ca->loss_cwnd = 0;
+
if (initial_ssthresh)
tcp_sk(sk)->snd_ssthresh = initial_ssthresh;
}
@@ -127,7 +130,7 @@ static inline void bictcp_update(struct bictcp *ca, u32 cwnd)
}
/* if in slow start or link utilization is very low */
- if (ca->loss_cwnd == 0) {
+ if (ca->last_max_cwnd == 0) {
if (ca->cnt > 20) /* increase cwnd 5% per RTT */
ca->cnt = 20;
}
@@ -185,7 +188,7 @@ static u32 bictcp_undo_cwnd(struct sock *sk)
{
const struct tcp_sock *tp = tcp_sk(sk);
const struct bictcp *ca = inet_csk_ca(sk);
- return max(tp->snd_cwnd, ca->last_max_cwnd);
+ return max(tp->snd_cwnd, ca->loss_cwnd);
}
static void bictcp_state(struct sock *sk, u8 new_state)
diff --git a/net/ipv4/tcp_cubic.c b/net/ipv4/tcp_cubic.c
index f376b05cca81..a9077f441cb2 100644
--- a/net/ipv4/tcp_cubic.c
+++ b/net/ipv4/tcp_cubic.c
@@ -107,7 +107,6 @@ static inline void bictcp_reset(struct bictcp *ca)
{
ca->cnt = 0;
ca->last_max_cwnd = 0;
- ca->loss_cwnd = 0;
ca->last_cwnd = 0;
ca->last_time = 0;
ca->bic_origin_point = 0;
@@ -142,7 +141,10 @@ static inline void bictcp_hystart_reset(struct sock *sk)
static void bictcp_init(struct sock *sk)
{
- bictcp_reset(inet_csk_ca(sk));
+ struct bictcp *ca = inet_csk_ca(sk);
+
+ bictcp_reset(ca);
+ ca->loss_cwnd = 0;
if (hystart)
bictcp_hystart_reset(sk);
@@ -275,7 +277,7 @@ static inline void bictcp_update(struct bictcp *ca, u32 cwnd)
* The initial growth of cubic function may be too conservative
* when the available bandwidth is still unknown.
*/
- if (ca->loss_cwnd == 0 && ca->cnt > 20)
+ if (ca->last_max_cwnd == 0 && ca->cnt > 20)
ca->cnt = 20; /* increase cwnd 5% per RTT */
/* TCP Friendly */
@@ -342,7 +344,7 @@ static u32 bictcp_undo_cwnd(struct sock *sk)
{
struct bictcp *ca = inet_csk_ca(sk);
- return max(tcp_sk(sk)->snd_cwnd, ca->last_max_cwnd);
+ return max(tcp_sk(sk)->snd_cwnd, ca->loss_cwnd);
}
static void bictcp_state(struct sock *sk, u8 new_state)
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 2877c3e09587..976034f82320 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -105,7 +105,6 @@ int sysctl_tcp_abc __read_mostly;
#define FLAG_SYN_ACKED 0x10 /* This ACK acknowledged SYN. */
#define FLAG_DATA_SACKED 0x20 /* New SACK. */
#define FLAG_ECE 0x40 /* ECE in this ACK */
-#define FLAG_DATA_LOST 0x80 /* SACK detected data lossage. */
#define FLAG_SLOWPATH 0x100 /* Do not skip RFC checks for window update.*/
#define FLAG_ONLY_ORIG_SACKED 0x200 /* SACKs only non-rexmit sent before RTO */
#define FLAG_SND_UNA_ADVANCED 0x400 /* Snd_una was changed (!= FLAG_DATA_ACKED) */
@@ -1040,13 +1039,11 @@ static void tcp_skb_mark_lost_uncond_verify(struct tcp_sock *tp,
* These 6 states form finite state machine, controlled by the following events:
* 1. New ACK (+SACK) arrives. (tcp_sacktag_write_queue())
* 2. Retransmission. (tcp_retransmit_skb(), tcp_xmit_retransmit_queue())
- * 3. Loss detection event of one of three flavors:
+ * 3. Loss detection event of two flavors:
* A. Scoreboard estimator decided the packet is lost.
* A'. Reno "three dupacks" marks head of queue lost.
- * A''. Its FACK modfication, head until snd.fack is lost.
- * B. SACK arrives sacking data transmitted after never retransmitted
- * hole was sent out.
- * C. SACK arrives sacking SND.NXT at the moment, when the
+ * A''. Its FACK modification, head until snd.fack is lost.
+ * B. SACK arrives sacking SND.NXT at the moment, when the
* segment was retransmitted.
* 4. D-SACK added new rule: D-SACK changes any tag to S.
*
@@ -1153,7 +1150,7 @@ static int tcp_is_sackblock_valid(struct tcp_sock *tp, int is_dsack,
}
/* Check for lost retransmit. This superb idea is borrowed from "ratehalving".
- * Event "C". Later note: FACK people cheated me again 8), we have to account
+ * Event "B". Later note: FACK people cheated me again 8), we have to account
* for reordering! Ugly, but should help.
*
* Search retransmitted skbs from write_queue that were sent when snd_nxt was
@@ -1844,10 +1841,6 @@ tcp_sacktag_write_queue(struct sock *sk, const struct sk_buff *ack_skb,
if (found_dup_sack && ((i + 1) == first_sack_index))
next_dup = &sp[i + 1];
- /* Event "B" in the comment above. */
- if (after(end_seq, tp->high_seq))
- state.flag |= FLAG_DATA_LOST;
-
/* Skip too early cached blocks */
while (tcp_sack_cache_ok(tp, cache) &&
!before(start_seq, cache->end_seq))
@@ -2515,8 +2508,11 @@ static void tcp_timeout_skbs(struct sock *sk)
tcp_verify_left_out(tp);
}
-/* Mark head of queue up as lost. With RFC3517 SACK, the packets is
- * is against sacked "cnt", otherwise it's against facked "cnt"
+/* Detect loss in event "A" above by marking head of queue up as lost.
+ * For FACK or non-SACK(Reno) senders, the first "packets" number of segments
+ * are considered lost. For RFC3517 SACK, a segment is considered lost if it
+ * has at least tp->reordering SACKed seqments above it; "packets" refers to
+ * the maximum SACKed segments to pass before reaching this limit.
*/
static void tcp_mark_head_lost(struct sock *sk, int packets, int mark_head)
{
@@ -2525,6 +2521,8 @@ static void tcp_mark_head_lost(struct sock *sk, int packets, int mark_head)
int cnt, oldcnt;
int err;
unsigned int mss;
+ /* Use SACK to deduce losses of new sequences sent during recovery */
+ const u32 loss_high = tcp_is_sack(tp) ? tp->snd_nxt : tp->high_seq;
WARN_ON(packets > tp->packets_out);
if (tp->lost_skb_hint) {
@@ -2546,7 +2544,7 @@ static void tcp_mark_head_lost(struct sock *sk, int packets, int mark_head)
tp->lost_skb_hint = skb;
tp->lost_cnt_hint = cnt;
- if (after(TCP_SKB_CB(skb)->end_seq, tp->high_seq))
+ if (after(TCP_SKB_CB(skb)->end_seq, loss_high))
break;
oldcnt = cnt;
@@ -3033,19 +3031,10 @@ static void tcp_fastretrans_alert(struct sock *sk, int pkts_acked,
if (tcp_check_sack_reneging(sk, flag))
return;
- /* C. Process data loss notification, provided it is valid. */
- if (tcp_is_fack(tp) && (flag & FLAG_DATA_LOST) &&
- before(tp->snd_una, tp->high_seq) &&
- icsk->icsk_ca_state != TCP_CA_Open &&
- tp->fackets_out > tp->reordering) {
- tcp_mark_head_lost(sk, tp->fackets_out - tp->reordering, 0);
- NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPLOSS);
- }
-
- /* D. Check consistency of the current state. */
+ /* C. Check consistency of the current state. */
tcp_verify_left_out(tp);
- /* E. Check state exit conditions. State can be terminated
+ /* D. Check state exit conditions. State can be terminated
* when high_seq is ACKed. */
if (icsk->icsk_ca_state == TCP_CA_Open) {
WARN_ON(tp->retrans_out != 0);
@@ -3077,7 +3066,7 @@ static void tcp_fastretrans_alert(struct sock *sk, int pkts_acked,
}
}
- /* F. Process state. */
+ /* E. Process state. */
switch (icsk->icsk_ca_state) {
case TCP_CA_Recovery:
if (!(flag & FLAG_SND_UNA_ADVANCED)) {
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 1eb4ad57670e..337ba4cca052 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -631,7 +631,7 @@ static void tcp_v4_send_reset(struct sock *sk, struct sk_buff *skb)
arg.iov[0].iov_len = sizeof(rep.th);
#ifdef CONFIG_TCP_MD5SIG
- key = sk ? tcp_v4_md5_do_lookup(sk, ip_hdr(skb)->daddr) : NULL;
+ key = sk ? tcp_v4_md5_do_lookup(sk, ip_hdr(skb)->saddr) : NULL;
if (key) {
rep.opt[0] = htonl((TCPOPT_NOP << 24) |
(TCPOPT_NOP << 16) |
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index a225d5ee3c2f..c02280a4d126 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -502,29 +502,31 @@ static void addrconf_forward_change(struct net *net, __s32 newf)
rcu_read_unlock();
}
-static int addrconf_fixup_forwarding(struct ctl_table *table, int *p, int old)
+static int addrconf_fixup_forwarding(struct ctl_table *table, int *p, int newf)
{
struct net *net;
+ int old;
+
+ if (!rtnl_trylock())
+ return restart_syscall();
net = (struct net *)table->extra2;
- if (p == &net->ipv6.devconf_dflt->forwarding)
- return 0;
+ old = *p;
+ *p = newf;
- if (!rtnl_trylock()) {
- /* Restore the original values before restarting */
- *p = old;
- return restart_syscall();
+ if (p == &net->ipv6.devconf_dflt->forwarding) {
+ rtnl_unlock();
+ return 0;
}
if (p == &net->ipv6.devconf_all->forwarding) {
- __s32 newf = net->ipv6.devconf_all->forwarding;
net->ipv6.devconf_dflt->forwarding = newf;
addrconf_forward_change(net, newf);
- } else if ((!*p) ^ (!old))
+ } else if ((!newf) ^ (!old))
dev_forward_change((struct inet6_dev *)table->extra1);
rtnl_unlock();
- if (*p)
+ if (newf)
rt6_purge_dflt_routers(net);
return 1;
}
@@ -4260,9 +4262,17 @@ int addrconf_sysctl_forward(ctl_table *ctl, int write,
int *valp = ctl->data;
int val = *valp;
loff_t pos = *ppos;
+ ctl_table lctl;
int ret;
- ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
+ /*
+ * ctl->data points to idev->cnf.forwarding, we should
+ * not modify it until we get the rtnl lock.
+ */
+ lctl = *ctl;
+ lctl.data = &val;
+
+ ret = proc_dointvec(&lctl, write, buffer, lenp, ppos);
if (write)
ret = addrconf_fixup_forwarding(ctl, valp, val);
@@ -4300,26 +4310,27 @@ static void addrconf_disable_change(struct net *net, __s32 newf)
rcu_read_unlock();
}
-static int addrconf_disable_ipv6(struct ctl_table *table, int *p, int old)
+static int addrconf_disable_ipv6(struct ctl_table *table, int *p, int newf)
{
struct net *net;
+ int old;
+
+ if (!rtnl_trylock())
+ return restart_syscall();
net = (struct net *)table->extra2;
+ old = *p;
+ *p = newf;
- if (p == &net->ipv6.devconf_dflt->disable_ipv6)
+ if (p == &net->ipv6.devconf_dflt->disable_ipv6) {
+ rtnl_unlock();
return 0;
-
- if (!rtnl_trylock()) {
- /* Restore the original values before restarting */
- *p = old;
- return restart_syscall();
}
if (p == &net->ipv6.devconf_all->disable_ipv6) {
- __s32 newf = net->ipv6.devconf_all->disable_ipv6;
net->ipv6.devconf_dflt->disable_ipv6 = newf;
addrconf_disable_change(net, newf);
- } else if ((!*p) ^ (!old))
+ } else if ((!newf) ^ (!old))
dev_disable_change((struct inet6_dev *)table->extra1);
rtnl_unlock();
@@ -4333,9 +4344,17 @@ int addrconf_sysctl_disable(ctl_table *ctl, int write,
int *valp = ctl->data;
int val = *valp;
loff_t pos = *ppos;
+ ctl_table lctl;
int ret;
- ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
+ /*
+ * ctl->data points to idev->cnf.disable_ipv6, we should
+ * not modify it until we get the rtnl lock.
+ */
+ lctl = *ctl;
+ lctl.data = &val;
+
+ ret = proc_dointvec(&lctl, write, buffer, lenp, ppos);
if (write)
ret = addrconf_disable_ipv6(ctl, valp, val);
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 906c7ca43542..3edd05ae4388 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -1083,7 +1083,7 @@ static void tcp_v6_send_reset(struct sock *sk, struct sk_buff *skb)
#ifdef CONFIG_TCP_MD5SIG
if (sk)
- key = tcp_v6_md5_do_lookup(sk, &ipv6_hdr(skb)->daddr);
+ key = tcp_v6_md5_do_lookup(sk, &ipv6_hdr(skb)->saddr);
#endif
if (th->ack)
diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c
index a18e6c3d36e3..b9bef2c75026 100644
--- a/net/llc/af_llc.c
+++ b/net/llc/af_llc.c
@@ -713,6 +713,7 @@ static int llc_ui_recvmsg(struct kiocb *iocb, struct socket *sock,
struct sk_buff *skb = NULL;
struct sock *sk = sock->sk;
struct llc_sock *llc = llc_sk(sk);
+ unsigned long cpu_flags;
size_t copied = 0;
u32 peek_seq = 0;
u32 *seq;
@@ -838,7 +839,9 @@ static int llc_ui_recvmsg(struct kiocb *iocb, struct socket *sock,
goto copy_uaddr;
if (!(flags & MSG_PEEK)) {
+ spin_lock_irqsave(&sk->sk_receive_queue.lock, cpu_flags);
sk_eat_skb(sk, skb, 0);
+ spin_unlock_irqrestore(&sk->sk_receive_queue.lock, cpu_flags);
*seq = 0;
}
@@ -859,7 +862,9 @@ copy_uaddr:
llc_cmsg_rcv(msg, skb);
if (!(flags & MSG_PEEK)) {
+ spin_lock_irqsave(&sk->sk_receive_queue.lock, cpu_flags);
sk_eat_skb(sk, skb, 0);
+ spin_unlock_irqrestore(&sk->sk_receive_queue.lock, cpu_flags);
*seq = 0;
}
diff --git a/net/mac80211/debugfs_key.c b/net/mac80211/debugfs_key.c
index 38e6101190d9..59edcd95a58d 100644
--- a/net/mac80211/debugfs_key.c
+++ b/net/mac80211/debugfs_key.c
@@ -225,9 +225,9 @@ KEY_OPS(key);
key, &key_##name##_ops);
void ieee80211_debugfs_key_add(struct ieee80211_key *key)
- {
+{
static int keycount;
- char buf[50];
+ char buf[100];
struct sta_info *sta;
if (!key->local->debugfs.keys)
@@ -244,7 +244,8 @@ void ieee80211_debugfs_key_add(struct ieee80211_key *key)
sta = key->sta;
if (sta) {
- sprintf(buf, "../../stations/%pM", sta->sta.addr);
+ sprintf(buf, "../../netdev:%s/stations/%pM",
+ sta->sdata->name, sta->sta.addr);
key->debugfs.stalink =
debugfs_create_symlink("station", key->debugfs.dir, buf);
}
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c
index 73abb7524b2c..54df1b2bafd2 100644
--- a/net/mac80211/mesh_hwmp.c
+++ b/net/mac80211/mesh_hwmp.c
@@ -119,12 +119,12 @@ static int mesh_path_sel_frame_tx(enum mpath_frame_type action, u8 flags,
int hdr_len = offsetof(struct ieee80211_mgmt, u.action.u.mesh_action) +
sizeof(mgmt->u.action.u.mesh_action);
- skb = dev_alloc_skb(local->hw.extra_tx_headroom +
+ skb = dev_alloc_skb(local->tx_headroom +
hdr_len +
2 + 37); /* max HWMP IE */
if (!skb)
return -1;
- skb_reserve(skb, local->hw.extra_tx_headroom);
+ skb_reserve(skb, local->tx_headroom);
mgmt = (struct ieee80211_mgmt *) skb_put(skb, hdr_len);
memset(mgmt, 0, hdr_len);
mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
@@ -250,12 +250,12 @@ int mesh_path_error_tx(u8 ttl, u8 *target, __le32 target_sn,
if (time_before(jiffies, ifmsh->next_perr))
return -EAGAIN;
- skb = dev_alloc_skb(local->hw.extra_tx_headroom +
+ skb = dev_alloc_skb(local->tx_headroom +
hdr_len +
2 + 15 /* PERR IE */);
if (!skb)
return -1;
- skb_reserve(skb, local->tx_headroom + local->hw.extra_tx_headroom);
+ skb_reserve(skb, local->tx_headroom);
mgmt = (struct ieee80211_mgmt *) skb_put(skb, hdr_len);
memset(mgmt, 0, hdr_len);
mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index 41ef1b476442..a17251730b9e 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -172,7 +172,7 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
int hdr_len = offsetof(struct ieee80211_mgmt, u.action.u.self_prot) +
sizeof(mgmt->u.action.u.self_prot);
- skb = dev_alloc_skb(local->hw.extra_tx_headroom +
+ skb = dev_alloc_skb(local->tx_headroom +
hdr_len +
2 + /* capability info */
2 + /* AID */
@@ -186,7 +186,7 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
sdata->u.mesh.ie_len);
if (!skb)
return -1;
- skb_reserve(skb, local->hw.extra_tx_headroom);
+ skb_reserve(skb, local->tx_headroom);
mgmt = (struct ieee80211_mgmt *) skb_put(skb, hdr_len);
memset(mgmt, 0, hdr_len);
mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index ecb4c84c1bb3..295be92f7c77 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -2750,7 +2750,6 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
{
struct ieee80211_local *local = sdata->local;
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
- struct ieee80211_work *wk;
u8 bssid[ETH_ALEN];
bool assoc_bss = false;
@@ -2763,30 +2762,47 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
assoc_bss = true;
} else {
bool not_auth_yet = false;
+ struct ieee80211_work *tmp, *wk = NULL;
mutex_unlock(&ifmgd->mtx);
mutex_lock(&local->mtx);
- list_for_each_entry(wk, &local->work_list, list) {
- if (wk->sdata != sdata)
+ list_for_each_entry(tmp, &local->work_list, list) {
+ if (tmp->sdata != sdata)
continue;
- if (wk->type != IEEE80211_WORK_DIRECT_PROBE &&
- wk->type != IEEE80211_WORK_AUTH &&
- wk->type != IEEE80211_WORK_ASSOC &&
- wk->type != IEEE80211_WORK_ASSOC_BEACON_WAIT)
+ if (tmp->type != IEEE80211_WORK_DIRECT_PROBE &&
+ tmp->type != IEEE80211_WORK_AUTH &&
+ tmp->type != IEEE80211_WORK_ASSOC &&
+ tmp->type != IEEE80211_WORK_ASSOC_BEACON_WAIT)
continue;
- if (memcmp(req->bss->bssid, wk->filter_ta, ETH_ALEN))
+ if (memcmp(req->bss->bssid, tmp->filter_ta, ETH_ALEN))
continue;
- not_auth_yet = wk->type == IEEE80211_WORK_DIRECT_PROBE;
- list_del_rcu(&wk->list);
- free_work(wk);
+ not_auth_yet = tmp->type == IEEE80211_WORK_DIRECT_PROBE;
+ list_del_rcu(&tmp->list);
+ synchronize_rcu();
+ wk = tmp;
break;
}
mutex_unlock(&local->mtx);
+ if (wk && wk->type == IEEE80211_WORK_ASSOC) {
+ /* clean up dummy sta & TX sync */
+ sta_info_destroy_addr(wk->sdata, wk->filter_ta);
+ if (wk->assoc.synced)
+ drv_finish_tx_sync(local, wk->sdata,
+ wk->filter_ta,
+ IEEE80211_TX_SYNC_ASSOC);
+ } else if (wk && wk->type == IEEE80211_WORK_AUTH) {
+ if (wk->probe_auth.synced)
+ drv_finish_tx_sync(local, wk->sdata,
+ wk->filter_ta,
+ IEEE80211_TX_SYNC_AUTH);
+ }
+ kfree(wk);
+
/*
* If somebody requests authentication and we haven't
* sent out an auth frame yet there's no need to send
diff --git a/net/rds/af_rds.c b/net/rds/af_rds.c
index bb6ad81b671d..424ff622ab5f 100644
--- a/net/rds/af_rds.c
+++ b/net/rds/af_rds.c
@@ -68,7 +68,6 @@ static int rds_release(struct socket *sock)
{
struct sock *sk = sock->sk;
struct rds_sock *rs;
- unsigned long flags;
if (!sk)
goto out;
@@ -94,10 +93,10 @@ static int rds_release(struct socket *sock)
rds_rdma_drop_keys(rs);
rds_notify_queue_get(rs, NULL);
- spin_lock_irqsave(&rds_sock_lock, flags);
+ spin_lock_bh(&rds_sock_lock);
list_del_init(&rs->rs_item);
rds_sock_count--;
- spin_unlock_irqrestore(&rds_sock_lock, flags);
+ spin_unlock_bh(&rds_sock_lock);
rds_trans_put(rs->rs_transport);
@@ -409,7 +408,6 @@ static const struct proto_ops rds_proto_ops = {
static int __rds_create(struct socket *sock, struct sock *sk, int protocol)
{
- unsigned long flags;
struct rds_sock *rs;
sock_init_data(sock, sk);
@@ -426,10 +424,10 @@ static int __rds_create(struct socket *sock, struct sock *sk, int protocol)
spin_lock_init(&rs->rs_rdma_lock);
rs->rs_rdma_keys = RB_ROOT;
- spin_lock_irqsave(&rds_sock_lock, flags);
+ spin_lock_bh(&rds_sock_lock);
list_add_tail(&rs->rs_item, &rds_sock_list);
rds_sock_count++;
- spin_unlock_irqrestore(&rds_sock_lock, flags);
+ spin_unlock_bh(&rds_sock_lock);
return 0;
}
@@ -471,12 +469,11 @@ static void rds_sock_inc_info(struct socket *sock, unsigned int len,
{
struct rds_sock *rs;
struct rds_incoming *inc;
- unsigned long flags;
unsigned int total = 0;
len /= sizeof(struct rds_info_message);
- spin_lock_irqsave(&rds_sock_lock, flags);
+ spin_lock_bh(&rds_sock_lock);
list_for_each_entry(rs, &rds_sock_list, rs_item) {
read_lock(&rs->rs_recv_lock);
@@ -492,7 +489,7 @@ static void rds_sock_inc_info(struct socket *sock, unsigned int len,
read_unlock(&rs->rs_recv_lock);
}
- spin_unlock_irqrestore(&rds_sock_lock, flags);
+ spin_unlock_bh(&rds_sock_lock);
lens->nr = total;
lens->each = sizeof(struct rds_info_message);
@@ -504,11 +501,10 @@ static void rds_sock_info(struct socket *sock, unsigned int len,
{
struct rds_info_socket sinfo;
struct rds_sock *rs;
- unsigned long flags;
len /= sizeof(struct rds_info_socket);
- spin_lock_irqsave(&rds_sock_lock, flags);
+ spin_lock_bh(&rds_sock_lock);
if (len < rds_sock_count)
goto out;
@@ -529,7 +525,7 @@ out:
lens->nr = rds_sock_count;
lens->each = sizeof(struct rds_info_socket);
- spin_unlock_irqrestore(&rds_sock_lock, flags);
+ spin_unlock_bh(&rds_sock_lock);
}
static void rds_exit(void)
diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c
index e7e1d0b57b3d..2776012132ea 100644
--- a/net/sched/sch_netem.c
+++ b/net/sched/sch_netem.c
@@ -419,7 +419,7 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch)
cb = netem_skb_cb(skb);
if (q->gap == 0 || /* not doing reordering */
- q->counter < q->gap || /* inside last reordering gap */
+ q->counter < q->gap - 1 || /* inside last reordering gap */
q->reorder < get_crandom(&q->reorder_cor)) {
psched_time_t now;
psched_tdiff_t delay;
diff --git a/scripts/kernel-doc b/scripts/kernel-doc
index d793001929cf..9b0c0b8b4ab4 100755
--- a/scripts/kernel-doc
+++ b/scripts/kernel-doc
@@ -5,7 +5,7 @@ use strict;
## Copyright (c) 1998 Michael Zucchi, All Rights Reserved ##
## Copyright (C) 2000, 1 Tim Waugh <twaugh@redhat.com> ##
## Copyright (C) 2001 Simon Huggins ##
-## Copyright (C) 2005-2010 Randy Dunlap ##
+## Copyright (C) 2005-2012 Randy Dunlap ##
## ##
## #define enhancements by Armin Kuster <akuster@mvista.com> ##
## Copyright (c) 2000 MontaVista Software, Inc. ##
@@ -1785,6 +1785,7 @@ sub dump_function($$) {
$prototype =~ s/__devinit +//;
$prototype =~ s/__init +//;
$prototype =~ s/__init_or_module +//;
+ $prototype =~ s/__must_check +//;
$prototype =~ s/^#\s*define\s+//; #ak added
$prototype =~ s/__attribute__\s*\(\([a-z,]*\)\)//;
diff --git a/security/keys/internal.h b/security/keys/internal.h
index c7a7caec4830..65647f825584 100644
--- a/security/keys/internal.h
+++ b/security/keys/internal.h
@@ -33,6 +33,7 @@
extern struct key_type key_type_dead;
extern struct key_type key_type_user;
+extern struct key_type key_type_logon;
/*****************************************************************************/
/*
diff --git a/security/keys/key.c b/security/keys/key.c
index 4f64c7267afb..7ada8019be1f 100644
--- a/security/keys/key.c
+++ b/security/keys/key.c
@@ -999,6 +999,7 @@ void __init key_init(void)
list_add_tail(&key_type_keyring.link, &key_types_list);
list_add_tail(&key_type_dead.link, &key_types_list);
list_add_tail(&key_type_user.link, &key_types_list);
+ list_add_tail(&key_type_logon.link, &key_types_list);
/* record the root user tracking */
rb_link_node(&root_key_user.node,
diff --git a/security/keys/user_defined.c b/security/keys/user_defined.c
index 2aee3c5a3b99..c7660a25a3e4 100644
--- a/security/keys/user_defined.c
+++ b/security/keys/user_defined.c
@@ -18,6 +18,8 @@
#include <asm/uaccess.h>
#include "internal.h"
+static int logon_vet_description(const char *desc);
+
/*
* user defined keys take an arbitrary string as the description and an
* arbitrary blob of data as the payload
@@ -36,6 +38,24 @@ struct key_type key_type_user = {
EXPORT_SYMBOL_GPL(key_type_user);
/*
+ * This key type is essentially the same as key_type_user, but it does
+ * not define a .read op. This is suitable for storing username and
+ * password pairs in the keyring that you do not want to be readable
+ * from userspace.
+ */
+struct key_type key_type_logon = {
+ .name = "logon",
+ .instantiate = user_instantiate,
+ .update = user_update,
+ .match = user_match,
+ .revoke = user_revoke,
+ .destroy = user_destroy,
+ .describe = user_describe,
+ .vet_description = logon_vet_description,
+};
+EXPORT_SYMBOL_GPL(key_type_logon);
+
+/*
* instantiate a user defined key
*/
int user_instantiate(struct key *key, const void *data, size_t datalen)
@@ -189,3 +209,20 @@ long user_read(const struct key *key, char __user *buffer, size_t buflen)
}
EXPORT_SYMBOL_GPL(user_read);
+
+/* Vet the description for a "logon" key */
+static int logon_vet_description(const char *desc)
+{
+ char *p;
+
+ /* require a "qualified" description string */
+ p = strchr(desc, ':');
+ if (!p)
+ return -EINVAL;
+
+ /* also reject description with ':' as first char */
+ if (p == desc)
+ return -EINVAL;
+
+ return 0;
+}
diff --git a/sound/pci/hda/alc880_quirks.c b/sound/pci/hda/alc880_quirks.c
index 5b68435d195b..501501ef36a9 100644
--- a/sound/pci/hda/alc880_quirks.c
+++ b/sound/pci/hda/alc880_quirks.c
@@ -762,16 +762,22 @@ static void alc880_uniwill_unsol_event(struct hda_codec *codec,
/* Looks like the unsol event is incompatible with the standard
* definition. 4bit tag is placed at 28 bit!
*/
- switch (res >> 28) {
+ res >>= 28;
+ switch (res) {
case ALC_MIC_EVENT:
alc88x_simple_mic_automute(codec);
break;
default:
- alc_sku_unsol_event(codec, res);
+ alc_exec_unsol_event(codec, res);
break;
}
}
+static void alc880_unsol_event(struct hda_codec *codec, unsigned int res)
+{
+ alc_exec_unsol_event(codec, res >> 28);
+}
+
static void alc880_uniwill_p53_setup(struct hda_codec *codec)
{
struct alc_spec *spec = codec->spec;
@@ -800,10 +806,11 @@ static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
/* Looks like the unsol event is incompatible with the standard
* definition. 4bit tag is placed at 28 bit!
*/
- if ((res >> 28) == ALC_DCVOL_EVENT)
+ res >>= 28;
+ if (res == ALC_DCVOL_EVENT)
alc880_uniwill_p53_dcvol_automute(codec);
else
- alc_sku_unsol_event(codec, res);
+ alc_exec_unsol_event(codec, res);
}
/*
@@ -1677,7 +1684,7 @@ static const struct alc_config_preset alc880_presets[] = {
.channel_mode = alc880_lg_ch_modes,
.need_dac_fix = 1,
.input_mux = &alc880_lg_capture_source,
- .unsol_event = alc_sku_unsol_event,
+ .unsol_event = alc880_unsol_event,
.setup = alc880_lg_setup,
.init_hook = alc_hp_automute,
#ifdef CONFIG_SND_HDA_POWER_SAVE
diff --git a/sound/pci/hda/alc882_quirks.c b/sound/pci/hda/alc882_quirks.c
index bdf0ed4ab3e2..bb364a53f546 100644
--- a/sound/pci/hda/alc882_quirks.c
+++ b/sound/pci/hda/alc882_quirks.c
@@ -730,6 +730,11 @@ static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res)
alc889A_mb31_automute(codec);
}
+static void alc882_unsol_event(struct hda_codec *codec, unsigned int res)
+{
+ alc_exec_unsol_event(codec, res >> 26);
+}
+
/*
* configuration and preset
*/
@@ -775,7 +780,7 @@ static const struct alc_config_preset alc882_presets[] = {
.channel_mode = alc885_mba21_ch_modes,
.num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
.input_mux = &alc882_capture_source,
- .unsol_event = alc_sku_unsol_event,
+ .unsol_event = alc882_unsol_event,
.setup = alc885_mba21_setup,
.init_hook = alc_hp_automute,
},
@@ -791,7 +796,7 @@ static const struct alc_config_preset alc882_presets[] = {
.input_mux = &alc882_capture_source,
.dig_out_nid = ALC882_DIGOUT_NID,
.dig_in_nid = ALC882_DIGIN_NID,
- .unsol_event = alc_sku_unsol_event,
+ .unsol_event = alc882_unsol_event,
.setup = alc885_mbp3_setup,
.init_hook = alc_hp_automute,
},
@@ -806,7 +811,7 @@ static const struct alc_config_preset alc882_presets[] = {
.input_mux = &mb5_capture_source,
.dig_out_nid = ALC882_DIGOUT_NID,
.dig_in_nid = ALC882_DIGIN_NID,
- .unsol_event = alc_sku_unsol_event,
+ .unsol_event = alc882_unsol_event,
.setup = alc885_mb5_setup,
.init_hook = alc_hp_automute,
},
@@ -821,7 +826,7 @@ static const struct alc_config_preset alc882_presets[] = {
.input_mux = &macmini3_capture_source,
.dig_out_nid = ALC882_DIGOUT_NID,
.dig_in_nid = ALC882_DIGIN_NID,
- .unsol_event = alc_sku_unsol_event,
+ .unsol_event = alc882_unsol_event,
.setup = alc885_macmini3_setup,
.init_hook = alc_hp_automute,
},
@@ -836,7 +841,7 @@ static const struct alc_config_preset alc882_presets[] = {
.input_mux = &alc889A_imac91_capture_source,
.dig_out_nid = ALC882_DIGOUT_NID,
.dig_in_nid = ALC882_DIGIN_NID,
- .unsol_event = alc_sku_unsol_event,
+ .unsol_event = alc882_unsol_event,
.setup = alc885_imac91_setup,
.init_hook = alc_hp_automute,
},
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index fb35474c1203..95dfb6874941 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -469,6 +469,7 @@ struct azx {
unsigned int irq_pending_warned :1;
unsigned int probing :1; /* codec probing phase */
unsigned int snoop:1;
+ unsigned int align_buffer_size:1;
/* for debugging */
unsigned int last_cmd[AZX_MAX_CODECS];
@@ -1690,7 +1691,7 @@ static int azx_pcm_open(struct snd_pcm_substream *substream)
runtime->hw.rates = hinfo->rates;
snd_pcm_limit_hw_rates(runtime);
snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
- if (align_buffer_size)
+ if (chip->align_buffer_size)
/* constrain buffer sizes to be multiple of 128
bytes. This is more efficient in terms of memory
access but isn't required by the HDA spec and
@@ -2773,8 +2774,9 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
}
/* disable buffer size rounding to 128-byte multiples if supported */
+ chip->align_buffer_size = align_buffer_size;
if (chip->driver_caps & AZX_DCAPS_BUFSIZE)
- align_buffer_size = 0;
+ chip->align_buffer_size = 0;
/* allow 64bit DMA address if supported by H/W */
if ((gcap & ICH6_GCAP_64OK) && !pci_set_dma_mask(pci, DMA_BIT_MASK(64)))
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index 8a32a69c83c3..a7a5733aa4d2 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -3027,7 +3027,7 @@ static const struct snd_pci_quirk cxt5066_cfg_tbl[] = {
SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400s", CXT5066_THINKPAD),
SND_PCI_QUIRK(0x17aa, 0x21c5, "Thinkpad Edge 13", CXT5066_THINKPAD),
SND_PCI_QUIRK(0x17aa, 0x21c6, "Thinkpad Edge 13", CXT5066_ASUS),
- SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo Thinkpad", CXT5066_THINKPAD),
+ SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo T510", CXT5066_AUTO),
SND_PCI_QUIRK(0x17aa, 0x21cf, "Lenovo T520 & W520", CXT5066_AUTO),
SND_PCI_QUIRK(0x17aa, 0x21da, "Lenovo X220", CXT5066_THINKPAD),
SND_PCI_QUIRK(0x17aa, 0x21db, "Lenovo X220-tablet", CXT5066_THINKPAD),
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 5e82acf77c5a..c95c8bde12d0 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -185,7 +185,6 @@ struct alc_spec {
unsigned int vol_in_capsrc:1; /* use capsrc volume (ADC has no vol) */
unsigned int parse_flags; /* passed to snd_hda_parse_pin_defcfg() */
unsigned int shared_mic_hp:1; /* HP/Mic-in sharing */
- unsigned int use_jack_tbl:1; /* 1 for model=auto */
/* auto-mute control */
int automute_mode;
@@ -621,17 +620,10 @@ static void alc_mic_automute(struct hda_codec *codec)
alc_mux_select(codec, 0, spec->int_mic_idx, false);
}
-/* unsolicited event for HP jack sensing */
-static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
+/* handle the specified unsol action (ALC_XXX_EVENT) */
+static void alc_exec_unsol_event(struct hda_codec *codec, int action)
{
- struct alc_spec *spec = codec->spec;
- if (codec->vendor_id == 0x10ec0880)
- res >>= 28;
- else
- res >>= 26;
- if (spec->use_jack_tbl)
- res = snd_hda_jack_get_action(codec, res);
- switch (res) {
+ switch (action) {
case ALC_HP_EVENT:
alc_hp_automute(codec);
break;
@@ -645,6 +637,17 @@ static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
snd_hda_jack_report_sync(codec);
}
+/* unsolicited event for HP jack sensing */
+static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
+{
+ if (codec->vendor_id == 0x10ec0880)
+ res >>= 28;
+ else
+ res >>= 26;
+ res = snd_hda_jack_get_action(codec, res);
+ alc_exec_unsol_event(codec, res);
+}
+
/* call init functions of standard auto-mute helpers */
static void alc_inithook(struct hda_codec *codec)
{
@@ -1883,7 +1886,7 @@ static const struct snd_kcontrol_new alc_beep_mixer[] = {
};
#endif
-static int alc_build_controls(struct hda_codec *codec)
+static int __alc_build_controls(struct hda_codec *codec)
{
struct alc_spec *spec = codec->spec;
struct snd_kcontrol *kctl = NULL;
@@ -2029,11 +2032,16 @@ static int alc_build_controls(struct hda_codec *codec)
alc_free_kctls(codec); /* no longer needed */
- err = snd_hda_jack_add_kctls(codec, &spec->autocfg);
+ return 0;
+}
+
+static int alc_build_controls(struct hda_codec *codec)
+{
+ struct alc_spec *spec = codec->spec;
+ int err = __alc_build_controls(codec);
if (err < 0)
return err;
-
- return 0;
+ return snd_hda_jack_add_kctls(codec, &spec->autocfg);
}
@@ -3233,7 +3241,7 @@ static int alc_auto_create_multi_out_ctls(struct hda_codec *codec,
int i, err, noutputs;
noutputs = cfg->line_outs;
- if (spec->multi_ios > 0)
+ if (spec->multi_ios > 0 && cfg->line_outs < 3)
noutputs += spec->multi_ios;
for (i = 0; i < noutputs; i++) {
@@ -3904,7 +3912,6 @@ static void set_capture_mixer(struct hda_codec *codec)
static void alc_auto_init_std(struct hda_codec *codec)
{
struct alc_spec *spec = codec->spec;
- spec->use_jack_tbl = 1;
alc_auto_init_multi_out(codec);
alc_auto_init_extra_out(codec);
alc_auto_init_analog_input(codec);
@@ -4168,6 +4175,8 @@ static int patch_alc880(struct hda_codec *codec)
codec->patch_ops = alc_patch_ops;
if (board_config == ALC_MODEL_AUTO)
spec->init_hook = alc_auto_init_std;
+ else
+ codec->patch_ops.build_controls = __alc_build_controls;
#ifdef CONFIG_SND_HDA_POWER_SAVE
if (!spec->loopback.amplist)
spec->loopback.amplist = alc880_loopbacks;
@@ -4297,6 +4306,8 @@ static int patch_alc260(struct hda_codec *codec)
codec->patch_ops = alc_patch_ops;
if (board_config == ALC_MODEL_AUTO)
spec->init_hook = alc_auto_init_std;
+ else
+ codec->patch_ops.build_controls = __alc_build_controls;
spec->shutup = alc_eapd_shutup;
#ifdef CONFIG_SND_HDA_POWER_SAVE
if (!spec->loopback.amplist)
@@ -4691,6 +4702,8 @@ static int patch_alc882(struct hda_codec *codec)
codec->patch_ops = alc_patch_ops;
if (board_config == ALC_MODEL_AUTO)
spec->init_hook = alc_auto_init_std;
+ else
+ codec->patch_ops.build_controls = __alc_build_controls;
#ifdef CONFIG_SND_HDA_POWER_SAVE
if (!spec->loopback.amplist)
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 3556408d6ece..336cfcd324f9 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -1608,7 +1608,7 @@ static const struct snd_pci_quirk stac92hd73xx_codec_id_cfg_tbl[] = {
SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x043a,
"Alienware M17x", STAC_ALIENWARE_M17X),
SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0490,
- "Alienware M17x", STAC_ALIENWARE_M17X),
+ "Alienware M17x R3", STAC_DELL_EQ),
{} /* terminator */
};
@@ -4163,13 +4163,15 @@ static int enable_pin_detect(struct hda_codec *codec, hda_nid_t nid,
return 1;
}
-static int is_nid_hp_pin(struct auto_pin_cfg *cfg, hda_nid_t nid)
+static int is_nid_out_jack_pin(struct auto_pin_cfg *cfg, hda_nid_t nid)
{
int i;
for (i = 0; i < cfg->hp_outs; i++)
if (cfg->hp_pins[i] == nid)
return 1; /* nid is a HP-Out */
-
+ for (i = 0; i < cfg->line_outs; i++)
+ if (cfg->line_out_pins[i] == nid)
+ return 1; /* nid is a line-Out */
return 0; /* nid is not a HP-Out */
};
@@ -4375,7 +4377,7 @@ static int stac92xx_init(struct hda_codec *codec)
continue;
}
- if (is_nid_hp_pin(cfg, nid))
+ if (is_nid_out_jack_pin(cfg, nid))
continue; /* already has an unsol event */
pinctl = snd_hda_codec_read(codec, nid, 0,
diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c
index f8863ebb4304..7f4ba819a9f6 100644
--- a/sound/soc/codecs/sgtl5000.c
+++ b/sound/soc/codecs/sgtl5000.c
@@ -987,12 +987,12 @@ static int sgtl5000_restore_regs(struct snd_soc_codec *codec)
/* restore regular registers */
for (reg = 0; reg <= SGTL5000_CHIP_SHORT_CTRL; reg += 2) {
- /* this regs depends on the others */
+ /* These regs should restore in particular order */
if (reg == SGTL5000_CHIP_ANA_POWER ||
reg == SGTL5000_CHIP_CLK_CTRL ||
reg == SGTL5000_CHIP_LINREG_CTRL ||
reg == SGTL5000_CHIP_LINE_OUT_CTRL ||
- reg == SGTL5000_CHIP_CLK_CTRL)
+ reg == SGTL5000_CHIP_REF_CTRL)
continue;
snd_soc_write(codec, reg, cache[reg]);
@@ -1003,8 +1003,17 @@ static int sgtl5000_restore_regs(struct snd_soc_codec *codec)
snd_soc_write(codec, reg, cache[reg]);
/*
- * restore power and other regs according
- * to set_power() and set_clock()
+ * restore these regs according to the power setting sequence in
+ * sgtl5000_set_power_regs() and clock setting sequence in
+ * sgtl5000_set_clock().
+ *
+ * The order of restore is:
+ * 1. SGTL5000_CHIP_CLK_CTRL MCLK_FREQ bits (1:0) should be restore after
+ * SGTL5000_CHIP_ANA_POWER PLL bits set
+ * 2. SGTL5000_CHIP_LINREG_CTRL should be set before
+ * SGTL5000_CHIP_ANA_POWER LINREG_D restored
+ * 3. SGTL5000_CHIP_REF_CTRL controls Analog Ground Voltage,
+ * prefer to resotre it after SGTL5000_CHIP_ANA_POWER restored
*/
snd_soc_write(codec, SGTL5000_CHIP_LINREG_CTRL,
cache[SGTL5000_CHIP_LINREG_CTRL]);
diff --git a/sound/soc/codecs/tlv320aic32x4.c b/sound/soc/codecs/tlv320aic32x4.c
index eb401ef021fb..372b0b83bd9f 100644
--- a/sound/soc/codecs/tlv320aic32x4.c
+++ b/sound/soc/codecs/tlv320aic32x4.c
@@ -60,7 +60,6 @@ struct aic32x4_rate_divs {
struct aic32x4_priv {
u32 sysclk;
- s32 master;
u8 page_no;
void *control_data;
u32 power_cfg;
@@ -369,7 +368,6 @@ static int aic32x4_set_dai_sysclk(struct snd_soc_dai *codec_dai,
static int aic32x4_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
{
struct snd_soc_codec *codec = codec_dai->codec;
- struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec);
u8 iface_reg_1;
u8 iface_reg_2;
u8 iface_reg_3;
@@ -384,11 +382,9 @@ static int aic32x4_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
/* set master/slave audio interface */
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
case SND_SOC_DAIFMT_CBM_CFM:
- aic32x4->master = 1;
iface_reg_1 |= AIC32X4_BCLKMASTER | AIC32X4_WCLKMASTER;
break;
case SND_SOC_DAIFMT_CBS_CFS:
- aic32x4->master = 0;
break;
default:
printk(KERN_ERR "aic32x4: invalid DAI master/slave interface\n");
@@ -526,64 +522,58 @@ static int aic32x4_mute(struct snd_soc_dai *dai, int mute)
static int aic32x4_set_bias_level(struct snd_soc_codec *codec,
enum snd_soc_bias_level level)
{
- struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec);
-
switch (level) {
case SND_SOC_BIAS_ON:
- if (aic32x4->master) {
- /* Switch on PLL */
- snd_soc_update_bits(codec, AIC32X4_PLLPR,
- AIC32X4_PLLEN, AIC32X4_PLLEN);
-
- /* Switch on NDAC Divider */
- snd_soc_update_bits(codec, AIC32X4_NDAC,
- AIC32X4_NDACEN, AIC32X4_NDACEN);
-
- /* Switch on MDAC Divider */
- snd_soc_update_bits(codec, AIC32X4_MDAC,
- AIC32X4_MDACEN, AIC32X4_MDACEN);
-
- /* Switch on NADC Divider */
- snd_soc_update_bits(codec, AIC32X4_NADC,
- AIC32X4_NADCEN, AIC32X4_NADCEN);
-
- /* Switch on MADC Divider */
- snd_soc_update_bits(codec, AIC32X4_MADC,
- AIC32X4_MADCEN, AIC32X4_MADCEN);
-
- /* Switch on BCLK_N Divider */
- snd_soc_update_bits(codec, AIC32X4_BCLKN,
- AIC32X4_BCLKEN, AIC32X4_BCLKEN);
- }
+ /* Switch on PLL */
+ snd_soc_update_bits(codec, AIC32X4_PLLPR,
+ AIC32X4_PLLEN, AIC32X4_PLLEN);
+
+ /* Switch on NDAC Divider */
+ snd_soc_update_bits(codec, AIC32X4_NDAC,
+ AIC32X4_NDACEN, AIC32X4_NDACEN);
+
+ /* Switch on MDAC Divider */
+ snd_soc_update_bits(codec, AIC32X4_MDAC,
+ AIC32X4_MDACEN, AIC32X4_MDACEN);
+
+ /* Switch on NADC Divider */
+ snd_soc_update_bits(codec, AIC32X4_NADC,
+ AIC32X4_NADCEN, AIC32X4_NADCEN);
+
+ /* Switch on MADC Divider */
+ snd_soc_update_bits(codec, AIC32X4_MADC,
+ AIC32X4_MADCEN, AIC32X4_MADCEN);
+
+ /* Switch on BCLK_N Divider */
+ snd_soc_update_bits(codec, AIC32X4_BCLKN,
+ AIC32X4_BCLKEN, AIC32X4_BCLKEN);
break;
case SND_SOC_BIAS_PREPARE:
break;
case SND_SOC_BIAS_STANDBY:
- if (aic32x4->master) {
- /* Switch off PLL */
- snd_soc_update_bits(codec, AIC32X4_PLLPR,
- AIC32X4_PLLEN, 0);
-
- /* Switch off NDAC Divider */
- snd_soc_update_bits(codec, AIC32X4_NDAC,
- AIC32X4_NDACEN, 0);
-
- /* Switch off MDAC Divider */
- snd_soc_update_bits(codec, AIC32X4_MDAC,
- AIC32X4_MDACEN, 0);
-
- /* Switch off NADC Divider */
- snd_soc_update_bits(codec, AIC32X4_NADC,
- AIC32X4_NADCEN, 0);
-
- /* Switch off MADC Divider */
- snd_soc_update_bits(codec, AIC32X4_MADC,
- AIC32X4_MADCEN, 0);
-
- /* Switch off BCLK_N Divider */
- snd_soc_update_bits(codec, AIC32X4_BCLKN,
- AIC32X4_BCLKEN, 0);
- }
+ /* Switch off PLL */
+ snd_soc_update_bits(codec, AIC32X4_PLLPR,
+ AIC32X4_PLLEN, 0);
+
+ /* Switch off NDAC Divider */
+ snd_soc_update_bits(codec, AIC32X4_NDAC,
+ AIC32X4_NDACEN, 0);
+
+ /* Switch off MDAC Divider */
+ snd_soc_update_bits(codec, AIC32X4_MDAC,
+ AIC32X4_MDACEN, 0);
+
+ /* Switch off NADC Divider */
+ snd_soc_update_bits(codec, AIC32X4_NADC,
+ AIC32X4_NADCEN, 0);
+
+ /* Switch off MADC Divider */
+ snd_soc_update_bits(codec, AIC32X4_MADC,
+ AIC32X4_MADCEN, 0);
+
+ /* Switch off BCLK_N Divider */
+ snd_soc_update_bits(codec, AIC32X4_BCLKN,
+ AIC32X4_BCLKEN, 0);
break;
case SND_SOC_BIAS_OFF:
break;
@@ -651,9 +641,11 @@ static int aic32x4_probe(struct snd_soc_codec *codec)
if (aic32x4->power_cfg & AIC32X4_PWR_AVDD_DVDD_WEAK_DISABLE) {
snd_soc_write(codec, AIC32X4_PWRCFG, AIC32X4_AVDDWEAKDISABLE);
}
- if (aic32x4->power_cfg & AIC32X4_PWR_AIC32X4_LDO_ENABLE) {
- snd_soc_write(codec, AIC32X4_LDOCTL, AIC32X4_LDOCTLEN);
- }
+
+ tmp_reg = (aic32x4->power_cfg & AIC32X4_PWR_AIC32X4_LDO_ENABLE) ?
+ AIC32X4_LDOCTLEN : 0;
+ snd_soc_write(codec, AIC32X4_LDOCTL, tmp_reg);
+
tmp_reg = snd_soc_read(codec, AIC32X4_CMMODE);
if (aic32x4->power_cfg & AIC32X4_PWR_CMMODE_LDOIN_RANGE_18_36) {
tmp_reg |= AIC32X4_LDOIN_18_36;
diff --git a/sound/soc/codecs/wm2000.c b/sound/soc/codecs/wm2000.c
index c2880907fced..a75c3766aede 100644
--- a/sound/soc/codecs/wm2000.c
+++ b/sound/soc/codecs/wm2000.c
@@ -733,8 +733,9 @@ static int __devinit wm2000_i2c_probe(struct i2c_client *i2c,
struct wm2000_priv *wm2000;
struct wm2000_platform_data *pdata;
const char *filename;
- const struct firmware *fw;
- int reg, ret;
+ const struct firmware *fw = NULL;
+ int ret;
+ int reg;
u16 id;
wm2000 = devm_kzalloc(&i2c->dev, sizeof(struct wm2000_priv),
@@ -751,7 +752,7 @@ static int __devinit wm2000_i2c_probe(struct i2c_client *i2c,
ret = PTR_ERR(wm2000->regmap);
dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
ret);
- goto err;
+ goto out;
}
/* Verify that this is a WM2000 */
@@ -763,7 +764,7 @@ static int __devinit wm2000_i2c_probe(struct i2c_client *i2c,
if (id != 0x2000) {
dev_err(&i2c->dev, "Device is not a WM2000 - ID %x\n", id);
ret = -ENODEV;
- goto err_regmap;
+ goto out_regmap_exit;
}
reg = wm2000_read(i2c, WM2000_REG_REVISON);
@@ -782,7 +783,7 @@ static int __devinit wm2000_i2c_probe(struct i2c_client *i2c,
ret = request_firmware(&fw, filename, &i2c->dev);
if (ret != 0) {
dev_err(&i2c->dev, "Failed to acquire ANC data: %d\n", ret);
- goto err_regmap;
+ goto out_regmap_exit;
}
/* Pre-cook the concatenation of the register address onto the image */
@@ -793,15 +794,13 @@ static int __devinit wm2000_i2c_probe(struct i2c_client *i2c,
if (wm2000->anc_download == NULL) {
dev_err(&i2c->dev, "Out of memory\n");
ret = -ENOMEM;
- goto err_fw;
+ goto out_regmap_exit;
}
wm2000->anc_download[0] = 0x80;
wm2000->anc_download[1] = 0x00;
memcpy(wm2000->anc_download + 2, fw->data, fw->size);
- release_firmware(fw);
-
wm2000->anc_eng_ena = 1;
wm2000->anc_active = 1;
wm2000->spk_ena = 1;
@@ -809,18 +808,14 @@ static int __devinit wm2000_i2c_probe(struct i2c_client *i2c,
wm2000_reset(wm2000);
- ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm2000,
- NULL, 0);
- if (ret != 0)
- goto err_fw;
+ ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm2000, NULL, 0);
+ if (!ret)
+ goto out;
- return 0;
-
-err_fw:
- release_firmware(fw);
-err_regmap:
+out_regmap_exit:
regmap_exit(wm2000->regmap);
-err:
+out:
+ release_firmware(fw);
return ret;
}
diff --git a/sound/soc/codecs/wm5100.c b/sound/soc/codecs/wm5100.c
index 8b24323d6b2c..66f0611e68b6 100644
--- a/sound/soc/codecs/wm5100.c
+++ b/sound/soc/codecs/wm5100.c
@@ -1377,6 +1377,7 @@ static int wm5100_set_bias_level(struct snd_soc_codec *codec,
switch (wm5100->rev) {
case 0:
+ regcache_cache_bypass(wm5100->regmap, true);
snd_soc_write(codec, 0x11, 0x3);
snd_soc_write(codec, 0x203, 0xc);
snd_soc_write(codec, 0x206, 0);
@@ -1392,6 +1393,7 @@ static int wm5100_set_bias_level(struct snd_soc_codec *codec,
snd_soc_write(codec,
wm5100_reva_patches[i].reg,
wm5100_reva_patches[i].val);
+ regcache_cache_bypass(wm5100->regmap, false);
break;
default:
break;
@@ -1402,6 +1404,7 @@ static int wm5100_set_bias_level(struct snd_soc_codec *codec,
break;
case SND_SOC_BIAS_OFF:
+ regcache_cache_only(wm5100->regmap, true);
if (wm5100->pdata.ldo_ena)
gpio_set_value_cansleep(wm5100->pdata.ldo_ena, 0);
regulator_bulk_disable(ARRAY_SIZE(wm5100->core_supplies),
diff --git a/sound/soc/codecs/wm8958-dsp2.c b/sound/soc/codecs/wm8958-dsp2.c
index 8d4ea43d40a3..40ac888faf3d 100644
--- a/sound/soc/codecs/wm8958-dsp2.c
+++ b/sound/soc/codecs/wm8958-dsp2.c
@@ -55,7 +55,7 @@ static int wm8958_dsp2_fw(struct snd_soc_codec *codec, const char *name,
return 0;
if (fw->size < 32) {
- dev_err(codec->dev, "%s: firmware too short (%d bytes)\n",
+ dev_err(codec->dev, "%s: firmware too short (%zd bytes)\n",
name, fw->size);
goto err;
}
diff --git a/sound/soc/codecs/wm8996.c b/sound/soc/codecs/wm8996.c
index d8da10fe5b52..13aa2bdaa7d7 100644
--- a/sound/soc/codecs/wm8996.c
+++ b/sound/soc/codecs/wm8996.c
@@ -1120,7 +1120,8 @@ SND_SOC_DAPM_SUPPLY_S("SYSCLK", 1, WM8996_AIF_CLOCKING_1, 0, 0, NULL, 0),
SND_SOC_DAPM_SUPPLY_S("SYSDSPCLK", 2, WM8996_CLOCKING_1, 1, 0, NULL, 0),
SND_SOC_DAPM_SUPPLY_S("AIFCLK", 2, WM8996_CLOCKING_1, 2, 0, NULL, 0),
SND_SOC_DAPM_SUPPLY_S("Charge Pump", 2, WM8996_CHARGE_PUMP_1, 15, 0, cp_event,
- SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_POST_PMD),
SND_SOC_DAPM_SUPPLY("Bandgap", SND_SOC_NOPM, 0, 0, bg_event,
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
SND_SOC_DAPM_SUPPLY("LDO2", WM8996_POWER_MANAGEMENT_2, 1, 0, NULL, 0),
@@ -2007,6 +2008,7 @@ static int wm8996_set_sysclk(struct snd_soc_dai *dai,
struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
int lfclk = 0;
int ratediv = 0;
+ int sync = WM8996_REG_SYNC;
int src;
int old;
@@ -2051,6 +2053,7 @@ static int wm8996_set_sysclk(struct snd_soc_dai *dai,
case 32000:
case 32768:
lfclk = WM8996_LFCLK_ENA;
+ sync = 0;
break;
default:
dev_warn(codec->dev, "Unsupported clock rate %dHz\n",
@@ -2064,6 +2067,8 @@ static int wm8996_set_sysclk(struct snd_soc_dai *dai,
WM8996_SYSCLK_SRC_MASK | WM8996_SYSCLK_DIV_MASK,
src << WM8996_SYSCLK_SRC_SHIFT | ratediv);
snd_soc_update_bits(codec, WM8996_CLOCKING_1, WM8996_LFCLK_ENA, lfclk);
+ snd_soc_update_bits(codec, WM8996_CONTROL_INTERFACE_1,
+ WM8996_REG_SYNC, sync);
snd_soc_update_bits(codec, WM8996_AIF_CLOCKING_1,
WM8996_SYSCLK_ENA, old);
diff --git a/sound/soc/codecs/wm8996.h b/sound/soc/codecs/wm8996.h
index 0fde643194ce..de9ac3e44aec 100644
--- a/sound/soc/codecs/wm8996.h
+++ b/sound/soc/codecs/wm8996.h
@@ -1567,6 +1567,10 @@ int wm8996_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
/*
* R257 (0x101) - Control Interface (1)
*/
+#define WM8996_REG_SYNC 0x8000 /* REG_SYNC */
+#define WM8996_REG_SYNC_MASK 0x8000 /* REG_SYNC */
+#define WM8996_REG_SYNC_SHIFT 15 /* REG_SYNC */
+#define WM8996_REG_SYNC_WIDTH 1 /* REG_SYNC */
#define WM8996_AUTO_INC 0x0004 /* AUTO_INC */
#define WM8996_AUTO_INC_MASK 0x0004 /* AUTO_INC */
#define WM8996_AUTO_INC_SHIFT 2 /* AUTO_INC */
diff --git a/sound/soc/mxs/mxs-saif.c b/sound/soc/mxs/mxs-saif.c
index dccfb37a9626..f204dbac11d4 100644
--- a/sound/soc/mxs/mxs-saif.c
+++ b/sound/soc/mxs/mxs-saif.c
@@ -124,6 +124,8 @@ static int mxs_saif_set_clk(struct mxs_saif *saif,
*
* If MCLK is not used, we just set saif clk to 512*fs.
*/
+ clk_prepare_enable(master_saif->clk);
+
if (master_saif->mclk_in_use) {
if (mclk % 32 == 0) {
scr &= ~BM_SAIF_CTRL_BITCLK_BASE_RATE;
@@ -133,6 +135,7 @@ static int mxs_saif_set_clk(struct mxs_saif *saif,
ret = clk_set_rate(master_saif->clk, 384 * rate);
} else {
/* SAIF MCLK should be either 32x or 48x */
+ clk_disable_unprepare(master_saif->clk);
return -EINVAL;
}
} else {
@@ -140,6 +143,8 @@ static int mxs_saif_set_clk(struct mxs_saif *saif,
scr &= ~BM_SAIF_CTRL_BITCLK_BASE_RATE;
}
+ clk_disable_unprepare(master_saif->clk);
+
if (ret)
return ret;