]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
Merge tag 'sound-4.1-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 29 May 2015 17:43:27 +0000 (10:43 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 29 May 2015 17:43:27 +0000 (10:43 -0700)
Pull sound fixes from Takashi Iwai:
 "No big surprise here, just a bunch of small fixes for HD-audio and
  USB-audio:

   - partial revert of widget power-saving for IDT codecs
   - revert mute-LED enum ctl for Thinkpads due to confusion
   - a quirk for a new Radeon HDMI controller
   - Realtek codec name fix for Dell
   - a workaround for headphone mic boost on some laptops
   - stream_pm ops setup (and its fix for regression)
   - another quirk for MS LifeCam USB-audio"

* tag 'sound-4.1-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound:
  ALSA: hda - Fix lost sound due to stream_pm ops cleanup
  ALSA: hda - Disable Headphone Mic boost for ALC662
  ALSA: hda - Disable power_save_node for IDT92HD71bxx
  ALSA: hda - Fix noise on AMD radeon 290x controller
  ALSA: hda - Set stream_pm ops automatically by generic parser
  ALSA: hda/realtek - Add ALC256 alias name for Dell
  Revert "ALSA: hda - Add mute-LED mode control to Thinkpad"
  ALSA: usb-audio: Add quirk for MS LifeCam HD-3000

568 files changed:
Documentation/ABI/testing/sysfs-devices-system-cpu
Documentation/devicetree/bindings/clock/silabs,si5351.txt
Documentation/devicetree/bindings/mtd/jedec,spi-nor.txt [moved from Documentation/devicetree/bindings/mtd/m25p80.txt with 85% similarity]
Documentation/devicetree/bindings/net/cdns-emac.txt
Documentation/serial/tty.txt
Documentation/virtual/kvm/mmu.txt
MAINTAINERS
Makefile
arch/alpha/boot/Makefile
arch/alpha/boot/main.c
arch/alpha/boot/stdio.c [new file with mode: 0644]
arch/alpha/boot/tools/objstrip.c
arch/alpha/include/asm/types.h
arch/alpha/include/asm/unistd.h
arch/alpha/include/uapi/asm/unistd.h
arch/alpha/kernel/err_ev6.c
arch/alpha/kernel/irq.c
arch/alpha/kernel/osf_sys.c
arch/alpha/kernel/process.c
arch/alpha/kernel/smp.c
arch/alpha/kernel/srmcons.c
arch/alpha/kernel/sys_marvel.c
arch/alpha/kernel/systbls.S
arch/alpha/kernel/traps.c
arch/alpha/oprofile/op_model_ev4.c
arch/alpha/oprofile/op_model_ev5.c
arch/alpha/oprofile/op_model_ev6.c
arch/alpha/oprofile/op_model_ev67.c
arch/arc/Kconfig.debug
arch/arc/include/asm/atomic.h
arch/arc/mm/cache_arc700.c
arch/arm/boot/dts/armada-375.dtsi
arch/arm/boot/dts/armada-38x.dtsi
arch/arm/boot/dts/armada-39x.dtsi
arch/arm/boot/dts/dove-cubox.dts
arch/arm/boot/dts/exynos5420-peach-pit.dts
arch/arm/boot/dts/exynos5800-peach-pi.dts
arch/arm/boot/dts/tegra124.dtsi
arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts
arch/arm/boot/dts/vexpress-v2p-ca9.dts
arch/arm/boot/dts/zynq-7000.dtsi
arch/arm/mach-exynos/common.h
arch/arm/mach-exynos/exynos.c
arch/arm/mach-exynos/platsmp.c
arch/arm/mach-exynos/pm_domains.c
arch/arm/mach-exynos/suspend.c
arch/arm/mach-gemini/common.h
arch/arm/mach-gemini/reset.c
arch/arm/mach-omap2/omap_hwmod.c
arch/arm/mach-omap2/omap_hwmod_43xx_data.c
arch/arm/mach-omap2/prcm43xx.h
arch/arm/mach-omap2/prminst44xx.c
arch/arm/mach-omap2/timer.c
arch/arm/mach-rockchip/pm.c
arch/arm/mach-rockchip/pm.h
arch/arm/net/bpf_jit_32.c
arch/arm/xen/enlighten.c
arch/arm64/boot/dts/arm/juno-motherboard.dtsi
arch/arm64/crypto/crc32-arm64.c
arch/arm64/crypto/sha1-ce-glue.c
arch/arm64/crypto/sha2-ce-glue.c
arch/arm64/kernel/alternative.c
arch/arm64/kernel/perf_event.c
arch/arm64/mm/dump.c
arch/arm64/net/bpf_jit_comp.c
arch/mips/Makefile
arch/mips/include/asm/elf.h
arch/mips/include/asm/smp.h
arch/mips/kernel/elf.c
arch/mips/kernel/ptrace.c
arch/mips/kernel/smp-cps.c
arch/mips/kernel/smp.c
arch/mips/kernel/traps.c
arch/mips/kvm/emulate.c
arch/mips/math-emu/cp1emu.c
arch/mips/mm/tlb-r4k.c
arch/mips/sgi-ip32/ip32-platform.c
arch/parisc/include/asm/elf.h
arch/parisc/kernel/process.c
arch/parisc/kernel/sys_parisc.c
arch/powerpc/kernel/mce.c
arch/powerpc/kernel/vmlinux.lds.S
arch/powerpc/kvm/book3s_hv.c
arch/powerpc/mm/hugetlbpage.c
arch/powerpc/mm/pgtable_64.c
arch/s390/crypto/ghash_s390.c
arch/s390/crypto/prng.c
arch/s390/include/asm/pgtable.h
arch/s390/net/bpf_jit_comp.c
arch/x86/include/asm/kvm_host.h
arch/x86/kernel/cpu/mcheck/mce.c
arch/x86/kernel/cpu/perf_event_intel.c
arch/x86/kernel/cpu/perf_event_intel_rapl.c
arch/x86/kernel/i387.c
arch/x86/kvm/cpuid.c
arch/x86/kvm/cpuid.h
arch/x86/kvm/mmu.c
arch/x86/kvm/mmu.h
arch/x86/kvm/paging_tmpl.h
arch/x86/kvm/svm.c
arch/x86/kvm/vmx.c
arch/x86/kvm/x86.c
arch/x86/net/bpf_jit_comp.c
arch/x86/vdso/Makefile
arch/xtensa/include/asm/dma-mapping.h
block/blk-core.c
crypto/Kconfig
crypto/algif_aead.c
drivers/acpi/acpica/utglobal.c
drivers/acpi/osl.c
drivers/ata/Kconfig
drivers/ata/Makefile
drivers/ata/ahci.c
drivers/ata/ahci_st.c
drivers/ata/libahci.c
drivers/ata/libata-core.c
drivers/ata/libata-eh.c
drivers/ata/pata_scc.c [deleted file]
drivers/block/nvme-scsi.c
drivers/bluetooth/ath3k.c
drivers/bluetooth/bt3c_cs.c
drivers/bluetooth/btbcm.c
drivers/bluetooth/btbcm.h
drivers/bluetooth/btusb.c
drivers/bluetooth/hci_ath.c
drivers/clk/clk-si5351.c
drivers/clk/clk.c
drivers/clk/qcom/gcc-msm8916.c
drivers/clk/samsung/Makefile
drivers/clk/samsung/clk-exynos5420.c
drivers/clk/samsung/clk-exynos5433.c
drivers/extcon/extcon-usb-gpio.c
drivers/firmware/dmi_scan.c
drivers/gpio/gpio-kempld.c
drivers/gpio/gpiolib.c
drivers/gpu/drm/exynos/exynos7_drm_decon.c
drivers/gpu/drm/exynos/exynos_dp_core.c
drivers/gpu/drm/exynos/exynos_drm_crtc.c
drivers/gpu/drm/exynos/exynos_drm_crtc.h
drivers/gpu/drm/exynos/exynos_drm_drv.h
drivers/gpu/drm/exynos/exynos_drm_fb.c
drivers/gpu/drm/exynos/exynos_drm_fimd.c
drivers/gpu/drm/exynos/exynos_drm_fimd.h [deleted file]
drivers/gpu/drm/exynos/exynos_drm_plane.c
drivers/gpu/drm/exynos/exynos_drm_vidi.c
drivers/gpu/drm/exynos/exynos_mixer.c
drivers/gpu/drm/i915/i915_drv.c
drivers/gpu/drm/i915/intel_pm.c
drivers/gpu/drm/msm/adreno/adreno_gpu.c
drivers/gpu/drm/msm/dsi/dsi.c
drivers/gpu/drm/msm/dsi/dsi_host.c
drivers/gpu/drm/msm/dsi/dsi_manager.c
drivers/gpu/drm/msm/edp/edp_aux.c
drivers/gpu/drm/msm/edp/edp_connector.c
drivers/gpu/drm/msm/edp/edp_ctrl.c
drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c
drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.h
drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c
drivers/gpu/drm/msm/msm_drv.c
drivers/gpu/drm/msm/msm_fb.c
drivers/gpu/drm/msm/msm_gem.c
drivers/gpu/drm/msm/msm_iommu.c
drivers/gpu/drm/msm/msm_ringbuffer.c
drivers/gpu/drm/radeon/atombios_dp.c
drivers/gpu/drm/radeon/cik.c
drivers/gpu/drm/radeon/evergreen.c
drivers/gpu/drm/radeon/ni.c
drivers/gpu/drm/radeon/r600.c
drivers/gpu/drm/radeon/radeon_dp_auxch.c
drivers/gpu/drm/radeon/radeon_dp_mst.c
drivers/gpu/drm/radeon/rv770.c
drivers/gpu/drm/radeon/si.c
drivers/hid/hid-ids.h
drivers/hid/hid-logitech-hidpp.c
drivers/hid/hid-sensor-hub.c
drivers/hid/i2c-hid/i2c-hid.c
drivers/hid/usbhid/hid-quirks.c
drivers/hid/wacom_wac.c
drivers/ide/Kconfig
drivers/ide/Makefile
drivers/ide/scc_pata.c [deleted file]
drivers/iio/accel/mma9551_core.c
drivers/iio/accel/mma9553.c
drivers/iio/accel/st_accel_core.c
drivers/iio/adc/axp288_adc.c
drivers/iio/adc/cc10001_adc.c
drivers/iio/adc/mcp320x.c
drivers/iio/adc/qcom-spmi-vadc.c
drivers/iio/adc/xilinx-xadc-core.c
drivers/iio/adc/xilinx-xadc.h
drivers/iio/common/st_sensors/st_sensors_core.c
drivers/iio/gyro/st_gyro_core.c
drivers/iio/kfifo_buf.c
drivers/iio/light/hid-sensor-prox.c
drivers/iio/magnetometer/st_magn_core.c
drivers/iio/pressure/bmp280.c
drivers/iio/pressure/hid-sensor-press.c
drivers/iio/pressure/st_pressure_core.c
drivers/infiniband/core/cm.c
drivers/infiniband/core/cma.c
drivers/infiniband/core/iwpm_msg.c
drivers/infiniband/hw/cxgb4/cm.c
drivers/infiniband/hw/cxgb4/device.c
drivers/infiniband/hw/ehca/ehca_mcast.c
drivers/infiniband/hw/mlx4/main.c
drivers/infiniband/hw/mlx5/qp.c
drivers/infiniband/hw/ocrdma/ocrdma.h
drivers/infiniband/hw/ocrdma/ocrdma_ah.c
drivers/infiniband/hw/ocrdma/ocrdma_hw.c
drivers/infiniband/hw/ocrdma/ocrdma_sli.h
drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
drivers/infiniband/hw/qib/qib.h
drivers/infiniband/hw/qib/qib_wc_x86_64.c
drivers/input/joydev.c
drivers/input/mouse/Kconfig
drivers/input/mouse/alps.c
drivers/input/mouse/elantech.c
drivers/input/touchscreen/stmpe-ts.c
drivers/input/touchscreen/sx8654.c
drivers/iommu/amd_iommu_v2.c
drivers/iommu/arm-smmu.c
drivers/iommu/rockchip-iommu.c
drivers/irqchip/irq-gic-v3-its.c
drivers/irqchip/irq-tegra.c
drivers/lguest/core.c
drivers/md/bitmap.c
drivers/md/md.c
drivers/md/raid0.c
drivers/md/raid5.c
drivers/md/raid5.h
drivers/mfd/da9052-core.c
drivers/mmc/host/atmel-mci.c
drivers/mtd/devices/m25p80.c
drivers/mtd/tests/readtest.c
drivers/mtd/ubi/block.c
drivers/net/bonding/bond_options.c
drivers/net/can/xilinx_can.c
drivers/net/dsa/mv88e6xxx.c
drivers/net/ethernet/amd/Kconfig
drivers/net/ethernet/apm/xgene/Kconfig
drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
drivers/net/ethernet/cadence/macb.c
drivers/net/ethernet/cadence/macb.h
drivers/net/ethernet/ibm/emac/core.c
drivers/net/ethernet/ibm/emac/core.h
drivers/net/ethernet/intel/e1000e/e1000.h
drivers/net/ethernet/intel/fm10k/fm10k_main.c
drivers/net/ethernet/intel/igb/igb_main.c
drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
drivers/net/ethernet/mellanox/mlx4/cmd.c
drivers/net/ethernet/mellanox/mlx4/en_port.c
drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c
drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c
drivers/net/ethernet/qualcomm/qca_spi.c
drivers/net/ethernet/realtek/r8169.c
drivers/net/ethernet/rocker/rocker.c
drivers/net/ethernet/smsc/smc91x.c
drivers/net/ethernet/smsc/smsc911x.c
drivers/net/ethernet/stmicro/stmmac/stmmac.h
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
drivers/net/ethernet/xilinx/ll_temac_main.c
drivers/net/hyperv/netvsc.c
drivers/net/ieee802154/at86rf230.c
drivers/net/macvlan.c
drivers/net/phy/Kconfig
drivers/net/phy/amd-xgbe-phy.c
drivers/net/phy/bcm7xxx.c
drivers/net/phy/dp83640.c
drivers/net/phy/mdio-gpio.c
drivers/net/phy/micrel.c
drivers/net/phy/phy.c
drivers/net/ppp/pppoe.c
drivers/net/usb/cdc_ncm.c
drivers/net/usb/r8152.c
drivers/net/usb/usbnet.c
drivers/net/vxlan.c
drivers/net/wireless/ath/ath9k/xmit.c
drivers/net/wireless/iwlwifi/Kconfig
drivers/net/wireless/iwlwifi/iwl-7000.c
drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c
drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h
drivers/net/wireless/iwlwifi/iwl-fw-file.h
drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
drivers/net/wireless/iwlwifi/iwl-trans.h
drivers/net/wireless/iwlwifi/mvm/coex_legacy.c
drivers/net/wireless/iwlwifi/mvm/d3.c
drivers/net/wireless/iwlwifi/mvm/fw-api-power.h
drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h
drivers/net/wireless/iwlwifi/mvm/fw-api.h
drivers/net/wireless/iwlwifi/mvm/fw.c
drivers/net/wireless/iwlwifi/mvm/mac80211.c
drivers/net/wireless/iwlwifi/mvm/mvm.h
drivers/net/wireless/iwlwifi/mvm/ops.c
drivers/net/wireless/iwlwifi/mvm/rs.c
drivers/net/wireless/iwlwifi/mvm/rx.c
drivers/net/wireless/iwlwifi/mvm/scan.c
drivers/net/wireless/iwlwifi/pcie/trans.c
drivers/net/wireless/rtlwifi/usb.c
drivers/net/xen-netback/xenbus.c
drivers/net/xen-netfront.c
drivers/parisc/superio.c
drivers/pinctrl/bcm/pinctrl-cygnus-gpio.c
drivers/pinctrl/intel/pinctrl-cherryview.c
drivers/pinctrl/meson/pinctrl-meson.c
drivers/pinctrl/meson/pinctrl-meson8b.c
drivers/platform/x86/thinkpad_acpi.c
drivers/power/axp288_fuel_gauge.c
drivers/power/bq27x00_battery.c
drivers/power/collie_battery.c
drivers/power/reset/Kconfig
drivers/power/reset/at91-reset.c
drivers/power/reset/ltc2952-poweroff.c
drivers/pwm/pwm-img.c
drivers/regulator/da9052-regulator.c
drivers/rtc/rtc-armada38x.c
drivers/s390/crypto/ap_bus.c
drivers/scsi/be2iscsi/be.h
drivers/scsi/be2iscsi/be_cmds.c
drivers/scsi/be2iscsi/be_cmds.h
drivers/scsi/be2iscsi/be_iscsi.c
drivers/scsi/be2iscsi/be_iscsi.h
drivers/scsi/be2iscsi/be_main.c
drivers/scsi/be2iscsi/be_main.h
drivers/scsi/be2iscsi/be_mgmt.c
drivers/scsi/be2iscsi/be_mgmt.h
drivers/scsi/lpfc/lpfc_scsi.c
drivers/scsi/sd.c
drivers/scsi/storvsc_drv.c
drivers/spi/Kconfig
drivers/spi/spi-bcm2835.c
drivers/spi/spi-bitbang.c
drivers/spi/spi-fsl-cpm.c
drivers/spi/spi-fsl-espi.c
drivers/spi/spi-omap2-mcspi.c
drivers/spi/spi.c
drivers/ssb/driver_pcicore.c
drivers/staging/gdm724x/gdm_mux.c
drivers/staging/rtl8712/rtl871x_ioctl_linux.c
drivers/staging/sm750fb/sm750.c
drivers/staging/vt6655/card.c
drivers/staging/vt6655/card.h
drivers/staging/vt6655/device_main.c
drivers/staging/vt6656/rxtx.c
drivers/thermal/armada_thermal.c
drivers/thermal/intel_powerclamp.c
drivers/thermal/rockchip_thermal.c
drivers/thermal/thermal_core.h
drivers/thermal/ti-soc-thermal/dra752-thermal-data.c
drivers/thermal/ti-soc-thermal/omap5-thermal-data.c
drivers/thermal/ti-soc-thermal/ti-bandgap.c
drivers/thermal/ti-soc-thermal/ti-bandgap.h
drivers/tty/hvc/hvc_xen.c
drivers/tty/n_gsm.c
drivers/tty/n_hdlc.c
drivers/tty/n_tty.c
drivers/tty/pty.c
drivers/tty/serial/amba-pl011.c
drivers/tty/serial/earlycon.c
drivers/tty/serial/omap-serial.c
drivers/tty/tty_buffer.c
drivers/usb/chipidea/debug.c
drivers/usb/core/quirks.c
drivers/usb/dwc3/dwc3-omap.c
drivers/usb/gadget/configfs.c
drivers/usb/gadget/function/f_hid.c
drivers/usb/gadget/function/u_serial.c
drivers/usb/gadget/legacy/acm_ms.c
drivers/usb/gadget/legacy/audio.c
drivers/usb/gadget/legacy/cdc2.c
drivers/usb/gadget/legacy/dbgp.c
drivers/usb/gadget/legacy/ether.c
drivers/usb/gadget/legacy/g_ffs.c
drivers/usb/gadget/legacy/gmidi.c
drivers/usb/gadget/legacy/hid.c
drivers/usb/gadget/legacy/mass_storage.c
drivers/usb/gadget/legacy/multi.c
drivers/usb/gadget/legacy/ncm.c
drivers/usb/gadget/legacy/nokia.c
drivers/usb/gadget/legacy/printer.c
drivers/usb/gadget/legacy/serial.c
drivers/usb/gadget/legacy/tcm_usb_gadget.c
drivers/usb/gadget/legacy/webcam.c
drivers/usb/gadget/legacy/zero.c
drivers/usb/gadget/udc/at91_udc.c
drivers/usb/gadget/udc/atmel_usba_udc.c
drivers/usb/gadget/udc/fsl_udc_core.c
drivers/usb/gadget/udc/fusb300_udc.c
drivers/usb/gadget/udc/m66592-udc.c
drivers/usb/gadget/udc/r8a66597-udc.c
drivers/usb/gadget/udc/udc-xilinx.c
drivers/usb/host/xhci-ring.c
drivers/usb/host/xhci.h
drivers/usb/phy/phy-isp1301-omap.c
drivers/usb/serial/cp210x.c
drivers/usb/serial/pl2303.c
drivers/usb/serial/pl2303.h
drivers/usb/serial/visor.c
drivers/usb/storage/unusual_devs.h
drivers/video/backlight/pwm_bl.c
drivers/xen/events/events_base.c
fs/btrfs/backref.c
fs/btrfs/extent-tree.c
fs/btrfs/extent_io.c
fs/btrfs/free-space-cache.c
fs/btrfs/ordered-data.c
fs/btrfs/volumes.c
fs/cifs/cifs_dfs_ref.c
fs/cifs/cifs_unicode.c
fs/cifs/cifsfs.c
fs/cifs/cifsproto.h
fs/cifs/cifssmb.c
fs/cifs/connect.c
fs/cifs/dir.c
fs/cifs/file.c
fs/cifs/inode.c
fs/cifs/link.c
fs/cifs/readdir.c
fs/cifs/smb1ops.c
fs/cifs/smb2pdu.c
fs/exec.c
fs/ext4/ext4.h
fs/ext4/ext4_jbd2.c
fs/ext4/extents.c
fs/ext4/inode.c
fs/ext4/super.c
fs/hostfs/hostfs_kern.c
fs/jbd2/recovery.c
fs/jbd2/revoke.c
fs/jbd2/transaction.c
fs/kernfs/dir.c
fs/nfs/nfs4proc.c
fs/nfs/write.c
fs/nfsd/blocklayout.c
fs/nfsd/nfs4callback.c
fs/nfsd/nfs4state.c
fs/nfsd/state.h
fs/nfsd/xdr4.h
fs/overlayfs/copy_up.c
fs/overlayfs/dir.c
fs/overlayfs/super.c
include/drm/drm_pciids.h
include/linux/blkdev.h
include/linux/brcmphy.h
include/linux/gfp.h
include/linux/hid-sensor-hub.h
include/linux/ktime.h
include/linux/libata.h
include/linux/memcontrol.h
include/linux/netdevice.h
include/linux/platform_data/si5351.h
include/linux/rhashtable.h
include/linux/sched/rt.h
include/linux/skbuff.h
include/linux/tcp.h
include/linux/tty.h
include/linux/uidgid.h
include/net/cfg802154.h
include/net/codel.h
include/net/inet_connection_sock.h
include/net/mac80211.h
include/net/mac802154.h
include/net/sctp/sctp.h
include/net/tcp.h
include/uapi/linux/inet_diag.h
include/uapi/linux/mpls.h
include/uapi/linux/netfilter/nf_conntrack_tcp.h
include/uapi/linux/rtnetlink.h
include/uapi/linux/tcp.h
include/xen/events.h
kernel/events/core.c
kernel/locking/rtmutex.c
kernel/sched/core.c
kernel/time/hrtimer.c
kernel/watchdog.c
lib/rhashtable.c
mm/kmemleak.c
mm/mempolicy.c
mm/page_isolation.c
net/8021q/vlan.c
net/bluetooth/hci_core.c
net/bridge/br_multicast.c
net/bridge/br_netfilter.c
net/bridge/br_stp_timer.c
net/bridge/netfilter/ebtables.c
net/caif/caif_socket.c
net/ceph/osd_client.c
net/core/dev.c
net/core/ethtool.c
net/core/net_namespace.c
net/core/rtnetlink.c
net/core/sock.c
net/ieee802154/Makefile
net/ieee802154/nl-phy.c
net/ieee802154/nl802154.c
net/ieee802154/rdev-ops.h
net/ieee802154/trace.c [new file with mode: 0644]
net/ieee802154/trace.h [new file with mode: 0644]
net/ipv4/fib_trie.c
net/ipv4/inet_diag.c
net/ipv4/netfilter/arp_tables.c
net/ipv4/netfilter/ip_tables.c
net/ipv4/route.c
net/ipv4/tcp.c
net/ipv4/tcp_dctcp.c
net/ipv4/tcp_fastopen.c
net/ipv4/tcp_illinois.c
net/ipv4/tcp_input.c
net/ipv4/tcp_minisocks.c
net/ipv4/tcp_vegas.c
net/ipv4/tcp_vegas.h
net/ipv4/tcp_westwood.c
net/ipv6/ip6_fib.c
net/ipv6/ip6_output.c
net/ipv6/netfilter/ip6_tables.c
net/ipv6/route.c
net/ipv6/tcp_ipv6.c
net/ipv6/udp.c
net/mac80211/cfg.c
net/mac80211/ieee80211_i.h
net/mac80211/iface.c
net/mac80211/key.c
net/mac80211/key.h
net/mac80211/rx.c
net/mac80211/sta_info.c
net/mac80211/util.c
net/mac80211/wep.c
net/mac802154/cfg.c
net/mac802154/ieee802154_i.h
net/mac802154/iface.c
net/mac802154/llsec.c
net/mac802154/main.c
net/mpls/af_mpls.c
net/mpls/internal.h
net/netfilter/Kconfig
net/netfilter/ipvs/ip_vs_ctl.c
net/netfilter/nf_conntrack_proto_tcp.c
net/netfilter/nf_tables_api.c
net/netfilter/nfnetlink_log.c
net/netfilter/nfnetlink_queue_core.c
net/netlink/af_netlink.c
net/packet/af_packet.c
net/rds/connection.c
net/rds/ib_cm.c
net/rds/tcp_connect.c
net/rds/tcp_listen.c
net/sched/cls_api.c
net/sched/sch_api.c
net/sched/sch_codel.c
net/sched/sch_fq_codel.c
net/sched/sch_gred.c
net/sunrpc/auth_gss/gss_rpc_xdr.c
net/switchdev/switchdev.c
net/unix/af_unix.c
tools/lib/lockdep/Makefile
tools/lib/lockdep/uinclude/linux/kernel.h
tools/net/bpf_jit_disasm.c
tools/perf/Makefile
tools/testing/selftests/x86/Makefile
tools/testing/selftests/x86/check_cc.sh [new file with mode: 0755]
tools/testing/selftests/x86/run_x86_tests.sh [deleted file]
tools/testing/selftests/x86/trivial_32bit_program.c
tools/testing/selftests/x86/trivial_64bit_program.c [new file with mode: 0644]
tools/thermal/tmon/Makefile
tools/vm/Makefile

index 99983e67c13c9f6aadff74c1969a4d27cede7d26..da95513571ea3e3e53263f6c91588fb58d50f3fb 100644 (file)
@@ -162,7 +162,7 @@ Description:        Discover CPUs in the same CPU frequency coordination domain
 What:          /sys/devices/system/cpu/cpu*/cache/index3/cache_disable_{0,1}
 Date:          August 2008
 KernelVersion: 2.6.27
-Contact:       discuss@x86-64.org
+Contact:       Linux kernel mailing list <linux-kernel@vger.kernel.org>
 Description:   Disable L3 cache indices
 
                These files exist in every CPU's cache/index3 directory. Each
index c40711e8e8f7df7c27f74d1dcf418909a96bedf2..28b28309f53575e91752cba6453e5594ea985de3 100644 (file)
@@ -17,7 +17,8 @@ Required properties:
 - #clock-cells: from common clock binding; shall be set to 1.
 - clocks: from common clock binding; list of parent clock
   handles, shall be xtal reference clock or xtal and clkin for
-  si5351c only.
+  si5351c only. Corresponding clock input names are "xtal" and
+  "clkin" respectively.
 - #address-cells: shall be set to 1.
 - #size-cells: shall be set to 0.
 
@@ -71,6 +72,7 @@ i2c-master-node {
 
                /* connect xtal input to 25MHz reference */
                clocks = <&ref25>;
+               clock-names = "xtal";
 
                /* connect xtal input as source of pll0 and pll1 */
                silabs,pll-source = <0 0>, <1 0>;
similarity index 85%
rename from Documentation/devicetree/bindings/mtd/m25p80.txt
rename to Documentation/devicetree/bindings/mtd/jedec,spi-nor.txt
index f20b111b502a7cfd29e45765bfb25ba3c8bd8f95..2bee68103b0112ecc106edc25a74a33f69462cc8 100644 (file)
@@ -8,8 +8,8 @@ Required properties:
                is not Linux-only, but in case of Linux, see the "m25p_ids"
                table in drivers/mtd/devices/m25p80.c for the list of supported
                chips.
-               Must also include "nor-jedec" for any SPI NOR flash that can be
-               identified by the JEDEC READ ID opcode (0x9F).
+               Must also include "jedec,spi-nor" for any SPI NOR flash that can
+               be identified by the JEDEC READ ID opcode (0x9F).
 - reg : Chip-Select number
 - spi-max-frequency : Maximum frequency of the SPI bus the chip can operate at
 
@@ -25,7 +25,7 @@ Example:
        flash: m25p80@0 {
                #address-cells = <1>;
                #size-cells = <1>;
-               compatible = "spansion,m25p80", "nor-jedec";
+               compatible = "spansion,m25p80", "jedec,spi-nor";
                reg = <0>;
                spi-max-frequency = <40000000>;
                m25p,fast-read;
index abd67c13d3442228834e7df36a53a71454132160..4451ee9732239b50d8329339eb57662e639c24b4 100644 (file)
@@ -3,7 +3,8 @@
 Required properties:
 - compatible: Should be "cdns,[<chip>-]{emac}"
   Use "cdns,at91rm9200-emac" Atmel at91rm9200 SoC.
-  or the generic form: "cdns,emac".
+  Use "cdns,zynq-gem" Xilinx Zynq-7xxx SoC.
+  Or the generic form: "cdns,emac".
 - reg: Address and length of the register set for the device
 - interrupts: Should contain macb interrupt
 - phy-mode: see ethernet.txt file in the same directory.
index 1e52d67d0abf5c8ccb86b6aa5d1170f509d73132..dbe6623fed1c286bd49277486492b2960428eff6 100644 (file)
@@ -198,6 +198,9 @@ TTY_IO_ERROR                If set, causes all subsequent userspace read/write
 
 TTY_OTHER_CLOSED       Device is a pty and the other side has closed.
 
+TTY_OTHER_DONE         Device is a pty and the other side has closed and
+                       all pending input processing has been completed.
+
 TTY_NO_WRITE_SPLIT     Prevent driver from splitting up writes into
                        smaller chunks.
 
index 53838d9c6295792501f2825175ac9c314c1a2fc7..c59bd9bc41efa984cfd5f0e17ac5fd6156acfca6 100644 (file)
@@ -169,6 +169,10 @@ Shadow pages contain the following information:
     Contains the value of cr4.smep && !cr0.wp for which the page is valid
     (pages for which this is true are different from other pages; see the
     treatment of cr0.wp=0 below).
+  role.smap_andnot_wp:
+    Contains the value of cr4.smap && !cr0.wp for which the page is valid
+    (pages for which this is true are different from other pages; see the
+    treatment of cr0.wp=0 below).
   gfn:
     Either the guest page table containing the translations shadowed by this
     page, or the base page frame for linear translations.  See role.direct.
@@ -344,10 +348,16 @@ on fault type:
 
 (user write faults generate a #PF)
 
-In the first case there is an additional complication if CR4.SMEP is
-enabled: since we've turned the page into a kernel page, the kernel may now
-execute it.  We handle this by also setting spte.nx.  If we get a user
-fetch or read fault, we'll change spte.u=1 and spte.nx=gpte.nx back.
+In the first case there are two additional complications:
+- if CR4.SMEP is enabled: since we've turned the page into a kernel page,
+  the kernel may now execute it.  We handle this by also setting spte.nx.
+  If we get a user fetch or read fault, we'll change spte.u=1 and
+  spte.nx=gpte.nx back.
+- if CR4.SMAP is disabled: since the page has been changed to a kernel
+  page, it can not be reused when CR4.SMAP is enabled. We set
+  CR4.SMAP && !CR0.WP into shadow page's role to avoid this case. Note,
+  here we do not care the case that CR4.SMAP is enabled since KVM will
+  directly inject #PF to guest due to failed permission check.
 
 To prevent an spte that was converted into a kernel page with cr0.wp=0
 from being written by the kernel after cr0.wp has changed to 1, we make
index 590304b96b0324da9935e360a95ee4fbb005789c..474bcb6c0bac6976302641f1592e4d449451bd0b 100644 (file)
@@ -974,7 +974,7 @@ S:  Maintained
 ARM/CORTINA SYSTEMS GEMINI ARM ARCHITECTURE
 M:     Hans Ulli Kroll <ulli.kroll@googlemail.com>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
-T:     git git://git.berlios.de/gemini-board
+T:     git git://github.com/ulli-kroll/linux.git
 S:     Maintained
 F:     arch/arm/mach-gemini/
 
@@ -1193,7 +1193,7 @@ ARM/MAGICIAN MACHINE SUPPORT
 M:     Philipp Zabel <philipp.zabel@gmail.com>
 S:     Maintained
 
-ARM/Marvell Armada 370 and Armada XP SOC support
+ARM/Marvell Kirkwood and Armada 370, 375, 38x, XP SOC support
 M:     Jason Cooper <jason@lakedaemon.net>
 M:     Andrew Lunn <andrew@lunn.ch>
 M:     Gregory Clement <gregory.clement@free-electrons.com>
@@ -1202,12 +1202,17 @@ L:      linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:     Maintained
 F:     arch/arm/mach-mvebu/
 F:     drivers/rtc/rtc-armada38x.c
+F:     arch/arm/boot/dts/armada*
+F:     arch/arm/boot/dts/kirkwood*
+
 
 ARM/Marvell Berlin SoC support
 M:     Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:     Maintained
 F:     arch/arm/mach-berlin/
+F:     arch/arm/boot/dts/berlin*
+
 
 ARM/Marvell Dove/MV78xx0/Orion SOC support
 M:     Jason Cooper <jason@lakedaemon.net>
@@ -1220,6 +1225,9 @@ F:        arch/arm/mach-dove/
 F:     arch/arm/mach-mv78xx0/
 F:     arch/arm/mach-orion5x/
 F:     arch/arm/plat-orion/
+F:     arch/arm/boot/dts/dove*
+F:     arch/arm/boot/dts/orion5x*
+
 
 ARM/Orion SoC/Technologic Systems TS-78xx platform support
 M:     Alexander Clouter <alex@digriz.org.uk>
@@ -1371,6 +1379,7 @@ N:        rockchip
 
 ARM/SAMSUNG EXYNOS ARM ARCHITECTURES
 M:     Kukjin Kim <kgene@kernel.org>
+M:     Krzysztof Kozlowski <k.kozlowski@samsung.com>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 L:     linux-samsung-soc@vger.kernel.org (moderated for non-subscribers)
 S:     Maintained
@@ -1935,7 +1944,7 @@ S:        Maintained
 F:     drivers/net/wireless/b43legacy/
 
 BACKLIGHT CLASS/SUBSYSTEM
-M:     Jingoo Han <jg1.han@samsung.com>
+M:     Jingoo Han <jingoohan1@gmail.com>
 M:     Lee Jones <lee.jones@linaro.org>
 S:     Maintained
 F:     drivers/video/backlight/
@@ -3816,10 +3825,11 @@ M:      David Woodhouse <dwmw2@infradead.org>
 L:     linux-embedded@vger.kernel.org
 S:     Maintained
 
-EMULEX LPFC FC SCSI DRIVER
-M:     James Smart <james.smart@emulex.com>
+EMULEX/AVAGO LPFC FC/FCOE SCSI DRIVER
+M:     James Smart <james.smart@avagotech.com>
+M:     Dick Kennedy <dick.kennedy@avagotech.com>
 L:     linux-scsi@vger.kernel.org
-W:     http://sourceforge.net/projects/lpfcxxxx
+W:     http://www.avagotech.com
 S:     Supported
 F:     drivers/scsi/lpfc/
 
@@ -3918,7 +3928,7 @@ F:        drivers/extcon/
 F:     Documentation/extcon/
 
 EXYNOS DP DRIVER
-M:     Jingoo Han <jg1.han@samsung.com>
+M:     Jingoo Han <jingoohan1@gmail.com>
 L:     dri-devel@lists.freedesktop.org
 S:     Maintained
 F:     drivers/gpu/drm/exynos/exynos_dp*
@@ -4377,11 +4387,10 @@ F:      fs/gfs2/
 F:     include/uapi/linux/gfs2_ondisk.h
 
 GIGASET ISDN DRIVERS
-M:     Hansjoerg Lipp <hjlipp@web.de>
-M:     Tilman Schmidt <tilman@imap.cc>
+M:     Paul Bolle <pebolle@tiscali.nl>
 L:     gigaset307x-common@lists.sourceforge.net
 W:     http://gigaset307x.sourceforge.net/
-S:     Maintained
+S:     Odd Fixes
 F:     Documentation/isdn/README.gigaset
 F:     drivers/isdn/gigaset/
 F:     include/uapi/linux/gigaset_dev.h
@@ -4528,7 +4537,7 @@ M:        Jean Delvare <jdelvare@suse.de>
 M:     Guenter Roeck <linux@roeck-us.net>
 L:     lm-sensors@lm-sensors.org
 W:     http://www.lm-sensors.org/
-T:     quilt kernel.org/pub/linux/kernel/people/jdelvare/linux-2.6/jdelvare-hwmon/
+T:     quilt http://jdelvare.nerim.net/devel/linux/jdelvare-hwmon/
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging.git
 S:     Maintained
 F:     Documentation/hwmon/
@@ -5054,7 +5063,7 @@ M:        Hal Rosenstock <hal.rosenstock@gmail.com>
 L:     linux-rdma@vger.kernel.org
 W:     http://www.openfabrics.org/
 Q:     http://patchwork.kernel.org/project/linux-rdma/list/
-T:     git git://github.com/dledford/linux.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/dledford/rdma.git
 S:     Supported
 F:     Documentation/infiniband/
 F:     drivers/infiniband/
@@ -6959,6 +6968,17 @@ T:       git git://git.rocketboards.org/linux-socfpga-next.git
 S:     Maintained
 F:     arch/nios2/
 
+NOKIA N900 POWER SUPPLY DRIVERS
+M:     Pali Rohár <pali.rohar@gmail.com>
+S:     Maintained
+F:     include/linux/power/bq2415x_charger.h
+F:     include/linux/power/bq27x00_battery.h
+F:     include/linux/power/isp1704_charger.h
+F:     drivers/power/bq2415x_charger.c
+F:     drivers/power/bq27x00_battery.c
+F:     drivers/power/isp1704_charger.c
+F:     drivers/power/rx51_battery.c
+
 NTB DRIVER
 M:     Jon Mason <jdmason@kudzu.us>
 M:     Dave Jiang <dave.jiang@intel.com>
@@ -7547,7 +7567,7 @@ S:        Maintained
 F:     drivers/pci/host/*rcar*
 
 PCI DRIVER FOR SAMSUNG EXYNOS
-M:     Jingoo Han <jg1.han@samsung.com>
+M:     Jingoo Han <jingoohan1@gmail.com>
 L:     linux-pci@vger.kernel.org
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 L:     linux-samsung-soc@vger.kernel.org (moderated for non-subscribers)
@@ -7555,7 +7575,7 @@ S:        Maintained
 F:     drivers/pci/host/pci-exynos.c
 
 PCI DRIVER FOR SYNOPSIS DESIGNWARE
-M:     Jingoo Han <jg1.han@samsung.com>
+M:     Jingoo Han <jingoohan1@gmail.com>
 L:     linux-pci@vger.kernel.org
 S:     Maintained
 F:     drivers/pci/host/*designware*
@@ -8511,7 +8531,7 @@ S:        Supported
 F:     sound/soc/samsung/
 
 SAMSUNG FRAMEBUFFER DRIVER
-M:     Jingoo Han <jg1.han@samsung.com>
+M:     Jingoo Han <jingoohan1@gmail.com>
 L:     linux-fbdev@vger.kernel.org
 S:     Maintained
 F:     drivers/video/fbdev/s3c-fb.c
@@ -8810,16 +8830,19 @@ F:      drivers/misc/phantom.c
 F:     include/uapi/linux/phantom.h
 
 SERVER ENGINES 10Gbps iSCSI - BladeEngine 2 DRIVER
-M:     Jayamohan Kallickal <jayamohan.kallickal@emulex.com>
+M:     Jayamohan Kallickal <jayamohan.kallickal@avagotech.com>
+M:     Minh Tran <minh.tran@avagotech.com>
+M:     John Soni Jose <sony.john-n@avagotech.com>
 L:     linux-scsi@vger.kernel.org
-W:     http://www.emulex.com
+W:     http://www.avagotech.com
 S:     Supported
 F:     drivers/scsi/be2iscsi/
 
-SERVER ENGINES 10Gbps NIC - BladeEngine 2 DRIVER
-M:     Sathya Perla <sathya.perla@emulex.com>
-M:     Subbu Seetharaman <subbu.seetharaman@emulex.com>
-M:     Ajit Khaparde <ajit.khaparde@emulex.com>
+Emulex 10Gbps NIC BE2, BE3-R, Lancer, Skyhawk-R DRIVER
+M:     Sathya Perla <sathya.perla@avagotech.com>
+M:     Ajit Khaparde <ajit.khaparde@avagotech.com>
+M:     Padmanabh Ratnakar <padmanabh.ratnakar@avagotech.com>
+M:     Sriharsha Basavapatna <sriharsha.basavapatna@avagotech.com>
 L:     netdev@vger.kernel.org
 W:     http://www.emulex.com
 S:     Supported
index eae539d69bf3abb62f38578883db9e7a1a1dd906..92a70785920535c6125d9695743149d3627efbc2 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 4
 PATCHLEVEL = 1
 SUBLEVEL = 0
-EXTRAVERSION = -rc3
+EXTRAVERSION = -rc5
 NAME = Hurr durr I'ma sheep
 
 # *DOCUMENTATION*
index cd143887380a26da88e8372828dc586ce3ff7b31..8399bd0e68e8e5cb7aba078cd40864d89b971eed 100644 (file)
@@ -14,6 +14,9 @@ targets               := vmlinux.gz vmlinux \
                   tools/bootpzh bootloader bootpheader bootpzheader 
 OBJSTRIP       := $(obj)/tools/objstrip
 
+HOSTCFLAGS     := -Wall -I$(objtree)/usr/include
+BOOTCFLAGS     += -I$(obj) -I$(srctree)/$(obj)
+
 # SRM bootable image.  Copy to offset 512 of a partition.
 $(obj)/bootimage: $(addprefix $(obj)/tools/,mkbb lxboot bootlx) $(obj)/vmlinux.nh
        ( cat $(obj)/tools/lxboot $(obj)/tools/bootlx $(obj)/vmlinux.nh ) > $@ 
@@ -96,13 +99,14 @@ $(obj)/tools/bootph: $(obj)/bootpheader $(OBJSTRIP) FORCE
 $(obj)/tools/bootpzh: $(obj)/bootpzheader $(OBJSTRIP) FORCE
        $(call if_changed,objstrip)
 
-LDFLAGS_bootloader   := -static -uvsprintf -T  #-N -relax
-LDFLAGS_bootpheader  := -static -uvsprintf -T  #-N -relax
-LDFLAGS_bootpzheader := -static -uvsprintf -T  #-N -relax
+LDFLAGS_bootloader   := -static -T # -N -relax
+LDFLAGS_bootloader   := -static -T # -N -relax
+LDFLAGS_bootpheader  := -static -T # -N -relax
+LDFLAGS_bootpzheader := -static -T # -N -relax
 
-OBJ_bootlx   := $(obj)/head.o $(obj)/main.o
-OBJ_bootph   := $(obj)/head.o $(obj)/bootp.o
-OBJ_bootpzh  := $(obj)/head.o $(obj)/bootpz.o $(obj)/misc.o
+OBJ_bootlx   := $(obj)/head.o $(obj)/stdio.o $(obj)/main.o
+OBJ_bootph   := $(obj)/head.o $(obj)/stdio.o $(obj)/bootp.o
+OBJ_bootpzh  := $(obj)/head.o $(obj)/stdio.o $(obj)/bootpz.o $(obj)/misc.o
 
 $(obj)/bootloader: $(obj)/bootloader.lds $(OBJ_bootlx) $(LIBS_Y) FORCE
        $(call if_changed,ld)
index 3baf2d1e908df5760f1304bab309ae70877eee03..dd6eb4a33582e63def4b015c0a1ad496889feacd 100644 (file)
@@ -19,7 +19,6 @@
 
 #include "ksize.h"
 
-extern int vsprintf(char *, const char *, va_list);
 extern unsigned long switch_to_osf_pal(unsigned long nr,
        struct pcb_struct * pcb_va, struct pcb_struct * pcb_pa,
        unsigned long *vptb);
diff --git a/arch/alpha/boot/stdio.c b/arch/alpha/boot/stdio.c
new file mode 100644 (file)
index 0000000..f844dae
--- /dev/null
@@ -0,0 +1,306 @@
+/*
+ * Copyright (C) Paul Mackerras 1997.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#include <stdarg.h>
+#include <stddef.h>
+
+size_t strnlen(const char * s, size_t count)
+{
+       const char *sc;
+
+       for (sc = s; count-- && *sc != '\0'; ++sc)
+               /* nothing */;
+       return sc - s;
+}
+
+# define do_div(n, base) ({                                            \
+       unsigned int __base = (base);                                   \
+       unsigned int __rem;                                             \
+       __rem = ((unsigned long long)(n)) % __base;                     \
+       (n) = ((unsigned long long)(n)) / __base;                       \
+       __rem;                                                          \
+})
+
+
+static int skip_atoi(const char **s)
+{
+       int i, c;
+
+       for (i = 0; '0' <= (c = **s) && c <= '9'; ++*s)
+               i = i*10 + c - '0';
+       return i;
+}
+
+#define ZEROPAD        1               /* pad with zero */
+#define SIGN   2               /* unsigned/signed long */
+#define PLUS   4               /* show plus */
+#define SPACE  8               /* space if plus */
+#define LEFT   16              /* left justified */
+#define SPECIAL        32              /* 0x */
+#define LARGE  64              /* use 'ABCDEF' instead of 'abcdef' */
+
+static char * number(char * str, unsigned long long num, int base, int size, int precision, int type)
+{
+       char c,sign,tmp[66];
+       const char *digits="0123456789abcdefghijklmnopqrstuvwxyz";
+       int i;
+
+       if (type & LARGE)
+               digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+       if (type & LEFT)
+               type &= ~ZEROPAD;
+       if (base < 2 || base > 36)
+               return 0;
+       c = (type & ZEROPAD) ? '0' : ' ';
+       sign = 0;
+       if (type & SIGN) {
+               if ((signed long long)num < 0) {
+                       sign = '-';
+                       num = - (signed long long)num;
+                       size--;
+               } else if (type & PLUS) {
+                       sign = '+';
+                       size--;
+               } else if (type & SPACE) {
+                       sign = ' ';
+                       size--;
+               }
+       }
+       if (type & SPECIAL) {
+               if (base == 16)
+                       size -= 2;
+               else if (base == 8)
+                       size--;
+       }
+       i = 0;
+       if (num == 0)
+               tmp[i++]='0';
+       else while (num != 0) {
+               tmp[i++] = digits[do_div(num, base)];
+       }
+       if (i > precision)
+               precision = i;
+       size -= precision;
+       if (!(type&(ZEROPAD+LEFT)))
+               while(size-->0)
+                       *str++ = ' ';
+       if (sign)
+               *str++ = sign;
+       if (type & SPECIAL) {
+               if (base==8)
+                       *str++ = '0';
+               else if (base==16) {
+                       *str++ = '0';
+                       *str++ = digits[33];
+               }
+       }
+       if (!(type & LEFT))
+               while (size-- > 0)
+                       *str++ = c;
+       while (i < precision--)
+               *str++ = '0';
+       while (i-- > 0)
+               *str++ = tmp[i];
+       while (size-- > 0)
+               *str++ = ' ';
+       return str;
+}
+
+int vsprintf(char *buf, const char *fmt, va_list args)
+{
+       int len;
+       unsigned long long num;
+       int i, base;
+       char * str;
+       const char *s;
+
+       int flags;              /* flags to number() */
+
+       int field_width;        /* width of output field */
+       int precision;          /* min. # of digits for integers; max
+                                  number of chars for from string */
+       int qualifier;          /* 'h', 'l', or 'L' for integer fields */
+                               /* 'z' support added 23/7/1999 S.H.    */
+                               /* 'z' changed to 'Z' --davidm 1/25/99 */
+
+
+       for (str=buf ; *fmt ; ++fmt) {
+               if (*fmt != '%') {
+                       *str++ = *fmt;
+                       continue;
+               }
+
+               /* process flags */
+               flags = 0;
+               repeat:
+                       ++fmt;          /* this also skips first '%' */
+                       switch (*fmt) {
+                               case '-': flags |= LEFT; goto repeat;
+                               case '+': flags |= PLUS; goto repeat;
+                               case ' ': flags |= SPACE; goto repeat;
+                               case '#': flags |= SPECIAL; goto repeat;
+                               case '0': flags |= ZEROPAD; goto repeat;
+                               }
+
+               /* get field width */
+               field_width = -1;
+               if ('0' <= *fmt && *fmt <= '9')
+                       field_width = skip_atoi(&fmt);
+               else if (*fmt == '*') {
+                       ++fmt;
+                       /* it's the next argument */
+                       field_width = va_arg(args, int);
+                       if (field_width < 0) {
+                               field_width = -field_width;
+                               flags |= LEFT;
+                       }
+               }
+
+               /* get the precision */
+               precision = -1;
+               if (*fmt == '.') {
+                       ++fmt;
+                       if ('0' <= *fmt && *fmt <= '9')
+                               precision = skip_atoi(&fmt);
+                       else if (*fmt == '*') {
+                               ++fmt;
+                               /* it's the next argument */
+                               precision = va_arg(args, int);
+                       }
+                       if (precision < 0)
+                               precision = 0;
+               }
+
+               /* get the conversion qualifier */
+               qualifier = -1;
+               if (*fmt == 'l' && *(fmt + 1) == 'l') {
+                       qualifier = 'q';
+                       fmt += 2;
+               } else if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L'
+                       || *fmt == 'Z') {
+                       qualifier = *fmt;
+                       ++fmt;
+               }
+
+               /* default base */
+               base = 10;
+
+               switch (*fmt) {
+               case 'c':
+                       if (!(flags & LEFT))
+                               while (--field_width > 0)
+                                       *str++ = ' ';
+                       *str++ = (unsigned char) va_arg(args, int);
+                       while (--field_width > 0)
+                               *str++ = ' ';
+                       continue;
+
+               case 's':
+                       s = va_arg(args, char *);
+                       if (!s)
+                               s = "<NULL>";
+
+                       len = strnlen(s, precision);
+
+                       if (!(flags & LEFT))
+                               while (len < field_width--)
+                                       *str++ = ' ';
+                       for (i = 0; i < len; ++i)
+                               *str++ = *s++;
+                       while (len < field_width--)
+                               *str++ = ' ';
+                       continue;
+
+               case 'p':
+                       if (field_width == -1) {
+                               field_width = 2*sizeof(void *);
+                               flags |= ZEROPAD;
+                       }
+                       str = number(str,
+                               (unsigned long) va_arg(args, void *), 16,
+                               field_width, precision, flags);
+                       continue;
+
+
+               case 'n':
+                       if (qualifier == 'l') {
+                               long * ip = va_arg(args, long *);
+                               *ip = (str - buf);
+                       } else if (qualifier == 'Z') {
+                               size_t * ip = va_arg(args, size_t *);
+                               *ip = (str - buf);
+                       } else {
+                               int * ip = va_arg(args, int *);
+                               *ip = (str - buf);
+                       }
+                       continue;
+
+               case '%':
+                       *str++ = '%';
+                       continue;
+
+               /* integer number formats - set up the flags and "break" */
+               case 'o':
+                       base = 8;
+                       break;
+
+               case 'X':
+                       flags |= LARGE;
+               case 'x':
+                       base = 16;
+                       break;
+
+               case 'd':
+               case 'i':
+                       flags |= SIGN;
+               case 'u':
+                       break;
+
+               default:
+                       *str++ = '%';
+                       if (*fmt)
+                               *str++ = *fmt;
+                       else
+                               --fmt;
+                       continue;
+               }
+               if (qualifier == 'l') {
+                       num = va_arg(args, unsigned long);
+                       if (flags & SIGN)
+                               num = (signed long) num;
+               } else if (qualifier == 'q') {
+                       num = va_arg(args, unsigned long long);
+                       if (flags & SIGN)
+                               num = (signed long long) num;
+               } else if (qualifier == 'Z') {
+                       num = va_arg(args, size_t);
+               } else if (qualifier == 'h') {
+                       num = (unsigned short) va_arg(args, int);
+                       if (flags & SIGN)
+                               num = (signed short) num;
+               } else {
+                       num = va_arg(args, unsigned int);
+                       if (flags & SIGN)
+                               num = (signed int) num;
+               }
+               str = number(str, num, base, field_width, precision, flags);
+       }
+       *str = '\0';
+       return str-buf;
+}
+
+int sprintf(char * buf, const char *fmt, ...)
+{
+       va_list args;
+       int i;
+
+       va_start(args, fmt);
+       i=vsprintf(buf,fmt,args);
+       va_end(args);
+       return i;
+}
index 367d53d031fc04d51af471273a0256a5a08432c7..dee82695f48bad69b0d9cf81457196e321d2ff55 100644 (file)
@@ -27,6 +27,9 @@
 #include <linux/param.h>
 #ifdef __ELF__
 # include <linux/elf.h>
+# define elfhdr elf64_hdr
+# define elf_phdr elf64_phdr
+# define elf_check_arch(x) ((x)->e_machine == EM_ALPHA)
 #endif
 
 /* bootfile size must be multiple of BLOCK_SIZE: */
index f61e1a56c3787bcbd4a2ab093d1c58c7715fa6c4..4cb4b6d3452c0b3439c3aa3c0f928f74de09fb3a 100644 (file)
@@ -2,6 +2,5 @@
 #define _ALPHA_TYPES_H
 
 #include <asm-generic/int-ll64.h>
-#include <uapi/asm/types.h>
 
 #endif /* _ALPHA_TYPES_H */
index c509d306db4561ea65a40703b42e7f9bd078d352..a56e608db2f9e4aad716b96669de02c7571dc1df 100644 (file)
@@ -3,7 +3,7 @@
 
 #include <uapi/asm/unistd.h>
 
-#define NR_SYSCALLS                    511
+#define NR_SYSCALLS                    514
 
 #define __ARCH_WANT_OLD_READDIR
 #define __ARCH_WANT_STAT64
index d214a0358100b6ad82a63fce68bc6016eb9ddaa4..aa33bf5aacb6c1666203e38700939750c90cb5c5 100644 (file)
 #define __NR_sched_setattr             508
 #define __NR_sched_getattr             509
 #define __NR_renameat2                 510
+#define __NR_getrandom                 511
+#define __NR_memfd_create              512
+#define __NR_execveat                  513
 
 #endif /* _UAPI_ALPHA_UNISTD_H */
index 253cf1a87481e815ad9a724dde1fef51b5616d09..51267ac5729b9c7276a0e838357bfb8ffd29e7db 100644 (file)
@@ -6,7 +6,6 @@
  *     Error handling code supporting Alpha systems
  */
 
-#include <linux/init.h>
 #include <linux/sched.h>
 
 #include <asm/io.h>
index 7b2be251c30fb92981d4aef8cf4f8951bed24728..51f2c8654253f2bd6667ccff24c0db09a7f80ccc 100644 (file)
@@ -19,7 +19,6 @@
 #include <linux/ptrace.h>
 #include <linux/interrupt.h>
 #include <linux/random.h>
-#include <linux/init.h>
 #include <linux/irq.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
index e51f578636a5718d4f0e438b90b4b78a12b6b7da..36dc91ace83ae97069df82f5e3923a24275c6a9b 100644 (file)
@@ -1019,14 +1019,13 @@ SYSCALL_DEFINE2(osf_settimeofday, struct timeval32 __user *, tv,
        if (tv) {
                if (get_tv32((struct timeval *)&kts, tv))
                        return -EFAULT;
+               kts.tv_nsec *= 1000;
        }
        if (tz) {
                if (copy_from_user(&ktz, tz, sizeof(*tz)))
                        return -EFAULT;
        }
 
-       kts.tv_nsec *= 1000;
-
        return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL);
 }
 
index 1941a07b5811f925aed82e853aab4efb081f74ca..84d13263ce46f193ef0b223466cea2f522ca109d 100644 (file)
@@ -236,12 +236,11 @@ release_thread(struct task_struct *dead_task)
 }
 
 /*
- * Copy an alpha thread..
+ * Copy architecture-specific thread state
  */
-
 int
 copy_thread(unsigned long clone_flags, unsigned long usp,
-           unsigned long arg,
+           unsigned long kthread_arg,
            struct task_struct *p)
 {
        extern void ret_from_fork(void);
@@ -262,7 +261,7 @@ copy_thread(unsigned long clone_flags, unsigned long usp,
                        sizeof(struct switch_stack) + sizeof(struct pt_regs));
                childstack->r26 = (unsigned long) ret_from_kernel_thread;
                childstack->r9 = usp;   /* function */
-               childstack->r10 = arg;
+               childstack->r10 = kthread_arg;
                childregs->hae = alpha_mv.hae_cache,
                childti->pcb.usp = 0;
                return 0;
index 99ac36d5de4efd10832804e82509e062606720e2..2f24447fef92071b0ba9b94d09f8ed1fdc25d2d1 100644 (file)
@@ -63,7 +63,6 @@ static struct {
 enum ipi_message_type {
        IPI_RESCHEDULE,
        IPI_CALL_FUNC,
-       IPI_CALL_FUNC_SINGLE,
        IPI_CPU_STOP,
 };
 
@@ -506,7 +505,6 @@ setup_profiling_timer(unsigned int multiplier)
        return -EINVAL;
 }
 
-\f
 static void
 send_ipi_message(const struct cpumask *to_whom, enum ipi_message_type operation)
 {
@@ -552,10 +550,6 @@ handle_ipi(struct pt_regs *regs)
                        generic_smp_call_function_interrupt();
                        break;
 
-               case IPI_CALL_FUNC_SINGLE:
-                       generic_smp_call_function_single_interrupt();
-                       break;
-
                case IPI_CPU_STOP:
                        halt();
 
@@ -606,7 +600,7 @@ void arch_send_call_function_ipi_mask(const struct cpumask *mask)
 
 void arch_send_call_function_single_ipi(int cpu)
 {
-       send_ipi_message(cpumask_of(cpu), IPI_CALL_FUNC_SINGLE);
+       send_ipi_message(cpumask_of(cpu), IPI_CALL_FUNC);
 }
 
 static void
index 6f01d9ad7b814700d8bd56094b13d3af3474cc11..72b59511e59aa350cc58d568cf896edba4f53602 100644 (file)
@@ -237,8 +237,7 @@ srmcons_init(void)
 
        return -ENODEV;
 }
-
-module_init(srmcons_init);
+device_initcall(srmcons_init);
 
 \f
 /*
index f21d61fab6787331d21571958185b637fc601bb7..24e41bd7d3c99060a7411c1c5774941249c89d72 100644 (file)
@@ -331,7 +331,7 @@ marvel_map_irq(const struct pci_dev *cdev, u8 slot, u8 pin)
        pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &intline);
        irq = intline;
 
-       msi_loc = pci_find_capability(dev, PCI_CAP_ID_MSI);
+       msi_loc = dev->msi_cap;
        msg_ctl = 0;
        if (msi_loc) 
                pci_read_config_word(dev, msi_loc + PCI_MSI_FLAGS, &msg_ctl);
index 24789713f1eafb4757ec1084c32225ce88bf4ad4..9b62e3fd4f038a925657beb15de3de89f8548473 100644 (file)
@@ -529,6 +529,9 @@ sys_call_table:
        .quad sys_sched_setattr
        .quad sys_sched_getattr
        .quad sys_renameat2                     /* 510 */
+       .quad sys_getrandom
+       .quad sys_memfd_create
+       .quad sys_execveat
 
        .size sys_call_table, . - sys_call_table
        .type sys_call_table, @object
index 9c4c189eb22f5a9db2d2ae678756a5241b3e1ee5..74aceead06e98a391a1f0fc49f5486ef2562844c 100644 (file)
@@ -14,7 +14,6 @@
 #include <linux/tty.h>
 #include <linux/delay.h>
 #include <linux/module.h>
-#include <linux/init.h>
 #include <linux/kallsyms.h>
 #include <linux/ratelimit.h>
 
index 18aa9b4f94f1822be3e01ea0906fd2cf234c1205..086a0d5445c528b631cec10fd48c5643a4101f86 100644 (file)
@@ -8,7 +8,6 @@
  */
 
 #include <linux/oprofile.h>
-#include <linux/init.h>
 #include <linux/smp.h>
 #include <asm/ptrace.h>
 
index c32f8a0ad92543a0d6e6767e698f51da0972c17e..c300f5ef3482b82330d41c0b4d318362d76d4092 100644 (file)
@@ -8,7 +8,6 @@
  */
 
 #include <linux/oprofile.h>
-#include <linux/init.h>
 #include <linux/smp.h>
 #include <asm/ptrace.h>
 
index 1c84cc257fc7ec7a6c3df970722b381f0ed17ff3..02edf59716144e0939eb2933cfb303fa457ecbd7 100644 (file)
@@ -8,7 +8,6 @@
  */
 
 #include <linux/oprofile.h>
-#include <linux/init.h>
 #include <linux/smp.h>
 #include <asm/ptrace.h>
 
index 34a57a12655377727930f8abba88082f3afde149..adb1744d20f3845efb48a314e56784a5c5470a0a 100644 (file)
@@ -9,7 +9,6 @@
  */
 
 #include <linux/oprofile.h>
-#include <linux/init.h>
 #include <linux/smp.h>
 #include <asm/ptrace.h>
 
index a7fc0da25650ef8920e5cfc9f25d417a36081617..ff6a4b5ce92781442aa10f37537d0d6afb1d15f3 100644 (file)
@@ -2,19 +2,6 @@ menu "Kernel hacking"
 
 source "lib/Kconfig.debug"
 
-config EARLY_PRINTK
-       bool "Early printk" if EMBEDDED
-       default y
-       help
-         Write kernel log output directly into the VGA buffer or to a serial
-         port.
-
-         This is useful for kernel debugging when your machine crashes very
-         early before the console code is initialized. For normal operation
-         it is not recommended because it looks ugly and doesn't cooperate
-         with klogd/syslogd or the X server. You should normally N here,
-         unless you want to debug such a crash.
-
 config 16KSTACKS
        bool "Use 16Kb for kernel stacks instead of 8Kb"
        help
index 067551b6920af99fe733f1f13d4aee8b1903a77b..9917a45fc430d042a4f59006abf84ceedad1bca7 100644 (file)
@@ -99,7 +99,7 @@ static inline void atomic_##op(int i, atomic_t *v)                    \
        atomic_ops_unlock(flags);                                       \
 }
 
-#define ATOMIC_OP_RETURN(op, c_op)                                     \
+#define ATOMIC_OP_RETURN(op, c_op, asm_op)                             \
 static inline int atomic_##op##_return(int i, atomic_t *v)             \
 {                                                                      \
        unsigned long flags;                                            \
index 8c3a3e02ba92c8adbc368dba9a3cd283f32c3e72..12b2100db0731a2a9ce99ce1398ae4599eaca87a 100644 (file)
@@ -266,7 +266,7 @@ static inline void __cache_line_loop(unsigned long paddr, unsigned long vaddr,
  * Machine specific helpers for Entire D-Cache or Per Line ops
  */
 
-static unsigned int __before_dc_op(const int op)
+static inline unsigned int __before_dc_op(const int op)
 {
        unsigned int reg = reg;
 
@@ -284,7 +284,7 @@ static unsigned int __before_dc_op(const int op)
        return reg;
 }
 
-static void __after_dc_op(const int op, unsigned int reg)
+static inline void __after_dc_op(const int op, unsigned int reg)
 {
        if (op & OP_FLUSH)      /* flush / flush-n-inv both wait */
                while (read_aux_reg(ARC_REG_DC_CTRL) & DC_CTRL_FLUSH_STATUS);
index c675257f2377f8797565871e38e77ba50fe7678b..f076ff856d8b8223466f3ec8536caaa1974186ca 100644 (file)
@@ -69,7 +69,7 @@ clocks {
                mainpll: mainpll {
                        compatible = "fixed-clock";
                        #clock-cells = <0>;
-                       clock-frequency = <2000000000>;
+                       clock-frequency = <1000000000>;
                };
                /* 25 MHz reference crystal */
                refclk: oscillator {
index ed2dd8ba4080df7a7f85db89068de44cd693446b..218a2acd36e509b0de8e22dc207e06253b1163fe 100644 (file)
@@ -585,7 +585,7 @@ clocks {
                mainpll: mainpll {
                        compatible = "fixed-clock";
                        #clock-cells = <0>;
-                       clock-frequency = <2000000000>;
+                       clock-frequency = <1000000000>;
                };
 
                /* 25 MHz reference crystal */
index 0e85fc15cedad84c1ea5ebea6db033a2ace60703..ecd1318109bac8fb5d1e29c96f7c30779d217fda 100644 (file)
@@ -502,7 +502,7 @@ clocks {
                mainpll: mainpll {
                        compatible = "fixed-clock";
                        #clock-cells = <0>;
-                       clock-frequency = <2000000000>;
+                       clock-frequency = <1000000000>;
                };
        };
 };
index aae7efc09b0bd1ecd66e72193c6aefe107008b9e..e6fa251e17b93b54f67bcd39b8da57476ddda519 100644 (file)
@@ -87,6 +87,7 @@ si5351: clock-generator {
 
                /* connect xtal input to 25MHz reference */
                clocks = <&ref25>;
+               clock-names = "xtal";
 
                /* connect xtal input as source of pll0 and pll1 */
                silabs,pll-source = <0 0>, <1 0>;
index 0788d08fb43edd00b65f64864ab4a4476f7aaff6..146e71118a72b4eef98faf47f644c0216bbb5894 100644 (file)
@@ -711,6 +711,7 @@ &mmc_1 {
        num-slots = <1>;
        broken-cd;
        cap-sdio-irq;
+       keep-power-in-suspend;
        card-detect-delay = <200>;
        clock-frequency = <400000000>;
        samsung,dw-mshc-ciu-div = <1>;
index 412f41d62686f3ae966df4640d98988dc489c65f..02eb8b15374f3c84ef4b215f4d7da85d2e9f342a 100644 (file)
@@ -674,6 +674,7 @@ &mmc_1 {
        num-slots = <1>;
        broken-cd;
        cap-sdio-irq;
+       keep-power-in-suspend;
        card-detect-delay = <200>;
        clock-frequency = <400000000>;
        samsung,dw-mshc-ciu-div = <1>;
index cf01c818b8ea41999f231f07211aec46a86e505c..13cc7ca5e031e5f1814697e8ead9546079f6d04e 100644 (file)
@@ -826,7 +826,7 @@ phy1: usb-phy@0,7d000000 {
                         <&tegra_car TEGRA124_CLK_PLL_U>,
                         <&tegra_car TEGRA124_CLK_USBD>;
                clock-names = "reg", "pll_u", "utmi-pads";
-               resets = <&tegra_car 59>, <&tegra_car 22>;
+               resets = <&tegra_car 22>, <&tegra_car 22>;
                reset-names = "usb", "utmi-pads";
                nvidia,hssync-start-delay = <0>;
                nvidia,idle-wait-delay = <17>;
@@ -838,6 +838,7 @@ phy1: usb-phy@0,7d000000 {
                nvidia,hssquelch-level = <2>;
                nvidia,hsdiscon-level = <5>;
                nvidia,xcvr-hsslew = <12>;
+               nvidia,has-utmi-pad-registers;
                status = "disabled";
        };
 
@@ -862,7 +863,7 @@ phy2: usb-phy@0,7d004000 {
                         <&tegra_car TEGRA124_CLK_PLL_U>,
                         <&tegra_car TEGRA124_CLK_USBD>;
                clock-names = "reg", "pll_u", "utmi-pads";
-               resets = <&tegra_car 22>, <&tegra_car 22>;
+               resets = <&tegra_car 58>, <&tegra_car 22>;
                reset-names = "usb", "utmi-pads";
                nvidia,hssync-start-delay = <0>;
                nvidia,idle-wait-delay = <17>;
@@ -874,7 +875,6 @@ phy2: usb-phy@0,7d004000 {
                nvidia,hssquelch-level = <2>;
                nvidia,hsdiscon-level = <5>;
                nvidia,xcvr-hsslew = <12>;
-               nvidia,has-utmi-pad-registers;
                status = "disabled";
        };
 
@@ -899,7 +899,7 @@ phy3: usb-phy@0,7d008000 {
                         <&tegra_car TEGRA124_CLK_PLL_U>,
                         <&tegra_car TEGRA124_CLK_USBD>;
                clock-names = "reg", "pll_u", "utmi-pads";
-               resets = <&tegra_car 58>, <&tegra_car 22>;
+               resets = <&tegra_car 59>, <&tegra_car 22>;
                reset-names = "usb", "utmi-pads";
                nvidia,hssync-start-delay = <0>;
                nvidia,idle-wait-delay = <17>;
index 7a2aeacd62c0c2cb23b1247ce3b5ca6c55225d24..107395c32d8265863fecb711311def376ab500b6 100644 (file)
@@ -191,6 +191,7 @@ pmu {
                compatible = "arm,cortex-a15-pmu";
                interrupts = <0 68 4>,
                             <0 69 4>;
+               interrupt-affinity = <&cpu0>, <&cpu1>;
        };
 
        oscclk6a: oscclk6a {
index 23662b5a5e9d84554f34eb0fc3edad1ef029f4e6..d949facba37641b3b36f337cd3eefce7932280d9 100644 (file)
@@ -33,28 +33,28 @@ cpus {
                #address-cells = <1>;
                #size-cells = <0>;
 
-               cpu@0 {
+               A9_0: cpu@0 {
                        device_type = "cpu";
                        compatible = "arm,cortex-a9";
                        reg = <0>;
                        next-level-cache = <&L2>;
                };
 
-               cpu@1 {
+               A9_1: cpu@1 {
                        device_type = "cpu";
                        compatible = "arm,cortex-a9";
                        reg = <1>;
                        next-level-cache = <&L2>;
                };
 
-               cpu@2 {
+               A9_2: cpu@2 {
                        device_type = "cpu";
                        compatible = "arm,cortex-a9";
                        reg = <2>;
                        next-level-cache = <&L2>;
                };
 
-               cpu@3 {
+               A9_3: cpu@3 {
                        device_type = "cpu";
                        compatible = "arm,cortex-a9";
                        reg = <3>;
@@ -170,6 +170,7 @@ L2: cache-controller@1e00a000 {
                compatible = "arm,pl310-cache";
                reg = <0x1e00a000 0x1000>;
                interrupts = <0 43 4>;
+               cache-unified;
                cache-level = <2>;
                arm,data-latency = <1 1 1>;
                arm,tag-latency = <1 1 1>;
@@ -181,6 +182,8 @@ pmu {
                             <0 61 4>,
                             <0 62 4>,
                             <0 63 4>;
+               interrupt-affinity = <&A9_0>, <&A9_1>, <&A9_2>, <&A9_3>;
+
        };
 
        dcc {
index a5cd2eda3edf4fdb4d616999532d8f94da2d7bd3..9ea54b3dba09b7de9be7936ae0a755c4ed115a97 100644 (file)
@@ -193,7 +193,7 @@ spi1: spi@e0007000 {
                };
 
                gem0: ethernet@e000b000 {
-                       compatible = "cdns,gem";
+                       compatible = "cdns,zynq-gem";
                        reg = <0xe000b000 0x1000>;
                        status = "disabled";
                        interrupts = <0 22 4>;
@@ -204,7 +204,7 @@ gem0: ethernet@e000b000 {
                };
 
                gem1: ethernet@e000c000 {
-                       compatible = "cdns,gem";
+                       compatible = "cdns,zynq-gem";
                        reg = <0xe000c000 0x1000>;
                        status = "disabled";
                        interrupts = <0 45 4>;
index acd5b560b72801c6e2e4b51baa5ca4c129f44b2d..5f5cd562c593ef5f6a9224254c146e7d3d0136a3 100644 (file)
@@ -159,6 +159,8 @@ extern void exynos_enter_aftr(void);
 
 extern struct cpuidle_exynos_data cpuidle_coupled_exynos_data;
 
+extern void exynos_set_delayed_reset_assertion(bool enable);
+
 extern void s5p_init_cpu(void __iomem *cpuid_addr);
 extern unsigned int samsung_rev(void);
 extern void __iomem *cpu_boot_reg_base(void);
index bcde0dd668df950f1918a66179715a56ec9578fa..5917a30eee33f286c80708dfb84cdd610bd2dd9d 100644 (file)
@@ -166,6 +166,33 @@ static void __init exynos_init_io(void)
        exynos_map_io();
 }
 
+/*
+ * Set or clear the USE_DELAYED_RESET_ASSERTION option. Used by smp code
+ * and suspend.
+ *
+ * This is necessary only on Exynos4 SoCs. When system is running
+ * USE_DELAYED_RESET_ASSERTION should be set so the ARM CLK clock down
+ * feature could properly detect global idle state when secondary CPU is
+ * powered down.
+ *
+ * However this should not be set when such system is going into suspend.
+ */
+void exynos_set_delayed_reset_assertion(bool enable)
+{
+       if (of_machine_is_compatible("samsung,exynos4")) {
+               unsigned int tmp, core_id;
+
+               for (core_id = 0; core_id < num_possible_cpus(); core_id++) {
+                       tmp = pmu_raw_readl(EXYNOS_ARM_CORE_OPTION(core_id));
+                       if (enable)
+                               tmp |= S5P_USE_DELAYED_RESET_ASSERTION;
+                       else
+                               tmp &= ~(S5P_USE_DELAYED_RESET_ASSERTION);
+                       pmu_raw_writel(tmp, EXYNOS_ARM_CORE_OPTION(core_id));
+               }
+       }
+}
+
 /*
  * Apparently, these SoCs are not able to wake-up from suspend using
  * the PMU. Too bad. Should they suddenly become capable of such a
index ebd135bb0995611517c1bce6d3b70deeeee37de4..a825bca2a2b699490809676cef6f66d4eb86fd21 100644 (file)
 
 extern void exynos4_secondary_startup(void);
 
-/*
- * Set or clear the USE_DELAYED_RESET_ASSERTION option, set on Exynos4 SoCs
- * during hot-(un)plugging CPUx.
- *
- * The feature can be cleared safely during first boot of secondary CPU.
- *
- * Exynos4 SoCs require setting USE_DELAYED_RESET_ASSERTION during powering
- * down a CPU so the CPU idle clock down feature could properly detect global
- * idle state when CPUx is off.
- */
-static void exynos_set_delayed_reset_assertion(u32 core_id, bool enable)
-{
-       if (soc_is_exynos4()) {
-               unsigned int tmp;
-
-               tmp = pmu_raw_readl(EXYNOS_ARM_CORE_OPTION(core_id));
-               if (enable)
-                       tmp |= S5P_USE_DELAYED_RESET_ASSERTION;
-               else
-                       tmp &= ~(S5P_USE_DELAYED_RESET_ASSERTION);
-               pmu_raw_writel(tmp, EXYNOS_ARM_CORE_OPTION(core_id));
-       }
-}
-
 #ifdef CONFIG_HOTPLUG_CPU
 static inline void cpu_leave_lowpower(u32 core_id)
 {
@@ -73,8 +49,6 @@ static inline void cpu_leave_lowpower(u32 core_id)
          : "=&r" (v)
          : "Ir" (CR_C), "Ir" (0x40)
          : "cc");
-
-        exynos_set_delayed_reset_assertion(core_id, false);
 }
 
 static inline void platform_do_lowpower(unsigned int cpu, int *spurious)
@@ -87,14 +61,6 @@ static inline void platform_do_lowpower(unsigned int cpu, int *spurious)
                /* Turn the CPU off on next WFI instruction. */
                exynos_cpu_power_down(core_id);
 
-               /*
-                * Exynos4 SoCs require setting
-                * USE_DELAYED_RESET_ASSERTION so the CPU idle
-                * clock down feature could properly detect
-                * global idle state when CPUx is off.
-                */
-               exynos_set_delayed_reset_assertion(core_id, true);
-
                wfi();
 
                if (pen_release == core_id) {
@@ -371,9 +337,6 @@ static int exynos_boot_secondary(unsigned int cpu, struct task_struct *idle)
                udelay(10);
        }
 
-       /* No harm if this is called during first boot of secondary CPU */
-       exynos_set_delayed_reset_assertion(core_id, false);
-
        /*
         * now the secondary core is starting up let it run its
         * calibrations, then wait for it to finish
@@ -420,6 +383,8 @@ static void __init exynos_smp_prepare_cpus(unsigned int max_cpus)
 
        exynos_sysram_init();
 
+       exynos_set_delayed_reset_assertion(true);
+
        if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9)
                scu_enable(scu_base_addr());
 
index cbe56b35aea000fe2ad5841851b5eb9a57a307d5..a9686535f9ed460706a41a99dc60d6d4f575ab3b 100644 (file)
@@ -188,7 +188,7 @@ static __init int exynos4_pm_init_power_domain(void)
                args.np = np;
                args.args_count = 0;
                child_domain = of_genpd_get_from_provider(&args);
-               if (!child_domain)
+               if (IS_ERR(child_domain))
                        continue;
 
                if (of_parse_phandle_with_args(np, "power-domains",
@@ -196,7 +196,7 @@ static __init int exynos4_pm_init_power_domain(void)
                        continue;
 
                parent_domain = of_genpd_get_from_provider(&args);
-               if (!parent_domain)
+               if (IS_ERR(parent_domain))
                        continue;
 
                if (pm_genpd_add_subdomain(parent_domain, child_domain))
index 3e6aea7f83af199d7c624372fb96549430504cc2..c0b6dccbf7bd5d8d14c05172d11d6ee690bf8fef 100644 (file)
@@ -342,6 +342,8 @@ static void exynos_pm_enter_sleep_mode(void)
 
 static void exynos_pm_prepare(void)
 {
+       exynos_set_delayed_reset_assertion(false);
+
        /* Set wake-up mask registers */
        exynos_pm_set_wakeup_mask();
 
@@ -482,6 +484,7 @@ static void exynos_pm_resume(void)
 
        /* Clear SLEEP mode set in INFORM1 */
        pmu_raw_writel(0x0, S5P_INFORM1);
+       exynos_set_delayed_reset_assertion(true);
 }
 
 static void exynos3250_pm_resume(void)
@@ -723,8 +726,10 @@ void __init exynos_pm_init(void)
                return;
        }
 
-       if (WARN_ON(!of_find_property(np, "interrupt-controller", NULL)))
+       if (WARN_ON(!of_find_property(np, "interrupt-controller", NULL))) {
                pr_warn("Outdated DT detected, suspend/resume will NOT work\n");
+               return;
+       }
 
        pm_data = (const struct exynos_pm_data *) match->data;
 
index 38a45260a7c8b522dc3b8c163a19d4debe711ca9..dd883698ff7eafe977d2a220468d5aad876ce5ce 100644 (file)
@@ -12,6 +12,8 @@
 #ifndef __GEMINI_COMMON_H__
 #define __GEMINI_COMMON_H__
 
+#include <linux/reboot.h>
+
 struct mtd_partition;
 
 extern void gemini_map_io(void);
@@ -26,6 +28,6 @@ extern int platform_register_pflash(unsigned int size,
                                    struct mtd_partition *parts,
                                    unsigned int nr_parts);
 
-extern void gemini_restart(char mode, const char *cmd);
+extern void gemini_restart(enum reboot_mode mode, const char *cmd);
 
 #endif /* __GEMINI_COMMON_H__ */
index b26659759e2750bfef5f171b7d770905019e58ed..21a6d6d4f9c43d1ab8a608962761098bc847e35f 100644 (file)
@@ -14,7 +14,9 @@
 #include <mach/hardware.h>
 #include <mach/global_reg.h>
 
-void gemini_restart(char mode, const char *cmd)
+#include "common.h"
+
+void gemini_restart(enum reboot_mode mode, const char *cmd)
 {
        __raw_writel(RESET_GLOBAL | RESET_CPU1,
                     IO_ADDRESS(GEMINI_GLOBAL_BASE) + GLOBAL_RESET);
index 355b089368715427627dd39f1014ed7024ae8459..752969ff9de04f95ef8b9a695325901b6297cf78 100644 (file)
  */
 #define LINKS_PER_OCP_IF               2
 
+/*
+ * Address offset (in bytes) between the reset control and the reset
+ * status registers: 4 bytes on OMAP4
+ */
+#define OMAP4_RST_CTRL_ST_OFFSET       4
+
 /**
  * struct omap_hwmod_soc_ops - fn ptrs for some SoC-specific operations
  * @enable_module: function to enable a module (via MODULEMODE)
@@ -3016,10 +3022,12 @@ static int _omap4_deassert_hardreset(struct omap_hwmod *oh,
        if (ohri->st_shift)
                pr_err("omap_hwmod: %s: %s: hwmod data error: OMAP4 does not support st_shift\n",
                       oh->name, ohri->name);
-       return omap_prm_deassert_hardreset(ohri->rst_shift, 0,
+       return omap_prm_deassert_hardreset(ohri->rst_shift, ohri->rst_shift,
                                           oh->clkdm->pwrdm.ptr->prcm_partition,
                                           oh->clkdm->pwrdm.ptr->prcm_offs,
-                                          oh->prcm.omap4.rstctrl_offs, 0);
+                                          oh->prcm.omap4.rstctrl_offs,
+                                          oh->prcm.omap4.rstctrl_offs +
+                                          OMAP4_RST_CTRL_ST_OFFSET);
 }
 
 /**
@@ -3047,27 +3055,6 @@ static int _omap4_is_hardreset_asserted(struct omap_hwmod *oh,
                                              oh->prcm.omap4.rstctrl_offs);
 }
 
-/**
- * _am33xx_assert_hardreset - call AM33XX PRM hardreset fn with hwmod args
- * @oh: struct omap_hwmod * to assert hardreset
- * @ohri: hardreset line data
- *
- * Call am33xx_prminst_assert_hardreset() with parameters extracted
- * from the hwmod @oh and the hardreset line data @ohri.  Only
- * intended for use as an soc_ops function pointer.  Passes along the
- * return value from am33xx_prminst_assert_hardreset().  XXX This
- * function is scheduled for removal when the PRM code is moved into
- * drivers/.
- */
-static int _am33xx_assert_hardreset(struct omap_hwmod *oh,
-                                  struct omap_hwmod_rst_info *ohri)
-
-{
-       return omap_prm_assert_hardreset(ohri->rst_shift, 0,
-                                        oh->clkdm->pwrdm.ptr->prcm_offs,
-                                        oh->prcm.omap4.rstctrl_offs);
-}
-
 /**
  * _am33xx_deassert_hardreset - call AM33XX PRM hardreset fn with hwmod args
  * @oh: struct omap_hwmod * to deassert hardreset
@@ -3083,32 +3070,13 @@ static int _am33xx_assert_hardreset(struct omap_hwmod *oh,
 static int _am33xx_deassert_hardreset(struct omap_hwmod *oh,
                                     struct omap_hwmod_rst_info *ohri)
 {
-       return omap_prm_deassert_hardreset(ohri->rst_shift, ohri->st_shift, 0,
+       return omap_prm_deassert_hardreset(ohri->rst_shift, ohri->st_shift,
+                                          oh->clkdm->pwrdm.ptr->prcm_partition,
                                           oh->clkdm->pwrdm.ptr->prcm_offs,
                                           oh->prcm.omap4.rstctrl_offs,
                                           oh->prcm.omap4.rstst_offs);
 }
 
-/**
- * _am33xx_is_hardreset_asserted - call AM33XX PRM hardreset fn with hwmod args
- * @oh: struct omap_hwmod * to test hardreset
- * @ohri: hardreset line data
- *
- * Call am33xx_prminst_is_hardreset_asserted() with parameters
- * extracted from the hwmod @oh and the hardreset line data @ohri.
- * Only intended for use as an soc_ops function pointer.  Passes along
- * the return value from am33xx_prminst_is_hardreset_asserted().  XXX
- * This function is scheduled for removal when the PRM code is moved
- * into drivers/.
- */
-static int _am33xx_is_hardreset_asserted(struct omap_hwmod *oh,
-                                       struct omap_hwmod_rst_info *ohri)
-{
-       return omap_prm_is_hardreset_asserted(ohri->rst_shift, 0,
-                                             oh->clkdm->pwrdm.ptr->prcm_offs,
-                                             oh->prcm.omap4.rstctrl_offs);
-}
-
 /* Public functions */
 
 u32 omap_hwmod_read(struct omap_hwmod *oh, u16 reg_offs)
@@ -3908,21 +3876,13 @@ void __init omap_hwmod_init(void)
                soc_ops.init_clkdm = _init_clkdm;
                soc_ops.update_context_lost = _omap4_update_context_lost;
                soc_ops.get_context_lost = _omap4_get_context_lost;
-       } else if (soc_is_am43xx()) {
+       } else if (cpu_is_ti816x() || soc_is_am33xx() || soc_is_am43xx()) {
                soc_ops.enable_module = _omap4_enable_module;
                soc_ops.disable_module = _omap4_disable_module;
                soc_ops.wait_target_ready = _omap4_wait_target_ready;
                soc_ops.assert_hardreset = _omap4_assert_hardreset;
-               soc_ops.deassert_hardreset = _omap4_deassert_hardreset;
-               soc_ops.is_hardreset_asserted = _omap4_is_hardreset_asserted;
-               soc_ops.init_clkdm = _init_clkdm;
-       } else if (cpu_is_ti816x() || soc_is_am33xx()) {
-               soc_ops.enable_module = _omap4_enable_module;
-               soc_ops.disable_module = _omap4_disable_module;
-               soc_ops.wait_target_ready = _omap4_wait_target_ready;
-               soc_ops.assert_hardreset = _am33xx_assert_hardreset;
                soc_ops.deassert_hardreset = _am33xx_deassert_hardreset;
-               soc_ops.is_hardreset_asserted = _am33xx_is_hardreset_asserted;
+               soc_ops.is_hardreset_asserted = _omap4_is_hardreset_asserted;
                soc_ops.init_clkdm = _init_clkdm;
        } else {
                WARN(1, "omap_hwmod: unknown SoC type\n");
index e2223148ba4d37a0818fc65d19ddb00bdc49d56c..17e8004fc20f9e48c69722c32643f7684b7c9eb2 100644 (file)
@@ -544,6 +544,44 @@ static struct omap_hwmod am43xx_hdq1w_hwmod = {
        },
 };
 
+static struct omap_hwmod_class_sysconfig am43xx_vpfe_sysc = {
+       .rev_offs       = 0x0,
+       .sysc_offs      = 0x104,
+       .sysc_flags     = SYSC_HAS_MIDLEMODE | SYSC_HAS_SIDLEMODE,
+       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+                               MSTANDBY_FORCE | MSTANDBY_SMART | MSTANDBY_NO),
+       .sysc_fields    = &omap_hwmod_sysc_type2,
+};
+
+static struct omap_hwmod_class am43xx_vpfe_hwmod_class = {
+       .name           = "vpfe",
+       .sysc           = &am43xx_vpfe_sysc,
+};
+
+static struct omap_hwmod am43xx_vpfe0_hwmod = {
+       .name           = "vpfe0",
+       .class          = &am43xx_vpfe_hwmod_class,
+       .clkdm_name     = "l3s_clkdm",
+       .prcm           = {
+               .omap4  = {
+                       .modulemode     = MODULEMODE_SWCTRL,
+                       .clkctrl_offs   = AM43XX_CM_PER_VPFE0_CLKCTRL_OFFSET,
+               },
+       },
+};
+
+static struct omap_hwmod am43xx_vpfe1_hwmod = {
+       .name           = "vpfe1",
+       .class          = &am43xx_vpfe_hwmod_class,
+       .clkdm_name     = "l3s_clkdm",
+       .prcm           = {
+               .omap4  = {
+                       .modulemode     = MODULEMODE_SWCTRL,
+                       .clkctrl_offs   = AM43XX_CM_PER_VPFE1_CLKCTRL_OFFSET,
+               },
+       },
+};
+
 /* Interfaces */
 static struct omap_hwmod_ocp_if am43xx_l3_main__l4_hs = {
        .master         = &am33xx_l3_main_hwmod,
@@ -825,6 +863,34 @@ static struct omap_hwmod_ocp_if am43xx_l4_ls__hdq1w = {
        .user           = OCP_USER_MPU | OCP_USER_SDMA,
 };
 
+static struct omap_hwmod_ocp_if am43xx_l3__vpfe0 = {
+       .master         = &am43xx_vpfe0_hwmod,
+       .slave          = &am33xx_l3_main_hwmod,
+       .clk            = "l3_gclk",
+       .user           = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_ocp_if am43xx_l3__vpfe1 = {
+       .master         = &am43xx_vpfe1_hwmod,
+       .slave          = &am33xx_l3_main_hwmod,
+       .clk            = "l3_gclk",
+       .user           = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_ocp_if am43xx_l4_ls__vpfe0 = {
+       .master         = &am33xx_l4_ls_hwmod,
+       .slave          = &am43xx_vpfe0_hwmod,
+       .clk            = "l4ls_gclk",
+       .user           = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_ocp_if am43xx_l4_ls__vpfe1 = {
+       .master         = &am33xx_l4_ls_hwmod,
+       .slave          = &am43xx_vpfe1_hwmod,
+       .clk            = "l4ls_gclk",
+       .user           = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
 static struct omap_hwmod_ocp_if *am43xx_hwmod_ocp_ifs[] __initdata = {
        &am33xx_l4_wkup__synctimer,
        &am43xx_l4_ls__timer8,
@@ -925,6 +991,10 @@ static struct omap_hwmod_ocp_if *am43xx_hwmod_ocp_ifs[] __initdata = {
        &am43xx_l4_ls__dss_dispc,
        &am43xx_l4_ls__dss_rfbi,
        &am43xx_l4_ls__hdq1w,
+       &am43xx_l3__vpfe0,
+       &am43xx_l3__vpfe1,
+       &am43xx_l4_ls__vpfe0,
+       &am43xx_l4_ls__vpfe1,
        NULL,
 };
 
index 48df3b55057e4d346076ada24e6e7404a13a117a..d0261996db6d5e0e0f91f40e9429b4c9ea73a4c8 100644 (file)
 #define AM43XX_CM_PER_USBPHYOCP2SCP1_CLKCTRL_OFFSET    0x05C0
 #define AM43XX_CM_PER_DSS_CLKCTRL_OFFSET               0x0a20
 #define AM43XX_CM_PER_HDQ1W_CLKCTRL_OFFSET             0x04a0
-
+#define AM43XX_CM_PER_VPFE0_CLKCTRL_OFFSET             0x0068
+#define AM43XX_CM_PER_VPFE1_CLKCTRL_OFFSET             0x0070
 #endif
index c4859c4d364692b575199f0287b4ee4751ccdee2..d0b15dbafa2efa01b1ba06531d1e163d0e70f16c 100644 (file)
@@ -87,12 +87,6 @@ u32 omap4_prminst_rmw_inst_reg_bits(u32 mask, u32 bits, u8 part, s16 inst,
        return v;
 }
 
-/*
- * Address offset (in bytes) between the reset control and the reset
- * status registers: 4 bytes on OMAP4
- */
-#define OMAP4_RST_CTRL_ST_OFFSET               4
-
 /**
  * omap4_prminst_is_hardreset_asserted - read the HW reset line state of
  * submodules contained in the hwmod module
@@ -141,11 +135,11 @@ int omap4_prminst_assert_hardreset(u8 shift, u8 part, s16 inst,
  * omap4_prminst_deassert_hardreset - deassert a submodule hardreset line and
  * wait
  * @shift: register bit shift corresponding to the reset line to deassert
- * @st_shift: status bit offset, not used for OMAP4+
+ * @st_shift: status bit offset corresponding to the reset line
  * @part: PRM partition
  * @inst: PRM instance offset
  * @rstctrl_offs: reset register offset
- * @st_offs: reset status register offset, not used for OMAP4+
+ * @rstst_offs: reset status register offset
  *
  * Some IPs like dsp, ipu or iva contain processors that require an HW
  * reset line to be asserted / deasserted in order to fully enable the
@@ -157,11 +151,11 @@ int omap4_prminst_assert_hardreset(u8 shift, u8 part, s16 inst,
  * of reset, or -EBUSY if the submodule did not exit reset promptly.
  */
 int omap4_prminst_deassert_hardreset(u8 shift, u8 st_shift, u8 part, s16 inst,
-                                    u16 rstctrl_offs, u16 st_offs)
+                                    u16 rstctrl_offs, u16 rstst_offs)
 {
        int c;
        u32 mask = 1 << shift;
-       u16 rstst_offs = rstctrl_offs + OMAP4_RST_CTRL_ST_OFFSET;
+       u32 st_mask = 1 << st_shift;
 
        /* Check the current status to avoid de-asserting the line twice */
        if (omap4_prminst_is_hardreset_asserted(shift, part, inst,
@@ -169,13 +163,13 @@ int omap4_prminst_deassert_hardreset(u8 shift, u8 st_shift, u8 part, s16 inst,
                return -EEXIST;
 
        /* Clear the reset status by writing 1 to the status bit */
-       omap4_prminst_rmw_inst_reg_bits(0xffffffff, mask, part, inst,
+       omap4_prminst_rmw_inst_reg_bits(0xffffffff, st_mask, part, inst,
                                        rstst_offs);
        /* de-assert the reset control line */
        omap4_prminst_rmw_inst_reg_bits(mask, 0, part, inst, rstctrl_offs);
        /* wait the status to be set */
-       omap_test_timeout(omap4_prminst_is_hardreset_asserted(shift, part, inst,
-                                                             rstst_offs),
+       omap_test_timeout(omap4_prminst_is_hardreset_asserted(st_shift, part,
+                                                             inst, rstst_offs),
                          MAX_MODULE_HARDRESET_WAIT, c);
 
        return (c == MAX_MODULE_HARDRESET_WAIT) ? -EBUSY : 0;
index cef67af9e9b88aa50416c46cf4aab66769964437..cac46d852da18003a21fa3d66278e11e6cf51afc 100644 (file)
@@ -298,14 +298,11 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer,
        if (IS_ERR(src))
                return PTR_ERR(src);
 
-       if (clk_get_parent(timer->fclk) != src) {
-               r = clk_set_parent(timer->fclk, src);
-               if (r < 0) {
-                       pr_warn("%s: %s cannot set source\n", __func__,
-                               oh->name);
-                       clk_put(src);
-                       return r;
-               }
+       r = clk_set_parent(timer->fclk, src);
+       if (r < 0) {
+               pr_warn("%s: %s cannot set source\n", __func__, oh->name);
+               clk_put(src);
+               return r;
        }
 
        clk_put(src);
index 22812fe06460c8bba1abd30730d3f72cf1299728..b0dcbe28f78cbd9fd73b399655b3b08b59938c8b 100644 (file)
@@ -44,11 +44,9 @@ static void __iomem *rk3288_bootram_base;
 static phys_addr_t rk3288_bootram_phy;
 
 static struct regmap *pmu_regmap;
-static struct regmap *grf_regmap;
 static struct regmap *sgrf_regmap;
 
 static u32 rk3288_pmu_pwr_mode_con;
-static u32 rk3288_grf_soc_con0;
 static u32 rk3288_sgrf_soc_con0;
 
 static inline u32 rk3288_l2_config(void)
@@ -72,25 +70,11 @@ static void rk3288_slp_mode_set(int level)
 {
        u32 mode_set, mode_set1;
 
-       regmap_read(grf_regmap, RK3288_GRF_SOC_CON0, &rk3288_grf_soc_con0);
-
        regmap_read(sgrf_regmap, RK3288_SGRF_SOC_CON0, &rk3288_sgrf_soc_con0);
 
        regmap_read(pmu_regmap, RK3288_PMU_PWRMODE_CON,
                    &rk3288_pmu_pwr_mode_con);
 
-       /*
-        * We need set this bit GRF_FORCE_JTAG here, for the debug module,
-        * otherwise, it may become inaccessible after resume.
-        * This creates a potential security issue, as the sdmmc pins may
-        * accept jtag data for a short time during resume if no card is
-        * inserted.
-        * But this is of course also true for the regular boot, before we
-        * turn of the jtag/sdmmc autodetect.
-        */
-       regmap_write(grf_regmap, RK3288_GRF_SOC_CON0, GRF_FORCE_JTAG |
-                    GRF_FORCE_JTAG_WRITE);
-
        /*
         * SGRF_FAST_BOOT_EN - system to boot from FAST_BOOT_ADDR
         * PCLK_WDT_GATE - disable WDT during suspend.
@@ -151,9 +135,6 @@ static void rk3288_slp_mode_set_resume(void)
        regmap_write(sgrf_regmap, RK3288_SGRF_SOC_CON0,
                     rk3288_sgrf_soc_con0 | SGRF_PCLK_WDT_GATE_WRITE
                     | SGRF_FAST_BOOT_EN_WRITE);
-
-       regmap_write(grf_regmap, RK3288_GRF_SOC_CON0, rk3288_grf_soc_con0 |
-                    GRF_FORCE_JTAG_WRITE);
 }
 
 static int rockchip_lpmode_enter(unsigned long arg)
@@ -212,13 +193,6 @@ static int rk3288_suspend_init(struct device_node *np)
                return PTR_ERR(pmu_regmap);
        }
 
-       grf_regmap = syscon_regmap_lookup_by_compatible(
-                               "rockchip,rk3288-grf");
-       if (IS_ERR(grf_regmap)) {
-               pr_err("%s: could not find grf regmap\n", __func__);
-               return PTR_ERR(pmu_regmap);
-       }
-
        sram_np = of_find_compatible_node(NULL, NULL,
                                          "rockchip,rk3288-pmu-sram");
        if (!sram_np) {
index f8a747bc1437aa4dc0c25fde77ea7294e7978c5b..3e8d39c0c3d5f09c78d38a830f56f5bfe1990c26 100644 (file)
@@ -48,10 +48,6 @@ static inline void rockchip_suspend_init(void)
 #define RK3288_PMU_WAKEUP_RST_CLR_CNT  0x44
 #define RK3288_PMU_PWRMODE_CON1                0x90
 
-#define RK3288_GRF_SOC_CON0            0x244
-#define GRF_FORCE_JTAG                 BIT(12)
-#define GRF_FORCE_JTAG_WRITE           BIT(28)
-
 #define RK3288_SGRF_SOC_CON0           (0x0000)
 #define RK3288_SGRF_FAST_BOOT_ADDR     (0x0120)
 #define SGRF_PCLK_WDT_GATE             BIT(6)
index e1268f90502682c75dfd7a98e6ed15272ea8d512..e0e23582c8b4e4687209a219c0d2bbc86b88bbd9 100644 (file)
@@ -54,6 +54,7 @@
 #define SEEN_DATA              (1 << (BPF_MEMWORDS + 3))
 
 #define FLAG_NEED_X_RESET      (1 << 0)
+#define FLAG_IMM_OVERFLOW      (1 << 1)
 
 struct jit_ctx {
        const struct bpf_prog *skf;
@@ -293,6 +294,15 @@ static u16 imm_offset(u32 k, struct jit_ctx *ctx)
        /* PC in ARM mode == address of the instruction + 8 */
        imm = offset - (8 + ctx->idx * 4);
 
+       if (imm & ~0xfff) {
+               /*
+                * literal pool is too far, signal it into flags. we
+                * can only detect it on the second pass unfortunately.
+                */
+               ctx->flags |= FLAG_IMM_OVERFLOW;
+               return 0;
+       }
+
        return imm;
 }
 
@@ -449,10 +459,21 @@ static inline void emit_udiv(u8 rd, u8 rm, u8 rn, struct jit_ctx *ctx)
                return;
        }
 #endif
-       if (rm != ARM_R0)
-               emit(ARM_MOV_R(ARM_R0, rm), ctx);
+
+       /*
+        * For BPF_ALU | BPF_DIV | BPF_K instructions, rm is ARM_R4
+        * (r_A) and rn is ARM_R0 (r_scratch) so load rn first into
+        * ARM_R1 to avoid accidentally overwriting ARM_R0 with rm
+        * before using it as a source for ARM_R1.
+        *
+        * For BPF_ALU | BPF_DIV | BPF_X rm is ARM_R4 (r_A) and rn is
+        * ARM_R5 (r_X) so there is no particular register overlap
+        * issues.
+        */
        if (rn != ARM_R1)
                emit(ARM_MOV_R(ARM_R1, rn), ctx);
+       if (rm != ARM_R0)
+               emit(ARM_MOV_R(ARM_R0, rm), ctx);
 
        ctx->seen |= SEEN_CALL;
        emit_mov_i(ARM_R3, (u32)jit_udiv, ctx);
@@ -855,6 +876,14 @@ static int build_body(struct jit_ctx *ctx)
                default:
                        return -1;
                }
+
+               if (ctx->flags & FLAG_IMM_OVERFLOW)
+                       /*
+                        * this instruction generated an overflow when
+                        * trying to access the literal pool, so
+                        * delegate this filter to the kernel interpreter.
+                        */
+                       return -1;
        }
 
        /* compute offsets only during the first pass */
@@ -917,7 +946,14 @@ void bpf_jit_compile(struct bpf_prog *fp)
        ctx.idx = 0;
 
        build_prologue(&ctx);
-       build_body(&ctx);
+       if (build_body(&ctx) < 0) {
+#if __LINUX_ARM_ARCH__ < 7
+               if (ctx.imm_count)
+                       kfree(ctx.imms);
+#endif
+               bpf_jit_binary_free(header);
+               goto out;
+       }
        build_epilogue(&ctx);
 
        flush_icache_range((u32)ctx.target, (u32)(ctx.target + ctx.idx));
index 224081ccc92fa6516cd67a95e4a5871aee6420a0..7d0f07020c809598c8a5ea292093d3676c083548 100644 (file)
@@ -272,6 +272,7 @@ void xen_arch_pre_suspend(void) { }
 void xen_arch_post_suspend(int suspend_cancelled) { }
 void xen_timer_resume(void) { }
 void xen_arch_resume(void) { }
+void xen_arch_suspend(void) { }
 
 
 /* In the hypervisor.S file. */
index c138b95a8356836929c0f2781c80933da4727953..351c95bda89e5215a9ca525171509bfb4f831bee 100644 (file)
@@ -21,6 +21,20 @@ mb_clk25mhz: clk25mhz {
                        clock-output-names = "juno_mb:clk25mhz";
                };
 
+               v2m_refclk1mhz: refclk1mhz {
+                       compatible = "fixed-clock";
+                       #clock-cells = <0>;
+                       clock-frequency = <1000000>;
+                       clock-output-names = "juno_mb:refclk1mhz";
+               };
+
+               v2m_refclk32khz: refclk32khz {
+                       compatible = "fixed-clock";
+                       #clock-cells = <0>;
+                       clock-frequency = <32768>;
+                       clock-output-names = "juno_mb:refclk32khz";
+               };
+
                motherboard {
                        compatible = "arm,vexpress,v2p-p1", "simple-bus";
                        #address-cells = <2>;  /* SMB chipselect number and offset */
@@ -66,6 +80,15 @@ iofpga@3,00000000 {
                                #size-cells = <1>;
                                ranges = <0 3 0 0x200000>;
 
+                               v2m_sysctl: sysctl@020000 {
+                                       compatible = "arm,sp810", "arm,primecell";
+                                       reg = <0x020000 0x1000>;
+                                       clocks = <&v2m_refclk32khz>, <&v2m_refclk1mhz>, <&mb_clk24mhz>;
+                                       clock-names = "refclk", "timclk", "apb_pclk";
+                                       #clock-cells = <1>;
+                                       clock-output-names = "timerclken0", "timerclken1", "timerclken2", "timerclken3";
+                               };
+
                                mmci@050000 {
                                        compatible = "arm,pl180", "arm,primecell";
                                        reg = <0x050000 0x1000>;
@@ -106,16 +129,16 @@ v2m_timer01: timer@110000 {
                                        compatible = "arm,sp804", "arm,primecell";
                                        reg = <0x110000 0x10000>;
                                        interrupts = <9>;
-                                       clocks = <&mb_clk24mhz>, <&soc_smc50mhz>;
-                                       clock-names = "timclken1", "apb_pclk";
+                                       clocks = <&v2m_sysctl 0>, <&v2m_sysctl 1>, <&mb_clk24mhz>;
+                                       clock-names = "timclken1", "timclken2", "apb_pclk";
                                };
 
                                v2m_timer23: timer@120000 {
                                        compatible = "arm,sp804", "arm,primecell";
                                        reg = <0x120000 0x10000>;
                                        interrupts = <9>;
-                                       clocks = <&mb_clk24mhz>, <&soc_smc50mhz>;
-                                       clock-names = "timclken1", "apb_pclk";
+                                       clocks = <&v2m_sysctl 2>, <&v2m_sysctl 3>, <&mb_clk24mhz>;
+                                       clock-names = "timclken1", "timclken2", "apb_pclk";
                                };
 
                                rtc@170000 {
index 9499199924aebd4d6b27ced325d69918b641ddf3..6a37c3c6b11d39acc0db9d142652abcb18d21b9c 100644 (file)
@@ -147,13 +147,21 @@ static int chksum_final(struct shash_desc *desc, u8 *out)
 {
        struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
 
+       put_unaligned_le32(ctx->crc, out);
+       return 0;
+}
+
+static int chksumc_final(struct shash_desc *desc, u8 *out)
+{
+       struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
+
        put_unaligned_le32(~ctx->crc, out);
        return 0;
 }
 
 static int __chksum_finup(u32 crc, const u8 *data, unsigned int len, u8 *out)
 {
-       put_unaligned_le32(~crc32_arm64_le_hw(crc, data, len), out);
+       put_unaligned_le32(crc32_arm64_le_hw(crc, data, len), out);
        return 0;
 }
 
@@ -199,6 +207,14 @@ static int crc32_cra_init(struct crypto_tfm *tfm)
 {
        struct chksum_ctx *mctx = crypto_tfm_ctx(tfm);
 
+       mctx->key = 0;
+       return 0;
+}
+
+static int crc32c_cra_init(struct crypto_tfm *tfm)
+{
+       struct chksum_ctx *mctx = crypto_tfm_ctx(tfm);
+
        mctx->key = ~0;
        return 0;
 }
@@ -229,7 +245,7 @@ static struct shash_alg crc32c_alg = {
        .setkey                 =       chksum_setkey,
        .init                   =       chksum_init,
        .update                 =       chksumc_update,
-       .final                  =       chksum_final,
+       .final                  =       chksumc_final,
        .finup                  =       chksumc_finup,
        .digest                 =       chksumc_digest,
        .descsize               =       sizeof(struct chksum_desc_ctx),
@@ -241,7 +257,7 @@ static struct shash_alg crc32c_alg = {
                .cra_alignmask          =       0,
                .cra_ctxsize            =       sizeof(struct chksum_ctx),
                .cra_module             =       THIS_MODULE,
-               .cra_init               =       crc32_cra_init,
+               .cra_init               =       crc32c_cra_init,
        }
 };
 
index 114e7cc5de8c09b4eb75f6b11294e9c689d1ebbc..aefda9868627bde843227d1074e7cc9b17004298 100644 (file)
@@ -74,6 +74,9 @@ static int sha1_ce_finup(struct shash_desc *desc, const u8 *data,
 
 static int sha1_ce_final(struct shash_desc *desc, u8 *out)
 {
+       struct sha1_ce_state *sctx = shash_desc_ctx(desc);
+
+       sctx->finalize = 0;
        kernel_neon_begin_partial(16);
        sha1_base_do_finalize(desc, (sha1_block_fn *)sha1_ce_transform);
        kernel_neon_end();
index 1340e44c048beab91279b6dd317f10590a6f06b9..7cd587564a4176e902f12c7c7043b714caab48ea 100644 (file)
@@ -75,6 +75,9 @@ static int sha256_ce_finup(struct shash_desc *desc, const u8 *data,
 
 static int sha256_ce_final(struct shash_desc *desc, u8 *out)
 {
+       struct sha256_ce_state *sctx = shash_desc_ctx(desc);
+
+       sctx->finalize = 0;
        kernel_neon_begin_partial(28);
        sha256_base_do_finalize(desc, (sha256_block_fn *)sha2_ce_transform);
        kernel_neon_end();
index 21033bba939051b7db11e415983d7b10fcc485ca..28f8365edc4c43edd00043f38d89f8ae8be6476f 100644 (file)
@@ -24,7 +24,6 @@
 #include <asm/cacheflush.h>
 #include <asm/alternative.h>
 #include <asm/cpufeature.h>
-#include <asm/insn.h>
 #include <linux/stop_machine.h>
 
 extern struct alt_instr __alt_instructions[], __alt_instructions_end[];
@@ -34,48 +33,6 @@ struct alt_region {
        struct alt_instr *end;
 };
 
-/*
- * Decode the imm field of a b/bl instruction, and return the byte
- * offset as a signed value (so it can be used when computing a new
- * branch target).
- */
-static s32 get_branch_offset(u32 insn)
-{
-       s32 imm = aarch64_insn_decode_immediate(AARCH64_INSN_IMM_26, insn);
-
-       /* sign-extend the immediate before turning it into a byte offset */
-       return (imm << 6) >> 4;
-}
-
-static u32 get_alt_insn(u8 *insnptr, u8 *altinsnptr)
-{
-       u32 insn;
-
-       aarch64_insn_read(altinsnptr, &insn);
-
-       /* Stop the world on instructions we don't support... */
-       BUG_ON(aarch64_insn_is_cbz(insn));
-       BUG_ON(aarch64_insn_is_cbnz(insn));
-       BUG_ON(aarch64_insn_is_bcond(insn));
-       /* ... and there is probably more. */
-
-       if (aarch64_insn_is_b(insn) || aarch64_insn_is_bl(insn)) {
-               enum aarch64_insn_branch_type type;
-               unsigned long target;
-
-               if (aarch64_insn_is_b(insn))
-                       type = AARCH64_INSN_BRANCH_NOLINK;
-               else
-                       type = AARCH64_INSN_BRANCH_LINK;
-
-               target = (unsigned long)altinsnptr + get_branch_offset(insn);
-               insn = aarch64_insn_gen_branch_imm((unsigned long)insnptr,
-                                                  target, type);
-       }
-
-       return insn;
-}
-
 static int __apply_alternatives(void *alt_region)
 {
        struct alt_instr *alt;
@@ -83,9 +40,6 @@ static int __apply_alternatives(void *alt_region)
        u8 *origptr, *replptr;
 
        for (alt = region->begin; alt < region->end; alt++) {
-               u32 insn;
-               int i;
-
                if (!cpus_have_cap(alt->cpufeature))
                        continue;
 
@@ -95,12 +49,7 @@ static int __apply_alternatives(void *alt_region)
 
                origptr = (u8 *)&alt->orig_offset + alt->orig_offset;
                replptr = (u8 *)&alt->alt_offset + alt->alt_offset;
-
-               for (i = 0; i < alt->alt_len; i += sizeof(insn)) {
-                       insn = get_alt_insn(origptr + i, replptr + i);
-                       aarch64_insn_write(origptr + i, insn);
-               }
-
+               memcpy(origptr, replptr, alt->alt_len);
                flush_icache_range((uintptr_t)origptr,
                                   (uintptr_t)(origptr + alt->alt_len));
        }
index 23f25acf43a9021ee9b4ad0f79e3b3e5d6ef49c4..cce18c85d2e8edc6edcf23d13ef13e99f6cbf835 100644 (file)
@@ -1315,15 +1315,15 @@ static int armpmu_device_probe(struct platform_device *pdev)
        if (!cpu_pmu)
                return -ENODEV;
 
-       irqs = kcalloc(pdev->num_resources, sizeof(*irqs), GFP_KERNEL);
-       if (!irqs)
-               return -ENOMEM;
-
        /* Don't bother with PPIs; they're already affine */
        irq = platform_get_irq(pdev, 0);
        if (irq >= 0 && irq_is_percpu(irq))
                return 0;
 
+       irqs = kcalloc(pdev->num_resources, sizeof(*irqs), GFP_KERNEL);
+       if (!irqs)
+               return -ENOMEM;
+
        for (i = 0; i < pdev->num_resources; ++i) {
                struct device_node *dn;
                int cpu;
index 74c256744b254e09c989cabcd9072aee93c9fd6d..f3d6221cd5bdd4c7bf59fd99c71415d3922e2572 100644 (file)
@@ -328,10 +328,12 @@ static int ptdump_init(void)
                        for (j = 0; j < pg_level[i].num; j++)
                                pg_level[i].mask |= pg_level[i].bits[j].mask;
 
+#ifdef CONFIG_SPARSEMEM_VMEMMAP
        address_markers[VMEMMAP_START_NR].start_address =
                                (unsigned long)virt_to_page(PAGE_OFFSET);
        address_markers[VMEMMAP_END_NR].start_address =
                                (unsigned long)virt_to_page(high_memory);
+#endif
 
        pe = debugfs_create_file("kernel_page_tables", 0400, NULL, NULL,
                                 &ptdump_fops);
index edba042b23259c6f4b642a842fc1a2eb740c59b3..dc6a4842683aa500b9a5fc3af41caec349472902 100644 (file)
@@ -487,7 +487,7 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
                        return -EINVAL;
                }
 
-               imm64 = (u64)insn1.imm << 32 | imm;
+               imm64 = (u64)insn1.imm << 32 | (u32)imm;
                emit_a64_mov_i64(dst, imm64, ctx);
 
                return 1;
index 5200f649dd4e3005423a81b4c608fc4ac49d2321..ae2dd59050f742c54c49b3f80925bbfc4e67fbbd 100644 (file)
@@ -277,7 +277,7 @@ LDFLAGS                     += -m $(ld-emul)
 ifdef CONFIG_MIPS
 CHECKFLAGS += $(shell $(CC) $(KBUILD_CFLAGS) -dM -E -x c /dev/null | \
        egrep -vw '__GNUC_(|MINOR_|PATCHLEVEL_)_' | \
-       sed -e "s/^\#define /-D'/" -e "s/ /'='/" -e "s/$$/'/")
+       sed -e "s/^\#define /-D'/" -e "s/ /'='/" -e "s/$$/'/" -e 's/\$$/&&/g')
 ifdef CONFIG_64BIT
 CHECKFLAGS             += -m64
 endif
index a594d8ed96980cd1e96c8bf3eb593368203fe53c..f19e890b99d2744ae4984ea54e2ca9e5128ce7fe 100644 (file)
@@ -304,7 +304,7 @@ do {                                                                        \
                                                                        \
        current->thread.abi = &mips_abi;                                \
                                                                        \
-       current->thread.fpu.fcr31 = current_cpu_data.fpu_csr31;         \
+       current->thread.fpu.fcr31 = boot_cpu_data.fpu_csr31;            \
 } while (0)
 
 #endif /* CONFIG_32BIT */
@@ -366,7 +366,7 @@ do {                                                                        \
        else                                                            \
                current->thread.abi = &mips_abi;                        \
                                                                        \
-       current->thread.fpu.fcr31 = current_cpu_data.fpu_csr31;         \
+       current->thread.fpu.fcr31 = boot_cpu_data.fpu_csr31;            \
                                                                        \
        p = personality(current->personality);                          \
        if (p != PER_LINUX32 && p != PER_LINUX)                         \
index bb02fac9b4fa0188e12b263376f3e1e08f83b022..2b25d1ba1ea037ca82212ec542a165e714ecf29c 100644 (file)
@@ -45,7 +45,7 @@ extern int __cpu_logical_map[NR_CPUS];
 #define SMP_DUMP               0x8
 #define SMP_ASK_C0COUNT                0x10
 
-extern volatile cpumask_t cpu_callin_map;
+extern cpumask_t cpu_callin_map;
 
 /* Mask of CPUs which are currently definitely operating coherently */
 extern cpumask_t cpu_coherent_mask;
index be4899f3c393275a992083d6f7e9f19c2fde5b87..4a4d9e067c89427fc34e990586f0e8237a9418ba 100644 (file)
@@ -76,14 +76,6 @@ int arch_elf_pt_proc(void *_ehdr, void *_phdr, struct file *elf,
 
        /* Lets see if this is an O32 ELF */
        if (ehdr32->e_ident[EI_CLASS] == ELFCLASS32) {
-               /* FR = 1 for N32 */
-               if (ehdr32->e_flags & EF_MIPS_ABI2)
-                       state->overall_fp_mode = FP_FR1;
-               else
-                       /* Set a good default FPU mode for O32 */
-                       state->overall_fp_mode = cpu_has_mips_r6 ?
-                               FP_FRE : FP_FR0;
-
                if (ehdr32->e_flags & EF_MIPS_FP64) {
                        /*
                         * Set MIPS_ABI_FP_OLD_64 for EF_MIPS_FP64. We will override it
@@ -104,9 +96,6 @@ int arch_elf_pt_proc(void *_ehdr, void *_phdr, struct file *elf,
                                  (char *)&abiflags,
                                  sizeof(abiflags));
        } else {
-               /* FR=1 is really the only option for 64-bit */
-               state->overall_fp_mode = FP_FR1;
-
                if (phdr64->p_type != PT_MIPS_ABIFLAGS)
                        return 0;
                if (phdr64->p_filesz < sizeof(abiflags))
@@ -137,6 +126,7 @@ int arch_check_elf(void *_ehdr, bool has_interpreter,
        struct elf32_hdr *ehdr = _ehdr;
        struct mode_req prog_req, interp_req;
        int fp_abi, interp_fp_abi, abi0, abi1, max_abi;
+       bool is_mips64;
 
        if (!config_enabled(CONFIG_MIPS_O32_FP64_SUPPORT))
                return 0;
@@ -152,10 +142,22 @@ int arch_check_elf(void *_ehdr, bool has_interpreter,
                abi0 = abi1 = fp_abi;
        }
 
-       /* ABI limits. O32 = FP_64A, N32/N64 = FP_SOFT */
-       max_abi = ((ehdr->e_ident[EI_CLASS] == ELFCLASS32) &&
-                  (!(ehdr->e_flags & EF_MIPS_ABI2))) ?
-               MIPS_ABI_FP_64A : MIPS_ABI_FP_SOFT;
+       is_mips64 = (ehdr->e_ident[EI_CLASS] == ELFCLASS64) ||
+                   (ehdr->e_flags & EF_MIPS_ABI2);
+
+       if (is_mips64) {
+               /* MIPS64 code always uses FR=1, thus the default is easy */
+               state->overall_fp_mode = FP_FR1;
+
+               /* Disallow access to the various FPXX & FP64 ABIs */
+               max_abi = MIPS_ABI_FP_SOFT;
+       } else {
+               /* Default to a mode capable of running code expecting FR=0 */
+               state->overall_fp_mode = cpu_has_mips_r6 ? FP_FRE : FP_FR0;
+
+               /* Allow all ABIs we know about */
+               max_abi = MIPS_ABI_FP_64A;
+       }
 
        if ((abi0 > max_abi && abi0 != MIPS_ABI_FP_UNKNOWN) ||
            (abi1 > max_abi && abi1 != MIPS_ABI_FP_UNKNOWN))
index d544e774eea6b1b6e0f811099290600b1fc5b534..e933a309f2ea5fa4498153a9b6a3caa0af4a1587 100644 (file)
@@ -176,7 +176,7 @@ int ptrace_setfpregs(struct task_struct *child, __u32 __user *data)
 
        __get_user(value, data + 64);
        fcr31 = child->thread.fpu.fcr31;
-       mask = current_cpu_data.fpu_msk31;
+       mask = boot_cpu_data.fpu_msk31;
        child->thread.fpu.fcr31 = (value & ~mask) | (fcr31 & mask);
 
        /* FIR may not be written.  */
index 7e011f95bb8e14785d447bf49bb1b8141cf0bc08..4251d390b5b66e0c20a7271659a280e448ca0ffe 100644 (file)
@@ -92,7 +92,7 @@ static void __init cps_smp_setup(void)
 #ifdef CONFIG_MIPS_MT_FPAFF
        /* If we have an FPU, enroll ourselves in the FPU-full mask */
        if (cpu_has_fpu)
-               cpu_set(0, mt_fpu_cpumask);
+               cpumask_set_cpu(0, &mt_fpu_cpumask);
 #endif /* CONFIG_MIPS_MT_FPAFF */
 }
 
index 193ace7955fb5eec377b666db534d76173a014c5..faa46ebd9ddae2fc43f20d6ff65f28688f665c4f 100644 (file)
@@ -43,7 +43,7 @@
 #include <asm/time.h>
 #include <asm/setup.h>
 
-volatile cpumask_t cpu_callin_map;     /* Bitmask of started secondaries */
+cpumask_t cpu_callin_map;              /* Bitmask of started secondaries */
 
 int __cpu_number_map[NR_CPUS];         /* Map physical to logical */
 EXPORT_SYMBOL(__cpu_number_map);
@@ -218,8 +218,10 @@ int __cpu_up(unsigned int cpu, struct task_struct *tidle)
        /*
         * Trust is futile.  We should really have timeouts ...
         */
-       while (!cpumask_test_cpu(cpu, &cpu_callin_map))
+       while (!cpumask_test_cpu(cpu, &cpu_callin_map)) {
                udelay(100);
+               schedule();
+       }
 
        synchronise_count_master(cpu);
        return 0;
index ba32e48d4697193f3410edd79153d392ab0d8311..d2d1c1933bc9f598efaa81735d132af1ff12adee 100644 (file)
@@ -269,7 +269,6 @@ static void __show_regs(const struct pt_regs *regs)
         */
        printk("epc   : %0*lx %pS\n", field, regs->cp0_epc,
               (void *) regs->cp0_epc);
-       printk("    %s\n", print_tainted());
        printk("ra    : %0*lx %pS\n", field, regs->regs[31],
               (void *) regs->regs[31]);
 
index 6230f376a44e7ab6f09041c4b805e54e59468489..4b50c5787e25bdb4bdb28eb7736296e1d5d3812c 100644 (file)
@@ -2389,7 +2389,6 @@ enum emulation_result kvm_mips_complete_mmio_load(struct kvm_vcpu *vcpu,
 {
        unsigned long *gpr = &vcpu->arch.gprs[vcpu->arch.io_gpr];
        enum emulation_result er = EMULATE_DONE;
-       unsigned long curr_pc;
 
        if (run->mmio.len > sizeof(*gpr)) {
                kvm_err("Bad MMIO length: %d", run->mmio.len);
@@ -2397,11 +2396,6 @@ enum emulation_result kvm_mips_complete_mmio_load(struct kvm_vcpu *vcpu,
                goto done;
        }
 
-       /*
-        * Update PC and hold onto current PC in case there is
-        * an error and we want to rollback the PC
-        */
-       curr_pc = vcpu->arch.pc;
        er = update_pc(vcpu, vcpu->arch.pending_load_cause);
        if (er == EMULATE_FAIL)
                return er;
index d31c537ace1d11b7f742fd9ead71d3f273cfa2d3..22b9b2cb9219fa4e4eb7b9cc340125a4c9aa4053 100644 (file)
@@ -889,7 +889,7 @@ static inline void cop1_cfc(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
                break;
 
        case FPCREG_RID:
-               value = current_cpu_data.fpu_id;
+               value = boot_cpu_data.fpu_id;
                break;
 
        default:
@@ -921,7 +921,7 @@ static inline void cop1_ctc(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
                         (void *)xcp->cp0_epc, MIPSInst_RT(ir), value);
 
                /* Preserve read-only bits.  */
-               mask = current_cpu_data.fpu_msk31;
+               mask = boot_cpu_data.fpu_msk31;
                fcr31 = (value & ~mask) | (fcr31 & mask);
                break;
 
index a27a088e6f9f830f7e3445abab6bae5cd8b60478..08318ecb803a08611adfd0025041c16526d097e2 100644 (file)
@@ -495,7 +495,7 @@ static void r4k_tlb_configure(void)
 
        if (cpu_has_rixi) {
                /*
-                * Enable the no read, no exec bits, and enable large virtual
+                * Enable the no read, no exec bits, and enable large physical
                 * address.
                 */
 #ifdef CONFIG_64BIT
index 0134db2ad0a850ca5f2e07c912fe24e746dda902..5a2a82148d8d4f633c644f951ca87f252bdce09b 100644 (file)
@@ -130,9 +130,9 @@ struct platform_device ip32_rtc_device = {
        .resource               = ip32_rtc_resources,
 };
 
-+static int __init sgio2_rtc_devinit(void)
+static __init int sgio2_rtc_devinit(void)
 {
        return platform_device_register(&ip32_rtc_device);
 }
 
-device_initcall(sgio2_cmos_devinit);
+device_initcall(sgio2_rtc_devinit);
index 3391d061eccc02fb64ebff9211cb9146c9f50a1c..78c9fd32c5546b6ec91d591e853d89a761383c92 100644 (file)
@@ -348,6 +348,10 @@ struct pt_regs;    /* forward declaration... */
 
 #define ELF_HWCAP      0
 
+#define STACK_RND_MASK (is_32bit_task() ? \
+                               0x7ff >> (PAGE_SHIFT - 12) : \
+                               0x3ffff >> (PAGE_SHIFT - 12))
+
 struct mm_struct;
 extern unsigned long arch_randomize_brk(struct mm_struct *);
 #define arch_randomize_brk arch_randomize_brk
index 8a488c22a99f7bb3836fc93a23a31561a237fb86..809905a811ed72a543ad257c1394900a4b976af8 100644 (file)
@@ -181,9 +181,12 @@ int dump_task_fpu (struct task_struct *tsk, elf_fpregset_t *r)
        return 1;
 }
 
+/*
+ * Copy architecture-specific thread state
+ */
 int
 copy_thread(unsigned long clone_flags, unsigned long usp,
-           unsigned long arg, struct task_struct *p)
+           unsigned long kthread_arg, struct task_struct *p)
 {
        struct pt_regs *cregs = &(p->thread.regs);
        void *stack = task_stack_page(p);
@@ -195,11 +198,10 @@ copy_thread(unsigned long clone_flags, unsigned long usp,
        extern void * const child_return;
 
        if (unlikely(p->flags & PF_KTHREAD)) {
+               /* kernel thread */
                memset(cregs, 0, sizeof(struct pt_regs));
                if (!usp) /* idle thread */
                        return 0;
-
-               /* kernel thread */
                /* Must exit via ret_from_kernel_thread in order
                 * to call schedule_tail()
                 */
@@ -215,7 +217,7 @@ copy_thread(unsigned long clone_flags, unsigned long usp,
 #else
                cregs->gr[26] = usp;
 #endif
-               cregs->gr[25] = arg;
+               cregs->gr[25] = kthread_arg;
        } else {
                /* user thread */
                /* usp must be word aligned.  This also prevents users from
index e1ffea2f9a0b05ccda844969dcb7c519ab17077a..5aba01ac457ffc5d4823cf09c071f02f00a1d015 100644 (file)
@@ -77,6 +77,9 @@ static unsigned long mmap_upper_limit(void)
        if (stack_base > STACK_SIZE_MAX)
                stack_base = STACK_SIZE_MAX;
 
+       /* Add space for stack randomization. */
+       stack_base += (STACK_RND_MASK << PAGE_SHIFT);
+
        return PAGE_ALIGN(STACK_TOP - stack_base);
 }
 
index 15c99b649b04cf2e946e2a612a3660dc50e6712c..b2eb4686bd8f40155bbb4a982549de0ae8de8567 100644 (file)
@@ -73,7 +73,7 @@ void save_mce_event(struct pt_regs *regs, long handled,
                    uint64_t nip, uint64_t addr)
 {
        uint64_t srr1;
-       int index = __this_cpu_inc_return(mce_nest_count);
+       int index = __this_cpu_inc_return(mce_nest_count) - 1;
        struct machine_check_event *mce = this_cpu_ptr(&mce_event[index]);
 
        /*
@@ -184,7 +184,7 @@ void machine_check_queue_event(void)
        if (!get_mce_event(&evt, MCE_EVENT_RELEASE))
                return;
 
-       index = __this_cpu_inc_return(mce_queue_count);
+       index = __this_cpu_inc_return(mce_queue_count) - 1;
        /* If queue is full, just return for now. */
        if (index >= MAX_MC_EVT) {
                __this_cpu_dec(mce_queue_count);
index f096e72262f41d121398f8fa27d5286bd8641bf4..1db685104ffc2b298375c9062590ae1c2f811db9 100644 (file)
@@ -213,6 +213,7 @@ SECTIONS
                *(.opd)
        }
 
+       . = ALIGN(256);
        .got : AT(ADDR(.got) - LOAD_OFFSET) {
                __toc_start = .;
 #ifndef CONFIG_RELOCATABLE
index 48d3c5d2ecc9ee83aab086715b3ffd6bf904d80a..df81caab738339c5b8dfe7c2def731bb9ba640d1 100644 (file)
@@ -1952,7 +1952,7 @@ static void post_guest_process(struct kvmppc_vcore *vc)
  */
 static noinline void kvmppc_run_core(struct kvmppc_vcore *vc)
 {
-       struct kvm_vcpu *vcpu;
+       struct kvm_vcpu *vcpu, *vnext;
        int i;
        int srcu_idx;
 
@@ -1982,7 +1982,8 @@ static noinline void kvmppc_run_core(struct kvmppc_vcore *vc)
         */
        if ((threads_per_core > 1) &&
            ((vc->num_threads > threads_per_subcore) || !on_primary_thread())) {
-               list_for_each_entry(vcpu, &vc->runnable_threads, arch.run_list) {
+               list_for_each_entry_safe(vcpu, vnext, &vc->runnable_threads,
+                                        arch.run_list) {
                        vcpu->arch.ret = -EBUSY;
                        kvmppc_remove_runnable(vc, vcpu);
                        wake_up(&vcpu->arch.cpu_run);
index 0ce968b00b7c665967ca3addc26d0cc04a72f729..3385e3d0506ec575f3eeebad77d2c65264a3acf3 100644 (file)
@@ -689,27 +689,34 @@ void hugetlb_free_pgd_range(struct mmu_gather *tlb,
 struct page *
 follow_huge_addr(struct mm_struct *mm, unsigned long address, int write)
 {
-       pte_t *ptep;
-       struct page *page;
+       pte_t *ptep, pte;
        unsigned shift;
        unsigned long mask, flags;
+       struct page *page = ERR_PTR(-EINVAL);
+
+       local_irq_save(flags);
+       ptep = find_linux_pte_or_hugepte(mm->pgd, address, &shift);
+       if (!ptep)
+               goto no_page;
+       pte = READ_ONCE(*ptep);
        /*
+        * Verify it is a huge page else bail.
         * Transparent hugepages are handled by generic code. We can skip them
         * here.
         */
-       local_irq_save(flags);
-       ptep = find_linux_pte_or_hugepte(mm->pgd, address, &shift);
+       if (!shift || pmd_trans_huge(__pmd(pte_val(pte))))
+               goto no_page;
 
-       /* Verify it is a huge page else bail. */
-       if (!ptep || !shift || pmd_trans_huge(*(pmd_t *)ptep)) {
-               local_irq_restore(flags);
-               return ERR_PTR(-EINVAL);
+       if (!pte_present(pte)) {
+               page = NULL;
+               goto no_page;
        }
        mask = (1UL << shift) - 1;
-       page = pte_page(*ptep);
+       page = pte_page(pte);
        if (page)
                page += (address & mask) / PAGE_SIZE;
 
+no_page:
        local_irq_restore(flags);
        return page;
 }
index 59daa5eeec2526ae481a5dda586c629a985813d7..6bfadf1aa5cbbfadbd7237e5f3da8ac8653a5651 100644 (file)
@@ -839,6 +839,17 @@ pmd_t pmdp_get_and_clear(struct mm_struct *mm,
         * hash fault look at them.
         */
        memset(pgtable, 0, PTE_FRAG_SIZE);
+       /*
+        * Serialize against find_linux_pte_or_hugepte which does lock-less
+        * lookup in page tables with local interrupts disabled. For huge pages
+        * it casts pmd_t to pte_t. Since format of pte_t is different from
+        * pmd_t we want to prevent transit from pmd pointing to page table
+        * to pmd pointing to huge page (and back) while interrupts are disabled.
+        * We clear pmd to possibly replace it with page table pointer in
+        * different code paths. So make sure we wait for the parallel
+        * find_linux_pte_or_hugepage to finish.
+        */
+       kick_all_cpus_sync();
        return old_pmd;
 }
 
index 7940dc90e80bc6729371ab565bad743b1087ef72..b258110da952d320443d113cdcff38beb14ae432 100644 (file)
 #define GHASH_DIGEST_SIZE      16
 
 struct ghash_ctx {
-       u8 icv[16];
-       u8 key[16];
+       u8 key[GHASH_BLOCK_SIZE];
 };
 
 struct ghash_desc_ctx {
+       u8 icv[GHASH_BLOCK_SIZE];
+       u8 key[GHASH_BLOCK_SIZE];
        u8 buffer[GHASH_BLOCK_SIZE];
        u32 bytes;
 };
@@ -28,8 +29,10 @@ struct ghash_desc_ctx {
 static int ghash_init(struct shash_desc *desc)
 {
        struct ghash_desc_ctx *dctx = shash_desc_ctx(desc);
+       struct ghash_ctx *ctx = crypto_shash_ctx(desc->tfm);
 
        memset(dctx, 0, sizeof(*dctx));
+       memcpy(dctx->key, ctx->key, GHASH_BLOCK_SIZE);
 
        return 0;
 }
@@ -45,7 +48,6 @@ static int ghash_setkey(struct crypto_shash *tfm,
        }
 
        memcpy(ctx->key, key, GHASH_BLOCK_SIZE);
-       memset(ctx->icv, 0, GHASH_BLOCK_SIZE);
 
        return 0;
 }
@@ -54,7 +56,6 @@ static int ghash_update(struct shash_desc *desc,
                         const u8 *src, unsigned int srclen)
 {
        struct ghash_desc_ctx *dctx = shash_desc_ctx(desc);
-       struct ghash_ctx *ctx = crypto_shash_ctx(desc->tfm);
        unsigned int n;
        u8 *buf = dctx->buffer;
        int ret;
@@ -70,7 +71,7 @@ static int ghash_update(struct shash_desc *desc,
                src += n;
 
                if (!dctx->bytes) {
-                       ret = crypt_s390_kimd(KIMD_GHASH, ctx, buf,
+                       ret = crypt_s390_kimd(KIMD_GHASH, dctx, buf,
                                              GHASH_BLOCK_SIZE);
                        if (ret != GHASH_BLOCK_SIZE)
                                return -EIO;
@@ -79,7 +80,7 @@ static int ghash_update(struct shash_desc *desc,
 
        n = srclen & ~(GHASH_BLOCK_SIZE - 1);
        if (n) {
-               ret = crypt_s390_kimd(KIMD_GHASH, ctx, src, n);
+               ret = crypt_s390_kimd(KIMD_GHASH, dctx, src, n);
                if (ret != n)
                        return -EIO;
                src += n;
@@ -94,7 +95,7 @@ static int ghash_update(struct shash_desc *desc,
        return 0;
 }
 
-static int ghash_flush(struct ghash_ctx *ctx, struct ghash_desc_ctx *dctx)
+static int ghash_flush(struct ghash_desc_ctx *dctx)
 {
        u8 *buf = dctx->buffer;
        int ret;
@@ -104,24 +105,24 @@ static int ghash_flush(struct ghash_ctx *ctx, struct ghash_desc_ctx *dctx)
 
                memset(pos, 0, dctx->bytes);
 
-               ret = crypt_s390_kimd(KIMD_GHASH, ctx, buf, GHASH_BLOCK_SIZE);
+               ret = crypt_s390_kimd(KIMD_GHASH, dctx, buf, GHASH_BLOCK_SIZE);
                if (ret != GHASH_BLOCK_SIZE)
                        return -EIO;
+
+               dctx->bytes = 0;
        }
 
-       dctx->bytes = 0;
        return 0;
 }
 
 static int ghash_final(struct shash_desc *desc, u8 *dst)
 {
        struct ghash_desc_ctx *dctx = shash_desc_ctx(desc);
-       struct ghash_ctx *ctx = crypto_shash_ctx(desc->tfm);
        int ret;
 
-       ret = ghash_flush(ctx, dctx);
+       ret = ghash_flush(dctx);
        if (!ret)
-               memcpy(dst, ctx->icv, GHASH_BLOCK_SIZE);
+               memcpy(dst, dctx->icv, GHASH_BLOCK_SIZE);
        return ret;
 }
 
index 1f374b39a4ec9a933249b3924d393d118084112f..9d5192c9496317d490a338e19a69718ef00741dd 100644 (file)
@@ -125,7 +125,7 @@ static int generate_entropy(u8 *ebuf, size_t nbytes)
                /* fill page with urandom bytes */
                get_random_bytes(pg, PAGE_SIZE);
                /* exor page with stckf values */
-               for (n = 0; n < sizeof(PAGE_SIZE/sizeof(u64)); n++) {
+               for (n = 0; n < PAGE_SIZE / sizeof(u64); n++) {
                        u64 *p = ((u64 *)pg) + n;
                        *p ^= get_tod_clock_fast();
                }
index fc642399b489d896f2b4494cc57456ab7bd2ddb9..ef24a212eeb727b8d8df3326115ef17dbeb0a272 100644 (file)
@@ -494,7 +494,7 @@ static inline int pmd_large(pmd_t pmd)
        return (pmd_val(pmd) & _SEGMENT_ENTRY_LARGE) != 0;
 }
 
-static inline int pmd_pfn(pmd_t pmd)
+static inline unsigned long pmd_pfn(pmd_t pmd)
 {
        unsigned long origin_mask;
 
index 7690dc8e1ab5bb619bb19ec1be1b12853e1b0589..20c146d1251ae2cd6c07279bf371adae6b2e3a1e 100644 (file)
@@ -443,8 +443,11 @@ static void bpf_jit_epilogue(struct bpf_jit *jit)
 
 /*
  * Compile one eBPF instruction into s390x code
+ *
+ * NOTE: Use noinline because for gcov (-fprofile-arcs) gcc allocates a lot of
+ * stack space for the large switch statement.
  */
-static int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, int i)
+static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, int i)
 {
        struct bpf_insn *insn = &fp->insnsi[i];
        int jmp_off, last, insn_count = 1;
@@ -588,8 +591,8 @@ static int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, int i)
                EMIT4(0xb9160000, dst_reg, rc_reg);
                break;
        }
-       case BPF_ALU64 | BPF_DIV | BPF_X: /* dst = dst / (u32) src */
-       case BPF_ALU64 | BPF_MOD | BPF_X: /* dst = dst % (u32) src */
+       case BPF_ALU64 | BPF_DIV | BPF_X: /* dst = dst / src */
+       case BPF_ALU64 | BPF_MOD | BPF_X: /* dst = dst % src */
        {
                int rc_reg = BPF_OP(insn->code) == BPF_DIV ? REG_W1 : REG_W0;
 
@@ -602,10 +605,8 @@ static int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, int i)
                EMIT4_IMM(0xa7090000, REG_W0, 0);
                /* lgr %w1,%dst */
                EMIT4(0xb9040000, REG_W1, dst_reg);
-               /* llgfr %dst,%src (u32 cast) */
-               EMIT4(0xb9160000, dst_reg, src_reg);
                /* dlgr %w0,%dst */
-               EMIT4(0xb9870000, REG_W0, dst_reg);
+               EMIT4(0xb9870000, REG_W0, src_reg);
                /* lgr %dst,%rc */
                EMIT4(0xb9040000, dst_reg, rc_reg);
                break;
@@ -632,8 +633,8 @@ static int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, int i)
                EMIT4(0xb9160000, dst_reg, rc_reg);
                break;
        }
-       case BPF_ALU64 | BPF_DIV | BPF_K: /* dst = dst / (u32) imm */
-       case BPF_ALU64 | BPF_MOD | BPF_K: /* dst = dst % (u32) imm */
+       case BPF_ALU64 | BPF_DIV | BPF_K: /* dst = dst / imm */
+       case BPF_ALU64 | BPF_MOD | BPF_K: /* dst = dst % imm */
        {
                int rc_reg = BPF_OP(insn->code) == BPF_DIV ? REG_W1 : REG_W0;
 
@@ -649,7 +650,7 @@ static int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, int i)
                EMIT4(0xb9040000, REG_W1, dst_reg);
                /* dlg %w0,<d(imm)>(%l) */
                EMIT6_DISP_LH(0xe3000000, 0x0087, REG_W0, REG_0, REG_L,
-                             EMIT_CONST_U64((u32) imm));
+                             EMIT_CONST_U64(imm));
                /* lgr %dst,%rc */
                EMIT4(0xb9040000, dst_reg, rc_reg);
                break;
index dea2e7e962e3e0648c9ecaaaffc5cb723b32f299..f4a555beef1908b78c9ad6992d4727d59d9c81ee 100644 (file)
@@ -207,6 +207,7 @@ union kvm_mmu_page_role {
                unsigned nxe:1;
                unsigned cr0_wp:1;
                unsigned smep_andnot_wp:1;
+               unsigned smap_andnot_wp:1;
        };
 };
 
@@ -400,6 +401,7 @@ struct kvm_vcpu_arch {
        struct kvm_mmu_memory_cache mmu_page_header_cache;
 
        struct fpu guest_fpu;
+       bool eager_fpu;
        u64 xcr0;
        u64 guest_supported_xcr0;
        u32 guest_xstate_size;
@@ -743,6 +745,7 @@ struct kvm_x86_ops {
        void (*cache_reg)(struct kvm_vcpu *vcpu, enum kvm_reg reg);
        unsigned long (*get_rflags)(struct kvm_vcpu *vcpu);
        void (*set_rflags)(struct kvm_vcpu *vcpu, unsigned long rflags);
+       void (*fpu_activate)(struct kvm_vcpu *vcpu);
        void (*fpu_deactivate)(struct kvm_vcpu *vcpu);
 
        void (*tlb_flush)(struct kvm_vcpu *vcpu);
index e535533d5ab89313ba51937ad8dd5740413f119e..20190bdac9d58ecabddd3cbe6692d0f52bb687ad 100644 (file)
@@ -708,6 +708,7 @@ static int mce_no_way_out(struct mce *m, char **msg, unsigned long *validp,
                          struct pt_regs *regs)
 {
        int i, ret = 0;
+       char *tmp;
 
        for (i = 0; i < mca_cfg.banks; i++) {
                m->status = mce_rdmsrl(MSR_IA32_MCx_STATUS(i));
@@ -716,9 +717,11 @@ static int mce_no_way_out(struct mce *m, char **msg, unsigned long *validp,
                        if (quirk_no_way_out)
                                quirk_no_way_out(i, m, regs);
                }
-               if (mce_severity(m, mca_cfg.tolerant, msg, true) >=
-                   MCE_PANIC_SEVERITY)
+
+               if (mce_severity(m, mca_cfg.tolerant, &tmp, true) >= MCE_PANIC_SEVERITY) {
+                       *msg = tmp;
                        ret = 1;
+               }
        }
        return ret;
 }
index 960e85de13fbca45c317eeb8b719f05c7914ba1f..3998131d1a683058d6382b527c187028a7fede38 100644 (file)
@@ -1134,7 +1134,7 @@ static __initconst const u64 slm_hw_cache_extra_regs
  [ C(LL  ) ] = {
        [ C(OP_READ) ] = {
                [ C(RESULT_ACCESS) ] = SLM_DMND_READ|SLM_LLC_ACCESS,
-               [ C(RESULT_MISS)   ] = SLM_DMND_READ|SLM_LLC_MISS,
+               [ C(RESULT_MISS)   ] = 0,
        },
        [ C(OP_WRITE) ] = {
                [ C(RESULT_ACCESS) ] = SLM_DMND_WRITE|SLM_LLC_ACCESS,
@@ -1184,8 +1184,7 @@ static __initconst const u64 slm_hw_cache_event_ids
        [ C(OP_READ) ] = {
                /* OFFCORE_RESPONSE.ANY_DATA.LOCAL_CACHE */
                [ C(RESULT_ACCESS) ] = 0x01b7,
-               /* OFFCORE_RESPONSE.ANY_DATA.ANY_LLC_MISS */
-               [ C(RESULT_MISS)   ] = 0x01b7,
+               [ C(RESULT_MISS)   ] = 0,
        },
        [ C(OP_WRITE) ] = {
                /* OFFCORE_RESPONSE.ANY_RFO.LOCAL_CACHE */
@@ -1217,7 +1216,7 @@ static __initconst const u64 slm_hw_cache_event_ids
  [ C(ITLB) ] = {
        [ C(OP_READ) ] = {
                [ C(RESULT_ACCESS) ] = 0x00c0, /* INST_RETIRED.ANY_P */
-               [ C(RESULT_MISS)   ] = 0x0282, /* ITLB.MISSES */
+               [ C(RESULT_MISS)   ] = 0x40205, /* PAGE_WALKS.I_SIDE_WALKS */
        },
        [ C(OP_WRITE) ] = {
                [ C(RESULT_ACCESS) ] = -1,
index 999289b94025623415693df205054e754e9a7d4b..358c54ad20d4084db807a05ae49def561aa4dd32 100644 (file)
@@ -722,6 +722,7 @@ static int __init rapl_pmu_init(void)
                break;
        case 60: /* Haswell */
        case 69: /* Haswell-Celeron */
+       case 61: /* Broadwell */
                rapl_cntr_mask = RAPL_IDX_HSW;
                rapl_pmu_events_group.attrs = rapl_events_hsw_attr;
                break;
index 009183276bb738fbd28805256ccfaa04e063c364..6185d3141219019d82fa2ea56c4f2f5728b8d17a 100644 (file)
@@ -173,6 +173,21 @@ static void init_thread_xstate(void)
                xstate_size = sizeof(struct i387_fxsave_struct);
        else
                xstate_size = sizeof(struct i387_fsave_struct);
+
+       /*
+        * Quirk: we don't yet handle the XSAVES* instructions
+        * correctly, as we don't correctly convert between
+        * standard and compacted format when interfacing
+        * with user-space - so disable it for now.
+        *
+        * The difference is small: with recent CPUs the
+        * compacted format is only marginally smaller than
+        * the standard FPU state format.
+        *
+        * ( This is easy to backport while we are fixing
+        *   XSAVES* support. )
+        */
+       setup_clear_cpu_cap(X86_FEATURE_XSAVES);
 }
 
 /*
index 59b69f6a2844cdce101a69c3bb34eb7ccd30556f..1d08ad3582d07fd61cd03302eba547e3a997058b 100644 (file)
@@ -16,6 +16,8 @@
 #include <linux/module.h>
 #include <linux/vmalloc.h>
 #include <linux/uaccess.h>
+#include <asm/i387.h> /* For use_eager_fpu.  Ugh! */
+#include <asm/fpu-internal.h> /* For use_eager_fpu.  Ugh! */
 #include <asm/user.h>
 #include <asm/xsave.h>
 #include "cpuid.h"
@@ -95,6 +97,8 @@ int kvm_update_cpuid(struct kvm_vcpu *vcpu)
        if (best && (best->eax & (F(XSAVES) | F(XSAVEC))))
                best->ebx = xstate_required_size(vcpu->arch.xcr0, true);
 
+       vcpu->arch.eager_fpu = guest_cpuid_has_mpx(vcpu);
+
        /*
         * The existing code assumes virtual address is 48-bit in the canonical
         * address checks; exit if it is ever changed.
index c3b1ad9fca818befb9e5920f7eb7c0d2b703d245..496b3695d3d3c96fd2687b2b6bc013d9ee8d96e5 100644 (file)
@@ -117,4 +117,12 @@ static inline bool guest_cpuid_has_rtm(struct kvm_vcpu *vcpu)
        best = kvm_find_cpuid_entry(vcpu, 7, 0);
        return best && (best->ebx & bit(X86_FEATURE_RTM));
 }
+
+static inline bool guest_cpuid_has_mpx(struct kvm_vcpu *vcpu)
+{
+       struct kvm_cpuid_entry2 *best;
+
+       best = kvm_find_cpuid_entry(vcpu, 7, 0);
+       return best && (best->ebx & bit(X86_FEATURE_MPX));
+}
 #endif
index d43867c33bc4efee0c970e9602cd63616b4ec739..44a7d25154973437e0ce4233e142d01c43a948b9 100644 (file)
@@ -3736,8 +3736,8 @@ static void reset_rsvds_bits_mask_ept(struct kvm_vcpu *vcpu,
        }
 }
 
-void update_permission_bitmask(struct kvm_vcpu *vcpu,
-               struct kvm_mmu *mmu, bool ept)
+static void update_permission_bitmask(struct kvm_vcpu *vcpu,
+                                     struct kvm_mmu *mmu, bool ept)
 {
        unsigned bit, byte, pfec;
        u8 map;
@@ -3918,6 +3918,7 @@ static void init_kvm_tdp_mmu(struct kvm_vcpu *vcpu)
 void kvm_init_shadow_mmu(struct kvm_vcpu *vcpu)
 {
        bool smep = kvm_read_cr4_bits(vcpu, X86_CR4_SMEP);
+       bool smap = kvm_read_cr4_bits(vcpu, X86_CR4_SMAP);
        struct kvm_mmu *context = &vcpu->arch.mmu;
 
        MMU_WARN_ON(VALID_PAGE(context->root_hpa));
@@ -3936,6 +3937,8 @@ void kvm_init_shadow_mmu(struct kvm_vcpu *vcpu)
        context->base_role.cr0_wp  = is_write_protection(vcpu);
        context->base_role.smep_andnot_wp
                = smep && !is_write_protection(vcpu);
+       context->base_role.smap_andnot_wp
+               = smap && !is_write_protection(vcpu);
 }
 EXPORT_SYMBOL_GPL(kvm_init_shadow_mmu);
 
@@ -4207,12 +4210,18 @@ void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa,
                       const u8 *new, int bytes)
 {
        gfn_t gfn = gpa >> PAGE_SHIFT;
-       union kvm_mmu_page_role mask = { .word = 0 };
        struct kvm_mmu_page *sp;
        LIST_HEAD(invalid_list);
        u64 entry, gentry, *spte;
        int npte;
        bool remote_flush, local_flush, zap_page;
+       union kvm_mmu_page_role mask = (union kvm_mmu_page_role) {
+               .cr0_wp = 1,
+               .cr4_pae = 1,
+               .nxe = 1,
+               .smep_andnot_wp = 1,
+               .smap_andnot_wp = 1,
+       };
 
        /*
         * If we don't have indirect shadow pages, it means no page is
@@ -4238,7 +4247,6 @@ void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa,
        ++vcpu->kvm->stat.mmu_pte_write;
        kvm_mmu_audit(vcpu, AUDIT_PRE_PTE_WRITE);
 
-       mask.cr0_wp = mask.cr4_pae = mask.nxe = 1;
        for_each_gfn_indirect_valid_sp(vcpu->kvm, sp, gfn) {
                if (detect_write_misaligned(sp, gpa, bytes) ||
                      detect_write_flooding(sp)) {
index c7d65637c8518e55e3650b01d3b106cea9597962..0ada65ecddcf27ca619269d92435012c3f19790a 100644 (file)
@@ -71,8 +71,6 @@ enum {
 int handle_mmio_page_fault_common(struct kvm_vcpu *vcpu, u64 addr, bool direct);
 void kvm_init_shadow_mmu(struct kvm_vcpu *vcpu);
 void kvm_init_shadow_ept_mmu(struct kvm_vcpu *vcpu, bool execonly);
-void update_permission_bitmask(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu,
-               bool ept);
 
 static inline unsigned int kvm_mmu_available_pages(struct kvm *kvm)
 {
@@ -166,6 +164,8 @@ static inline bool permission_fault(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu,
        int index = (pfec >> 1) +
                    (smap >> (X86_EFLAGS_AC_BIT - PFERR_RSVD_BIT + 1));
 
+       WARN_ON(pfec & PFERR_RSVD_MASK);
+
        return (mmu->permissions[index] >> pte_access) & 1;
 }
 
index fd49c867b25a11927fc2f6ef4522e1ef9ee80c11..6e6d115fe9b542607c946cf57d1cc37ca948c923 100644 (file)
@@ -718,6 +718,13 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr, u32 error_code,
                                              mmu_is_nested(vcpu));
                if (likely(r != RET_MMIO_PF_INVALID))
                        return r;
+
+               /*
+                * page fault with PFEC.RSVD  = 1 is caused by shadow
+                * page fault, should not be used to walk guest page
+                * table.
+                */
+               error_code &= ~PFERR_RSVD_MASK;
        };
 
        r = mmu_topup_memory_caches(vcpu);
index ce741b8650f6ece694fb47e1750d153291a1803f..9afa233b5482f6a68addba2494916e9624e52566 100644 (file)
@@ -4381,6 +4381,7 @@ static struct kvm_x86_ops svm_x86_ops = {
        .cache_reg = svm_cache_reg,
        .get_rflags = svm_get_rflags,
        .set_rflags = svm_set_rflags,
+       .fpu_activate = svm_fpu_activate,
        .fpu_deactivate = svm_fpu_deactivate,
 
        .tlb_flush = svm_flush_tlb,
index f7b61687bd79facc3f6ed0339b68ecf3fcf43aed..2d73807f0d317f3c46a7aa42234a67d6894b20a2 100644 (file)
@@ -10185,6 +10185,7 @@ static struct kvm_x86_ops vmx_x86_ops = {
        .cache_reg = vmx_cache_reg,
        .get_rflags = vmx_get_rflags,
        .set_rflags = vmx_set_rflags,
+       .fpu_activate = vmx_fpu_activate,
        .fpu_deactivate = vmx_fpu_deactivate,
 
        .tlb_flush = vmx_flush_tlb,
index c73efcd03e294a2e5bc2ef276dc7fa4a6e9d837f..ea306adbbc13603591d46d3f062cc20cf1bc37d1 100644 (file)
@@ -702,8 +702,9 @@ EXPORT_SYMBOL_GPL(kvm_set_xcr);
 int kvm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
 {
        unsigned long old_cr4 = kvm_read_cr4(vcpu);
-       unsigned long pdptr_bits = X86_CR4_PGE | X86_CR4_PSE |
-                                  X86_CR4_PAE | X86_CR4_SMEP;
+       unsigned long pdptr_bits = X86_CR4_PGE | X86_CR4_PSE | X86_CR4_PAE |
+                                  X86_CR4_SMEP | X86_CR4_SMAP;
+
        if (cr4 & CR4_RESERVED_BITS)
                return 1;
 
@@ -744,9 +745,6 @@ int kvm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
            (!(cr4 & X86_CR4_PCIDE) && (old_cr4 & X86_CR4_PCIDE)))
                kvm_mmu_reset_context(vcpu);
 
-       if ((cr4 ^ old_cr4) & X86_CR4_SMAP)
-               update_permission_bitmask(vcpu, vcpu->arch.walk_mmu, false);
-
        if ((cr4 ^ old_cr4) & X86_CR4_OSXSAVE)
                kvm_update_cpuid(vcpu);
 
@@ -6197,6 +6195,8 @@ void kvm_vcpu_reload_apic_access_page(struct kvm_vcpu *vcpu)
                return;
 
        page = gfn_to_page(vcpu->kvm, APIC_DEFAULT_PHYS_BASE >> PAGE_SHIFT);
+       if (is_error_page(page))
+               return;
        kvm_x86_ops->set_apic_access_page_addr(vcpu, page_to_phys(page));
 
        /*
@@ -7060,7 +7060,9 @@ void kvm_put_guest_fpu(struct kvm_vcpu *vcpu)
        fpu_save_init(&vcpu->arch.guest_fpu);
        __kernel_fpu_end();
        ++vcpu->stat.fpu_reload;
-       kvm_make_request(KVM_REQ_DEACTIVATE_FPU, vcpu);
+       if (!vcpu->arch.eager_fpu)
+               kvm_make_request(KVM_REQ_DEACTIVATE_FPU, vcpu);
+
        trace_kvm_fpu(0);
 }
 
@@ -7076,11 +7078,21 @@ void kvm_arch_vcpu_free(struct kvm_vcpu *vcpu)
 struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm,
                                                unsigned int id)
 {
+       struct kvm_vcpu *vcpu;
+
        if (check_tsc_unstable() && atomic_read(&kvm->online_vcpus) != 0)
                printk_once(KERN_WARNING
                "kvm: SMP vm created on host with unstable TSC; "
                "guest TSC will not be reliable\n");
-       return kvm_x86_ops->vcpu_create(kvm, id);
+
+       vcpu = kvm_x86_ops->vcpu_create(kvm, id);
+
+       /*
+        * Activate fpu unconditionally in case the guest needs eager FPU.  It will be
+        * deactivated soon if it doesn't.
+        */
+       kvm_x86_ops->fpu_activate(vcpu);
+       return vcpu;
 }
 
 int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)
index 987514396c1e443376bffe70e050b72f86509102..ddeff4844a100de83b52ef9dae9f42974666dc23 100644 (file)
@@ -559,6 +559,13 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image,
                                if (is_ereg(dst_reg))
                                        EMIT1(0x41);
                                EMIT3(0xC1, add_1reg(0xC8, dst_reg), 8);
+
+                               /* emit 'movzwl eax, ax' */
+                               if (is_ereg(dst_reg))
+                                       EMIT3(0x45, 0x0F, 0xB7);
+                               else
+                                       EMIT2(0x0F, 0xB7);
+                               EMIT1(add_2reg(0xC0, dst_reg, dst_reg));
                                break;
                        case 32:
                                /* emit 'bswap eax' to swap lower 4 bytes */
@@ -577,6 +584,27 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image,
                        break;
 
                case BPF_ALU | BPF_END | BPF_FROM_LE:
+                       switch (imm32) {
+                       case 16:
+                               /* emit 'movzwl eax, ax' to zero extend 16-bit
+                                * into 64 bit
+                                */
+                               if (is_ereg(dst_reg))
+                                       EMIT3(0x45, 0x0F, 0xB7);
+                               else
+                                       EMIT2(0x0F, 0xB7);
+                               EMIT1(add_2reg(0xC0, dst_reg, dst_reg));
+                               break;
+                       case 32:
+                               /* emit 'mov eax, eax' to clear upper 32-bits */
+                               if (is_ereg(dst_reg))
+                                       EMIT1(0x45);
+                               EMIT2(0x89, add_2reg(0xC0, dst_reg, dst_reg));
+                               break;
+                       case 64:
+                               /* nop */
+                               break;
+                       }
                        break;
 
                        /* ST: *(u8*)(dst_reg + off) = imm */
@@ -938,7 +966,12 @@ void bpf_int_jit_compile(struct bpf_prog *prog)
        }
        ctx.cleanup_addr = proglen;
 
-       for (pass = 0; pass < 10; pass++) {
+       /* JITed image shrinks with every pass and the loop iterates
+        * until the image stops shrinking. Very large bpf programs
+        * may converge on the last pass. In such case do one more
+        * pass to emit the final image
+        */
+       for (pass = 0; pass < 10 || image; pass++) {
                proglen = do_jit(prog, addrs, image, oldproglen, &ctx);
                if (proglen <= 0) {
                        image = NULL;
index 275a3a8b78afa3221b78296d2a7e3c2945de512b..e97032069f88cdcc8f1c692bd63960fd8bda517d 100644 (file)
@@ -51,7 +51,7 @@ VDSO_LDFLAGS_vdso.lds = -m64 -Wl,-soname=linux-vdso.so.1 \
 $(obj)/vdso64.so.dbg: $(src)/vdso.lds $(vobjs) FORCE
        $(call if_changed,vdso)
 
-HOST_EXTRACFLAGS += -I$(srctree)/tools/include -I$(srctree)/include/uapi
+HOST_EXTRACFLAGS += -I$(srctree)/tools/include -I$(srctree)/include/uapi -I$(srctree)/arch/x86/include/uapi
 hostprogs-y                    += vdso2c
 
 quiet_cmd_vdso2c = VDSO2C  $@
index 172a02a6ad146fea24ab966cf46a3612434a03da..ba78ccf651e7764e9db92cfca37927a8d68e3892 100644 (file)
@@ -185,4 +185,17 @@ static inline int dma_get_sgtable(struct device *dev, struct sg_table *sgt,
        return -EINVAL;
 }
 
+static inline void *dma_alloc_attrs(struct device *dev, size_t size,
+                                   dma_addr_t *dma_handle, gfp_t flag,
+                                   struct dma_attrs *attrs)
+{
+       return NULL;
+}
+
+static inline void dma_free_attrs(struct device *dev, size_t size,
+                                 void *vaddr, dma_addr_t dma_handle,
+                                 struct dma_attrs *attrs)
+{
+}
+
 #endif /* _XTENSA_DMA_MAPPING_H */
index 7871603f0a29bba5dbdc6548174595bf827fa912..03b5f8d77f37b4cbad3a12f3a98f9c3ea63a50e7 100644 (file)
@@ -734,6 +734,8 @@ blk_init_queue_node(request_fn_proc *rfn, spinlock_t *lock, int node_id)
 }
 EXPORT_SYMBOL(blk_init_queue_node);
 
+static void blk_queue_bio(struct request_queue *q, struct bio *bio);
+
 struct request_queue *
 blk_init_allocated_queue(struct request_queue *q, request_fn_proc *rfn,
                         spinlock_t *lock)
@@ -1578,7 +1580,7 @@ void init_request_from_bio(struct request *req, struct bio *bio)
        blk_rq_bio_prep(req->q, req, bio);
 }
 
-void blk_queue_bio(struct request_queue *q, struct bio *bio)
+static void blk_queue_bio(struct request_queue *q, struct bio *bio)
 {
        const bool sync = !!(bio->bi_rw & REQ_SYNC);
        struct blk_plug *plug;
@@ -1686,7 +1688,6 @@ void blk_queue_bio(struct request_queue *q, struct bio *bio)
                spin_unlock_irq(q->queue_lock);
        }
 }
-EXPORT_SYMBOL_GPL(blk_queue_bio);      /* for device mapper only */
 
 /*
  * If bio->bi_dev is a partition, remap the location
index 8aaf298a80e165f3fb5f83b1e00b8636cf9d08a3..362905e7c841ff55b204891e9e93748f2cfea96e 100644 (file)
@@ -1512,15 +1512,6 @@ config CRYPTO_USER_API_RNG
          This option enables the user-spaces interface for random
          number generator algorithms.
 
-config CRYPTO_USER_API_AEAD
-       tristate "User-space interface for AEAD cipher algorithms"
-       depends on NET
-       select CRYPTO_AEAD
-       select CRYPTO_USER_API
-       help
-         This option enables the user-spaces interface for AEAD
-         cipher algorithms.
-
 config CRYPTO_HASH_INFO
        bool
 
index 00a6fe166fed52863e5b6249858adeee5690a394..69abada22373f54b5dd434ba514e9c6c80c180e5 100644 (file)
@@ -33,7 +33,7 @@ struct aead_ctx {
        /*
         * RSGL_MAX_ENTRIES is an artificial limit where user space at maximum
         * can cause the kernel to allocate RSGL_MAX_ENTRIES * ALG_MAX_PAGES
-        * bytes
+        * pages
         */
 #define RSGL_MAX_ENTRIES ALG_MAX_PAGES
        struct af_alg_sgl rsgl[RSGL_MAX_ENTRIES];
@@ -435,11 +435,10 @@ static int aead_recvmsg(struct socket *sock, struct msghdr *msg, size_t ignored,
                if (err < 0)
                        goto unlock;
                usedpages += err;
-               /* chain the new scatterlist with initial list */
+               /* chain the new scatterlist with previous one */
                if (cnt)
-                       scatterwalk_crypto_chain(ctx->rsgl[0].sg,
-                                       ctx->rsgl[cnt].sg, 1,
-                                       sg_nents(ctx->rsgl[cnt-1].sg));
+                       af_alg_link_sg(&ctx->rsgl[cnt-1], &ctx->rsgl[cnt]);
+
                /* we do not need more iovecs as we have sufficient memory */
                if (outlen <= usedpages)
                        break;
index a72685c1e819660768933e84abe9d1076c953bff..5e8df9177da44781ac07942d146e47b97e954cda 100644 (file)
@@ -102,19 +102,12 @@ const struct acpi_predefined_names acpi_gbl_pre_defined_names[] = {
        {"_SB_", ACPI_TYPE_DEVICE, NULL},
        {"_SI_", ACPI_TYPE_LOCAL_SCOPE, NULL},
        {"_TZ_", ACPI_TYPE_DEVICE, NULL},
-       /*
-        * March, 2015:
-        * The _REV object is in the process of being deprecated, because
-        * other ACPI implementations permanently return 2. Thus, it
-        * has little or no value. Return 2 for compatibility with
-        * other ACPI implementations.
-        */
-       {"_REV", ACPI_TYPE_INTEGER, ACPI_CAST_PTR(char, 2)},
+       {"_REV", ACPI_TYPE_INTEGER, (char *)ACPI_CA_SUPPORT_LEVEL},
        {"_OS_", ACPI_TYPE_STRING, ACPI_OS_NAME},
-       {"_GL_", ACPI_TYPE_MUTEX, ACPI_CAST_PTR(char, 1)},
+       {"_GL_", ACPI_TYPE_MUTEX, (char *)1},
 
 #if !defined (ACPI_NO_METHOD_EXECUTION) || defined (ACPI_CONSTANT_EVAL_ONLY)
-       {"_OSI", ACPI_TYPE_METHOD, ACPI_CAST_PTR(char, 1)},
+       {"_OSI", ACPI_TYPE_METHOD, (char *)1},
 #endif
 
        /* Table terminator */
index 39748bb3a5430111b8cf4723462eb837137b0213..7ccba395c9ddbeb7a6725b336d69d01abd4b82b1 100644 (file)
@@ -182,7 +182,7 @@ static void __init acpi_request_region (struct acpi_generic_address *gas,
                request_mem_region(addr, length, desc);
 }
 
-static int __init acpi_reserve_resources(void)
+static void __init acpi_reserve_resources(void)
 {
        acpi_request_region(&acpi_gbl_FADT.xpm1a_event_block, acpi_gbl_FADT.pm1_event_length,
                "ACPI PM1a_EVT_BLK");
@@ -211,10 +211,7 @@ static int __init acpi_reserve_resources(void)
        if (!(acpi_gbl_FADT.gpe1_block_length & 0x1))
                acpi_request_region(&acpi_gbl_FADT.xgpe1_block,
                               acpi_gbl_FADT.gpe1_block_length, "ACPI GPE1_BLK");
-
-       return 0;
 }
-device_initcall(acpi_reserve_resources);
 
 void acpi_os_printf(const char *fmt, ...)
 {
@@ -1845,6 +1842,7 @@ acpi_status __init acpi_os_initialize(void)
 
 acpi_status __init acpi_os_initialize1(void)
 {
+       acpi_reserve_resources();
        kacpid_wq = alloc_workqueue("kacpid", 0, 1);
        kacpi_notify_wq = alloc_workqueue("kacpi_notify", 0, 1);
        kacpi_hotplug_wq = alloc_ordered_workqueue("kacpi_hotplug", 0);
index 5f601553b9b043fff9ac80552ab55dbc4173c714..9dca4b995be0792b6c4f1920b9786cb6517a2b5f 100644 (file)
@@ -270,6 +270,7 @@ config ATA_PIIX
 config SATA_DWC
        tristate "DesignWare Cores SATA support"
        depends on 460EX
+       select DW_DMAC
        help
          This option enables support for the on-chip SATA controller of the
          AppliedMicro processor 460EX.
@@ -729,15 +730,6 @@ config PATA_SC1200
 
          If unsure, say N.
 
-config PATA_SCC
-       tristate "Toshiba's Cell Reference Set IDE support"
-       depends on PCI && PPC_CELLEB
-       help
-         This option enables support for the built-in IDE controller on
-         Toshiba Cell Reference Board.
-
-         If unsure, say N.
-
 config PATA_SCH
        tristate "Intel SCH PATA support"
        depends on PCI
index b67e995179a947bcdda7e5bf6f5d95275841ad49..40f7865f20a1dbf62123da6998fcef81fa9a2690 100644 (file)
@@ -75,7 +75,6 @@ obj-$(CONFIG_PATA_PDC_OLD)    += pata_pdc202xx_old.o
 obj-$(CONFIG_PATA_RADISYS)     += pata_radisys.o
 obj-$(CONFIG_PATA_RDC)         += pata_rdc.o
 obj-$(CONFIG_PATA_SC1200)      += pata_sc1200.o
-obj-$(CONFIG_PATA_SCC)         += pata_scc.o
 obj-$(CONFIG_PATA_SCH)         += pata_sch.o
 obj-$(CONFIG_PATA_SERVERWORKS) += pata_serverworks.o
 obj-$(CONFIG_PATA_SIL680)      += pata_sil680.o
index c7a92a743ed035e9af81ac779180fc65456a8390..65ee94454bbd2c92f1879386b19a346a5632794f 100644 (file)
@@ -66,6 +66,7 @@ enum board_ids {
        board_ahci_yes_fbs,
 
        /* board IDs for specific chipsets in alphabetical order */
+       board_ahci_avn,
        board_ahci_mcp65,
        board_ahci_mcp77,
        board_ahci_mcp89,
@@ -84,6 +85,8 @@ enum board_ids {
 static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
 static int ahci_vt8251_hardreset(struct ata_link *link, unsigned int *class,
                                 unsigned long deadline);
+static int ahci_avn_hardreset(struct ata_link *link, unsigned int *class,
+                             unsigned long deadline);
 static void ahci_mcp89_apple_enable(struct pci_dev *pdev);
 static bool is_mcp89_apple(struct pci_dev *pdev);
 static int ahci_p5wdh_hardreset(struct ata_link *link, unsigned int *class,
@@ -107,6 +110,11 @@ static struct ata_port_operations ahci_p5wdh_ops = {
        .hardreset              = ahci_p5wdh_hardreset,
 };
 
+static struct ata_port_operations ahci_avn_ops = {
+       .inherits               = &ahci_ops,
+       .hardreset              = ahci_avn_hardreset,
+};
+
 static const struct ata_port_info ahci_port_info[] = {
        /* by features */
        [board_ahci] = {
@@ -151,6 +159,12 @@ static const struct ata_port_info ahci_port_info[] = {
                .port_ops       = &ahci_ops,
        },
        /* by chipsets */
+       [board_ahci_avn] = {
+               .flags          = AHCI_FLAG_COMMON,
+               .pio_mask       = ATA_PIO4,
+               .udma_mask      = ATA_UDMA6,
+               .port_ops       = &ahci_avn_ops,
+       },
        [board_ahci_mcp65] = {
                AHCI_HFLAGS     (AHCI_HFLAG_NO_FPDMA_AA | AHCI_HFLAG_NO_PMP |
                                 AHCI_HFLAG_YES_NCQ),
@@ -290,14 +304,14 @@ static const struct pci_device_id ahci_pci_tbl[] = {
        { PCI_VDEVICE(INTEL, 0x1f27), board_ahci }, /* Avoton RAID */
        { PCI_VDEVICE(INTEL, 0x1f2e), board_ahci }, /* Avoton RAID */
        { PCI_VDEVICE(INTEL, 0x1f2f), board_ahci }, /* Avoton RAID */
-       { PCI_VDEVICE(INTEL, 0x1f32), board_ahci }, /* Avoton AHCI */
-       { PCI_VDEVICE(INTEL, 0x1f33), board_ahci }, /* Avoton AHCI */
-       { PCI_VDEVICE(INTEL, 0x1f34), board_ahci }, /* Avoton RAID */
-       { PCI_VDEVICE(INTEL, 0x1f35), board_ahci }, /* Avoton RAID */
-       { PCI_VDEVICE(INTEL, 0x1f36), board_ahci }, /* Avoton RAID */
-       { PCI_VDEVICE(INTEL, 0x1f37), board_ahci }, /* Avoton RAID */
-       { PCI_VDEVICE(INTEL, 0x1f3e), board_ahci }, /* Avoton RAID */
-       { PCI_VDEVICE(INTEL, 0x1f3f), board_ahci }, /* Avoton RAID */
+       { PCI_VDEVICE(INTEL, 0x1f32), board_ahci_avn }, /* Avoton AHCI */
+       { PCI_VDEVICE(INTEL, 0x1f33), board_ahci_avn }, /* Avoton AHCI */
+       { PCI_VDEVICE(INTEL, 0x1f34), board_ahci_avn }, /* Avoton RAID */
+       { PCI_VDEVICE(INTEL, 0x1f35), board_ahci_avn }, /* Avoton RAID */
+       { PCI_VDEVICE(INTEL, 0x1f36), board_ahci_avn }, /* Avoton RAID */
+       { PCI_VDEVICE(INTEL, 0x1f37), board_ahci_avn }, /* Avoton RAID */
+       { PCI_VDEVICE(INTEL, 0x1f3e), board_ahci_avn }, /* Avoton RAID */
+       { PCI_VDEVICE(INTEL, 0x1f3f), board_ahci_avn }, /* Avoton RAID */
        { PCI_VDEVICE(INTEL, 0x2823), board_ahci }, /* Wellsburg RAID */
        { PCI_VDEVICE(INTEL, 0x2827), board_ahci }, /* Wellsburg RAID */
        { PCI_VDEVICE(INTEL, 0x8d02), board_ahci }, /* Wellsburg AHCI */
@@ -670,6 +684,79 @@ static int ahci_p5wdh_hardreset(struct ata_link *link, unsigned int *class,
        return rc;
 }
 
+/*
+ * ahci_avn_hardreset - attempt more aggressive recovery of Avoton ports.
+ *
+ * It has been observed with some SSDs that the timing of events in the
+ * link synchronization phase can leave the port in a state that can not
+ * be recovered by a SATA-hard-reset alone.  The failing signature is
+ * SStatus.DET stuck at 1 ("Device presence detected but Phy
+ * communication not established").  It was found that unloading and
+ * reloading the driver when this problem occurs allows the drive
+ * connection to be recovered (DET advanced to 0x3).  The critical
+ * component of reloading the driver is that the port state machines are
+ * reset by bouncing "port enable" in the AHCI PCS configuration
+ * register.  So, reproduce that effect by bouncing a port whenever we
+ * see DET==1 after a reset.
+ */
+static int ahci_avn_hardreset(struct ata_link *link, unsigned int *class,
+                             unsigned long deadline)
+{
+       const unsigned long *timing = sata_ehc_deb_timing(&link->eh_context);
+       struct ata_port *ap = link->ap;
+       struct ahci_port_priv *pp = ap->private_data;
+       struct ahci_host_priv *hpriv = ap->host->private_data;
+       u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG;
+       unsigned long tmo = deadline - jiffies;
+       struct ata_taskfile tf;
+       bool online;
+       int rc, i;
+
+       DPRINTK("ENTER\n");
+
+       ahci_stop_engine(ap);
+
+       for (i = 0; i < 2; i++) {
+               u16 val;
+               u32 sstatus;
+               int port = ap->port_no;
+               struct ata_host *host = ap->host;
+               struct pci_dev *pdev = to_pci_dev(host->dev);
+
+               /* clear D2H reception area to properly wait for D2H FIS */
+               ata_tf_init(link->device, &tf);
+               tf.command = ATA_BUSY;
+               ata_tf_to_fis(&tf, 0, 0, d2h_fis);
+
+               rc = sata_link_hardreset(link, timing, deadline, &online,
+                               ahci_check_ready);
+
+               if (sata_scr_read(link, SCR_STATUS, &sstatus) != 0 ||
+                               (sstatus & 0xf) != 1)
+                       break;
+
+               ata_link_printk(link, KERN_INFO, "avn bounce port%d\n",
+                               port);
+
+               pci_read_config_word(pdev, 0x92, &val);
+               val &= ~(1 << port);
+               pci_write_config_word(pdev, 0x92, val);
+               ata_msleep(ap, 1000);
+               val |= 1 << port;
+               pci_write_config_word(pdev, 0x92, val);
+               deadline += tmo;
+       }
+
+       hpriv->start_engine(ap);
+
+       if (online)
+               *class = ahci_dev_classify(ap);
+
+       DPRINTK("EXIT, rc=%d, class=%u\n", rc, *class);
+       return rc;
+}
+
+
 #ifdef CONFIG_PM
 static int ahci_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg)
 {
index ea0ff005b86ce702e4ccd0224c5b8f14c0fcfc89..8ff428fe8e0fa00659218f58f041cf948ae8327c 100644 (file)
@@ -37,7 +37,6 @@ struct st_ahci_drv_data {
        struct reset_control *pwr;
        struct reset_control *sw_rst;
        struct reset_control *pwr_rst;
-       struct ahci_host_priv *hpriv;
 };
 
 static void st_ahci_configure_oob(void __iomem *mmio)
@@ -55,9 +54,10 @@ static void st_ahci_configure_oob(void __iomem *mmio)
        writel(new_val, mmio + ST_AHCI_OOBR);
 }
 
-static int st_ahci_deassert_resets(struct device *dev)
+static int st_ahci_deassert_resets(struct ahci_host_priv *hpriv,
+                               struct device *dev)
 {
-       struct st_ahci_drv_data *drv_data = dev_get_drvdata(dev);
+       struct st_ahci_drv_data *drv_data = hpriv->plat_data;
        int err;
 
        if (drv_data->pwr) {
@@ -90,8 +90,8 @@ static int st_ahci_deassert_resets(struct device *dev)
 static void st_ahci_host_stop(struct ata_host *host)
 {
        struct ahci_host_priv *hpriv = host->private_data;
+       struct st_ahci_drv_data *drv_data = hpriv->plat_data;
        struct device *dev = host->dev;
-       struct st_ahci_drv_data *drv_data = dev_get_drvdata(dev);
        int err;
 
        if (drv_data->pwr) {
@@ -103,29 +103,30 @@ static void st_ahci_host_stop(struct ata_host *host)
        ahci_platform_disable_resources(hpriv);
 }
 
-static int st_ahci_probe_resets(struct platform_device *pdev)
+static int st_ahci_probe_resets(struct ahci_host_priv *hpriv,
+                               struct device *dev)
 {
-       struct st_ahci_drv_data *drv_data = platform_get_drvdata(pdev);
+       struct st_ahci_drv_data *drv_data = hpriv->plat_data;
 
-       drv_data->pwr = devm_reset_control_get(&pdev->dev, "pwr-dwn");
+       drv_data->pwr = devm_reset_control_get(dev, "pwr-dwn");
        if (IS_ERR(drv_data->pwr)) {
-               dev_info(&pdev->dev, "power reset control not defined\n");
+               dev_info(dev, "power reset control not defined\n");
                drv_data->pwr = NULL;
        }
 
-       drv_data->sw_rst = devm_reset_control_get(&pdev->dev, "sw-rst");
+       drv_data->sw_rst = devm_reset_control_get(dev, "sw-rst");
        if (IS_ERR(drv_data->sw_rst)) {
-               dev_info(&pdev->dev, "soft reset control not defined\n");
+               dev_info(dev, "soft reset control not defined\n");
                drv_data->sw_rst = NULL;
        }
 
-       drv_data->pwr_rst = devm_reset_control_get(&pdev->dev, "pwr-rst");
+       drv_data->pwr_rst = devm_reset_control_get(dev, "pwr-rst");
        if (IS_ERR(drv_data->pwr_rst)) {
-               dev_dbg(&pdev->dev, "power soft reset control not defined\n");
+               dev_dbg(dev, "power soft reset control not defined\n");
                drv_data->pwr_rst = NULL;
        }
 
-       return st_ahci_deassert_resets(&pdev->dev);
+       return st_ahci_deassert_resets(hpriv, dev);
 }
 
 static struct ata_port_operations st_ahci_port_ops = {
@@ -154,15 +155,12 @@ static int st_ahci_probe(struct platform_device *pdev)
        if (!drv_data)
                return -ENOMEM;
 
-       platform_set_drvdata(pdev, drv_data);
-
        hpriv = ahci_platform_get_resources(pdev);
        if (IS_ERR(hpriv))
                return PTR_ERR(hpriv);
+       hpriv->plat_data = drv_data;
 
-       drv_data->hpriv = hpriv;
-
-       err = st_ahci_probe_resets(pdev);
+       err = st_ahci_probe_resets(hpriv, &pdev->dev);
        if (err)
                return err;
 
@@ -170,7 +168,7 @@ static int st_ahci_probe(struct platform_device *pdev)
        if (err)
                return err;
 
-       st_ahci_configure_oob(drv_data->hpriv->mmio);
+       st_ahci_configure_oob(hpriv->mmio);
 
        err = ahci_platform_init_host(pdev, hpriv, &st_ahci_port_info,
                                      &ahci_platform_sht);
@@ -185,8 +183,9 @@ static int st_ahci_probe(struct platform_device *pdev)
 #ifdef CONFIG_PM_SLEEP
 static int st_ahci_suspend(struct device *dev)
 {
-       struct st_ahci_drv_data *drv_data = dev_get_drvdata(dev);
-       struct ahci_host_priv *hpriv = drv_data->hpriv;
+       struct ata_host *host = dev_get_drvdata(dev);
+       struct ahci_host_priv *hpriv = host->private_data;
+       struct st_ahci_drv_data *drv_data = hpriv->plat_data;
        int err;
 
        err = ahci_platform_suspend_host(dev);
@@ -208,21 +207,21 @@ static int st_ahci_suspend(struct device *dev)
 
 static int st_ahci_resume(struct device *dev)
 {
-       struct st_ahci_drv_data *drv_data = dev_get_drvdata(dev);
-       struct ahci_host_priv *hpriv = drv_data->hpriv;
+       struct ata_host *host = dev_get_drvdata(dev);
+       struct ahci_host_priv *hpriv = host->private_data;
        int err;
 
        err = ahci_platform_enable_resources(hpriv);
        if (err)
                return err;
 
-       err = st_ahci_deassert_resets(dev);
+       err = st_ahci_deassert_resets(hpriv, dev);
        if (err) {
                ahci_platform_disable_resources(hpriv);
                return err;
        }
 
-       st_ahci_configure_oob(drv_data->hpriv->mmio);
+       st_ahci_configure_oob(hpriv->mmio);
 
        return ahci_platform_resume_host(dev);
 }
index 61a9c07e0dff5b277dba35cfa135bac449f9ce84..287c4ba0219f7ced8c76af999dd1eeb3e5ed2639 100644 (file)
@@ -1707,8 +1707,7 @@ static void ahci_handle_port_interrupt(struct ata_port *ap,
        if (unlikely(resetting))
                status &= ~PORT_IRQ_BAD_PMP;
 
-       /* if LPM is enabled, PHYRDY doesn't mean anything */
-       if (ap->link.lpm_policy > ATA_LPM_MAX_POWER) {
+       if (sata_lpm_ignore_phy_events(&ap->link)) {
                status &= ~PORT_IRQ_PHYRDY;
                ahci_scr_write(&ap->link, SCR_ERROR, SERR_PHYRDY_CHG);
        }
index f6cb1f1b30b7466278d47dae09bc959db24dfef1..577849c6611ac5efa2c948c7b274dc894a19890d 100644 (file)
@@ -4235,7 +4235,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
                                                ATA_HORKAGE_ZERO_AFTER_TRIM, },
        { "Crucial_CT*MX100*",          "MU01", ATA_HORKAGE_NO_NCQ_TRIM |
                                                ATA_HORKAGE_ZERO_AFTER_TRIM, },
-       { "Samsung SSD 850 PRO*",       NULL,   ATA_HORKAGE_NO_NCQ_TRIM |
+       { "Samsung SSD 8*",             NULL,   ATA_HORKAGE_NO_NCQ_TRIM |
                                                ATA_HORKAGE_ZERO_AFTER_TRIM, },
 
        /*
@@ -6752,6 +6752,38 @@ u32 ata_wait_register(struct ata_port *ap, void __iomem *reg, u32 mask, u32 val,
        return tmp;
 }
 
+/**
+ *     sata_lpm_ignore_phy_events - test if PHY event should be ignored
+ *     @link: Link receiving the event
+ *
+ *     Test whether the received PHY event has to be ignored or not.
+ *
+ *     LOCKING:
+ *     None:
+ *
+ *     RETURNS:
+ *     True if the event has to be ignored.
+ */
+bool sata_lpm_ignore_phy_events(struct ata_link *link)
+{
+       unsigned long lpm_timeout = link->last_lpm_change +
+                                   msecs_to_jiffies(ATA_TMOUT_SPURIOUS_PHY);
+
+       /* if LPM is enabled, PHYRDY doesn't mean anything */
+       if (link->lpm_policy > ATA_LPM_MAX_POWER)
+               return true;
+
+       /* ignore the first PHY event after the LPM policy changed
+        * as it is might be spurious
+        */
+       if ((link->flags & ATA_LFLAG_CHANGED) &&
+           time_before(jiffies, lpm_timeout))
+               return true;
+
+       return false;
+}
+EXPORT_SYMBOL_GPL(sata_lpm_ignore_phy_events);
+
 /*
  * Dummy port_ops
  */
index 07f41be38fbe556ffff9bd5efcacf8ed4538034e..cf0022ec07f2420c37fb8a52dc904530f0df2e38 100644 (file)
@@ -3597,6 +3597,9 @@ static int ata_eh_set_lpm(struct ata_link *link, enum ata_lpm_policy policy,
                }
        }
 
+       link->last_lpm_change = jiffies;
+       link->flags |= ATA_LFLAG_CHANGED;
+
        return 0;
 
 fail:
diff --git a/drivers/ata/pata_scc.c b/drivers/ata/pata_scc.c
deleted file mode 100644 (file)
index 5cd60d6..0000000
+++ /dev/null
@@ -1,1110 +0,0 @@
-/*
- * Support for IDE interfaces on Celleb platform
- *
- * (C) Copyright 2006 TOSHIBA CORPORATION
- *
- * This code is based on drivers/ata/ata_piix.c:
- *  Copyright 2003-2005 Red Hat Inc
- *  Copyright 2003-2005 Jeff Garzik
- *  Copyright (C) 1998-1999 Andrzej Krzysztofowicz, Author and Maintainer
- *  Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org>
- *  Copyright (C) 2003 Red Hat Inc
- *
- * and drivers/ata/ahci.c:
- *  Copyright 2004-2005 Red Hat, Inc.
- *
- * and drivers/ata/libata-core.c:
- *  Copyright 2003-2004 Red Hat, Inc.  All rights reserved.
- *  Copyright 2003-2004 Jeff Garzik
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/blkdev.h>
-#include <linux/delay.h>
-#include <linux/device.h>
-#include <scsi/scsi_host.h>
-#include <linux/libata.h>
-
-#define DRV_NAME               "pata_scc"
-#define DRV_VERSION            "0.3"
-
-#define PCI_DEVICE_ID_TOSHIBA_SCC_ATA          0x01b4
-
-/* PCI BARs */
-#define SCC_CTRL_BAR           0
-#define SCC_BMID_BAR           1
-
-/* offset of CTRL registers */
-#define SCC_CTL_PIOSHT         0x000
-#define SCC_CTL_PIOCT          0x004
-#define SCC_CTL_MDMACT         0x008
-#define SCC_CTL_MCRCST         0x00C
-#define SCC_CTL_SDMACT         0x010
-#define SCC_CTL_SCRCST         0x014
-#define SCC_CTL_UDENVT         0x018
-#define SCC_CTL_TDVHSEL        0x020
-#define SCC_CTL_MODEREG        0x024
-#define SCC_CTL_ECMODE         0xF00
-#define SCC_CTL_MAEA0          0xF50
-#define SCC_CTL_MAEC0          0xF54
-#define SCC_CTL_CCKCTRL        0xFF0
-
-/* offset of BMID registers */
-#define SCC_DMA_CMD            0x000
-#define SCC_DMA_STATUS         0x004
-#define SCC_DMA_TABLE_OFS      0x008
-#define SCC_DMA_INTMASK        0x010
-#define SCC_DMA_INTST          0x014
-#define SCC_DMA_PTERADD        0x018
-#define SCC_REG_CMD_ADDR       0x020
-#define SCC_REG_DATA           0x000
-#define SCC_REG_ERR            0x004
-#define SCC_REG_FEATURE        0x004
-#define SCC_REG_NSECT          0x008
-#define SCC_REG_LBAL           0x00C
-#define SCC_REG_LBAM           0x010
-#define SCC_REG_LBAH           0x014
-#define SCC_REG_DEVICE         0x018
-#define SCC_REG_STATUS         0x01C
-#define SCC_REG_CMD            0x01C
-#define SCC_REG_ALTSTATUS      0x020
-
-/* register value */
-#define TDVHSEL_MASTER         0x00000001
-#define TDVHSEL_SLAVE          0x00000004
-
-#define MODE_JCUSFEN           0x00000080
-
-#define ECMODE_VALUE           0x01
-
-#define CCKCTRL_ATARESET       0x00040000
-#define CCKCTRL_BUFCNT         0x00020000
-#define CCKCTRL_CRST           0x00010000
-#define CCKCTRL_OCLKEN         0x00000100
-#define CCKCTRL_ATACLKOEN      0x00000002
-#define CCKCTRL_LCLKEN         0x00000001
-
-#define QCHCD_IOS_SS           0x00000001
-
-#define QCHSD_STPDIAG          0x00020000
-
-#define INTMASK_MSK            0xD1000012
-#define INTSTS_SERROR          0x80000000
-#define INTSTS_PRERR           0x40000000
-#define INTSTS_RERR            0x10000000
-#define INTSTS_ICERR           0x01000000
-#define INTSTS_BMSINT          0x00000010
-#define INTSTS_BMHE            0x00000008
-#define INTSTS_IOIRQS          0x00000004
-#define INTSTS_INTRQ           0x00000002
-#define INTSTS_ACTEINT         0x00000001
-
-
-/* PIO transfer mode table */
-/* JCHST */
-static const unsigned long JCHSTtbl[2][7] = {
-       {0x0E, 0x05, 0x02, 0x03, 0x02, 0x00, 0x00},     /* 100MHz */
-       {0x13, 0x07, 0x04, 0x04, 0x03, 0x00, 0x00}      /* 133MHz */
-};
-
-/* JCHHT */
-static const unsigned long JCHHTtbl[2][7] = {
-       {0x0E, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00},     /* 100MHz */
-       {0x13, 0x03, 0x03, 0x03, 0x03, 0x00, 0x00}      /* 133MHz */
-};
-
-/* JCHCT */
-static const unsigned long JCHCTtbl[2][7] = {
-       {0x1D, 0x1D, 0x1C, 0x0B, 0x06, 0x00, 0x00},     /* 100MHz */
-       {0x27, 0x26, 0x26, 0x0E, 0x09, 0x00, 0x00}      /* 133MHz */
-};
-
-/* DMA transfer mode  table */
-/* JCHDCTM/JCHDCTS */
-static const unsigned long JCHDCTxtbl[2][7] = {
-       {0x0A, 0x06, 0x04, 0x03, 0x01, 0x00, 0x00},     /* 100MHz */
-       {0x0E, 0x09, 0x06, 0x04, 0x02, 0x01, 0x00}      /* 133MHz */
-};
-
-/* JCSTWTM/JCSTWTS  */
-static const unsigned long JCSTWTxtbl[2][7] = {
-       {0x06, 0x04, 0x03, 0x02, 0x02, 0x02, 0x00},     /* 100MHz */
-       {0x09, 0x06, 0x04, 0x02, 0x02, 0x02, 0x02}      /* 133MHz */
-};
-
-/* JCTSS */
-static const unsigned long JCTSStbl[2][7] = {
-       {0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x00},     /* 100MHz */
-       {0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05}      /* 133MHz */
-};
-
-/* JCENVT */
-static const unsigned long JCENVTtbl[2][7] = {
-       {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00},     /* 100MHz */
-       {0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02}      /* 133MHz */
-};
-
-/* JCACTSELS/JCACTSELM */
-static const unsigned long JCACTSELtbl[2][7] = {
-       {0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00},     /* 100MHz */
-       {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}      /* 133MHz */
-};
-
-static const struct pci_device_id scc_pci_tbl[] = {
-       { PCI_VDEVICE(TOSHIBA_2, PCI_DEVICE_ID_TOSHIBA_SCC_ATA), 0},
-       { }     /* terminate list */
-};
-
-/**
- *     scc_set_piomode - Initialize host controller PATA PIO timings
- *     @ap: Port whose timings we are configuring
- *     @adev: um
- *
- *     Set PIO mode for device.
- *
- *     LOCKING:
- *     None (inherited from caller).
- */
-
-static void scc_set_piomode (struct ata_port *ap, struct ata_device *adev)
-{
-       unsigned int pio = adev->pio_mode - XFER_PIO_0;
-       void __iomem *ctrl_base = ap->host->iomap[SCC_CTRL_BAR];
-       void __iomem *cckctrl_port = ctrl_base + SCC_CTL_CCKCTRL;
-       void __iomem *piosht_port = ctrl_base + SCC_CTL_PIOSHT;
-       void __iomem *pioct_port = ctrl_base + SCC_CTL_PIOCT;
-       unsigned long reg;
-       int offset;
-
-       reg = in_be32(cckctrl_port);
-       if (reg & CCKCTRL_ATACLKOEN)
-               offset = 1;     /* 133MHz */
-       else
-               offset = 0;     /* 100MHz */
-
-       reg = JCHSTtbl[offset][pio] << 16 | JCHHTtbl[offset][pio];
-       out_be32(piosht_port, reg);
-       reg = JCHCTtbl[offset][pio];
-       out_be32(pioct_port, reg);
-}
-
-/**
- *     scc_set_dmamode - Initialize host controller PATA DMA timings
- *     @ap: Port whose timings we are configuring
- *     @adev: um
- *
- *     Set UDMA mode for device.
- *
- *     LOCKING:
- *     None (inherited from caller).
- */
-
-static void scc_set_dmamode (struct ata_port *ap, struct ata_device *adev)
-{
-       unsigned int udma = adev->dma_mode;
-       unsigned int is_slave = (adev->devno != 0);
-       u8 speed = udma;
-       void __iomem *ctrl_base = ap->host->iomap[SCC_CTRL_BAR];
-       void __iomem *cckctrl_port = ctrl_base + SCC_CTL_CCKCTRL;
-       void __iomem *mdmact_port = ctrl_base + SCC_CTL_MDMACT;
-       void __iomem *mcrcst_port = ctrl_base + SCC_CTL_MCRCST;
-       void __iomem *sdmact_port = ctrl_base + SCC_CTL_SDMACT;
-       void __iomem *scrcst_port = ctrl_base + SCC_CTL_SCRCST;
-       void __iomem *udenvt_port = ctrl_base + SCC_CTL_UDENVT;
-       void __iomem *tdvhsel_port = ctrl_base + SCC_CTL_TDVHSEL;
-       int offset, idx;
-
-       if (in_be32(cckctrl_port) & CCKCTRL_ATACLKOEN)
-               offset = 1;     /* 133MHz */
-       else
-               offset = 0;     /* 100MHz */
-
-       if (speed >= XFER_UDMA_0)
-               idx = speed - XFER_UDMA_0;
-       else
-               return;
-
-       if (is_slave) {
-               out_be32(sdmact_port, JCHDCTxtbl[offset][idx]);
-               out_be32(scrcst_port, JCSTWTxtbl[offset][idx]);
-               out_be32(tdvhsel_port,
-                        (in_be32(tdvhsel_port) & ~TDVHSEL_SLAVE) | (JCACTSELtbl[offset][idx] << 2));
-       } else {
-               out_be32(mdmact_port, JCHDCTxtbl[offset][idx]);
-               out_be32(mcrcst_port, JCSTWTxtbl[offset][idx]);
-               out_be32(tdvhsel_port,
-                        (in_be32(tdvhsel_port) & ~TDVHSEL_MASTER) | JCACTSELtbl[offset][idx]);
-       }
-       out_be32(udenvt_port,
-                JCTSStbl[offset][idx] << 16 | JCENVTtbl[offset][idx]);
-}
-
-unsigned long scc_mode_filter(struct ata_device *adev, unsigned long mask)
-{
-       /* errata A308 workaround: limit ATAPI UDMA mode to UDMA4 */
-       if (adev->class == ATA_DEV_ATAPI &&
-           (mask & (0xE0 << ATA_SHIFT_UDMA))) {
-               printk(KERN_INFO "%s: limit ATAPI UDMA to UDMA4\n", DRV_NAME);
-               mask &= ~(0xE0 << ATA_SHIFT_UDMA);
-       }
-       return mask;
-}
-
-/**
- *     scc_tf_load - send taskfile registers to host controller
- *     @ap: Port to which output is sent
- *     @tf: ATA taskfile register set
- *
- *     Note: Original code is ata_sff_tf_load().
- */
-
-static void scc_tf_load (struct ata_port *ap, const struct ata_taskfile *tf)
-{
-       struct ata_ioports *ioaddr = &ap->ioaddr;
-       unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR;
-
-       if (tf->ctl != ap->last_ctl) {
-               out_be32(ioaddr->ctl_addr, tf->ctl);
-               ap->last_ctl = tf->ctl;
-               ata_wait_idle(ap);
-       }
-
-       if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) {
-               out_be32(ioaddr->feature_addr, tf->hob_feature);
-               out_be32(ioaddr->nsect_addr, tf->hob_nsect);
-               out_be32(ioaddr->lbal_addr, tf->hob_lbal);
-               out_be32(ioaddr->lbam_addr, tf->hob_lbam);
-               out_be32(ioaddr->lbah_addr, tf->hob_lbah);
-               VPRINTK("hob: feat 0x%X nsect 0x%X, lba 0x%X 0x%X 0x%X\n",
-                       tf->hob_feature,
-                       tf->hob_nsect,
-                       tf->hob_lbal,
-                       tf->hob_lbam,
-                       tf->hob_lbah);
-       }
-
-       if (is_addr) {
-               out_be32(ioaddr->feature_addr, tf->feature);
-               out_be32(ioaddr->nsect_addr, tf->nsect);
-               out_be32(ioaddr->lbal_addr, tf->lbal);
-               out_be32(ioaddr->lbam_addr, tf->lbam);
-               out_be32(ioaddr->lbah_addr, tf->lbah);
-               VPRINTK("feat 0x%X nsect 0x%X lba 0x%X 0x%X 0x%X\n",
-                       tf->feature,
-                       tf->nsect,
-                       tf->lbal,
-                       tf->lbam,
-                       tf->lbah);
-       }
-
-       if (tf->flags & ATA_TFLAG_DEVICE) {
-               out_be32(ioaddr->device_addr, tf->device);
-               VPRINTK("device 0x%X\n", tf->device);
-       }
-
-       ata_wait_idle(ap);
-}
-
-/**
- *     scc_check_status - Read device status reg & clear interrupt
- *     @ap: port where the device is
- *
- *     Note: Original code is ata_check_status().
- */
-
-static u8 scc_check_status (struct ata_port *ap)
-{
-       return in_be32(ap->ioaddr.status_addr);
-}
-
-/**
- *     scc_tf_read - input device's ATA taskfile shadow registers
- *     @ap: Port from which input is read
- *     @tf: ATA taskfile register set for storing input
- *
- *     Note: Original code is ata_sff_tf_read().
- */
-
-static void scc_tf_read (struct ata_port *ap, struct ata_taskfile *tf)
-{
-       struct ata_ioports *ioaddr = &ap->ioaddr;
-
-       tf->command = scc_check_status(ap);
-       tf->feature = in_be32(ioaddr->error_addr);
-       tf->nsect = in_be32(ioaddr->nsect_addr);
-       tf->lbal = in_be32(ioaddr->lbal_addr);
-       tf->lbam = in_be32(ioaddr->lbam_addr);
-       tf->lbah = in_be32(ioaddr->lbah_addr);
-       tf->device = in_be32(ioaddr->device_addr);
-
-       if (tf->flags & ATA_TFLAG_LBA48) {
-               out_be32(ioaddr->ctl_addr, tf->ctl | ATA_HOB);
-               tf->hob_feature = in_be32(ioaddr->error_addr);
-               tf->hob_nsect = in_be32(ioaddr->nsect_addr);
-               tf->hob_lbal = in_be32(ioaddr->lbal_addr);
-               tf->hob_lbam = in_be32(ioaddr->lbam_addr);
-               tf->hob_lbah = in_be32(ioaddr->lbah_addr);
-               out_be32(ioaddr->ctl_addr, tf->ctl);
-               ap->last_ctl = tf->ctl;
-       }
-}
-
-/**
- *     scc_exec_command - issue ATA command to host controller
- *     @ap: port to which command is being issued
- *     @tf: ATA taskfile register set
- *
- *     Note: Original code is ata_sff_exec_command().
- */
-
-static void scc_exec_command (struct ata_port *ap,
-                             const struct ata_taskfile *tf)
-{
-       DPRINTK("ata%u: cmd 0x%X\n", ap->print_id, tf->command);
-
-       out_be32(ap->ioaddr.command_addr, tf->command);
-       ata_sff_pause(ap);
-}
-
-/**
- *     scc_check_altstatus - Read device alternate status reg
- *     @ap: port where the device is
- */
-
-static u8 scc_check_altstatus (struct ata_port *ap)
-{
-       return in_be32(ap->ioaddr.altstatus_addr);
-}
-
-/**
- *     scc_dev_select - Select device 0/1 on ATA bus
- *     @ap: ATA channel to manipulate
- *     @device: ATA device (numbered from zero) to select
- *
- *     Note: Original code is ata_sff_dev_select().
- */
-
-static void scc_dev_select (struct ata_port *ap, unsigned int device)
-{
-       u8 tmp;
-
-       if (device == 0)
-               tmp = ATA_DEVICE_OBS;
-       else
-               tmp = ATA_DEVICE_OBS | ATA_DEV1;
-
-       out_be32(ap->ioaddr.device_addr, tmp);
-       ata_sff_pause(ap);
-}
-
-/**
- *     scc_set_devctl - Write device control reg
- *     @ap: port where the device is
- *     @ctl: value to write
- */
-
-static void scc_set_devctl(struct ata_port *ap, u8 ctl)
-{
-       out_be32(ap->ioaddr.ctl_addr, ctl);
-}
-
-/**
- *     scc_bmdma_setup - Set up PCI IDE BMDMA transaction
- *     @qc: Info associated with this ATA transaction.
- *
- *     Note: Original code is ata_bmdma_setup().
- */
-
-static void scc_bmdma_setup (struct ata_queued_cmd *qc)
-{
-       struct ata_port *ap = qc->ap;
-       unsigned int rw = (qc->tf.flags & ATA_TFLAG_WRITE);
-       u8 dmactl;
-       void __iomem *mmio = ap->ioaddr.bmdma_addr;
-
-       /* load PRD table addr */
-       out_be32(mmio + SCC_DMA_TABLE_OFS, ap->bmdma_prd_dma);
-
-       /* specify data direction, triple-check start bit is clear */
-       dmactl = in_be32(mmio + SCC_DMA_CMD);
-       dmactl &= ~(ATA_DMA_WR | ATA_DMA_START);
-       if (!rw)
-               dmactl |= ATA_DMA_WR;
-       out_be32(mmio + SCC_DMA_CMD, dmactl);
-
-       /* issue r/w command */
-       ap->ops->sff_exec_command(ap, &qc->tf);
-}
-
-/**
- *     scc_bmdma_start - Start a PCI IDE BMDMA transaction
- *     @qc: Info associated with this ATA transaction.
- *
- *     Note: Original code is ata_bmdma_start().
- */
-
-static void scc_bmdma_start (struct ata_queued_cmd *qc)
-{
-       struct ata_port *ap = qc->ap;
-       u8 dmactl;
-       void __iomem *mmio = ap->ioaddr.bmdma_addr;
-
-       /* start host DMA transaction */
-       dmactl = in_be32(mmio + SCC_DMA_CMD);
-       out_be32(mmio + SCC_DMA_CMD, dmactl | ATA_DMA_START);
-}
-
-/**
- *     scc_devchk - PATA device presence detection
- *     @ap: ATA channel to examine
- *     @device: Device to examine (starting at zero)
- *
- *     Note: Original code is ata_devchk().
- */
-
-static unsigned int scc_devchk (struct ata_port *ap,
-                               unsigned int device)
-{
-       struct ata_ioports *ioaddr = &ap->ioaddr;
-       u8 nsect, lbal;
-
-       ap->ops->sff_dev_select(ap, device);
-
-       out_be32(ioaddr->nsect_addr, 0x55);
-       out_be32(ioaddr->lbal_addr, 0xaa);
-
-       out_be32(ioaddr->nsect_addr, 0xaa);
-       out_be32(ioaddr->lbal_addr, 0x55);
-
-       out_be32(ioaddr->nsect_addr, 0x55);
-       out_be32(ioaddr->lbal_addr, 0xaa);
-
-       nsect = in_be32(ioaddr->nsect_addr);
-       lbal = in_be32(ioaddr->lbal_addr);
-
-       if ((nsect == 0x55) && (lbal == 0xaa))
-               return 1;       /* we found a device */
-
-       return 0;               /* nothing found */
-}
-
-/**
- *     scc_wait_after_reset - wait for devices to become ready after reset
- *
- *     Note: Original code is ata_sff_wait_after_reset
- */
-
-static int scc_wait_after_reset(struct ata_link *link, unsigned int devmask,
-                               unsigned long deadline)
-{
-       struct ata_port *ap = link->ap;
-       struct ata_ioports *ioaddr = &ap->ioaddr;
-       unsigned int dev0 = devmask & (1 << 0);
-       unsigned int dev1 = devmask & (1 << 1);
-       int rc, ret = 0;
-
-       /* Spec mandates ">= 2ms" before checking status.  We wait
-        * 150ms, because that was the magic delay used for ATAPI
-        * devices in Hale Landis's ATADRVR, for the period of time
-        * between when the ATA command register is written, and then
-        * status is checked.  Because waiting for "a while" before
-        * checking status is fine, post SRST, we perform this magic
-        * delay here as well.
-        *
-        * Old drivers/ide uses the 2mS rule and then waits for ready.
-        */
-       ata_msleep(ap, 150);
-
-       /* always check readiness of the master device */
-       rc = ata_sff_wait_ready(link, deadline);
-       /* -ENODEV means the odd clown forgot the D7 pulldown resistor
-        * and TF status is 0xff, bail out on it too.
-        */
-       if (rc)
-               return rc;
-
-       /* if device 1 was found in ata_devchk, wait for register
-        * access briefly, then wait for BSY to clear.
-        */
-       if (dev1) {
-               int i;
-
-               ap->ops->sff_dev_select(ap, 1);
-
-               /* Wait for register access.  Some ATAPI devices fail
-                * to set nsect/lbal after reset, so don't waste too
-                * much time on it.  We're gonna wait for !BSY anyway.
-                */
-               for (i = 0; i < 2; i++) {
-                       u8 nsect, lbal;
-
-                       nsect = in_be32(ioaddr->nsect_addr);
-                       lbal = in_be32(ioaddr->lbal_addr);
-                       if ((nsect == 1) && (lbal == 1))
-                               break;
-                       ata_msleep(ap, 50);     /* give drive a breather */
-               }
-
-               rc = ata_sff_wait_ready(link, deadline);
-               if (rc) {
-                       if (rc != -ENODEV)
-                               return rc;
-                       ret = rc;
-               }
-       }
-
-       /* is all this really necessary? */
-       ap->ops->sff_dev_select(ap, 0);
-       if (dev1)
-               ap->ops->sff_dev_select(ap, 1);
-       if (dev0)
-               ap->ops->sff_dev_select(ap, 0);
-
-       return ret;
-}
-
-/**
- *     scc_bus_softreset - PATA device software reset
- *
- *     Note: Original code is ata_bus_softreset().
- */
-
-static int scc_bus_softreset(struct ata_port *ap, unsigned int devmask,
-                                      unsigned long deadline)
-{
-       struct ata_ioports *ioaddr = &ap->ioaddr;
-
-       DPRINTK("ata%u: bus reset via SRST\n", ap->print_id);
-
-       /* software reset.  causes dev0 to be selected */
-       out_be32(ioaddr->ctl_addr, ap->ctl);
-       udelay(20);
-       out_be32(ioaddr->ctl_addr, ap->ctl | ATA_SRST);
-       udelay(20);
-       out_be32(ioaddr->ctl_addr, ap->ctl);
-
-       return scc_wait_after_reset(&ap->link, devmask, deadline);
-}
-
-/**
- *     scc_softreset - reset host port via ATA SRST
- *     @ap: port to reset
- *     @classes: resulting classes of attached devices
- *     @deadline: deadline jiffies for the operation
- *
- *     Note: Original code is ata_sff_softreset().
- */
-
-static int scc_softreset(struct ata_link *link, unsigned int *classes,
-                        unsigned long deadline)
-{
-       struct ata_port *ap = link->ap;
-       unsigned int slave_possible = ap->flags & ATA_FLAG_SLAVE_POSS;
-       unsigned int devmask = 0;
-       int rc;
-       u8 err;
-
-       DPRINTK("ENTER\n");
-
-       /* determine if device 0/1 are present */
-       if (scc_devchk(ap, 0))
-               devmask |= (1 << 0);
-       if (slave_possible && scc_devchk(ap, 1))
-               devmask |= (1 << 1);
-
-       /* select device 0 again */
-       ap->ops->sff_dev_select(ap, 0);
-
-       /* issue bus reset */
-       DPRINTK("about to softreset, devmask=%x\n", devmask);
-       rc = scc_bus_softreset(ap, devmask, deadline);
-       if (rc) {
-               ata_port_err(ap, "SRST failed (err_mask=0x%x)\n", rc);
-               return -EIO;
-       }
-
-       /* determine by signature whether we have ATA or ATAPI devices */
-       classes[0] = ata_sff_dev_classify(&ap->link.device[0],
-                                         devmask & (1 << 0), &err);
-       if (slave_possible && err != 0x81)
-               classes[1] = ata_sff_dev_classify(&ap->link.device[1],
-                                                 devmask & (1 << 1), &err);
-
-       DPRINTK("EXIT, classes[0]=%u [1]=%u\n", classes[0], classes[1]);
-       return 0;
-}
-
-/**
- *     scc_bmdma_stop - Stop PCI IDE BMDMA transfer
- *     @qc: Command we are ending DMA for
- */
-
-static void scc_bmdma_stop (struct ata_queued_cmd *qc)
-{
-       struct ata_port *ap = qc->ap;
-       void __iomem *ctrl_base = ap->host->iomap[SCC_CTRL_BAR];
-       void __iomem *bmid_base = ap->host->iomap[SCC_BMID_BAR];
-       u32 reg;
-
-       while (1) {
-               reg = in_be32(bmid_base + SCC_DMA_INTST);
-
-               if (reg & INTSTS_SERROR) {
-                       printk(KERN_WARNING "%s: SERROR\n", DRV_NAME);
-                       out_be32(bmid_base + SCC_DMA_INTST, INTSTS_SERROR|INTSTS_BMSINT);
-                       out_be32(bmid_base + SCC_DMA_CMD,
-                                in_be32(bmid_base + SCC_DMA_CMD) & ~ATA_DMA_START);
-                       continue;
-               }
-
-               if (reg & INTSTS_PRERR) {
-                       u32 maea0, maec0;
-                       maea0 = in_be32(ctrl_base + SCC_CTL_MAEA0);
-                       maec0 = in_be32(ctrl_base + SCC_CTL_MAEC0);
-                       printk(KERN_WARNING "%s: PRERR [addr:%x cmd:%x]\n", DRV_NAME, maea0, maec0);
-                       out_be32(bmid_base + SCC_DMA_INTST, INTSTS_PRERR|INTSTS_BMSINT);
-                       out_be32(bmid_base + SCC_DMA_CMD,
-                                in_be32(bmid_base + SCC_DMA_CMD) & ~ATA_DMA_START);
-                       continue;
-               }
-
-               if (reg & INTSTS_RERR) {
-                       printk(KERN_WARNING "%s: Response Error\n", DRV_NAME);
-                       out_be32(bmid_base + SCC_DMA_INTST, INTSTS_RERR|INTSTS_BMSINT);
-                       out_be32(bmid_base + SCC_DMA_CMD,
-                                in_be32(bmid_base + SCC_DMA_CMD) & ~ATA_DMA_START);
-                       continue;
-               }
-
-               if (reg & INTSTS_ICERR) {
-                       out_be32(bmid_base + SCC_DMA_CMD,
-                                in_be32(bmid_base + SCC_DMA_CMD) & ~ATA_DMA_START);
-                       printk(KERN_WARNING "%s: Illegal Configuration\n", DRV_NAME);
-                       out_be32(bmid_base + SCC_DMA_INTST, INTSTS_ICERR|INTSTS_BMSINT);
-                       continue;
-               }
-
-               if (reg & INTSTS_BMSINT) {
-                       unsigned int classes;
-                       unsigned long deadline = ata_deadline(jiffies, ATA_TMOUT_BOOT);
-                       printk(KERN_WARNING "%s: Internal Bus Error\n", DRV_NAME);
-                       out_be32(bmid_base + SCC_DMA_INTST, INTSTS_BMSINT);
-                       /* TBD: SW reset */
-                       scc_softreset(&ap->link, &classes, deadline);
-                       continue;
-               }
-
-               if (reg & INTSTS_BMHE) {
-                       out_be32(bmid_base + SCC_DMA_INTST, INTSTS_BMHE);
-                       continue;
-               }
-
-               if (reg & INTSTS_ACTEINT) {
-                       out_be32(bmid_base + SCC_DMA_INTST, INTSTS_ACTEINT);
-                       continue;
-               }
-
-               if (reg & INTSTS_IOIRQS) {
-                       out_be32(bmid_base + SCC_DMA_INTST, INTSTS_IOIRQS);
-                       continue;
-               }
-               break;
-       }
-
-       /* clear start/stop bit */
-       out_be32(bmid_base + SCC_DMA_CMD,
-                in_be32(bmid_base + SCC_DMA_CMD) & ~ATA_DMA_START);
-
-       /* one-PIO-cycle guaranteed wait, per spec, for HDMA1:0 transition */
-       ata_sff_dma_pause(ap);  /* dummy read */
-}
-
-/**
- *     scc_bmdma_status - Read PCI IDE BMDMA status
- *     @ap: Port associated with this ATA transaction.
- */
-
-static u8 scc_bmdma_status (struct ata_port *ap)
-{
-       void __iomem *mmio = ap->ioaddr.bmdma_addr;
-       u8 host_stat = in_be32(mmio + SCC_DMA_STATUS);
-       u32 int_status = in_be32(mmio + SCC_DMA_INTST);
-       struct ata_queued_cmd *qc = ata_qc_from_tag(ap, ap->link.active_tag);
-       static int retry = 0;
-
-       /* return if IOS_SS is cleared */
-       if (!(in_be32(mmio + SCC_DMA_CMD) & ATA_DMA_START))
-               return host_stat;
-
-       /* errata A252,A308 workaround: Step4 */
-       if ((scc_check_altstatus(ap) & ATA_ERR)
-                                       && (int_status & INTSTS_INTRQ))
-               return (host_stat | ATA_DMA_INTR);
-
-       /* errata A308 workaround Step5 */
-       if (int_status & INTSTS_IOIRQS) {
-               host_stat |= ATA_DMA_INTR;
-
-               /* We don't check ATAPI DMA because it is limited to UDMA4 */
-               if ((qc->tf.protocol == ATA_PROT_DMA &&
-                    qc->dev->xfer_mode > XFER_UDMA_4)) {
-                       if (!(int_status & INTSTS_ACTEINT)) {
-                               printk(KERN_WARNING "ata%u: operation failed (transfer data loss)\n",
-                                      ap->print_id);
-                               host_stat |= ATA_DMA_ERR;
-                               if (retry++)
-                                       ap->udma_mask &= ~(1 << qc->dev->xfer_mode);
-                       } else
-                               retry = 0;
-               }
-       }
-
-       return host_stat;
-}
-
-/**
- *     scc_data_xfer - Transfer data by PIO
- *     @dev: device for this I/O
- *     @buf: data buffer
- *     @buflen: buffer length
- *     @rw: read/write
- *
- *     Note: Original code is ata_sff_data_xfer().
- */
-
-static unsigned int scc_data_xfer (struct ata_device *dev, unsigned char *buf,
-                                  unsigned int buflen, int rw)
-{
-       struct ata_port *ap = dev->link->ap;
-       unsigned int words = buflen >> 1;
-       unsigned int i;
-       __le16 *buf16 = (__le16 *) buf;
-       void __iomem *mmio = ap->ioaddr.data_addr;
-
-       /* Transfer multiple of 2 bytes */
-       if (rw == READ)
-               for (i = 0; i < words; i++)
-                       buf16[i] = cpu_to_le16(in_be32(mmio));
-       else
-               for (i = 0; i < words; i++)
-                       out_be32(mmio, le16_to_cpu(buf16[i]));
-
-       /* Transfer trailing 1 byte, if any. */
-       if (unlikely(buflen & 0x01)) {
-               __le16 align_buf[1] = { 0 };
-               unsigned char *trailing_buf = buf + buflen - 1;
-
-               if (rw == READ) {
-                       align_buf[0] = cpu_to_le16(in_be32(mmio));
-                       memcpy(trailing_buf, align_buf, 1);
-               } else {
-                       memcpy(align_buf, trailing_buf, 1);
-                       out_be32(mmio, le16_to_cpu(align_buf[0]));
-               }
-               words++;
-       }
-
-       return words << 1;
-}
-
-/**
- *     scc_postreset - standard postreset callback
- *     @ap: the target ata_port
- *     @classes: classes of attached devices
- *
- *     Note: Original code is ata_sff_postreset().
- */
-
-static void scc_postreset(struct ata_link *link, unsigned int *classes)
-{
-       struct ata_port *ap = link->ap;
-
-       DPRINTK("ENTER\n");
-
-       /* is double-select really necessary? */
-       if (classes[0] != ATA_DEV_NONE)
-               ap->ops->sff_dev_select(ap, 1);
-       if (classes[1] != ATA_DEV_NONE)
-               ap->ops->sff_dev_select(ap, 0);
-
-       /* bail out if no device is present */
-       if (classes[0] == ATA_DEV_NONE && classes[1] == ATA_DEV_NONE) {
-               DPRINTK("EXIT, no device\n");
-               return;
-       }
-
-       /* set up device control */
-       out_be32(ap->ioaddr.ctl_addr, ap->ctl);
-
-       DPRINTK("EXIT\n");
-}
-
-/**
- *     scc_irq_clear - Clear PCI IDE BMDMA interrupt.
- *     @ap: Port associated with this ATA transaction.
- *
- *     Note: Original code is ata_bmdma_irq_clear().
- */
-
-static void scc_irq_clear (struct ata_port *ap)
-{
-       void __iomem *mmio = ap->ioaddr.bmdma_addr;
-
-       if (!mmio)
-               return;
-
-       out_be32(mmio + SCC_DMA_STATUS, in_be32(mmio + SCC_DMA_STATUS));
-}
-
-/**
- *     scc_port_start - Set port up for dma.
- *     @ap: Port to initialize
- *
- *     Allocate space for PRD table using ata_bmdma_port_start().
- *     Set PRD table address for PTERADD. (PRD Transfer End Read)
- */
-
-static int scc_port_start (struct ata_port *ap)
-{
-       void __iomem *mmio = ap->ioaddr.bmdma_addr;
-       int rc;
-
-       rc = ata_bmdma_port_start(ap);
-       if (rc)
-               return rc;
-
-       out_be32(mmio + SCC_DMA_PTERADD, ap->bmdma_prd_dma);
-       return 0;
-}
-
-/**
- *     scc_port_stop - Undo scc_port_start()
- *     @ap: Port to shut down
- *
- *     Reset PTERADD.
- */
-
-static void scc_port_stop (struct ata_port *ap)
-{
-       void __iomem *mmio = ap->ioaddr.bmdma_addr;
-
-       out_be32(mmio + SCC_DMA_PTERADD, 0);
-}
-
-static struct scsi_host_template scc_sht = {
-       ATA_BMDMA_SHT(DRV_NAME),
-};
-
-static struct ata_port_operations scc_pata_ops = {
-       .inherits               = &ata_bmdma_port_ops,
-
-       .set_piomode            = scc_set_piomode,
-       .set_dmamode            = scc_set_dmamode,
-       .mode_filter            = scc_mode_filter,
-
-       .sff_tf_load            = scc_tf_load,
-       .sff_tf_read            = scc_tf_read,
-       .sff_exec_command       = scc_exec_command,
-       .sff_check_status       = scc_check_status,
-       .sff_check_altstatus    = scc_check_altstatus,
-       .sff_dev_select         = scc_dev_select,
-       .sff_set_devctl         = scc_set_devctl,
-
-       .bmdma_setup            = scc_bmdma_setup,
-       .bmdma_start            = scc_bmdma_start,
-       .bmdma_stop             = scc_bmdma_stop,
-       .bmdma_status           = scc_bmdma_status,
-       .sff_data_xfer          = scc_data_xfer,
-
-       .cable_detect           = ata_cable_80wire,
-       .softreset              = scc_softreset,
-       .postreset              = scc_postreset,
-
-       .sff_irq_clear          = scc_irq_clear,
-
-       .port_start             = scc_port_start,
-       .port_stop              = scc_port_stop,
-};
-
-static struct ata_port_info scc_port_info[] = {
-       {
-               .flags          = ATA_FLAG_SLAVE_POSS,
-               .pio_mask       = ATA_PIO4,
-               /* No MWDMA */
-               .udma_mask      = ATA_UDMA6,
-               .port_ops       = &scc_pata_ops,
-       },
-};
-
-/**
- *     scc_reset_controller - initialize SCC PATA controller.
- */
-
-static int scc_reset_controller(struct ata_host *host)
-{
-       void __iomem *ctrl_base = host->iomap[SCC_CTRL_BAR];
-       void __iomem *bmid_base = host->iomap[SCC_BMID_BAR];
-       void __iomem *cckctrl_port = ctrl_base + SCC_CTL_CCKCTRL;
-       void __iomem *mode_port = ctrl_base + SCC_CTL_MODEREG;
-       void __iomem *ecmode_port = ctrl_base + SCC_CTL_ECMODE;
-       void __iomem *intmask_port = bmid_base + SCC_DMA_INTMASK;
-       void __iomem *dmastatus_port = bmid_base + SCC_DMA_STATUS;
-       u32 reg = 0;
-
-       out_be32(cckctrl_port, reg);
-       reg |= CCKCTRL_ATACLKOEN;
-       out_be32(cckctrl_port, reg);
-       reg |= CCKCTRL_LCLKEN | CCKCTRL_OCLKEN;
-       out_be32(cckctrl_port, reg);
-       reg |= CCKCTRL_CRST;
-       out_be32(cckctrl_port, reg);
-
-       for (;;) {
-               reg = in_be32(cckctrl_port);
-               if (reg & CCKCTRL_CRST)
-                       break;
-               udelay(5000);
-       }
-
-       reg |= CCKCTRL_ATARESET;
-       out_be32(cckctrl_port, reg);
-       out_be32(ecmode_port, ECMODE_VALUE);
-       out_be32(mode_port, MODE_JCUSFEN);
-       out_be32(intmask_port, INTMASK_MSK);
-
-       if (in_be32(dmastatus_port) & QCHSD_STPDIAG) {
-               printk(KERN_WARNING "%s: failed to detect 80c cable. (PDIAG# is high)\n", DRV_NAME);
-               return -EIO;
-       }
-
-       return 0;
-}
-
-/**
- *     scc_setup_ports - initialize ioaddr with SCC PATA port offsets.
- *     @ioaddr: IO address structure to be initialized
- *     @base: base address of BMID region
- */
-
-static void scc_setup_ports (struct ata_ioports *ioaddr, void __iomem *base)
-{
-       ioaddr->cmd_addr = base + SCC_REG_CMD_ADDR;
-       ioaddr->altstatus_addr = ioaddr->cmd_addr + SCC_REG_ALTSTATUS;
-       ioaddr->ctl_addr = ioaddr->cmd_addr + SCC_REG_ALTSTATUS;
-       ioaddr->bmdma_addr = base;
-       ioaddr->data_addr = ioaddr->cmd_addr + SCC_REG_DATA;
-       ioaddr->error_addr = ioaddr->cmd_addr + SCC_REG_ERR;
-       ioaddr->feature_addr = ioaddr->cmd_addr + SCC_REG_FEATURE;
-       ioaddr->nsect_addr = ioaddr->cmd_addr + SCC_REG_NSECT;
-       ioaddr->lbal_addr = ioaddr->cmd_addr + SCC_REG_LBAL;
-       ioaddr->lbam_addr = ioaddr->cmd_addr + SCC_REG_LBAM;
-       ioaddr->lbah_addr = ioaddr->cmd_addr + SCC_REG_LBAH;
-       ioaddr->device_addr = ioaddr->cmd_addr + SCC_REG_DEVICE;
-       ioaddr->status_addr = ioaddr->cmd_addr + SCC_REG_STATUS;
-       ioaddr->command_addr = ioaddr->cmd_addr + SCC_REG_CMD;
-}
-
-static int scc_host_init(struct ata_host *host)
-{
-       struct pci_dev *pdev = to_pci_dev(host->dev);
-       int rc;
-
-       rc = scc_reset_controller(host);
-       if (rc)
-               return rc;
-
-       rc = dma_set_mask(&pdev->dev, ATA_DMA_MASK);
-       if (rc)
-               return rc;
-       rc = dma_set_coherent_mask(&pdev->dev, ATA_DMA_MASK);
-       if (rc)
-               return rc;
-
-       scc_setup_ports(&host->ports[0]->ioaddr, host->iomap[SCC_BMID_BAR]);
-
-       pci_set_master(pdev);
-
-       return 0;
-}
-
-/**
- *     scc_init_one - Register SCC PATA device with kernel services
- *     @pdev: PCI device to register
- *     @ent: Entry in scc_pci_tbl matching with @pdev
- *
- *     LOCKING:
- *     Inherited from PCI layer (may sleep).
- *
- *     RETURNS:
- *     Zero on success, or -ERRNO value.
- */
-
-static int scc_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
-{
-       unsigned int board_idx = (unsigned int) ent->driver_data;
-       const struct ata_port_info *ppi[] = { &scc_port_info[board_idx], NULL };
-       struct ata_host *host;
-       int rc;
-
-       ata_print_version_once(&pdev->dev, DRV_VERSION);
-
-       host = ata_host_alloc_pinfo(&pdev->dev, ppi, 1);
-       if (!host)
-               return -ENOMEM;
-
-       rc = pcim_enable_device(pdev);
-       if (rc)
-               return rc;
-
-       rc = pcim_iomap_regions(pdev, (1 << SCC_CTRL_BAR) | (1 << SCC_BMID_BAR), DRV_NAME);
-       if (rc == -EBUSY)
-               pcim_pin_device(pdev);
-       if (rc)
-               return rc;
-       host->iomap = pcim_iomap_table(pdev);
-
-       ata_port_pbar_desc(host->ports[0], SCC_CTRL_BAR, -1, "ctrl");
-       ata_port_pbar_desc(host->ports[0], SCC_BMID_BAR, -1, "bmid");
-
-       rc = scc_host_init(host);
-       if (rc)
-               return rc;
-
-       return ata_host_activate(host, pdev->irq, ata_bmdma_interrupt,
-                                IRQF_SHARED, &scc_sht);
-}
-
-static struct pci_driver scc_pci_driver = {
-       .name                   = DRV_NAME,
-       .id_table               = scc_pci_tbl,
-       .probe                  = scc_init_one,
-       .remove                 = ata_pci_remove_one,
-#ifdef CONFIG_PM_SLEEP
-       .suspend                = ata_pci_device_suspend,
-       .resume                 = ata_pci_device_resume,
-#endif
-};
-
-module_pci_driver(scc_pci_driver);
-
-MODULE_AUTHOR("Toshiba corp");
-MODULE_DESCRIPTION("SCSI low-level driver for Toshiba SCC PATA controller");
-MODULE_LICENSE("GPL");
-MODULE_DEVICE_TABLE(pci, scc_pci_tbl);
-MODULE_VERSION(DRV_VERSION);
index 88f13c525712f700d05428e741cafeeac752ad2d..44f2514fb7755d0bdf9f4524ebbe5364a84af5a3 100644 (file)
@@ -2257,7 +2257,8 @@ static int nvme_trans_inquiry(struct nvme_ns *ns, struct sg_io_hdr *hdr,
        page_code = GET_INQ_PAGE_CODE(cmd);
        alloc_len = GET_INQ_ALLOC_LENGTH(cmd);
 
-       inq_response = kmalloc(alloc_len, GFP_KERNEL);
+       inq_response = kmalloc(max(alloc_len, STANDARD_INQUIRY_LENGTH),
+                               GFP_KERNEL);
        if (inq_response == NULL) {
                res = -ENOMEM;
                goto out_mem;
index 288547a3c566753d146e28924c7d3b023e8c0d3b..8c81af6dbe06365462b3c1d56481385a2db60881 100644 (file)
@@ -88,6 +88,7 @@ static const struct usb_device_id ath3k_table[] = {
        { USB_DEVICE(0x04CA, 0x3007) },
        { USB_DEVICE(0x04CA, 0x3008) },
        { USB_DEVICE(0x04CA, 0x300b) },
+       { USB_DEVICE(0x04CA, 0x300f) },
        { USB_DEVICE(0x04CA, 0x3010) },
        { USB_DEVICE(0x0930, 0x0219) },
        { USB_DEVICE(0x0930, 0x0220) },
@@ -104,6 +105,7 @@ static const struct usb_device_id ath3k_table[] = {
        { USB_DEVICE(0x0cf3, 0xe003) },
        { USB_DEVICE(0x0CF3, 0xE004) },
        { USB_DEVICE(0x0CF3, 0xE005) },
+       { USB_DEVICE(0x0CF3, 0xE006) },
        { USB_DEVICE(0x13d3, 0x3362) },
        { USB_DEVICE(0x13d3, 0x3375) },
        { USB_DEVICE(0x13d3, 0x3393) },
@@ -143,6 +145,7 @@ static const struct usb_device_id ath3k_blist_tbl[] = {
        { USB_DEVICE(0x04ca, 0x3007), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x04ca, 0x300b), .driver_info = BTUSB_ATH3012 },
+       { USB_DEVICE(0x04ca, 0x300f), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x04ca, 0x3010), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x0930, 0x0220), .driver_info = BTUSB_ATH3012 },
@@ -158,6 +161,7 @@ static const struct usb_device_id ath3k_blist_tbl[] = {
        { USB_DEVICE(0x0CF3, 0x817a), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x0cf3, 0xe005), .driver_info = BTUSB_ATH3012 },
+       { USB_DEVICE(0x0cf3, 0xe006), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x0cf3, 0xe003), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },
index 4f7e8d400bc01a178bcbfcf499340b40545fb54f..6de97b3871b0f8cffe4d2c9b2b78eb5e87c48247 100644 (file)
@@ -227,7 +227,6 @@ static void bt3c_receive(struct bt3c_info *info)
        iobase = info->p_dev->resource[0]->start;
 
        avail = bt3c_read(iobase, 0x7006);
-       //printk("bt3c_cs: receiving %d bytes\n", avail);
 
        bt3c_address(iobase, 0x7480);
        while (size < avail) {
@@ -250,7 +249,6 @@ static void bt3c_receive(struct bt3c_info *info)
 
                        bt_cb(info->rx_skb)->pkt_type = inb(iobase + DATA_L);
                        inb(iobase + DATA_H);
-                       //printk("bt3c: PACKET_TYPE=%02x\n", bt_cb(info->rx_skb)->pkt_type);
 
                        switch (bt_cb(info->rx_skb)->pkt_type) {
 
@@ -364,7 +362,6 @@ static irqreturn_t bt3c_interrupt(int irq, void *dev_inst)
                        if (stat & 0x0001)
                                bt3c_receive(info);
                        if (stat & 0x0002) {
-                               //BT_ERR("Ack (stat=0x%04x)", stat);
                                clear_bit(XMIT_SENDING, &(info->tx_state));
                                bt3c_write_wakeup(info);
                        }
index d0741f3ed7ec36b49f1c50ff119fabc7368d3a9e..4bba86677adc64553fe8415d9b6812bfb3e1449d 100644 (file)
@@ -95,6 +95,78 @@ int btbcm_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr)
 }
 EXPORT_SYMBOL_GPL(btbcm_set_bdaddr);
 
+int btbcm_patchram(struct hci_dev *hdev, const char *firmware)
+{
+       const struct hci_command_hdr *cmd;
+       const struct firmware *fw;
+       const u8 *fw_ptr;
+       size_t fw_size;
+       struct sk_buff *skb;
+       u16 opcode;
+       int err;
+
+       err = request_firmware(&fw, firmware, &hdev->dev);
+       if (err < 0) {
+               BT_INFO("%s: BCM: Patch %s not found", hdev->name, firmware);
+               return err;
+       }
+
+       /* Start Download */
+       skb = __hci_cmd_sync(hdev, 0xfc2e, 0, NULL, HCI_INIT_TIMEOUT);
+       if (IS_ERR(skb)) {
+               err = PTR_ERR(skb);
+               BT_ERR("%s: BCM: Download Minidrv command failed (%d)",
+                      hdev->name, err);
+               goto done;
+       }
+       kfree_skb(skb);
+
+       /* 50 msec delay after Download Minidrv completes */
+       msleep(50);
+
+       fw_ptr = fw->data;
+       fw_size = fw->size;
+
+       while (fw_size >= sizeof(*cmd)) {
+               const u8 *cmd_param;
+
+               cmd = (struct hci_command_hdr *)fw_ptr;
+               fw_ptr += sizeof(*cmd);
+               fw_size -= sizeof(*cmd);
+
+               if (fw_size < cmd->plen) {
+                       BT_ERR("%s: BCM: Patch %s is corrupted", hdev->name,
+                              firmware);
+                       err = -EINVAL;
+                       goto done;
+               }
+
+               cmd_param = fw_ptr;
+               fw_ptr += cmd->plen;
+               fw_size -= cmd->plen;
+
+               opcode = le16_to_cpu(cmd->opcode);
+
+               skb = __hci_cmd_sync(hdev, opcode, cmd->plen, cmd_param,
+                                    HCI_INIT_TIMEOUT);
+               if (IS_ERR(skb)) {
+                       err = PTR_ERR(skb);
+                       BT_ERR("%s: BCM: Patch command %04x failed (%d)",
+                              hdev->name, opcode, err);
+                       goto done;
+               }
+               kfree_skb(skb);
+       }
+
+       /* 250 msec delay after Launch Ram completes */
+       msleep(250);
+
+done:
+       release_firmware(fw);
+       return err;
+}
+EXPORT_SYMBOL(btbcm_patchram);
+
 static int btbcm_reset(struct hci_dev *hdev)
 {
        struct sk_buff *skb;
@@ -198,12 +270,8 @@ static const struct {
 
 int btbcm_setup_patchram(struct hci_dev *hdev)
 {
-       const struct hci_command_hdr *cmd;
-       const struct firmware *fw;
-       const u8 *fw_ptr;
-       size_t fw_size;
        char fw_name[64];
-       u16 opcode, subver, rev, pid, vid;
+       u16 subver, rev, pid, vid;
        const char *hw_name = NULL;
        struct sk_buff *skb;
        struct hci_rp_read_local_version *ver;
@@ -273,74 +341,19 @@ int btbcm_setup_patchram(struct hci_dev *hdev)
                hw_name ? : "BCM", (subver & 0x7000) >> 13,
                (subver & 0x1f00) >> 8, (subver & 0x00ff), rev & 0x0fff);
 
-       err = request_firmware(&fw, fw_name, &hdev->dev);
-       if (err < 0) {
-               BT_INFO("%s: BCM: patch %s not found", hdev->name, fw_name);
+       err = btbcm_patchram(hdev, fw_name);
+       if (err == -ENOENT)
                return 0;
-       }
-
-       /* Start Download */
-       skb = __hci_cmd_sync(hdev, 0xfc2e, 0, NULL, HCI_INIT_TIMEOUT);
-       if (IS_ERR(skb)) {
-               err = PTR_ERR(skb);
-               BT_ERR("%s: BCM: Download Minidrv command failed (%d)",
-                      hdev->name, err);
-               goto reset;
-       }
-       kfree_skb(skb);
-
-       /* 50 msec delay after Download Minidrv completes */
-       msleep(50);
-
-       fw_ptr = fw->data;
-       fw_size = fw->size;
-
-       while (fw_size >= sizeof(*cmd)) {
-               const u8 *cmd_param;
-
-               cmd = (struct hci_command_hdr *)fw_ptr;
-               fw_ptr += sizeof(*cmd);
-               fw_size -= sizeof(*cmd);
-
-               if (fw_size < cmd->plen) {
-                       BT_ERR("%s: BCM: patch %s is corrupted", hdev->name,
-                              fw_name);
-                       err = -EINVAL;
-                       goto reset;
-               }
 
-               cmd_param = fw_ptr;
-               fw_ptr += cmd->plen;
-               fw_size -= cmd->plen;
-
-               opcode = le16_to_cpu(cmd->opcode);
-
-               skb = __hci_cmd_sync(hdev, opcode, cmd->plen, cmd_param,
-                                    HCI_INIT_TIMEOUT);
-               if (IS_ERR(skb)) {
-                       err = PTR_ERR(skb);
-                       BT_ERR("%s: BCM: patch command %04x failed (%d)",
-                              hdev->name, opcode, err);
-                       goto reset;
-               }
-               kfree_skb(skb);
-       }
-
-       /* 250 msec delay after Launch Ram completes */
-       msleep(250);
-
-reset:
        /* Reset */
        err = btbcm_reset(hdev);
        if (err)
-               goto done;
+               return err;
 
        /* Read Local Version Info */
        skb = btbcm_read_local_version(hdev);
-       if (IS_ERR(skb)) {
-               err = PTR_ERR(skb);
-               goto done;
-       }
+       if (IS_ERR(skb))
+               return PTR_ERR(skb);
 
        ver = (struct hci_rp_read_local_version *)skb->data;
        rev = le16_to_cpu(ver->hci_rev);
@@ -355,10 +368,7 @@ int btbcm_setup_patchram(struct hci_dev *hdev)
 
        set_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks);
 
-done:
-       release_firmware(fw);
-
-       return err;
+       return 0;
 }
 EXPORT_SYMBOL_GPL(btbcm_setup_patchram);
 
index 34268ae3eb4607e16f5c9e017b23cb904a80b459..eb6ab5f9483d3b510ab6a2decfb1d694af8facb7 100644 (file)
@@ -25,6 +25,7 @@
 
 int btbcm_check_bdaddr(struct hci_dev *hdev);
 int btbcm_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr);
+int btbcm_patchram(struct hci_dev *hdev, const char *firmware);
 
 int btbcm_setup_patchram(struct hci_dev *hdev);
 int btbcm_setup_apple(struct hci_dev *hdev);
@@ -41,6 +42,11 @@ static inline int btbcm_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr)
        return -EOPNOTSUPP;
 }
 
+static inline int btbcm_patchram(struct hci_dev *hdev, const char *firmware)
+{
+       return -EOPNOTSUPP;
+}
+
 static inline int btbcm_setup_patchram(struct hci_dev *hdev)
 {
        return 0;
index de7b236eeae7777f71389ec42c233525d309aef2..3c10d4dfe9a790e6e34f12022b1bcc2321ac648c 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/module.h>
 #include <linux/usb.h>
 #include <linux/firmware.h>
+#include <asm/unaligned.h>
 
 #include <net/bluetooth/bluetooth.h>
 #include <net/bluetooth/hci_core.h>
@@ -57,6 +58,7 @@ static struct usb_driver btusb_driver;
 #define BTUSB_AMP              0x4000
 #define BTUSB_QCA_ROME         0x8000
 #define BTUSB_BCM_APPLE                0x10000
+#define BTUSB_REALTEK          0x20000
 
 static const struct usb_device_id btusb_table[] = {
        /* Generic Bluetooth USB device */
@@ -184,6 +186,7 @@ static const struct usb_device_id blacklist_table[] = {
        { USB_DEVICE(0x04ca, 0x3007), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x04ca, 0x300b), .driver_info = BTUSB_ATH3012 },
+       { USB_DEVICE(0x04ca, 0x300f), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x04ca, 0x3010), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x0930, 0x0220), .driver_info = BTUSB_ATH3012 },
@@ -200,6 +203,7 @@ static const struct usb_device_id blacklist_table[] = {
        { USB_DEVICE(0x0cf3, 0xe003), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x0cf3, 0xe005), .driver_info = BTUSB_ATH3012 },
+       { USB_DEVICE(0x0cf3, 0xe006), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 },
@@ -216,6 +220,7 @@ static const struct usb_device_id blacklist_table[] = {
        { USB_DEVICE(0x0489, 0xe03c), .driver_info = BTUSB_ATH3012 },
 
        /* QCA ROME chipset */
+       { USB_DEVICE(0x0cf3, 0xe007), .driver_info = BTUSB_QCA_ROME },
        { USB_DEVICE(0x0cf3, 0xe300), .driver_info = BTUSB_QCA_ROME },
        { USB_DEVICE(0x0cf3, 0xe360), .driver_info = BTUSB_QCA_ROME },
 
@@ -288,6 +293,28 @@ static const struct usb_device_id blacklist_table[] = {
        { USB_VENDOR_AND_INTERFACE_INFO(0x8087, 0xe0, 0x01, 0x01),
          .driver_info = BTUSB_IGNORE },
 
+       /* Realtek Bluetooth devices */
+       { USB_VENDOR_AND_INTERFACE_INFO(0x0bda, 0xe0, 0x01, 0x01),
+         .driver_info = BTUSB_REALTEK },
+
+       /* Additional Realtek 8723AE Bluetooth devices */
+       { USB_DEVICE(0x0930, 0x021d), .driver_info = BTUSB_REALTEK },
+       { USB_DEVICE(0x13d3, 0x3394), .driver_info = BTUSB_REALTEK },
+
+       /* Additional Realtek 8723BE Bluetooth devices */
+       { USB_DEVICE(0x0489, 0xe085), .driver_info = BTUSB_REALTEK },
+       { USB_DEVICE(0x0489, 0xe08b), .driver_info = BTUSB_REALTEK },
+       { USB_DEVICE(0x13d3, 0x3410), .driver_info = BTUSB_REALTEK },
+       { USB_DEVICE(0x13d3, 0x3416), .driver_info = BTUSB_REALTEK },
+       { USB_DEVICE(0x13d3, 0x3459), .driver_info = BTUSB_REALTEK },
+
+       /* Additional Realtek 8821AE Bluetooth devices */
+       { USB_DEVICE(0x0b05, 0x17dc), .driver_info = BTUSB_REALTEK },
+       { USB_DEVICE(0x13d3, 0x3414), .driver_info = BTUSB_REALTEK },
+       { USB_DEVICE(0x13d3, 0x3458), .driver_info = BTUSB_REALTEK },
+       { USB_DEVICE(0x13d3, 0x3461), .driver_info = BTUSB_REALTEK },
+       { USB_DEVICE(0x13d3, 0x3462), .driver_info = BTUSB_REALTEK },
+
        { }     /* Terminating entry */
 };
 
@@ -892,7 +919,7 @@ static int btusb_open(struct hci_dev *hdev)
         */
        if (data->setup_on_usb) {
                err = data->setup_on_usb(hdev);
-               if (err <0)
+               if (err < 0)
                        return err;
        }
 
@@ -1345,6 +1372,378 @@ static int btusb_setup_csr(struct hci_dev *hdev)
        return ret;
 }
 
+#define RTL_FRAG_LEN 252
+
+struct rtl_download_cmd {
+       __u8 index;
+       __u8 data[RTL_FRAG_LEN];
+} __packed;
+
+struct rtl_download_response {
+       __u8 status;
+       __u8 index;
+} __packed;
+
+struct rtl_rom_version_evt {
+       __u8 status;
+       __u8 version;
+} __packed;
+
+struct rtl_epatch_header {
+       __u8 signature[8];
+       __le32 fw_version;
+       __le16 num_patches;
+} __packed;
+
+#define RTL_EPATCH_SIGNATURE   "Realtech"
+#define RTL_ROM_LMP_3499       0x3499
+#define RTL_ROM_LMP_8723A      0x1200
+#define RTL_ROM_LMP_8723B      0x8723
+#define RTL_ROM_LMP_8821A      0x8821
+#define RTL_ROM_LMP_8761A      0x8761
+
+static int rtl_read_rom_version(struct hci_dev *hdev, u8 *version)
+{
+       struct rtl_rom_version_evt *rom_version;
+       struct sk_buff *skb;
+       int ret;
+
+       /* Read RTL ROM version command */
+       skb = __hci_cmd_sync(hdev, 0xfc6d, 0, NULL, HCI_INIT_TIMEOUT);
+       if (IS_ERR(skb)) {
+               BT_ERR("%s: Read ROM version failed (%ld)",
+                      hdev->name, PTR_ERR(skb));
+               return PTR_ERR(skb);
+       }
+
+       if (skb->len != sizeof(*rom_version)) {
+               BT_ERR("%s: RTL version event length mismatch", hdev->name);
+               kfree_skb(skb);
+               return -EIO;
+       }
+
+       rom_version = (struct rtl_rom_version_evt *)skb->data;
+       BT_INFO("%s: rom_version status=%x version=%x",
+               hdev->name, rom_version->status, rom_version->version);
+
+       ret = rom_version->status;
+       if (ret == 0)
+               *version = rom_version->version;
+
+       kfree_skb(skb);
+       return ret;
+}
+
+static int rtl8723b_parse_firmware(struct hci_dev *hdev, u16 lmp_subver,
+                                  const struct firmware *fw,
+                                  unsigned char **_buf)
+{
+       const u8 extension_sig[] = { 0x51, 0x04, 0xfd, 0x77 };
+       struct rtl_epatch_header *epatch_info;
+       unsigned char *buf;
+       int i, ret, len;
+       size_t min_size;
+       u8 opcode, length, data, rom_version = 0;
+       int project_id = -1;
+       const unsigned char *fwptr, *chip_id_base;
+       const unsigned char *patch_length_base, *patch_offset_base;
+       u32 patch_offset = 0;
+       u16 patch_length, num_patches;
+       const u16 project_id_to_lmp_subver[] = {
+               RTL_ROM_LMP_8723A,
+               RTL_ROM_LMP_8723B,
+               RTL_ROM_LMP_8821A,
+               RTL_ROM_LMP_8761A
+       };
+
+       ret = rtl_read_rom_version(hdev, &rom_version);
+       if (ret)
+               return -bt_to_errno(ret);
+
+       min_size = sizeof(struct rtl_epatch_header) + sizeof(extension_sig) + 3;
+       if (fw->size < min_size)
+               return -EINVAL;
+
+       fwptr = fw->data + fw->size - sizeof(extension_sig);
+       if (memcmp(fwptr, extension_sig, sizeof(extension_sig)) != 0) {
+               BT_ERR("%s: extension section signature mismatch", hdev->name);
+               return -EINVAL;
+       }
+
+       /* Loop from the end of the firmware parsing instructions, until
+        * we find an instruction that identifies the "project ID" for the
+        * hardware supported by this firwmare file.
+        * Once we have that, we double-check that that project_id is suitable
+        * for the hardware we are working with.
+        */
+       while (fwptr >= fw->data + (sizeof(struct rtl_epatch_header) + 3)) {
+               opcode = *--fwptr;
+               length = *--fwptr;
+               data = *--fwptr;
+
+               BT_DBG("check op=%x len=%x data=%x", opcode, length, data);
+
+               if (opcode == 0xff) /* EOF */
+                       break;
+
+               if (length == 0) {
+                       BT_ERR("%s: found instruction with length 0",
+                              hdev->name);
+                       return -EINVAL;
+               }
+
+               if (opcode == 0 && length == 1) {
+                       project_id = data;
+                       break;
+               }
+
+               fwptr -= length;
+       }
+
+       if (project_id < 0) {
+               BT_ERR("%s: failed to find version instruction", hdev->name);
+               return -EINVAL;
+       }
+
+       if (project_id >= ARRAY_SIZE(project_id_to_lmp_subver)) {
+               BT_ERR("%s: unknown project id %d", hdev->name, project_id);
+               return -EINVAL;
+       }
+
+       if (lmp_subver != project_id_to_lmp_subver[project_id]) {
+               BT_ERR("%s: firmware is for %x but this is a %x", hdev->name,
+                      project_id_to_lmp_subver[project_id], lmp_subver);
+               return -EINVAL;
+       }
+
+       epatch_info = (struct rtl_epatch_header *)fw->data;
+       if (memcmp(epatch_info->signature, RTL_EPATCH_SIGNATURE, 8) != 0) {
+               BT_ERR("%s: bad EPATCH signature", hdev->name);
+               return -EINVAL;
+       }
+
+       num_patches = le16_to_cpu(epatch_info->num_patches);
+       BT_DBG("fw_version=%x, num_patches=%d",
+              le32_to_cpu(epatch_info->fw_version), num_patches);
+
+       /* After the rtl_epatch_header there is a funky patch metadata section.
+        * Assuming 2 patches, the layout is:
+        * ChipID1 ChipID2 PatchLength1 PatchLength2 PatchOffset1 PatchOffset2
+        *
+        * Find the right patch for this chip.
+        */
+       min_size += 8 * num_patches;
+       if (fw->size < min_size)
+               return -EINVAL;
+
+       chip_id_base = fw->data + sizeof(struct rtl_epatch_header);
+       patch_length_base = chip_id_base + (sizeof(u16) * num_patches);
+       patch_offset_base = patch_length_base + (sizeof(u16) * num_patches);
+       for (i = 0; i < num_patches; i++) {
+               u16 chip_id = get_unaligned_le16(chip_id_base +
+                                                (i * sizeof(u16)));
+               if (chip_id == rom_version + 1) {
+                       patch_length = get_unaligned_le16(patch_length_base +
+                                                         (i * sizeof(u16)));
+                       patch_offset = get_unaligned_le32(patch_offset_base +
+                                                         (i * sizeof(u32)));
+                       break;
+               }
+       }
+
+       if (!patch_offset) {
+               BT_ERR("%s: didn't find patch for chip id %d",
+                      hdev->name, rom_version);
+               return -EINVAL;
+       }
+
+       BT_DBG("length=%x offset=%x index %d", patch_length, patch_offset, i);
+       min_size = patch_offset + patch_length;
+       if (fw->size < min_size)
+               return -EINVAL;
+
+       /* Copy the firmware into a new buffer and write the version at
+        * the end.
+        */
+       len = patch_length;
+       buf = kmemdup(fw->data + patch_offset, patch_length, GFP_KERNEL);
+       if (!buf)
+               return -ENOMEM;
+
+       memcpy(buf + patch_length - 4, &epatch_info->fw_version, 4);
+
+       *_buf = buf;
+       return len;
+}
+
+static int rtl_download_firmware(struct hci_dev *hdev,
+                                const unsigned char *data, int fw_len)
+{
+       struct rtl_download_cmd *dl_cmd;
+       int frag_num = fw_len / RTL_FRAG_LEN + 1;
+       int frag_len = RTL_FRAG_LEN;
+       int ret = 0;
+       int i;
+
+       dl_cmd = kmalloc(sizeof(struct rtl_download_cmd), GFP_KERNEL);
+       if (!dl_cmd)
+               return -ENOMEM;
+
+       for (i = 0; i < frag_num; i++) {
+               struct rtl_download_response *dl_resp;
+               struct sk_buff *skb;
+
+               BT_DBG("download fw (%d/%d)", i, frag_num);
+
+               dl_cmd->index = i;
+               if (i == (frag_num - 1)) {
+                       dl_cmd->index |= 0x80; /* data end */
+                       frag_len = fw_len % RTL_FRAG_LEN;
+               }
+               memcpy(dl_cmd->data, data, frag_len);
+
+               /* Send download command */
+               skb = __hci_cmd_sync(hdev, 0xfc20, frag_len + 1, dl_cmd,
+                                    HCI_INIT_TIMEOUT);
+               if (IS_ERR(skb)) {
+                       BT_ERR("%s: download fw command failed (%ld)",
+                              hdev->name, PTR_ERR(skb));
+                       ret = -PTR_ERR(skb);
+                       goto out;
+               }
+
+               if (skb->len != sizeof(*dl_resp)) {
+                       BT_ERR("%s: download fw event length mismatch",
+                              hdev->name);
+                       kfree_skb(skb);
+                       ret = -EIO;
+                       goto out;
+               }
+
+               dl_resp = (struct rtl_download_response *)skb->data;
+               if (dl_resp->status != 0) {
+                       kfree_skb(skb);
+                       ret = bt_to_errno(dl_resp->status);
+                       goto out;
+               }
+
+               kfree_skb(skb);
+               data += RTL_FRAG_LEN;
+       }
+
+out:
+       kfree(dl_cmd);
+       return ret;
+}
+
+static int btusb_setup_rtl8723a(struct hci_dev *hdev)
+{
+       struct btusb_data *data = dev_get_drvdata(&hdev->dev);
+       struct usb_device *udev = interface_to_usbdev(data->intf);
+       const struct firmware *fw;
+       int ret;
+
+       BT_INFO("%s: rtl: loading rtl_bt/rtl8723a_fw.bin", hdev->name);
+       ret = request_firmware(&fw, "rtl_bt/rtl8723a_fw.bin", &udev->dev);
+       if (ret < 0) {
+               BT_ERR("%s: Failed to load rtl_bt/rtl8723a_fw.bin", hdev->name);
+               return ret;
+       }
+
+       if (fw->size < 8) {
+               ret = -EINVAL;
+               goto out;
+       }
+
+       /* Check that the firmware doesn't have the epatch signature
+        * (which is only for RTL8723B and newer).
+        */
+       if (!memcmp(fw->data, RTL_EPATCH_SIGNATURE, 8)) {
+               BT_ERR("%s: unexpected EPATCH signature!", hdev->name);
+               ret = -EINVAL;
+               goto out;
+       }
+
+       ret = rtl_download_firmware(hdev, fw->data, fw->size);
+
+out:
+       release_firmware(fw);
+       return ret;
+}
+
+static int btusb_setup_rtl8723b(struct hci_dev *hdev, u16 lmp_subver,
+                               const char *fw_name)
+{
+       struct btusb_data *data = dev_get_drvdata(&hdev->dev);
+       struct usb_device *udev = interface_to_usbdev(data->intf);
+       unsigned char *fw_data = NULL;
+       const struct firmware *fw;
+       int ret;
+
+       BT_INFO("%s: rtl: loading %s", hdev->name, fw_name);
+       ret = request_firmware(&fw, fw_name, &udev->dev);
+       if (ret < 0) {
+               BT_ERR("%s: Failed to load %s", hdev->name, fw_name);
+               return ret;
+       }
+
+       ret = rtl8723b_parse_firmware(hdev, lmp_subver, fw, &fw_data);
+       if (ret < 0)
+               goto out;
+
+       ret = rtl_download_firmware(hdev, fw_data, ret);
+       kfree(fw_data);
+       if (ret < 0)
+               goto out;
+
+out:
+       release_firmware(fw);
+       return ret;
+}
+
+static int btusb_setup_realtek(struct hci_dev *hdev)
+{
+       struct sk_buff *skb;
+       struct hci_rp_read_local_version *resp;
+       u16 lmp_subver;
+
+       skb = btusb_read_local_version(hdev);
+       if (IS_ERR(skb))
+               return -PTR_ERR(skb);
+
+       resp = (struct hci_rp_read_local_version *)skb->data;
+       BT_INFO("%s: rtl: examining hci_ver=%02x hci_rev=%04x lmp_ver=%02x "
+               "lmp_subver=%04x", hdev->name, resp->hci_ver, resp->hci_rev,
+               resp->lmp_ver, resp->lmp_subver);
+
+       lmp_subver = le16_to_cpu(resp->lmp_subver);
+       kfree_skb(skb);
+
+       /* Match a set of subver values that correspond to stock firmware,
+        * which is not compatible with standard btusb.
+        * If matched, upload an alternative firmware that does conform to
+        * standard btusb. Once that firmware is uploaded, the subver changes
+        * to a different value.
+        */
+       switch (lmp_subver) {
+       case RTL_ROM_LMP_8723A:
+       case RTL_ROM_LMP_3499:
+               return btusb_setup_rtl8723a(hdev);
+       case RTL_ROM_LMP_8723B:
+               return btusb_setup_rtl8723b(hdev, lmp_subver,
+                                           "rtl_bt/rtl8723b_fw.bin");
+       case RTL_ROM_LMP_8821A:
+               return btusb_setup_rtl8723b(hdev, lmp_subver,
+                                           "rtl_bt/rtl8821a_fw.bin");
+       case RTL_ROM_LMP_8761A:
+               return btusb_setup_rtl8723b(hdev, lmp_subver,
+                                           "rtl_bt/rtl8761a_fw.bin");
+       default:
+               BT_INFO("rtl: assuming no firmware upload needed.");
+               return 0;
+       }
+}
+
 static const struct firmware *btusb_setup_intel_get_fw(struct hci_dev *hdev,
                                                       struct intel_version *ver)
 {
@@ -2577,7 +2976,7 @@ static int btusb_setup_qca(struct hci_dev *hdev)
        int i, err;
 
        err = btusb_qca_send_vendor_req(hdev, QCA_GET_TARGET_VERSION, &ver,
-                                       sizeof(ver));
+                                       sizeof(ver));
        if (err < 0)
                return err;
 
@@ -2776,6 +3175,9 @@ static int btusb_probe(struct usb_interface *intf,
                hdev->set_bdaddr = btusb_set_bdaddr_ath3012;
        }
 
+       if (id->driver_info & BTUSB_REALTEK)
+               hdev->setup = btusb_setup_realtek;
+
        if (id->driver_info & BTUSB_AMP) {
                /* AMP controllers do not support SCO packets */
                data->isoc = NULL;
index 1b3f8647ea2fd446e1a6f14979a27e399fb0dbf5..ec8fa0e0f03630c9646a60b831277477a249b010 100644 (file)
@@ -95,7 +95,6 @@ static void ath_hci_uart_work(struct work_struct *work)
        hci_uart_tx_wakeup(hu);
 }
 
-/* Initialize protocol */
 static int ath_open(struct hci_uart *hu)
 {
        struct ath_struct *ath;
@@ -116,8 +115,7 @@ static int ath_open(struct hci_uart *hu)
        return 0;
 }
 
-/* Flush protocol data */
-static int ath_flush(struct hci_uart *hu)
+static int ath_close(struct hci_uart *hu)
 {
        struct ath_struct *ath = hu->priv;
 
@@ -125,11 +123,17 @@ static int ath_flush(struct hci_uart *hu)
 
        skb_queue_purge(&ath->txq);
 
+       kfree_skb(ath->rx_skb);
+
+       cancel_work_sync(&ath->ctxtsw);
+
+       hu->priv = NULL;
+       kfree(ath);
+
        return 0;
 }
 
-/* Close protocol */
-static int ath_close(struct hci_uart *hu)
+static int ath_flush(struct hci_uart *hu)
 {
        struct ath_struct *ath = hu->priv;
 
@@ -137,19 +141,65 @@ static int ath_close(struct hci_uart *hu)
 
        skb_queue_purge(&ath->txq);
 
-       kfree_skb(ath->rx_skb);
+       return 0;
+}
 
-       cancel_work_sync(&ath->ctxtsw);
+static int ath_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr)
+{
+       struct sk_buff *skb;
+       u8 buf[10];
+       int err;
+
+       buf[0] = 0x01;
+       buf[1] = 0x01;
+       buf[2] = 0x00;
+       buf[3] = sizeof(bdaddr_t);
+       memcpy(buf + 4, bdaddr, sizeof(bdaddr_t));
+
+       skb = __hci_cmd_sync(hdev, 0xfc0b, sizeof(buf), buf, HCI_INIT_TIMEOUT);
+       if (IS_ERR(skb)) {
+               err = PTR_ERR(skb);
+               BT_ERR("%s: Change address command failed (%d)",
+                      hdev->name, err);
+               return err;
+       }
+       kfree_skb(skb);
 
-       hu->priv = NULL;
-       kfree(ath);
+       return 0;
+}
+
+static int ath_setup(struct hci_uart *hu)
+{
+       BT_DBG("hu %p", hu);
+
+       hu->hdev->set_bdaddr = ath_set_bdaddr;
 
        return 0;
 }
 
+static const struct h4_recv_pkt ath_recv_pkts[] = {
+       { H4_RECV_ACL,   .recv = hci_recv_frame },
+       { H4_RECV_SCO,   .recv = hci_recv_frame },
+       { H4_RECV_EVENT, .recv = hci_recv_frame },
+};
+
+static int ath_recv(struct hci_uart *hu, const void *data, int count)
+{
+       struct ath_struct *ath = hu->priv;
+
+       ath->rx_skb = h4_recv_buf(hu->hdev, ath->rx_skb, data, count,
+                                 ath_recv_pkts, ARRAY_SIZE(ath_recv_pkts));
+       if (IS_ERR(ath->rx_skb)) {
+               int err = PTR_ERR(ath->rx_skb);
+               BT_ERR("%s: Frame reassembly failed (%d)", hu->hdev->name, err);
+               return err;
+       }
+
+       return count;
+}
+
 #define HCI_OP_ATH_SLEEP 0xFC04
 
-/* Enqueue frame for transmittion */
 static int ath_enqueue(struct hci_uart *hu, struct sk_buff *skb)
 {
        struct ath_struct *ath = hu->priv;
@@ -159,8 +209,7 @@ static int ath_enqueue(struct hci_uart *hu, struct sk_buff *skb)
                return 0;
        }
 
-       /*
-        * Update power management enable flag with parameters of
+       /* Update power management enable flag with parameters of
         * HCI sleep enable vendor specific HCI command.
         */
        if (bt_cb(skb)->pkt_type == HCI_COMMAND_PKT) {
@@ -190,37 +239,16 @@ static struct sk_buff *ath_dequeue(struct hci_uart *hu)
        return skb_dequeue(&ath->txq);
 }
 
-static const struct h4_recv_pkt ath_recv_pkts[] = {
-       { H4_RECV_ACL,   .recv = hci_recv_frame },
-       { H4_RECV_SCO,   .recv = hci_recv_frame },
-       { H4_RECV_EVENT, .recv = hci_recv_frame },
-};
-
-/* Recv data */
-static int ath_recv(struct hci_uart *hu, const void *data, int count)
-{
-       struct ath_struct *ath = hu->priv;
-
-       ath->rx_skb = h4_recv_buf(hu->hdev, ath->rx_skb, data, count,
-                                 ath_recv_pkts, ARRAY_SIZE(ath_recv_pkts));
-       if (IS_ERR(ath->rx_skb)) {
-               int err = PTR_ERR(ath->rx_skb);
-               BT_ERR("%s: Frame reassembly failed (%d)", hu->hdev->name, err);
-               return err;
-       }
-
-       return count;
-}
-
 static const struct hci_uart_proto athp = {
        .id             = HCI_UART_ATH3K,
        .name           = "ATH3K",
        .open           = ath_open,
        .close          = ath_close,
+       .flush          = ath_flush,
+       .setup          = ath_setup,
        .recv           = ath_recv,
        .enqueue        = ath_enqueue,
        .dequeue        = ath_dequeue,
-       .flush          = ath_flush,
 };
 
 int __init ath_init(void)
index 44ea107cfc6729818ea8a02dfd250f7e6a557967..30335d3b99afb197332505d5be045f2d5d75be4c 100644 (file)
@@ -1128,13 +1128,6 @@ static int si5351_dt_parse(struct i2c_client *client,
        if (!pdata)
                return -ENOMEM;
 
-       pdata->clk_xtal = of_clk_get(np, 0);
-       if (!IS_ERR(pdata->clk_xtal))
-               clk_put(pdata->clk_xtal);
-       pdata->clk_clkin = of_clk_get(np, 1);
-       if (!IS_ERR(pdata->clk_clkin))
-               clk_put(pdata->clk_clkin);
-
        /*
         * property silabs,pll-source : <num src>, [<..>]
         * allow to selectively set pll source
@@ -1328,8 +1321,22 @@ static int si5351_i2c_probe(struct i2c_client *client,
        i2c_set_clientdata(client, drvdata);
        drvdata->client = client;
        drvdata->variant = variant;
-       drvdata->pxtal = pdata->clk_xtal;
-       drvdata->pclkin = pdata->clk_clkin;
+       drvdata->pxtal = devm_clk_get(&client->dev, "xtal");
+       drvdata->pclkin = devm_clk_get(&client->dev, "clkin");
+
+       if (PTR_ERR(drvdata->pxtal) == -EPROBE_DEFER ||
+           PTR_ERR(drvdata->pclkin) == -EPROBE_DEFER)
+               return -EPROBE_DEFER;
+
+       /*
+        * Check for valid parent clock: VARIANT_A and VARIANT_B need XTAL,
+        *   VARIANT_C can have CLKIN instead.
+        */
+       if (IS_ERR(drvdata->pxtal) &&
+           (drvdata->variant != SI5351_VARIANT_C || IS_ERR(drvdata->pclkin))) {
+               dev_err(&client->dev, "missing parent clock\n");
+               return -EINVAL;
+       }
 
        drvdata->regmap = devm_regmap_init_i2c(client, &si5351_regmap_config);
        if (IS_ERR(drvdata->regmap)) {
@@ -1393,6 +1400,11 @@ static int si5351_i2c_probe(struct i2c_client *client,
                }
        }
 
+       if (!IS_ERR(drvdata->pxtal))
+               clk_prepare_enable(drvdata->pxtal);
+       if (!IS_ERR(drvdata->pclkin))
+               clk_prepare_enable(drvdata->pclkin);
+
        /* register xtal input clock gate */
        memset(&init, 0, sizeof(init));
        init.name = si5351_input_names[0];
@@ -1407,7 +1419,8 @@ static int si5351_i2c_probe(struct i2c_client *client,
        clk = devm_clk_register(&client->dev, &drvdata->xtal);
        if (IS_ERR(clk)) {
                dev_err(&client->dev, "unable to register %s\n", init.name);
-               return PTR_ERR(clk);
+               ret = PTR_ERR(clk);
+               goto err_clk;
        }
 
        /* register clkin input clock gate */
@@ -1425,7 +1438,8 @@ static int si5351_i2c_probe(struct i2c_client *client,
                if (IS_ERR(clk)) {
                        dev_err(&client->dev, "unable to register %s\n",
                                init.name);
-                       return PTR_ERR(clk);
+                       ret = PTR_ERR(clk);
+                       goto err_clk;
                }
        }
 
@@ -1447,7 +1461,8 @@ static int si5351_i2c_probe(struct i2c_client *client,
        clk = devm_clk_register(&client->dev, &drvdata->pll[0].hw);
        if (IS_ERR(clk)) {
                dev_err(&client->dev, "unable to register %s\n", init.name);
-               return -EINVAL;
+               ret = PTR_ERR(clk);
+               goto err_clk;
        }
 
        /* register PLLB or VXCO (Si5351B) */
@@ -1471,7 +1486,8 @@ static int si5351_i2c_probe(struct i2c_client *client,
        clk = devm_clk_register(&client->dev, &drvdata->pll[1].hw);
        if (IS_ERR(clk)) {
                dev_err(&client->dev, "unable to register %s\n", init.name);
-               return -EINVAL;
+               ret = PTR_ERR(clk);
+               goto err_clk;
        }
 
        /* register clk multisync and clk out divider */
@@ -1492,8 +1508,10 @@ static int si5351_i2c_probe(struct i2c_client *client,
                num_clocks * sizeof(*drvdata->onecell.clks), GFP_KERNEL);
 
        if (WARN_ON(!drvdata->msynth || !drvdata->clkout ||
-                   !drvdata->onecell.clks))
-               return -ENOMEM;
+                   !drvdata->onecell.clks)) {
+               ret = -ENOMEM;
+               goto err_clk;
+       }
 
        for (n = 0; n < num_clocks; n++) {
                drvdata->msynth[n].num = n;
@@ -1511,7 +1529,8 @@ static int si5351_i2c_probe(struct i2c_client *client,
                if (IS_ERR(clk)) {
                        dev_err(&client->dev, "unable to register %s\n",
                                init.name);
-                       return -EINVAL;
+                       ret = PTR_ERR(clk);
+                       goto err_clk;
                }
        }
 
@@ -1538,7 +1557,8 @@ static int si5351_i2c_probe(struct i2c_client *client,
                if (IS_ERR(clk)) {
                        dev_err(&client->dev, "unable to register %s\n",
                                init.name);
-                       return -EINVAL;
+                       ret = PTR_ERR(clk);
+                       goto err_clk;
                }
                drvdata->onecell.clks[n] = clk;
 
@@ -1557,10 +1577,17 @@ static int si5351_i2c_probe(struct i2c_client *client,
                                  &drvdata->onecell);
        if (ret) {
                dev_err(&client->dev, "unable to add clk provider\n");
-               return ret;
+               goto err_clk;
        }
 
        return 0;
+
+err_clk:
+       if (!IS_ERR(drvdata->pxtal))
+               clk_disable_unprepare(drvdata->pxtal);
+       if (!IS_ERR(drvdata->pclkin))
+               clk_disable_unprepare(drvdata->pclkin);
+       return ret;
 }
 
 static const struct i2c_device_id si5351_i2c_ids[] = {
index 459ce9da13e0631b41e6cafc5ed9a85523e5e1b7..5b0f41868b425672e6295ac6b30a52e43cf5730c 100644 (file)
@@ -1475,8 +1475,10 @@ static struct clk_core *__clk_set_parent_before(struct clk_core *clk,
         */
        if (clk->prepare_count) {
                clk_core_prepare(parent);
+               flags = clk_enable_lock();
                clk_core_enable(parent);
                clk_core_enable(clk);
+               clk_enable_unlock(flags);
        }
 
        /* update the clk tree topology */
@@ -1491,13 +1493,17 @@ static void __clk_set_parent_after(struct clk_core *core,
                                   struct clk_core *parent,
                                   struct clk_core *old_parent)
 {
+       unsigned long flags;
+
        /*
         * Finish the migration of prepare state and undo the changes done
         * for preventing a race with clk_enable().
         */
        if (core->prepare_count) {
+               flags = clk_enable_lock();
                clk_core_disable(core);
                clk_core_disable(old_parent);
+               clk_enable_unlock(flags);
                clk_core_unprepare(old_parent);
        }
 }
@@ -1525,8 +1531,10 @@ static int __clk_set_parent(struct clk_core *clk, struct clk_core *parent,
                clk_enable_unlock(flags);
 
                if (clk->prepare_count) {
+                       flags = clk_enable_lock();
                        clk_core_disable(clk);
                        clk_core_disable(parent);
+                       clk_enable_unlock(flags);
                        clk_core_unprepare(parent);
                }
                return ret;
index d3458474eb3a1ef6bbc67f919b60b725978e8aee..c66f7bc2ae87cde429121af226970c2c7fd973c4 100644 (file)
@@ -71,8 +71,8 @@ static const char *gcc_xo_gpll0_bimc[] = {
 static const struct parent_map gcc_xo_gpll0a_gpll1_gpll2a_map[] = {
        { P_XO, 0 },
        { P_GPLL0_AUX, 3 },
-       { P_GPLL2_AUX, 2 },
        { P_GPLL1, 1 },
+       { P_GPLL2_AUX, 2 },
 };
 
 static const char *gcc_xo_gpll0a_gpll1_gpll2a[] = {
@@ -1115,7 +1115,7 @@ static struct clk_rcg2 usb_hs_system_clk_src = {
 static const struct freq_tbl ftbl_gcc_venus0_vcodec0_clk[] = {
        F(100000000, P_GPLL0, 8, 0, 0),
        F(160000000, P_GPLL0, 5, 0, 0),
-       F(228570000, P_GPLL0, 5, 0, 0),
+       F(228570000, P_GPLL0, 3.5, 0, 0),
        { }
 };
 
index 17e9af7fe81fe0aad57ad6ec1c2a2ac05b2280dd..a17683b2cf276b03e287bd6959f217e7aacb7c5f 100644 (file)
@@ -10,7 +10,7 @@ obj-$(CONFIG_SOC_EXYNOS5250)  += clk-exynos5250.o
 obj-$(CONFIG_SOC_EXYNOS5260)   += clk-exynos5260.o
 obj-$(CONFIG_SOC_EXYNOS5410)   += clk-exynos5410.o
 obj-$(CONFIG_SOC_EXYNOS5420)   += clk-exynos5420.o
-obj-$(CONFIG_ARCH_EXYNOS5433)  += clk-exynos5433.o
+obj-$(CONFIG_ARCH_EXYNOS)      += clk-exynos5433.o
 obj-$(CONFIG_SOC_EXYNOS5440)   += clk-exynos5440.o
 obj-$(CONFIG_ARCH_EXYNOS)      += clk-exynos-audss.o
 obj-$(CONFIG_ARCH_EXYNOS)      += clk-exynos-clkout.o
index 07d666cc6a29b9f3567deec197756b5927f68ac7..bea4a173eef5e40e12a4a05f8f6ccb3310700814 100644 (file)
@@ -271,6 +271,7 @@ static const struct samsung_clk_reg_dump exynos5420_set_clksrc[] = {
        { .offset = SRC_MASK_PERIC0,            .value = 0x11111110, },
        { .offset = SRC_MASK_PERIC1,            .value = 0x11111100, },
        { .offset = SRC_MASK_ISP,               .value = 0x11111000, },
+       { .offset = GATE_BUS_TOP,               .value = 0xffffffff, },
        { .offset = GATE_BUS_DISP1,             .value = 0xffffffff, },
        { .offset = GATE_IP_PERIC,              .value = 0xffffffff, },
 };
index 387e3e39e63519d401cbfe87c949308d64db5897..9e04ae2bb4d74912f18976c305a1738756b19837 100644 (file)
@@ -748,7 +748,7 @@ static struct samsung_pll_rate_table exynos5443_pll_rates[] = {
        PLL_35XX_RATE(825000000U,  275, 4,  1),
        PLL_35XX_RATE(800000000U,  400, 6,  1),
        PLL_35XX_RATE(733000000U,  733, 12, 1),
-       PLL_35XX_RATE(700000000U,  360, 6,  1),
+       PLL_35XX_RATE(700000000U,  175, 3,  1),
        PLL_35XX_RATE(667000000U,  222, 4,  1),
        PLL_35XX_RATE(633000000U,  211, 4,  1),
        PLL_35XX_RATE(600000000U,  500, 5,  2),
@@ -760,14 +760,14 @@ static struct samsung_pll_rate_table exynos5443_pll_rates[] = {
        PLL_35XX_RATE(444000000U,  370, 5,  2),
        PLL_35XX_RATE(420000000U,  350, 5,  2),
        PLL_35XX_RATE(400000000U,  400, 6,  2),
-       PLL_35XX_RATE(350000000U,  360, 6,  2),
+       PLL_35XX_RATE(350000000U,  350, 6,  2),
        PLL_35XX_RATE(333000000U,  222, 4,  2),
        PLL_35XX_RATE(300000000U,  500, 5,  3),
        PLL_35XX_RATE(266000000U,  532, 6,  3),
        PLL_35XX_RATE(200000000U,  400, 6,  3),
        PLL_35XX_RATE(166000000U,  332, 6,  3),
        PLL_35XX_RATE(160000000U,  320, 6,  3),
-       PLL_35XX_RATE(133000000U,  552, 6,  4),
+       PLL_35XX_RATE(133000000U,  532, 6,  4),
        PLL_35XX_RATE(100000000U,  400, 6,  4),
        { /* sentinel */ }
 };
@@ -1490,7 +1490,7 @@ static struct samsung_gate_clock mif_gate_clks[] __initdata = {
 
        /* ENABLE_PCLK_MIF_SECURE_MONOTONIC_CNT */
        GATE(CLK_PCLK_MONOTONIC_CNT, "pclk_monotonic_cnt", "div_aclk_mif_133",
-                       ENABLE_PCLK_MIF_SECURE_RTC, 0, 0, 0),
+                       ENABLE_PCLK_MIF_SECURE_MONOTONIC_CNT, 0, 0, 0),
 
        /* ENABLE_PCLK_MIF_SECURE_RTC */
        GATE(CLK_PCLK_RTC, "pclk_rtc", "div_aclk_mif_133",
@@ -3665,7 +3665,7 @@ static struct samsung_gate_clock apollo_gate_clks[] __initdata = {
                        ENABLE_SCLK_APOLLO, 3, CLK_IGNORE_UNUSED, 0),
        GATE(CLK_SCLK_HPM_APOLLO, "sclk_hpm_apollo", "div_sclk_hpm_apollo",
                        ENABLE_SCLK_APOLLO, 1, CLK_IGNORE_UNUSED, 0),
-       GATE(CLK_SCLK_APOLLO, "sclk_apollo", "div_apollo_pll",
+       GATE(CLK_SCLK_APOLLO, "sclk_apollo", "div_apollo2",
                        ENABLE_SCLK_APOLLO, 0, CLK_IGNORE_UNUSED, 0),
 };
 
@@ -3927,7 +3927,7 @@ CLK_OF_DECLARE(exynos5433_cmu_atlas, "samsung,exynos5433-cmu-atlas",
 #define ENABLE_PCLK_MSCL                               0x0900
 #define ENABLE_PCLK_MSCL_SECURE_SMMU_M2MSCALER0                0x0904
 #define ENABLE_PCLK_MSCL_SECURE_SMMU_M2MSCALER1                0x0908
-#define ENABLE_PCLK_MSCL_SECURE_SMMU_JPEG              0x000c
+#define ENABLE_PCLK_MSCL_SECURE_SMMU_JPEG              0x090c
 #define ENABLE_SCLK_MSCL                               0x0a00
 #define ENABLE_IP_MSCL0                                        0x0b00
 #define ENABLE_IP_MSCL1                                        0x0b04
index de67fce189840eee2d75ad42e23f862103d7540b..e45d1f13f4458e9130d8f052494b33b1a11a9c60 100644 (file)
@@ -119,6 +119,18 @@ static int usb_extcon_probe(struct platform_device *pdev)
                return PTR_ERR(info->id_gpiod);
        }
 
+       info->edev = devm_extcon_dev_allocate(dev, usb_extcon_cable);
+       if (IS_ERR(info->edev)) {
+               dev_err(dev, "failed to allocate extcon device\n");
+               return -ENOMEM;
+       }
+
+       ret = devm_extcon_dev_register(dev, info->edev);
+       if (ret < 0) {
+               dev_err(dev, "failed to register extcon device\n");
+               return ret;
+       }
+
        ret = gpiod_set_debounce(info->id_gpiod,
                                 USB_GPIO_DEBOUNCE_MS * 1000);
        if (ret < 0)
@@ -142,18 +154,6 @@ static int usb_extcon_probe(struct platform_device *pdev)
                return ret;
        }
 
-       info->edev = devm_extcon_dev_allocate(dev, usb_extcon_cable);
-       if (IS_ERR(info->edev)) {
-               dev_err(dev, "failed to allocate extcon device\n");
-               return -ENOMEM;
-       }
-
-       ret = devm_extcon_dev_register(dev, info->edev);
-       if (ret < 0) {
-               dev_err(dev, "failed to register extcon device\n");
-               return ret;
-       }
-
        platform_set_drvdata(pdev, info);
        device_init_wakeup(dev, 1);
 
index 6e45a43ffe8476686bcaee1157a7acc641fc3e6b..97b1616aa391819c0579d12efcca286cfa1c7075 100644 (file)
@@ -499,19 +499,19 @@ static int __init dmi_present(const u8 *buf)
        buf += 16;
 
        if (memcmp(buf, "_DMI_", 5) == 0 && dmi_checksum(buf, 15)) {
+               if (smbios_ver)
+                       dmi_ver = smbios_ver;
+               else
+                       dmi_ver = (buf[14] & 0xF0) << 4 | (buf[14] & 0x0F);
                dmi_num = get_unaligned_le16(buf + 12);
                dmi_len = get_unaligned_le16(buf + 6);
                dmi_base = get_unaligned_le32(buf + 8);
 
                if (dmi_walk_early(dmi_decode) == 0) {
                        if (smbios_ver) {
-                               dmi_ver = smbios_ver;
-                               pr_info("SMBIOS %d.%d%s present.\n",
-                                       dmi_ver >> 8, dmi_ver & 0xFF,
-                                       (dmi_ver < 0x0300) ? "" : ".x");
+                               pr_info("SMBIOS %d.%d present.\n",
+                                      dmi_ver >> 8, dmi_ver & 0xFF);
                        } else {
-                               dmi_ver = (buf[14] & 0xF0) << 4 |
-                                          (buf[14] & 0x0F);
                                pr_info("Legacy DMI %d.%d present.\n",
                                       dmi_ver >> 8, dmi_ver & 0xFF);
                        }
index 6b8115f342085bb3b25f78ad8c13ed6ce10a9d7b..83f281dda1e0f41fc4be3c8d2cb4e02407ab837d 100644 (file)
@@ -117,7 +117,7 @@ static int kempld_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
                = container_of(chip, struct kempld_gpio_data, chip);
        struct kempld_device_data *pld = gpio->pld;
 
-       return kempld_gpio_get_bit(pld, KEMPLD_GPIO_DIR_NUM(offset), offset);
+       return !kempld_gpio_get_bit(pld, KEMPLD_GPIO_DIR_NUM(offset), offset);
 }
 
 static int kempld_gpio_pincount(struct kempld_device_data *pld)
index 59eaa23767d8dca5bddf740fa90a24c9699c4a0b..6bc612b8a49fcf859261173e00d0e7389d7d2b05 100644 (file)
@@ -53,6 +53,11 @@ static DEFINE_MUTEX(gpio_lookup_lock);
 static LIST_HEAD(gpio_lookup_list);
 LIST_HEAD(gpio_chips);
 
+
+static void gpiochip_free_hogs(struct gpio_chip *chip);
+static void gpiochip_irqchip_remove(struct gpio_chip *gpiochip);
+
+
 static inline void desc_set_label(struct gpio_desc *d, const char *label)
 {
        d->label = label;
@@ -297,6 +302,7 @@ int gpiochip_add(struct gpio_chip *chip)
 
 err_remove_chip:
        acpi_gpiochip_remove(chip);
+       gpiochip_free_hogs(chip);
        of_gpiochip_remove(chip);
        spin_lock_irqsave(&gpio_lock, flags);
        list_del(&chip->list);
@@ -313,10 +319,6 @@ int gpiochip_add(struct gpio_chip *chip)
 }
 EXPORT_SYMBOL_GPL(gpiochip_add);
 
-/* Forward-declaration */
-static void gpiochip_irqchip_remove(struct gpio_chip *gpiochip);
-static void gpiochip_free_hogs(struct gpio_chip *chip);
-
 /**
  * gpiochip_remove() - unregister a gpio_chip
  * @chip: the chip to unregister
index 1f7e33f59de69e3ecf6c4f4ac865c1746d491d8d..6714e5b193ead813ab44f77d0f890f5cd359491f 100644 (file)
@@ -91,7 +91,7 @@ static void decon_wait_for_vblank(struct exynos_drm_crtc *crtc)
 
 static void decon_clear_channel(struct decon_context *ctx)
 {
-       int win, ch_enabled = 0;
+       unsigned int win, ch_enabled = 0;
 
        DRM_DEBUG_KMS("%s\n", __FILE__);
 
@@ -710,7 +710,7 @@ static void decon_dpms(struct exynos_drm_crtc *crtc, int mode)
        }
 }
 
-static struct exynos_drm_crtc_ops decon_crtc_ops = {
+static const struct exynos_drm_crtc_ops decon_crtc_ops = {
        .dpms = decon_dpms,
        .mode_fixup = decon_mode_fixup,
        .commit = decon_commit,
index 1dbfba58f9091b70aac969a55e270d844ea5fb05..30feb7d066244bfa078e36a518293a9195c3437c 100644 (file)
@@ -32,7 +32,6 @@
 #include <drm/bridge/ptn3460.h>
 
 #include "exynos_dp_core.h"
-#include "exynos_drm_fimd.h"
 
 #define ctx_from_connector(c)  container_of(c, struct exynos_dp_device, \
                                        connector)
@@ -196,7 +195,7 @@ static int exynos_dp_read_edid(struct exynos_dp_device *dp)
                }
        }
 
-       dev_err(dp->dev, "EDID Read success!\n");
+       dev_dbg(dp->dev, "EDID Read success!\n");
        return 0;
 }
 
@@ -1066,6 +1065,8 @@ static void exynos_dp_phy_exit(struct exynos_dp_device *dp)
 
 static void exynos_dp_poweron(struct exynos_dp_device *dp)
 {
+       struct exynos_drm_crtc *crtc = dp_to_crtc(dp);
+
        if (dp->dpms_mode == DRM_MODE_DPMS_ON)
                return;
 
@@ -1076,7 +1077,8 @@ static void exynos_dp_poweron(struct exynos_dp_device *dp)
                }
        }
 
-       fimd_dp_clock_enable(dp_to_crtc(dp), true);
+       if (crtc->ops->clock_enable)
+               crtc->ops->clock_enable(dp_to_crtc(dp), true);
 
        clk_prepare_enable(dp->clock);
        exynos_dp_phy_init(dp);
@@ -1087,6 +1089,8 @@ static void exynos_dp_poweron(struct exynos_dp_device *dp)
 
 static void exynos_dp_poweroff(struct exynos_dp_device *dp)
 {
+       struct exynos_drm_crtc *crtc = dp_to_crtc(dp);
+
        if (dp->dpms_mode != DRM_MODE_DPMS_ON)
                return;
 
@@ -1102,7 +1106,8 @@ static void exynos_dp_poweroff(struct exynos_dp_device *dp)
        exynos_dp_phy_exit(dp);
        clk_disable_unprepare(dp->clock);
 
-       fimd_dp_clock_enable(dp_to_crtc(dp), false);
+       if (crtc->ops->clock_enable)
+               crtc->ops->clock_enable(dp_to_crtc(dp), false);
 
        if (dp->panel) {
                if (drm_panel_unprepare(dp->panel))
index eb49195cec5c2396831ebfbf37e42bb5fa54ed81..9006b947e03c0a431141144c7ed21ae88b14f02b 100644 (file)
@@ -238,11 +238,11 @@ static struct drm_crtc_funcs exynos_crtc_funcs = {
 };
 
 struct exynos_drm_crtc *exynos_drm_crtc_create(struct drm_device *drm_dev,
-                                              struct drm_plane *plane,
-                                              int pipe,
-                                              enum exynos_drm_output_type type,
-                                              struct exynos_drm_crtc_ops *ops,
-                                              void *ctx)
+                                       struct drm_plane *plane,
+                                       int pipe,
+                                       enum exynos_drm_output_type type,
+                                       const struct exynos_drm_crtc_ops *ops,
+                                       void *ctx)
 {
        struct exynos_drm_crtc *exynos_crtc;
        struct exynos_drm_private *private = drm_dev->dev_private;
index 0ecd8fc45cff3349afe5d5858a713da124e30944..0f3aa70818e31059bfc6369c258dcd326fa07d53 100644 (file)
 #include "exynos_drm_drv.h"
 
 struct exynos_drm_crtc *exynos_drm_crtc_create(struct drm_device *drm_dev,
-                                              struct drm_plane *plane,
-                                              int pipe,
-                                              enum exynos_drm_output_type type,
-                                              struct exynos_drm_crtc_ops *ops,
-                                              void *context);
+                                       struct drm_plane *plane,
+                                       int pipe,
+                                       enum exynos_drm_output_type type,
+                                       const struct exynos_drm_crtc_ops *ops,
+                                       void *context);
 int exynos_drm_crtc_enable_vblank(struct drm_device *dev, int pipe);
 void exynos_drm_crtc_disable_vblank(struct drm_device *dev, int pipe);
 void exynos_drm_crtc_finish_pageflip(struct drm_device *dev, int pipe);
index e12ecb5d5d9aa01a7618eafb8930b5dc552cb14e..29e3fb78c615fa7ad58ee21a1c7c0ad19bd6ffd3 100644 (file)
@@ -71,13 +71,6 @@ enum exynos_drm_output_type {
  * @dma_addr: array of bus(accessed by dma) address to the memory region
  *           allocated for a overlay.
  * @zpos: order of overlay layer(z position).
- * @index_color: if using color key feature then this value would be used
- *                     as index color.
- * @default_win: a window to be enabled.
- * @color_key: color key on or off.
- * @local_path: in case of lcd type, local path mode on or off.
- * @transparency: transparency on or off.
- * @activated: activated or not.
  * @enabled: enabled or not.
  * @resume: to resume or not.
  *
@@ -108,13 +101,7 @@ struct exynos_drm_plane {
        uint32_t pixel_format;
        dma_addr_t dma_addr[MAX_FB_BUFFER];
        unsigned int zpos;
-       unsigned int index_color;
 
-       bool default_win:1;
-       bool color_key:1;
-       bool local_path:1;
-       bool transparency:1;
-       bool activated:1;
        bool enabled:1;
        bool resume:1;
 };
@@ -181,6 +168,10 @@ struct exynos_drm_display {
  * @win_disable: disable hardware specific overlay.
  * @te_handler: trigger to transfer video image at the tearing effect
  *     synchronization signal if there is a page flip request.
+ * @clock_enable: optional function enabling/disabling display domain clock,
+ *     called from exynos-dp driver before powering up (with
+ *     'enable' argument as true) and after powering down (with
+ *     'enable' as false).
  */
 struct exynos_drm_crtc;
 struct exynos_drm_crtc_ops {
@@ -195,6 +186,7 @@ struct exynos_drm_crtc_ops {
        void (*win_commit)(struct exynos_drm_crtc *crtc, unsigned int zpos);
        void (*win_disable)(struct exynos_drm_crtc *crtc, unsigned int zpos);
        void (*te_handler)(struct exynos_drm_crtc *crtc);
+       void (*clock_enable)(struct exynos_drm_crtc *crtc, bool enable);
 };
 
 /*
@@ -221,7 +213,7 @@ struct exynos_drm_crtc {
        unsigned int                    dpms;
        wait_queue_head_t               pending_flip_queue;
        struct drm_pending_vblank_event *event;
-       struct exynos_drm_crtc_ops      *ops;
+       const struct exynos_drm_crtc_ops        *ops;
        void                            *ctx;
 };
 
index 929cb03a8eab15d6daee766016dc59070130a240..142eb4e3f59ea5501805cc56bed7cbef4106ae7b 100644 (file)
@@ -171,43 +171,6 @@ exynos_drm_framebuffer_init(struct drm_device *dev,
        return &exynos_fb->fb;
 }
 
-static u32 exynos_drm_format_num_buffers(struct drm_mode_fb_cmd2 *mode_cmd)
-{
-       unsigned int cnt = 0;
-
-       if (mode_cmd->pixel_format != DRM_FORMAT_NV12)
-               return drm_format_num_planes(mode_cmd->pixel_format);
-
-       while (cnt != MAX_FB_BUFFER) {
-               if (!mode_cmd->handles[cnt])
-                       break;
-               cnt++;
-       }
-
-       /*
-        * check if NV12 or NV12M.
-        *
-        * NV12
-        * handles[0] = base1, offsets[0] = 0
-        * handles[1] = base1, offsets[1] = Y_size
-        *
-        * NV12M
-        * handles[0] = base1, offsets[0] = 0
-        * handles[1] = base2, offsets[1] = 0
-        */
-       if (cnt == 2) {
-               /*
-                * in case of NV12 format, offsets[1] is not 0 and
-                * handles[0] is same as handles[1].
-                */
-               if (mode_cmd->offsets[1] &&
-                       mode_cmd->handles[0] == mode_cmd->handles[1])
-                       cnt = 1;
-       }
-
-       return cnt;
-}
-
 static struct drm_framebuffer *
 exynos_user_fb_create(struct drm_device *dev, struct drm_file *file_priv,
                      struct drm_mode_fb_cmd2 *mode_cmd)
@@ -230,7 +193,7 @@ exynos_user_fb_create(struct drm_device *dev, struct drm_file *file_priv,
 
        drm_helper_mode_fill_fb_struct(&exynos_fb->fb, mode_cmd);
        exynos_fb->exynos_gem_obj[0] = to_exynos_gem_obj(obj);
-       exynos_fb->buf_cnt = exynos_drm_format_num_buffers(mode_cmd);
+       exynos_fb->buf_cnt = drm_format_num_planes(mode_cmd->pixel_format);
 
        DRM_DEBUG_KMS("buf_cnt = %d\n", exynos_fb->buf_cnt);
 
index 9819fa6a9e2a41867da1ddaab9fb052dc0a74310..a0edab833148adf2abf99a3cde1d60eee6d5619b 100644 (file)
@@ -33,7 +33,6 @@
 #include "exynos_drm_crtc.h"
 #include "exynos_drm_plane.h"
 #include "exynos_drm_iommu.h"
-#include "exynos_drm_fimd.h"
 
 /*
  * FIMD stands for Fully Interactive Mobile Display and
@@ -216,7 +215,7 @@ static void fimd_wait_for_vblank(struct exynos_drm_crtc *crtc)
                DRM_DEBUG_KMS("vblank wait timed out.\n");
 }
 
-static void fimd_enable_video_output(struct fimd_context *ctx, int win,
+static void fimd_enable_video_output(struct fimd_context *ctx, unsigned int win,
                                        bool enable)
 {
        u32 val = readl(ctx->regs + WINCON(win));
@@ -229,7 +228,8 @@ static void fimd_enable_video_output(struct fimd_context *ctx, int win,
        writel(val, ctx->regs + WINCON(win));
 }
 
-static void fimd_enable_shadow_channel_path(struct fimd_context *ctx, int win,
+static void fimd_enable_shadow_channel_path(struct fimd_context *ctx,
+                                               unsigned int win,
                                                bool enable)
 {
        u32 val = readl(ctx->regs + SHADOWCON);
@@ -244,7 +244,7 @@ static void fimd_enable_shadow_channel_path(struct fimd_context *ctx, int win,
 
 static void fimd_clear_channel(struct fimd_context *ctx)
 {
-       int win, ch_enabled = 0;
+       unsigned int win, ch_enabled = 0;
 
        DRM_DEBUG_KMS("%s\n", __FILE__);
 
@@ -946,7 +946,24 @@ static void fimd_te_handler(struct exynos_drm_crtc *crtc)
                drm_handle_vblank(ctx->drm_dev, ctx->pipe);
 }
 
-static struct exynos_drm_crtc_ops fimd_crtc_ops = {
+static void fimd_dp_clock_enable(struct exynos_drm_crtc *crtc, bool enable)
+{
+       struct fimd_context *ctx = crtc->ctx;
+       u32 val;
+
+       /*
+        * Only Exynos 5250, 5260, 5410 and 542x requires enabling DP/MIE
+        * clock. On these SoCs the bootloader may enable it but any
+        * power domain off/on will reset it to disable state.
+        */
+       if (ctx->driver_data != &exynos5_fimd_driver_data)
+               return;
+
+       val = enable ? DP_MIE_CLK_DP_ENABLE : DP_MIE_CLK_DISABLE;
+       writel(DP_MIE_CLK_DP_ENABLE, ctx->regs + DP_MIE_CLKCON);
+}
+
+static const struct exynos_drm_crtc_ops fimd_crtc_ops = {
        .dpms = fimd_dpms,
        .mode_fixup = fimd_mode_fixup,
        .commit = fimd_commit,
@@ -956,6 +973,7 @@ static struct exynos_drm_crtc_ops fimd_crtc_ops = {
        .win_commit = fimd_win_commit,
        .win_disable = fimd_win_disable,
        .te_handler = fimd_te_handler,
+       .clock_enable = fimd_dp_clock_enable,
 };
 
 static irqreturn_t fimd_irq_handler(int irq, void *dev_id)
@@ -1025,12 +1043,7 @@ static int fimd_bind(struct device *dev, struct device *master, void *data)
        if (ctx->display)
                exynos_drm_create_enc_conn(drm_dev, ctx->display);
 
-       ret = fimd_iommu_attach_devices(ctx, drm_dev);
-       if (ret)
-               return ret;
-
-       return 0;
-
+       return fimd_iommu_attach_devices(ctx, drm_dev);
 }
 
 static void fimd_unbind(struct device *dev, struct device *master,
@@ -1192,24 +1205,6 @@ static int fimd_remove(struct platform_device *pdev)
        return 0;
 }
 
-void fimd_dp_clock_enable(struct exynos_drm_crtc *crtc, bool enable)
-{
-       struct fimd_context *ctx = crtc->ctx;
-       u32 val;
-
-       /*
-        * Only Exynos 5250, 5260, 5410 and 542x requires enabling DP/MIE
-        * clock. On these SoCs the bootloader may enable it but any
-        * power domain off/on will reset it to disable state.
-        */
-       if (ctx->driver_data != &exynos5_fimd_driver_data)
-               return;
-
-       val = enable ? DP_MIE_CLK_DP_ENABLE : DP_MIE_CLK_DISABLE;
-       writel(DP_MIE_CLK_DP_ENABLE, ctx->regs + DP_MIE_CLKCON);
-}
-EXPORT_SYMBOL_GPL(fimd_dp_clock_enable);
-
 struct platform_driver fimd_driver = {
        .probe          = fimd_probe,
        .remove         = fimd_remove,
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.h b/drivers/gpu/drm/exynos/exynos_drm_fimd.h
deleted file mode 100644 (file)
index b4fcaa5..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
- *
- * This program is free software; you can redistribute  it and/or modify it
- * under  the terms of  the GNU General  Public License as published by the
- * Free Software Foundation;  either version 2 of the  License, or (at your
- * option) any later version.
- */
-
-#ifndef _EXYNOS_DRM_FIMD_H_
-#define _EXYNOS_DRM_FIMD_H_
-
-extern void fimd_dp_clock_enable(struct exynos_drm_crtc *crtc, bool enable);
-
-#endif /* _EXYNOS_DRM_FIMD_H_ */
index 13ea3349363b153a8225aece3acc3e70a05dbe51..b1180fbe754690f700c124bdd50f72adb28d2295 100644 (file)
@@ -76,7 +76,7 @@ int exynos_check_plane(struct drm_plane *plane, struct drm_framebuffer *fb)
                        return -EFAULT;
                }
 
-               exynos_plane->dma_addr[i] = buffer->dma_addr;
+               exynos_plane->dma_addr[i] = buffer->dma_addr + fb->offsets[i];
 
                DRM_DEBUG_KMS("buffer: %d, dma_addr = 0x%lx\n",
                                i, (unsigned long)exynos_plane->dma_addr[i]);
index 27e84ec21694d587f26a78d258c216d52bd450ea..1b3479a8db5f08dd2b3c1c4fa0de5758d2ae7b26 100644 (file)
@@ -217,7 +217,7 @@ static int vidi_ctx_initialize(struct vidi_context *ctx,
        return 0;
 }
 
-static struct exynos_drm_crtc_ops vidi_crtc_ops = {
+static const struct exynos_drm_crtc_ops vidi_crtc_ops = {
        .dpms = vidi_dpms,
        .enable_vblank = vidi_enable_vblank,
        .disable_vblank = vidi_disable_vblank,
index fbec750574e64a3158b232d15ef309b29ed5340c..8874c1fcb3ab778b7faa82b0cedf1e47a7c2cd7c 100644 (file)
 #define MIXER_WIN_NR           3
 #define MIXER_DEFAULT_WIN      0
 
+/* The pixelformats that are natively supported by the mixer. */
+#define MXR_FORMAT_RGB565      4
+#define MXR_FORMAT_ARGB1555    5
+#define MXR_FORMAT_ARGB4444    6
+#define MXR_FORMAT_ARGB8888    7
+
 struct mixer_resources {
        int                     irq;
        void __iomem            *mixer_regs;
@@ -327,7 +333,8 @@ static void mixer_cfg_rgb_fmt(struct mixer_context *ctx, unsigned int height)
        mixer_reg_writemask(res, MXR_CFG, val, MXR_CFG_RGB_FMT_MASK);
 }
 
-static void mixer_cfg_layer(struct mixer_context *ctx, int win, bool enable)
+static void mixer_cfg_layer(struct mixer_context *ctx, unsigned int win,
+                               bool enable)
 {
        struct mixer_resources *res = &ctx->mixer_res;
        u32 val = enable ? ~0 : 0;
@@ -359,8 +366,6 @@ static void mixer_run(struct mixer_context *ctx)
        struct mixer_resources *res = &ctx->mixer_res;
 
        mixer_reg_writemask(res, MXR_STATUS, ~0, MXR_STATUS_REG_RUN);
-
-       mixer_regs_dump(ctx);
 }
 
 static void mixer_stop(struct mixer_context *ctx)
@@ -373,16 +378,13 @@ static void mixer_stop(struct mixer_context *ctx)
        while (!(mixer_reg_read(res, MXR_STATUS) & MXR_STATUS_REG_IDLE) &&
                        --timeout)
                usleep_range(10000, 12000);
-
-       mixer_regs_dump(ctx);
 }
 
-static void vp_video_buffer(struct mixer_context *ctx, int win)
+static void vp_video_buffer(struct mixer_context *ctx, unsigned int win)
 {
        struct mixer_resources *res = &ctx->mixer_res;
        unsigned long flags;
        struct exynos_drm_plane *plane;
-       unsigned int buf_num = 1;
        dma_addr_t luma_addr[2], chroma_addr[2];
        bool tiled_mode = false;
        bool crcb_mode = false;
@@ -393,27 +395,18 @@ static void vp_video_buffer(struct mixer_context *ctx, int win)
        switch (plane->pixel_format) {
        case DRM_FORMAT_NV12:
                crcb_mode = false;
-               buf_num = 2;
                break;
-       /* TODO: single buffer format NV12, NV21 */
+       case DRM_FORMAT_NV21:
+               crcb_mode = true;
+               break;
        default:
-               /* ignore pixel format at disable time */
-               if (!plane->dma_addr[0])
-                       break;
-
                DRM_ERROR("pixel format for vp is wrong [%d].\n",
                                plane->pixel_format);
                return;
        }
 
-       if (buf_num == 2) {
-               luma_addr[0] = plane->dma_addr[0];
-               chroma_addr[0] = plane->dma_addr[1];
-       } else {
-               luma_addr[0] = plane->dma_addr[0];
-               chroma_addr[0] = plane->dma_addr[0]
-                       + (plane->pitch * plane->fb_height);
-       }
+       luma_addr[0] = plane->dma_addr[0];
+       chroma_addr[0] = plane->dma_addr[1];
 
        if (plane->scan_flag & DRM_MODE_FLAG_INTERLACE) {
                ctx->interlace = true;
@@ -484,6 +477,7 @@ static void vp_video_buffer(struct mixer_context *ctx, int win)
        mixer_vsync_set_update(ctx, true);
        spin_unlock_irqrestore(&res->reg_slock, flags);
 
+       mixer_regs_dump(ctx);
        vp_regs_dump(ctx);
 }
 
@@ -518,7 +512,7 @@ static int mixer_setup_scale(const struct exynos_drm_plane *plane,
        return -ENOTSUPP;
 }
 
-static void mixer_graph_buffer(struct mixer_context *ctx, int win)
+static void mixer_graph_buffer(struct mixer_context *ctx, unsigned int win)
 {
        struct mixer_resources *res = &ctx->mixer_res;
        unsigned long flags;
@@ -531,20 +525,27 @@ static void mixer_graph_buffer(struct mixer_context *ctx, int win)
 
        plane = &ctx->planes[win];
 
-       #define RGB565 4
-       #define ARGB1555 5
-       #define ARGB4444 6
-       #define ARGB8888 7
+       switch (plane->pixel_format) {
+       case DRM_FORMAT_XRGB4444:
+               fmt = MXR_FORMAT_ARGB4444;
+               break;
 
-       switch (plane->bpp) {
-       case 16:
-               fmt = ARGB4444;
+       case DRM_FORMAT_XRGB1555:
+               fmt = MXR_FORMAT_ARGB1555;
                break;
-       case 32:
-               fmt = ARGB8888;
+
+       case DRM_FORMAT_RGB565:
+               fmt = MXR_FORMAT_RGB565;
+               break;
+
+       case DRM_FORMAT_XRGB8888:
+       case DRM_FORMAT_ARGB8888:
+               fmt = MXR_FORMAT_ARGB8888;
                break;
+
        default:
-               fmt = ARGB8888;
+               DRM_DEBUG_KMS("pixelformat unsupported by mixer\n");
+               return;
        }
 
        /* check if mixer supports requested scaling setup */
@@ -617,6 +618,8 @@ static void mixer_graph_buffer(struct mixer_context *ctx, int win)
 
        mixer_vsync_set_update(ctx, true);
        spin_unlock_irqrestore(&res->reg_slock, flags);
+
+       mixer_regs_dump(ctx);
 }
 
 static void vp_win_reset(struct mixer_context *ctx)
@@ -1070,6 +1073,7 @@ static void mixer_poweroff(struct mixer_context *ctx)
        mutex_unlock(&ctx->mixer_mutex);
 
        mixer_stop(ctx);
+       mixer_regs_dump(ctx);
        mixer_window_suspend(ctx);
 
        ctx->int_en = mixer_reg_read(res, MXR_INT_EN);
@@ -1126,7 +1130,7 @@ int mixer_check_mode(struct drm_display_mode *mode)
        return -EINVAL;
 }
 
-static struct exynos_drm_crtc_ops mixer_crtc_ops = {
+static const struct exynos_drm_crtc_ops mixer_crtc_ops = {
        .dpms                   = mixer_dpms,
        .enable_vblank          = mixer_enable_vblank,
        .disable_vblank         = mixer_disable_vblank,
@@ -1156,7 +1160,7 @@ static struct mixer_drv_data exynos4210_mxr_drv_data = {
        .has_sclk = 1,
 };
 
-static struct platform_device_id mixer_driver_types[] = {
+static const struct platform_device_id mixer_driver_types[] = {
        {
                .name           = "s5p-mixer",
                .driver_data    = (unsigned long)&exynos4210_mxr_drv_data,
index c302ffb5a16814b41086abe52a25c7f7debd40a8..a19d2c71e20505aba9ca25158d6e5acd6ba6f920 100644 (file)
@@ -699,6 +699,16 @@ static int i915_drm_resume(struct drm_device *dev)
        intel_init_pch_refclk(dev);
        drm_mode_config_reset(dev);
 
+       /*
+        * Interrupts have to be enabled before any batches are run. If not the
+        * GPU will hang. i915_gem_init_hw() will initiate batches to
+        * update/restore the context.
+        *
+        * Modeset enabling in intel_modeset_init_hw() also needs working
+        * interrupts.
+        */
+       intel_runtime_pm_enable_interrupts(dev_priv);
+
        mutex_lock(&dev->struct_mutex);
        if (i915_gem_init_hw(dev)) {
                DRM_ERROR("failed to re-initialize GPU, declaring wedged!\n");
@@ -706,9 +716,6 @@ static int i915_drm_resume(struct drm_device *dev)
        }
        mutex_unlock(&dev->struct_mutex);
 
-       /* We need working interrupts for modeset enabling ... */
-       intel_runtime_pm_enable_interrupts(dev_priv);
-
        intel_modeset_init_hw(dev);
 
        spin_lock_irq(&dev_priv->irq_lock);
index fa4ccb346389e2369effb3b3c48f6f211afa4832..555b896d2bdadec44aebc821a2f7fd9a09d58441 100644 (file)
@@ -2045,22 +2045,20 @@ static void ilk_compute_wm_parameters(struct drm_crtc *crtc,
        p->pipe_htotal = intel_crtc->config->base.adjusted_mode.crtc_htotal;
        p->pixel_rate = ilk_pipe_pixel_rate(dev, crtc);
 
-       if (crtc->primary->state->fb) {
-               p->pri.enabled = true;
+       if (crtc->primary->state->fb)
                p->pri.bytes_per_pixel =
                        crtc->primary->state->fb->bits_per_pixel / 8;
-       } else {
-               p->pri.enabled = false;
-               p->pri.bytes_per_pixel = 0;
-       }
+       else
+               p->pri.bytes_per_pixel = 4;
+
+       p->cur.bytes_per_pixel = 4;
+       /*
+        * TODO: for now, assume primary and cursor planes are always enabled.
+        * Setting them to false makes the screen flicker.
+        */
+       p->pri.enabled = true;
+       p->cur.enabled = true;
 
-       if (crtc->cursor->state->fb) {
-               p->cur.enabled = true;
-               p->cur.bytes_per_pixel = 4;
-       } else {
-               p->cur.enabled = false;
-               p->cur.bytes_per_pixel = 0;
-       }
        p->pri.horiz_pixels = intel_crtc->config->pipe_src_w;
        p->cur.horiz_pixels = intel_crtc->base.cursor->state->crtc_w;
 
index 94a5bee69fe724c94542bc5181e4309e78b78300..bbdcab0a56c1734d672457623d0eb071b881ceda 100644 (file)
@@ -384,7 +384,7 @@ void adreno_gpu_cleanup(struct adreno_gpu *gpu)
        if (gpu->memptrs_bo) {
                if (gpu->memptrs_iova)
                        msm_gem_put_iova(gpu->memptrs_bo, gpu->base.id);
-               drm_gem_object_unreference(gpu->memptrs_bo);
+               drm_gem_object_unreference_unlocked(gpu->memptrs_bo);
        }
        release_firmware(gpu->pm4);
        release_firmware(gpu->pfp);
index 28d1f95a90ccf0c87b10b26818ce0d14f106d1b9..ad50b80225f5b95d7f90252ea4ba086109a730d7 100644 (file)
@@ -177,6 +177,11 @@ int msm_dsi_modeset_init(struct msm_dsi *msm_dsi, struct drm_device *dev,
                goto fail;
        }
 
+       for (i = 0; i < MSM_DSI_ENCODER_NUM; i++) {
+               encoders[i]->bridge = msm_dsi->bridge;
+               msm_dsi->encoders[i] = encoders[i];
+       }
+
        msm_dsi->connector = msm_dsi_manager_connector_init(msm_dsi->id);
        if (IS_ERR(msm_dsi->connector)) {
                ret = PTR_ERR(msm_dsi->connector);
@@ -185,11 +190,6 @@ int msm_dsi_modeset_init(struct msm_dsi *msm_dsi, struct drm_device *dev,
                goto fail;
        }
 
-       for (i = 0; i < MSM_DSI_ENCODER_NUM; i++) {
-               encoders[i]->bridge = msm_dsi->bridge;
-               msm_dsi->encoders[i] = encoders[i];
-       }
-
        priv->bridges[priv->num_bridges++]       = msm_dsi->bridge;
        priv->connectors[priv->num_connectors++] = msm_dsi->connector;
 
index 956b22492c9a8f81db4ad38abc1a4edbb477bd38..649d20d29f9298a8852e6d0368008becb348fe03 100644 (file)
@@ -1023,7 +1023,7 @@ static int dsi_short_read1_resp(u8 *buf, const struct mipi_dsi_msg *msg)
                *data = buf[1]; /* strip out dcs type */
                return 1;
        } else {
-               pr_err("%s: read data does not match with rx_buf len %d\n",
+               pr_err("%s: read data does not match with rx_buf len %zu\n",
                        __func__, msg->rx_len);
                return -EINVAL;
        }
@@ -1040,7 +1040,7 @@ static int dsi_short_read2_resp(u8 *buf, const struct mipi_dsi_msg *msg)
                data[1] = buf[2];
                return 2;
        } else {
-               pr_err("%s: read data does not match with rx_buf len %d\n",
+               pr_err("%s: read data does not match with rx_buf len %zu\n",
                        __func__, msg->rx_len);
                return -EINVAL;
        }
@@ -1093,7 +1093,6 @@ static int dsi_cmd_dma_rx(struct msm_dsi_host *msm_host,
 {
        u32 *lp, *temp, data;
        int i, j = 0, cnt;
-       bool ack_error = false;
        u32 read_cnt;
        u8 reg[16];
        int repeated_bytes = 0;
@@ -1105,15 +1104,10 @@ static int dsi_cmd_dma_rx(struct msm_dsi_host *msm_host,
        if (cnt > 4)
                cnt = 4; /* 4 x 32 bits registers only */
 
-       /* Calculate real read data count */
-       read_cnt = dsi_read(msm_host, 0x1d4) >> 16;
-
-       ack_error = (rx_byte == 4) ?
-               (read_cnt == 8) : /* short pkt + 4-byte error pkt */
-               (read_cnt == (pkt_size + 6 + 4)); /* long pkt+4-byte error pkt*/
-
-       if (ack_error)
-               read_cnt -= 4; /* Remove 4 byte error pkt */
+       if (rx_byte == 4)
+               read_cnt = 4;
+       else
+               read_cnt = pkt_size + 6;
 
        /*
         * In case of multiple reads from the panel, after the first read, there
@@ -1215,7 +1209,7 @@ static void dsi_err_worker(struct work_struct *work)
                container_of(work, struct msm_dsi_host, err_work);
        u32 status = msm_host->err_work_state;
 
-       pr_err("%s: status=%x\n", __func__, status);
+       pr_err_ratelimited("%s: status=%x\n", __func__, status);
        if (status & DSI_ERR_STATE_MDP_FIFO_UNDERFLOW)
                dsi_sw_reset_restore(msm_host);
 
@@ -1797,6 +1791,7 @@ int msm_dsi_host_cmd_rx(struct mipi_dsi_host *host,
        case MIPI_DSI_RX_ACKNOWLEDGE_AND_ERROR_REPORT:
                pr_err("%s: rx ACK_ERR_PACLAGE\n", __func__);
                ret = 0;
+               break;
        case MIPI_DSI_RX_GENERIC_SHORT_READ_RESPONSE_1BYTE:
        case MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_1BYTE:
                ret = dsi_short_read1_resp(buf, msg);
index ee3ebcaa33f52f09cfe46dc34be7b7894b2753fa..0a40f3c64e8b3d05ce78af069f97851f8561c502 100644 (file)
@@ -462,7 +462,7 @@ struct drm_connector *msm_dsi_manager_connector_init(u8 id)
        struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
        struct drm_connector *connector = NULL;
        struct dsi_connector *dsi_connector;
-       int ret;
+       int ret, i;
 
        dsi_connector = devm_kzalloc(msm_dsi->dev->dev,
                                sizeof(*dsi_connector), GFP_KERNEL);
@@ -495,6 +495,10 @@ struct drm_connector *msm_dsi_manager_connector_init(u8 id)
        if (ret)
                goto fail;
 
+       for (i = 0; i < MSM_DSI_ENCODER_NUM; i++)
+               drm_mode_connector_attach_encoder(connector,
+                                               msm_dsi->encoders[i]);
+
        return connector;
 
 fail:
index 5f5a84f6074c73469a3a7e19e37fc1d5f55edab2..208f9d47f82ece1a98d7ea7d1bde3281ca1838c1 100644 (file)
@@ -132,7 +132,7 @@ ssize_t edp_aux_transfer(struct drm_dp_aux *drm_aux, struct drm_dp_aux_msg *msg)
        /* msg sanity check */
        if ((native && (msg->size > AUX_CMD_NATIVE_MAX)) ||
                (msg->size > AUX_CMD_I2C_MAX)) {
-               pr_err("%s: invalid msg: size(%d), request(%x)\n",
+               pr_err("%s: invalid msg: size(%zu), request(%x)\n",
                        __func__, msg->size, msg->request);
                return -EINVAL;
        }
@@ -155,7 +155,7 @@ ssize_t edp_aux_transfer(struct drm_dp_aux *drm_aux, struct drm_dp_aux_msg *msg)
                 */
                edp_write(aux->base + REG_EDP_AUX_TRANS_CTRL, 0);
                msm_edp_aux_ctrl(aux, 1);
-               pr_err("%s: aux timeout, %d\n", __func__, ret);
+               pr_err("%s: aux timeout, %zd\n", __func__, ret);
                goto unlock_exit;
        }
        DBG("completion");
index d8812e84da54332388ea9acad7d44403c27178e8..b4d1b469862a4c0281156f578492b8de43b2765e 100644 (file)
@@ -151,6 +151,8 @@ struct drm_connector *msm_edp_connector_init(struct msm_edp *edp)
        if (ret)
                goto fail;
 
+       drm_mode_connector_attach_encoder(connector, edp->encoder);
+
        return connector;
 
 fail:
index 0ec5abdba5c421b4a7604c4fa1b70ff8e3c129f9..29e52d7c61c06873c712254dd3ba4c14c0284f2d 100644 (file)
@@ -1149,12 +1149,13 @@ int msm_edp_ctrl_init(struct msm_edp *edp)
        ctrl->aux = msm_edp_aux_init(dev, ctrl->base, &ctrl->drm_aux);
        if (!ctrl->aux || !ctrl->drm_aux) {
                pr_err("%s:failed to init aux\n", __func__);
-               return ret;
+               return -ENOMEM;
        }
 
        ctrl->phy = msm_edp_phy_init(dev, ctrl->base);
        if (!ctrl->phy) {
                pr_err("%s:failed to init phy\n", __func__);
+               ret = -ENOMEM;
                goto err_destory_aux;
        }
 
index e001e6b2296a2ebd5cf602fbf0e3ba89f49ecf0d..8b9a7931b1624365dac35be9ca492b04967487b0 100644 (file)
@@ -72,14 +72,13 @@ const struct mdp5_cfg_hw msm8x74_config = {
                .base = { 0x12d00, 0x12e00, 0x12f00 },
        },
        .intf = {
-               .count = 4,
                .base = { 0x12500, 0x12700, 0x12900, 0x12b00 },
-       },
-       .intfs = {
-               [0] = INTF_eDP,
-               [1] = INTF_DSI,
-               [2] = INTF_DSI,
-               [3] = INTF_HDMI,
+               .connect = {
+                       [0] = INTF_eDP,
+                       [1] = INTF_DSI,
+                       [2] = INTF_DSI,
+                       [3] = INTF_HDMI,
+               },
        },
        .max_clk = 200000000,
 };
@@ -142,14 +141,13 @@ const struct mdp5_cfg_hw apq8084_config = {
                .base = { 0x12f00, 0x13000, 0x13100, 0x13200 },
        },
        .intf = {
-               .count = 5,
                .base = { 0x12500, 0x12700, 0x12900, 0x12b00, 0x12d00 },
-       },
-       .intfs = {
-               [0] = INTF_eDP,
-               [1] = INTF_DSI,
-               [2] = INTF_DSI,
-               [3] = INTF_HDMI,
+               .connect = {
+                       [0] = INTF_eDP,
+                       [1] = INTF_DSI,
+                       [2] = INTF_DSI,
+                       [3] = INTF_HDMI,
+               },
        },
        .max_clk = 320000000,
 };
@@ -196,10 +194,12 @@ const struct mdp5_cfg_hw msm8x16_config = {
 
        },
        .intf = {
-               .count = 1, /* INTF_1 */
-               .base = { 0x6B800 },
+               .base = { 0x00000, 0x6b800 },
+               .connect = {
+                       [0] = INTF_DISABLED,
+                       [1] = INTF_DSI,
+               },
        },
-       /* TODO enable .intfs[] with [1] = INTF_DSI, once DSI is implemented */
        .max_clk = 320000000,
 };
 
index 3a551b0892d847e50fb48054bfb6c409887fd40b..69349abe59f2a4a614a9a9379b5c26f232087a3c 100644 (file)
@@ -59,6 +59,11 @@ struct mdp5_smp_block {
 
 #define MDP5_INTF_NUM_MAX      5
 
+struct mdp5_intf_block {
+       uint32_t base[MAX_BASES];
+       u32 connect[MDP5_INTF_NUM_MAX]; /* array of enum mdp5_intf_type */
+};
+
 struct mdp5_cfg_hw {
        char  *name;
 
@@ -72,9 +77,7 @@ struct mdp5_cfg_hw {
        struct mdp5_sub_block dspp;
        struct mdp5_sub_block ad;
        struct mdp5_sub_block pp;
-       struct mdp5_sub_block intf;
-
-       u32 intfs[MDP5_INTF_NUM_MAX]; /* array of enum mdp5_intf_type */
+       struct mdp5_intf_block intf;
 
        uint32_t max_clk;
 };
index dfa8beb9343aaa171110adabb49c549e4143c0da..bbacf9d2b7383cc12d21bfeb48327c4b04604f56 100644 (file)
@@ -206,8 +206,8 @@ static struct drm_encoder *construct_encoder(struct mdp5_kms *mdp5_kms,
 
 static int get_dsi_id_from_intf(const struct mdp5_cfg_hw *hw_cfg, int intf_num)
 {
-       const int intf_cnt = hw_cfg->intf.count;
-       const u32 *intfs = hw_cfg->intfs;
+       const enum mdp5_intf_type *intfs = hw_cfg->intf.connect;
+       const int intf_cnt = ARRAY_SIZE(hw_cfg->intf.connect);
        int id = 0, i;
 
        for (i = 0; i < intf_cnt; i++) {
@@ -228,7 +228,7 @@ static int modeset_init_intf(struct mdp5_kms *mdp5_kms, int intf_num)
        struct msm_drm_private *priv = dev->dev_private;
        const struct mdp5_cfg_hw *hw_cfg =
                                        mdp5_cfg_get_hw_config(mdp5_kms->cfg);
-       enum mdp5_intf_type intf_type = hw_cfg->intfs[intf_num];
+       enum mdp5_intf_type intf_type = hw_cfg->intf.connect[intf_num];
        struct drm_encoder *encoder;
        int ret = 0;
 
@@ -365,7 +365,7 @@ static int modeset_init(struct mdp5_kms *mdp5_kms)
        /* Construct encoders and modeset initialize connector devices
         * for each external display interface.
         */
-       for (i = 0; i < ARRAY_SIZE(hw_cfg->intfs); i++) {
+       for (i = 0; i < ARRAY_SIZE(hw_cfg->intf.connect); i++) {
                ret = modeset_init_intf(mdp5_kms, i);
                if (ret)
                        goto fail;
@@ -514,8 +514,8 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev)
         */
        mdp5_enable(mdp5_kms);
        for (i = 0; i < MDP5_INTF_NUM_MAX; i++) {
-               if (!config->hw->intf.base[i] ||
-                               mdp5_cfg_intf_is_virtual(config->hw->intfs[i]))
+               if (mdp5_cfg_intf_is_virtual(config->hw->intf.connect[i]) ||
+                               !config->hw->intf.base[i])
                        continue;
                mdp5_write(mdp5_kms, REG_MDP5_INTF_TIMING_ENGINE_EN(i), 0);
        }
index 18a3d203b17439c2be3f0b0c72e033ed3996ae86..57b8f56ae9d06fb458266181a8344858e381e6b5 100644 (file)
@@ -273,7 +273,7 @@ static void set_scanout_locked(struct drm_plane *plane,
        mdp5_write(mdp5_kms, REG_MDP5_PIPE_SRC2_ADDR(pipe),
                        msm_framebuffer_iova(fb, mdp5_kms->id, 2));
        mdp5_write(mdp5_kms, REG_MDP5_PIPE_SRC3_ADDR(pipe),
-                       msm_framebuffer_iova(fb, mdp5_kms->id, 4));
+                       msm_framebuffer_iova(fb, mdp5_kms->id, 3));
 
        plane->fb = fb;
 }
index 47f4dd407671970fc247c4a9999dcccc03202c8e..c80a6bee2b18f373c9f2191bebbbb44e82db7663 100644 (file)
 
 static void msm_fb_output_poll_changed(struct drm_device *dev)
 {
+#ifdef CONFIG_DRM_MSM_FBDEV
        struct msm_drm_private *priv = dev->dev_private;
        if (priv->fbdev)
                drm_fb_helper_hotplug_event(priv->fbdev);
+#endif
 }
 
 static const struct drm_mode_config_funcs mode_config_funcs = {
@@ -94,7 +96,7 @@ void __iomem *msm_ioremap(struct platform_device *pdev, const char *name,
        }
 
        if (reglog)
-               printk(KERN_DEBUG "IO:region %s %08x %08lx\n", dbgname, (u32)ptr, size);
+               printk(KERN_DEBUG "IO:region %s %p %08lx\n", dbgname, ptr, size);
 
        return ptr;
 }
@@ -102,7 +104,7 @@ void __iomem *msm_ioremap(struct platform_device *pdev, const char *name,
 void msm_writel(u32 data, void __iomem *addr)
 {
        if (reglog)
-               printk(KERN_DEBUG "IO:W %08x %08x\n", (u32)addr, data);
+               printk(KERN_DEBUG "IO:W %p %08x\n", addr, data);
        writel(data, addr);
 }
 
@@ -110,7 +112,7 @@ u32 msm_readl(const void __iomem *addr)
 {
        u32 val = readl(addr);
        if (reglog)
-               printk(KERN_ERR "IO:R %08x %08x\n", (u32)addr, val);
+               printk(KERN_ERR "IO:R %p %08x\n", addr, val);
        return val;
 }
 
@@ -143,8 +145,8 @@ static int msm_unload(struct drm_device *dev)
        if (gpu) {
                mutex_lock(&dev->struct_mutex);
                gpu->funcs->pm_suspend(gpu);
-               gpu->funcs->destroy(gpu);
                mutex_unlock(&dev->struct_mutex);
+               gpu->funcs->destroy(gpu);
        }
 
        if (priv->vram.paddr) {
@@ -177,7 +179,7 @@ static int get_mdp_ver(struct platform_device *pdev)
        const struct of_device_id *match;
        match = of_match_node(match_types, dev->of_node);
        if (match)
-               return (int)match->data;
+               return (int)(unsigned long)match->data;
 #endif
        return 4;
 }
@@ -216,7 +218,7 @@ static int msm_init_vram(struct drm_device *dev)
                if (ret)
                        return ret;
                size = r.end - r.start;
-               DRM_INFO("using VRAM carveout: %lx@%08x\n", size, r.start);
+               DRM_INFO("using VRAM carveout: %lx@%pa\n", size, &r.start);
        } else
 #endif
 
@@ -283,10 +285,6 @@ static int msm_load(struct drm_device *dev, unsigned long flags)
 
        drm_mode_config_init(dev);
 
-       ret = msm_init_vram(dev);
-       if (ret)
-               goto fail;
-
        platform_set_drvdata(pdev, dev);
 
        /* Bind all our sub-components: */
@@ -294,6 +292,10 @@ static int msm_load(struct drm_device *dev, unsigned long flags)
        if (ret)
                return ret;
 
+       ret = msm_init_vram(dev);
+       if (ret)
+               goto fail;
+
        switch (get_mdp_ver(pdev)) {
        case 4:
                kms = mdp4_kms_init(dev);
@@ -419,9 +421,11 @@ static void msm_preclose(struct drm_device *dev, struct drm_file *file)
 
 static void msm_lastclose(struct drm_device *dev)
 {
+#ifdef CONFIG_DRM_MSM_FBDEV
        struct msm_drm_private *priv = dev->dev_private;
        if (priv->fbdev)
                drm_fb_helper_restore_fbdev_mode_unlocked(priv->fbdev);
+#endif
 }
 
 static irqreturn_t msm_irq(int irq, void *arg)
index 6b573e612f270bcbcc9e1d92cd3e3318fc80cb98..121713281417a92fc2270c7f907a082a1e0c4a87 100644 (file)
@@ -172,8 +172,8 @@ struct drm_framebuffer *msm_framebuffer_init(struct drm_device *dev,
 {
        struct msm_drm_private *priv = dev->dev_private;
        struct msm_kms *kms = priv->kms;
-       struct msm_framebuffer *msm_fb;
-       struct drm_framebuffer *fb = NULL;
+       struct msm_framebuffer *msm_fb = NULL;
+       struct drm_framebuffer *fb;
        const struct msm_format *format;
        int ret, i, n;
        unsigned int hsub, vsub;
@@ -239,8 +239,7 @@ struct drm_framebuffer *msm_framebuffer_init(struct drm_device *dev,
        return fb;
 
 fail:
-       if (fb)
-               msm_framebuffer_destroy(fb);
+       kfree(msm_fb);
 
        return ERR_PTR(ret);
 }
index 479d8af72bcb77d822ea92614ea3b91601e9ac6d..52839769eb6c091ba9f64a73e72d89191a3615cb 100644 (file)
@@ -483,7 +483,7 @@ void msm_gem_describe(struct drm_gem_object *obj, struct seq_file *m)
        uint64_t off = drm_vma_node_start(&obj->vma_node);
 
        WARN_ON(!mutex_is_locked(&dev->struct_mutex));
-       seq_printf(m, "%08x: %c(r=%u,w=%u) %2d (%2d) %08llx %p %d\n",
+       seq_printf(m, "%08x: %c(r=%u,w=%u) %2d (%2d) %08llx %p %zu\n",
                        msm_obj->flags, is_active(msm_obj) ? 'A' : 'I',
                        msm_obj->read_fence, msm_obj->write_fence,
                        obj->name, obj->refcount.refcount.counter,
index 7acdaa5688b77e89f3afa786da19903d0d0c7b6d..7ac2f1997e4a4cbe4e57003f001928bba8a2c490 100644 (file)
@@ -60,7 +60,7 @@ static int msm_iommu_map(struct msm_mmu *mmu, uint32_t iova,
                u32 pa = sg_phys(sg) - sg->offset;
                size_t bytes = sg->length + sg->offset;
 
-               VERB("map[%d]: %08x %08x(%x)", i, iova, pa, bytes);
+               VERB("map[%d]: %08x %08x(%zx)", i, iova, pa, bytes);
 
                ret = iommu_map(domain, da, pa, bytes, prot);
                if (ret)
@@ -99,7 +99,7 @@ static int msm_iommu_unmap(struct msm_mmu *mmu, uint32_t iova,
                if (unmapped < bytes)
                        return unmapped;
 
-               VERB("unmap[%d]: %08x(%x)", i, iova, bytes);
+               VERB("unmap[%d]: %08x(%zx)", i, iova, bytes);
 
                BUG_ON(!PAGE_ALIGNED(bytes));
 
index 8171537dd7d127f9c104bb9417bf5b71a4bf91d8..1f14b908b22136117eb2b37179d05abfedce2b13 100644 (file)
@@ -56,6 +56,6 @@ struct msm_ringbuffer *msm_ringbuffer_new(struct msm_gpu *gpu, int size)
 void msm_ringbuffer_destroy(struct msm_ringbuffer *ring)
 {
        if (ring->bo)
-               drm_gem_object_unreference(ring->bo);
+               drm_gem_object_unreference_unlocked(ring->bo);
        kfree(ring);
 }
index 3e3290c203c625d781f7dfacc13977c50c54d34b..b435c859dcbc3a76d7590f0cd1a6a785230037cf 100644 (file)
@@ -421,19 +421,21 @@ bool radeon_dp_getdpcd(struct radeon_connector *radeon_connector)
 {
        struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv;
        u8 msg[DP_DPCD_SIZE];
-       int ret;
+       int ret, i;
 
-       ret = drm_dp_dpcd_read(&radeon_connector->ddc_bus->aux, DP_DPCD_REV, msg,
-                              DP_DPCD_SIZE);
-       if (ret > 0) {
-               memcpy(dig_connector->dpcd, msg, DP_DPCD_SIZE);
+       for (i = 0; i < 7; i++) {
+               ret = drm_dp_dpcd_read(&radeon_connector->ddc_bus->aux, DP_DPCD_REV, msg,
+                                      DP_DPCD_SIZE);
+               if (ret == DP_DPCD_SIZE) {
+                       memcpy(dig_connector->dpcd, msg, DP_DPCD_SIZE);
 
-               DRM_DEBUG_KMS("DPCD: %*ph\n", (int)sizeof(dig_connector->dpcd),
-                             dig_connector->dpcd);
+                       DRM_DEBUG_KMS("DPCD: %*ph\n", (int)sizeof(dig_connector->dpcd),
+                                     dig_connector->dpcd);
 
-               radeon_dp_probe_oui(radeon_connector);
+                       radeon_dp_probe_oui(radeon_connector);
 
-               return true;
+                       return true;
+               }
        }
        dig_connector->dpcd[0] = 0;
        return false;
index 28faea9996f9e111d6b35e547587025aa93c3089..a0c35bbc85462587be95048bd996aecb8ec481e2 100644 (file)
@@ -5822,7 +5822,7 @@ static int cik_pcie_gart_enable(struct radeon_device *rdev)
               L2_CACHE_BIGK_FRAGMENT_SIZE(4));
        /* setup context0 */
        WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR, rdev->mc.gtt_start >> 12);
-       WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, rdev->mc.gtt_end >> 12);
+       WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, (rdev->mc.gtt_end >> 12) - 1);
        WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, rdev->gart.table_addr >> 12);
        WREG32(VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR,
                        (u32)(rdev->dummy_page.addr >> 12));
@@ -5837,7 +5837,7 @@ static int cik_pcie_gart_enable(struct radeon_device *rdev)
        /* restore context1-15 */
        /* set vm size, must be a multiple of 4 */
        WREG32(VM_CONTEXT1_PAGE_TABLE_START_ADDR, 0);
-       WREG32(VM_CONTEXT1_PAGE_TABLE_END_ADDR, rdev->vm_manager.max_pfn);
+       WREG32(VM_CONTEXT1_PAGE_TABLE_END_ADDR, rdev->vm_manager.max_pfn - 1);
        for (i = 1; i < 16; i++) {
                if (i < 8)
                        WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (i << 2),
index f848acfd3fc8a94fb4674cf13d9442857e367567..05e6d6ef596385ecab450bbd1831e942186021d2 100644 (file)
@@ -2485,7 +2485,7 @@ static int evergreen_pcie_gart_enable(struct radeon_device *rdev)
        WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp);
        WREG32(MC_VM_MB_L1_TLB3_CNTL, tmp);
        WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR, rdev->mc.gtt_start >> 12);
-       WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, rdev->mc.gtt_end >> 12);
+       WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, (rdev->mc.gtt_end >> 12) - 1);
        WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, rdev->gart.table_addr >> 12);
        WREG32(VM_CONTEXT0_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(0) |
                                RANGE_PROTECTION_FAULT_ENABLE_DEFAULT);
index e8a496ff007ee680d30a2bd688f30d094b58461c..aba2f428c0a895380a4a3251e51c6484fba4b3be 100644 (file)
@@ -1282,7 +1282,7 @@ static int cayman_pcie_gart_enable(struct radeon_device *rdev)
               L2_CACHE_BIGK_FRAGMENT_SIZE(6));
        /* setup context0 */
        WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR, rdev->mc.gtt_start >> 12);
-       WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, rdev->mc.gtt_end >> 12);
+       WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, (rdev->mc.gtt_end >> 12) - 1);
        WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, rdev->gart.table_addr >> 12);
        WREG32(VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR,
                        (u32)(rdev->dummy_page.addr >> 12));
@@ -1301,7 +1301,8 @@ static int cayman_pcie_gart_enable(struct radeon_device *rdev)
         */
        for (i = 1; i < 8; i++) {
                WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR + (i << 2), 0);
-               WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR + (i << 2), rdev->vm_manager.max_pfn);
+               WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR + (i << 2),
+                       rdev->vm_manager.max_pfn - 1);
                WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (i << 2),
                       rdev->vm_manager.saved_table_addr[i]);
        }
index 8f6d862a188228101dc9070f5ab2ada5f819d1a6..25b4ac967742c034372caa1dbf67d6476fd6bb92 100644 (file)
@@ -1112,7 +1112,7 @@ static int r600_pcie_gart_enable(struct radeon_device *rdev)
        WREG32(MC_VM_L1_TLB_MCB_RD_SEM_CNTL, tmp | ENABLE_SEMAPHORE_MODE);
        WREG32(MC_VM_L1_TLB_MCB_WR_SEM_CNTL, tmp | ENABLE_SEMAPHORE_MODE);
        WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR, rdev->mc.gtt_start >> 12);
-       WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, rdev->mc.gtt_end >> 12);
+       WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, (rdev->mc.gtt_end >> 12) - 1);
        WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, rdev->gart.table_addr >> 12);
        WREG32(VM_CONTEXT0_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(0) |
                                RANGE_PROTECTION_FAULT_ENABLE_DEFAULT);
index bf1fecc6cceb2cba743bce902f26598f7156d03a..fcbd60bb03495740d435b7a33521ff698b171c40 100644 (file)
@@ -30,8 +30,6 @@
                            AUX_SW_RX_HPD_DISCON |           \
                            AUX_SW_RX_PARTIAL_BYTE |         \
                            AUX_SW_NON_AUX_MODE |            \
-                           AUX_SW_RX_MIN_COUNT_VIOL |       \
-                           AUX_SW_RX_INVALID_STOP |         \
                            AUX_SW_RX_SYNC_INVALID_L |       \
                            AUX_SW_RX_SYNC_INVALID_H |       \
                            AUX_SW_RX_INVALID_START |        \
index 1017338a49d9f49aaad6dc594d6ec1bef8a5f111..2b98ed3e684d706a07e3c43b6da9f2232143e580 100644 (file)
@@ -666,6 +666,9 @@ radeon_dp_mst_probe(struct radeon_connector *radeon_connector)
        int ret;
        u8 msg[1];
 
+       if (!radeon_mst)
+               return 0;
+
        if (dig_connector->dpcd[DP_DPCD_REV] < 0x12)
                return 0;
 
index 01ee96acb3985ea65ec2470456381251d51f444e..c54d6313a46d243a226b5d969b597dcb062773ff 100644 (file)
@@ -921,7 +921,7 @@ static int rv770_pcie_gart_enable(struct radeon_device *rdev)
        WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp);
        WREG32(MC_VM_MB_L1_TLB3_CNTL, tmp);
        WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR, rdev->mc.gtt_start >> 12);
-       WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, rdev->mc.gtt_end >> 12);
+       WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, (rdev->mc.gtt_end >> 12) - 1);
        WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, rdev->gart.table_addr >> 12);
        WREG32(VM_CONTEXT0_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(0) |
                                RANGE_PROTECTION_FAULT_ENABLE_DEFAULT);
index b1d74bc375d82f665dbb4455db5aa84db0c8d8dc..5326f753e10760ec04e27701e2eef4674139494f 100644 (file)
@@ -4303,7 +4303,7 @@ static int si_pcie_gart_enable(struct radeon_device *rdev)
               L2_CACHE_BIGK_FRAGMENT_SIZE(4));
        /* setup context0 */
        WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR, rdev->mc.gtt_start >> 12);
-       WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, rdev->mc.gtt_end >> 12);
+       WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, (rdev->mc.gtt_end >> 12) - 1);
        WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, rdev->gart.table_addr >> 12);
        WREG32(VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR,
                        (u32)(rdev->dummy_page.addr >> 12));
@@ -4318,7 +4318,7 @@ static int si_pcie_gart_enable(struct radeon_device *rdev)
        /* empty context1-15 */
        /* set vm size, must be a multiple of 4 */
        WREG32(VM_CONTEXT1_PAGE_TABLE_START_ADDR, 0);
-       WREG32(VM_CONTEXT1_PAGE_TABLE_END_ADDR, rdev->vm_manager.max_pfn);
+       WREG32(VM_CONTEXT1_PAGE_TABLE_END_ADDR, rdev->vm_manager.max_pfn - 1);
        /* Assign the pt base to something valid for now; the pts used for
         * the VMs are determined by the application and setup and assigned
         * on the fly in the vm part of radeon_gart.c
index 41f167e4d75fdeec20d795b566fdeba1c642497f..7ce93d927f62d8d029c3f32cefd3dc3f3b2f36dd 100644 (file)
 #define USB_DEVICE_ID_ATEN_2PORTKVM    0x2204
 #define USB_DEVICE_ID_ATEN_4PORTKVM    0x2205
 #define USB_DEVICE_ID_ATEN_4PORTKVMC   0x2208
+#define USB_DEVICE_ID_ATEN_CS682       0x2213
 
 #define USB_VENDOR_ID_ATMEL            0x03eb
 #define USB_DEVICE_ID_ATMEL_MULTITOUCH 0x211c
index b3cf6fd4be96473ba62ebbbf92d1522c024a509e..5fd530acf747c50fcd5bfbd51d19d3271e5d716b 100644 (file)
@@ -44,7 +44,6 @@ MODULE_PARM_DESC(disable_raw_mode,
 /* bits 1..20 are reserved for classes */
 #define HIDPP_QUIRK_DELAYED_INIT               BIT(21)
 #define HIDPP_QUIRK_WTP_PHYSICAL_BUTTONS       BIT(22)
-#define HIDPP_QUIRK_MULTI_INPUT                        BIT(23)
 
 /*
  * There are two hidpp protocols in use, the first version hidpp10 is known
@@ -706,12 +705,6 @@ static int wtp_input_mapping(struct hid_device *hdev, struct hid_input *hi,
                struct hid_field *field, struct hid_usage *usage,
                unsigned long **bit, int *max)
 {
-       struct hidpp_device *hidpp = hid_get_drvdata(hdev);
-
-       if ((hidpp->quirks & HIDPP_QUIRK_MULTI_INPUT) &&
-           (field->application == HID_GD_KEYBOARD))
-               return 0;
-
        return -1;
 }
 
@@ -720,10 +713,6 @@ static void wtp_populate_input(struct hidpp_device *hidpp,
 {
        struct wtp_data *wd = hidpp->private_data;
 
-       if ((hidpp->quirks & HIDPP_QUIRK_MULTI_INPUT) && origin_is_hid_core)
-               /* this is the generic hid-input call */
-               return;
-
        __set_bit(EV_ABS, input_dev->evbit);
        __set_bit(EV_KEY, input_dev->evbit);
        __clear_bit(EV_REL, input_dev->evbit);
@@ -1245,10 +1234,6 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id)
        if (hidpp->quirks & HIDPP_QUIRK_DELAYED_INIT)
                connect_mask &= ~HID_CONNECT_HIDINPUT;
 
-       /* Re-enable hidinput for multi-input devices */
-       if (hidpp->quirks & HIDPP_QUIRK_MULTI_INPUT)
-               connect_mask |= HID_CONNECT_HIDINPUT;
-
        ret = hid_hw_start(hdev, connect_mask);
        if (ret) {
                hid_err(hdev, "%s:hid_hw_start returned error\n", __func__);
@@ -1296,11 +1281,6 @@ static const struct hid_device_id hidpp_devices[] = {
          HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH,
                USB_DEVICE_ID_LOGITECH_T651),
          .driver_data = HIDPP_QUIRK_CLASS_WTP },
-       { /* Keyboard TK820 */
-         HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE,
-               USB_VENDOR_ID_LOGITECH, 0x4102),
-         .driver_data = HIDPP_QUIRK_DELAYED_INIT | HIDPP_QUIRK_MULTI_INPUT |
-                        HIDPP_QUIRK_CLASS_WTP },
 
        { HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE,
                USB_VENDOR_ID_LOGITECH, HID_ANY_ID)},
index c3f6f1e311ea0d98da6981669e292e085552a927..090a1ba0abb6fb1f6c937a7190980bbd8f318a0c 100644 (file)
@@ -294,7 +294,7 @@ int sensor_hub_input_attr_get_raw_value(struct hid_sensor_hub_device *hsdev,
        if (!report)
                return -EINVAL;
 
-       mutex_lock(&hsdev->mutex);
+       mutex_lock(hsdev->mutex_ptr);
        if (flag == SENSOR_HUB_SYNC) {
                memset(&hsdev->pending, 0, sizeof(hsdev->pending));
                init_completion(&hsdev->pending.ready);
@@ -328,7 +328,7 @@ int sensor_hub_input_attr_get_raw_value(struct hid_sensor_hub_device *hsdev,
                kfree(hsdev->pending.raw_data);
                hsdev->pending.status = false;
        }
-       mutex_unlock(&hsdev->mutex);
+       mutex_unlock(hsdev->mutex_ptr);
 
        return ret_val;
 }
@@ -667,7 +667,14 @@ static int sensor_hub_probe(struct hid_device *hdev,
                        hsdev->vendor_id = hdev->vendor;
                        hsdev->product_id = hdev->product;
                        hsdev->usage = collection->usage;
-                       mutex_init(&hsdev->mutex);
+                       hsdev->mutex_ptr = devm_kzalloc(&hdev->dev,
+                                                       sizeof(struct mutex),
+                                                       GFP_KERNEL);
+                       if (!hsdev->mutex_ptr) {
+                               ret = -ENOMEM;
+                               goto err_stop_hw;
+                       }
+                       mutex_init(hsdev->mutex_ptr);
                        hsdev->start_collection_index = i;
                        if (last_hsdev)
                                last_hsdev->end_collection_index = i;
index ab4dd952b6ba654d91d75523951f4f02cbfa1138..92d6cdf024607d848249e011d14f19e88d7c4a39 100644 (file)
@@ -862,6 +862,7 @@ static int i2c_hid_acpi_pdata(struct i2c_client *client,
        union acpi_object *obj;
        struct acpi_device *adev;
        acpi_handle handle;
+       int ret;
 
        handle = ACPI_HANDLE(&client->dev);
        if (!handle || acpi_bus_get_device(handle, &adev))
@@ -877,7 +878,9 @@ static int i2c_hid_acpi_pdata(struct i2c_client *client,
        pdata->hid_descriptor_address = obj->integer.value;
        ACPI_FREE(obj);
 
-       return acpi_dev_add_driver_gpios(adev, i2c_hid_acpi_gpios);
+       /* GPIOs are optional */
+       ret = acpi_dev_add_driver_gpios(adev, i2c_hid_acpi_gpios);
+       return ret < 0 && ret != -ENXIO ? ret : 0;
 }
 
 static const struct acpi_device_id i2c_hid_acpi_match[] = {
index a775143e6265e337597e2dd15e6c9d682c04354f..4696895eb708316944dac63092e959e4b1bb1765 100644 (file)
@@ -61,6 +61,7 @@ static const struct hid_blacklist {
        { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_2PORTKVM, HID_QUIRK_NOGET },
        { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVM, HID_QUIRK_NOGET },
        { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVMC, HID_QUIRK_NOGET },
+       { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS682, HID_QUIRK_NOGET },
        { USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_FIGHTERSTICK, HID_QUIRK_NOGET },
        { USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_COMBATSTICK, HID_QUIRK_NOGET },
        { USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_FLIGHT_SIM_ECLIPSE_YOKE, HID_QUIRK_NOGET },
index fa54d329065945bade5b9048df9cb5a98c0bf7f2..adf959dcfa5df9da7bca7414e2d4ac74a35e1457 100644 (file)
@@ -1072,6 +1072,9 @@ static int wacom_wac_finger_count_touches(struct wacom_wac *wacom)
        int count = 0;
        int i;
 
+       if (!touch_max)
+               return 0;
+
        /* non-HID_GENERIC single touch input doesn't call this routine */
        if ((touch_max == 1) && (wacom->features.type == HID_GENERIC))
                return wacom->hid_data.tipswitch &&
index a04c49f2a0118a887e22c16b9716656af6e87723..39ea67f9b066989ff901674cea38d2b1bb0ff2b3 100644 (file)
@@ -643,15 +643,6 @@ config BLK_DEV_TC86C001
        help
        This driver adds support for Toshiba TC86C001 GOKU-S chip.
 
-config BLK_DEV_CELLEB
-       tristate "Toshiba's Cell Reference Set IDE support"
-       depends on PPC_CELLEB
-       select BLK_DEV_IDEDMA_PCI
-       help
-         This driver provides support for the on-board IDE controller on
-         Toshiba Cell Reference Board.
-         If unsure, say Y.
-
 endif
 
 # TODO: BLK_DEV_IDEDMA_PCI -> BLK_DEV_IDEDMA_SFF
index a04ee82f1c8f5bf5bd712f90dd73744a37762e2a..2a8c417d4081087daa50d154844bcb65f6cb55c0 100644 (file)
@@ -38,7 +38,6 @@ obj-$(CONFIG_BLK_DEV_AEC62XX)         += aec62xx.o
 obj-$(CONFIG_BLK_DEV_ALI15X3)          += alim15x3.o
 obj-$(CONFIG_BLK_DEV_AMD74XX)          += amd74xx.o
 obj-$(CONFIG_BLK_DEV_ATIIXP)           += atiixp.o
-obj-$(CONFIG_BLK_DEV_CELLEB)           += scc_pata.o
 obj-$(CONFIG_BLK_DEV_CMD64X)           += cmd64x.o
 obj-$(CONFIG_BLK_DEV_CS5520)           += cs5520.o
 obj-$(CONFIG_BLK_DEV_CS5530)           += cs5530.o
diff --git a/drivers/ide/scc_pata.c b/drivers/ide/scc_pata.c
deleted file mode 100644 (file)
index 2a2d188..0000000
+++ /dev/null
@@ -1,887 +0,0 @@
-/*
- * Support for IDE interfaces on Celleb platform
- *
- * (C) Copyright 2006 TOSHIBA CORPORATION
- *
- * This code is based on drivers/ide/pci/siimage.c:
- * Copyright (C) 2001-2002     Andre Hedrick <andre@linux-ide.org>
- * Copyright (C) 2003          Red Hat
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include <linux/types.h>
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/delay.h>
-#include <linux/ide.h>
-#include <linux/init.h>
-
-#define PCI_DEVICE_ID_TOSHIBA_SCC_ATA            0x01b4
-
-#define SCC_PATA_NAME           "scc IDE"
-
-#define TDVHSEL_MASTER          0x00000001
-#define TDVHSEL_SLAVE           0x00000004
-
-#define MODE_JCUSFEN            0x00000080
-
-#define CCKCTRL_ATARESET        0x00040000
-#define CCKCTRL_BUFCNT          0x00020000
-#define CCKCTRL_CRST            0x00010000
-#define CCKCTRL_OCLKEN          0x00000100
-#define CCKCTRL_ATACLKOEN       0x00000002
-#define CCKCTRL_LCLKEN          0x00000001
-
-#define QCHCD_IOS_SS           0x00000001
-
-#define QCHSD_STPDIAG          0x00020000
-
-#define INTMASK_MSK             0xD1000012
-#define INTSTS_SERROR          0x80000000
-#define INTSTS_PRERR           0x40000000
-#define INTSTS_RERR            0x10000000
-#define INTSTS_ICERR           0x01000000
-#define INTSTS_BMSINT          0x00000010
-#define INTSTS_BMHE            0x00000008
-#define INTSTS_IOIRQS           0x00000004
-#define INTSTS_INTRQ            0x00000002
-#define INTSTS_ACTEINT          0x00000001
-
-#define ECMODE_VALUE 0x01
-
-static struct scc_ports {
-       unsigned long ctl, dma;
-       struct ide_host *host;  /* for removing port from system */
-} scc_ports[MAX_HWIFS];
-
-/* PIO transfer mode  table */
-/* JCHST */
-static unsigned long JCHSTtbl[2][7] = {
-       {0x0E, 0x05, 0x02, 0x03, 0x02, 0x00, 0x00},   /* 100MHz */
-       {0x13, 0x07, 0x04, 0x04, 0x03, 0x00, 0x00}    /* 133MHz */
-};
-
-/* JCHHT */
-static unsigned long JCHHTtbl[2][7] = {
-       {0x0E, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00},   /* 100MHz */
-       {0x13, 0x03, 0x03, 0x03, 0x03, 0x00, 0x00}    /* 133MHz */
-};
-
-/* JCHCT */
-static unsigned long JCHCTtbl[2][7] = {
-       {0x1D, 0x1D, 0x1C, 0x0B, 0x06, 0x00, 0x00},   /* 100MHz */
-       {0x27, 0x26, 0x26, 0x0E, 0x09, 0x00, 0x00}    /* 133MHz */
-};
-
-
-/* DMA transfer mode  table */
-/* JCHDCTM/JCHDCTS */
-static unsigned long JCHDCTxtbl[2][7] = {
-       {0x0A, 0x06, 0x04, 0x03, 0x01, 0x00, 0x00},   /* 100MHz */
-       {0x0E, 0x09, 0x06, 0x04, 0x02, 0x01, 0x00}    /* 133MHz */
-};
-
-/* JCSTWTM/JCSTWTS  */
-static unsigned long JCSTWTxtbl[2][7] = {
-       {0x06, 0x04, 0x03, 0x02, 0x02, 0x02, 0x00},   /* 100MHz */
-       {0x09, 0x06, 0x04, 0x02, 0x02, 0x02, 0x02}    /* 133MHz */
-};
-
-/* JCTSS */
-static unsigned long JCTSStbl[2][7] = {
-       {0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x00},   /* 100MHz */
-       {0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05}    /* 133MHz */
-};
-
-/* JCENVT */
-static unsigned long JCENVTtbl[2][7] = {
-       {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00},   /* 100MHz */
-       {0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02}    /* 133MHz */
-};
-
-/* JCACTSELS/JCACTSELM */
-static unsigned long JCACTSELtbl[2][7] = {
-       {0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00},   /* 100MHz */
-       {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}    /* 133MHz */
-};
-
-
-static u8 scc_ide_inb(unsigned long port)
-{
-       u32 data = in_be32((void*)port);
-       return (u8)data;
-}
-
-static void scc_exec_command(ide_hwif_t *hwif, u8 cmd)
-{
-       out_be32((void *)hwif->io_ports.command_addr, cmd);
-       eieio();
-       in_be32((void *)(hwif->dma_base + 0x01c));
-       eieio();
-}
-
-static u8 scc_read_status(ide_hwif_t *hwif)
-{
-       return (u8)in_be32((void *)hwif->io_ports.status_addr);
-}
-
-static u8 scc_read_altstatus(ide_hwif_t *hwif)
-{
-       return (u8)in_be32((void *)hwif->io_ports.ctl_addr);
-}
-
-static u8 scc_dma_sff_read_status(ide_hwif_t *hwif)
-{
-       return (u8)in_be32((void *)(hwif->dma_base + 4));
-}
-
-static void scc_write_devctl(ide_hwif_t *hwif, u8 ctl)
-{
-       out_be32((void *)hwif->io_ports.ctl_addr, ctl);
-       eieio();
-       in_be32((void *)(hwif->dma_base + 0x01c));
-       eieio();
-}
-
-static void scc_ide_insw(unsigned long port, void *addr, u32 count)
-{
-       u16 *ptr = (u16 *)addr;
-       while (count--) {
-               *ptr++ = le16_to_cpu(in_be32((void*)port));
-       }
-}
-
-static void scc_ide_insl(unsigned long port, void *addr, u32 count)
-{
-       u16 *ptr = (u16 *)addr;
-       while (count--) {
-               *ptr++ = le16_to_cpu(in_be32((void*)port));
-               *ptr++ = le16_to_cpu(in_be32((void*)port));
-       }
-}
-
-static void scc_ide_outb(u8 addr, unsigned long port)
-{
-       out_be32((void*)port, addr);
-}
-
-static void
-scc_ide_outsw(unsigned long port, void *addr, u32 count)
-{
-       u16 *ptr = (u16 *)addr;
-       while (count--) {
-               out_be32((void*)port, cpu_to_le16(*ptr++));
-       }
-}
-
-static void
-scc_ide_outsl(unsigned long port, void *addr, u32 count)
-{
-       u16 *ptr = (u16 *)addr;
-       while (count--) {
-               out_be32((void*)port, cpu_to_le16(*ptr++));
-               out_be32((void*)port, cpu_to_le16(*ptr++));
-       }
-}
-
-/**
- *     scc_set_pio_mode        -       set host controller for PIO mode
- *     @hwif: port
- *     @drive: drive
- *
- *     Load the timing settings for this device mode into the
- *     controller.
- */
-
-static void scc_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
-{
-       struct scc_ports *ports = ide_get_hwifdata(hwif);
-       unsigned long ctl_base = ports->ctl;
-       unsigned long cckctrl_port = ctl_base + 0xff0;
-       unsigned long piosht_port = ctl_base + 0x000;
-       unsigned long pioct_port = ctl_base + 0x004;
-       unsigned long reg;
-       int offset;
-       const u8 pio = drive->pio_mode - XFER_PIO_0;
-
-       reg = in_be32((void __iomem *)cckctrl_port);
-       if (reg & CCKCTRL_ATACLKOEN) {
-               offset = 1; /* 133MHz */
-       } else {
-               offset = 0; /* 100MHz */
-       }
-       reg = JCHSTtbl[offset][pio] << 16 | JCHHTtbl[offset][pio];
-       out_be32((void __iomem *)piosht_port, reg);
-       reg = JCHCTtbl[offset][pio];
-       out_be32((void __iomem *)pioct_port, reg);
-}
-
-/**
- *     scc_set_dma_mode        -       set host controller for DMA mode
- *     @hwif: port
- *     @drive: drive
- *
- *     Load the timing settings for this device mode into the
- *     controller.
- */
-
-static void scc_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
-{
-       struct scc_ports *ports = ide_get_hwifdata(hwif);
-       unsigned long ctl_base = ports->ctl;
-       unsigned long cckctrl_port = ctl_base + 0xff0;
-       unsigned long mdmact_port = ctl_base + 0x008;
-       unsigned long mcrcst_port = ctl_base + 0x00c;
-       unsigned long sdmact_port = ctl_base + 0x010;
-       unsigned long scrcst_port = ctl_base + 0x014;
-       unsigned long udenvt_port = ctl_base + 0x018;
-       unsigned long tdvhsel_port   = ctl_base + 0x020;
-       int is_slave = drive->dn & 1;
-       int offset, idx;
-       unsigned long reg;
-       unsigned long jcactsel;
-       const u8 speed = drive->dma_mode;
-
-       reg = in_be32((void __iomem *)cckctrl_port);
-       if (reg & CCKCTRL_ATACLKOEN) {
-               offset = 1; /* 133MHz */
-       } else {
-               offset = 0; /* 100MHz */
-       }
-
-       idx = speed - XFER_UDMA_0;
-
-       jcactsel = JCACTSELtbl[offset][idx];
-       if (is_slave) {
-               out_be32((void __iomem *)sdmact_port, JCHDCTxtbl[offset][idx]);
-               out_be32((void __iomem *)scrcst_port, JCSTWTxtbl[offset][idx]);
-               jcactsel = jcactsel << 2;
-               out_be32((void __iomem *)tdvhsel_port, (in_be32((void __iomem *)tdvhsel_port) & ~TDVHSEL_SLAVE) | jcactsel);
-       } else {
-               out_be32((void __iomem *)mdmact_port, JCHDCTxtbl[offset][idx]);
-               out_be32((void __iomem *)mcrcst_port, JCSTWTxtbl[offset][idx]);
-               out_be32((void __iomem *)tdvhsel_port, (in_be32((void __iomem *)tdvhsel_port) & ~TDVHSEL_MASTER) | jcactsel);
-       }
-       reg = JCTSStbl[offset][idx] << 16 | JCENVTtbl[offset][idx];
-       out_be32((void __iomem *)udenvt_port, reg);
-}
-
-static void scc_dma_host_set(ide_drive_t *drive, int on)
-{
-       ide_hwif_t *hwif = drive->hwif;
-       u8 unit = drive->dn & 1;
-       u8 dma_stat = scc_dma_sff_read_status(hwif);
-
-       if (on)
-               dma_stat |= (1 << (5 + unit));
-       else
-               dma_stat &= ~(1 << (5 + unit));
-
-       scc_ide_outb(dma_stat, hwif->dma_base + 4);
-}
-
-/**
- *     scc_dma_setup   -       begin a DMA phase
- *     @drive: target device
- *     @cmd: command
- *
- *     Build an IDE DMA PRD (IDE speak for scatter gather table)
- *     and then set up the DMA transfer registers.
- *
- *     Returns 0 on success. If a PIO fallback is required then 1
- *     is returned.
- */
-
-static int scc_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
-{
-       ide_hwif_t *hwif = drive->hwif;
-       u32 rw = (cmd->tf_flags & IDE_TFLAG_WRITE) ? 0 : ATA_DMA_WR;
-       u8 dma_stat;
-
-       /* fall back to pio! */
-       if (ide_build_dmatable(drive, cmd) == 0)
-               return 1;
-
-       /* PRD table */
-       out_be32((void __iomem *)(hwif->dma_base + 8), hwif->dmatable_dma);
-
-       /* specify r/w */
-       out_be32((void __iomem *)hwif->dma_base, rw);
-
-       /* read DMA status for INTR & ERROR flags */
-       dma_stat = scc_dma_sff_read_status(hwif);
-
-       /* clear INTR & ERROR flags */
-       out_be32((void __iomem *)(hwif->dma_base + 4), dma_stat | 6);
-
-       return 0;
-}
-
-static void scc_dma_start(ide_drive_t *drive)
-{
-       ide_hwif_t *hwif = drive->hwif;
-       u8 dma_cmd = scc_ide_inb(hwif->dma_base);
-
-       /* start DMA */
-       scc_ide_outb(dma_cmd | 1, hwif->dma_base);
-}
-
-static int __scc_dma_end(ide_drive_t *drive)
-{
-       ide_hwif_t *hwif = drive->hwif;
-       u8 dma_stat, dma_cmd;
-
-       /* get DMA command mode */
-       dma_cmd = scc_ide_inb(hwif->dma_base);
-       /* stop DMA */
-       scc_ide_outb(dma_cmd & ~1, hwif->dma_base);
-       /* get DMA status */
-       dma_stat = scc_dma_sff_read_status(hwif);
-       /* clear the INTR & ERROR bits */
-       scc_ide_outb(dma_stat | 6, hwif->dma_base + 4);
-       /* verify good DMA status */
-       return (dma_stat & 7) != 4 ? (0x10 | dma_stat) : 0;
-}
-
-/**
- *     scc_dma_end     -       Stop DMA
- *     @drive: IDE drive
- *
- *     Check and clear INT Status register.
- *     Then call __scc_dma_end().
- */
-
-static int scc_dma_end(ide_drive_t *drive)
-{
-       ide_hwif_t *hwif = drive->hwif;
-       void __iomem *dma_base = (void __iomem *)hwif->dma_base;
-       unsigned long intsts_port = hwif->dma_base + 0x014;
-       u32 reg;
-       int dma_stat, data_loss = 0;
-       static int retry = 0;
-
-       /* errata A308 workaround: Step5 (check data loss) */
-       /* We don't check non ide_disk because it is limited to UDMA4 */
-       if (!(in_be32((void __iomem *)hwif->io_ports.ctl_addr)
-             & ATA_ERR) &&
-           drive->media == ide_disk && drive->current_speed > XFER_UDMA_4) {
-               reg = in_be32((void __iomem *)intsts_port);
-               if (!(reg & INTSTS_ACTEINT)) {
-                       printk(KERN_WARNING "%s: operation failed (transfer data loss)\n",
-                              drive->name);
-                       data_loss = 1;
-                       if (retry++) {
-                               struct request *rq = hwif->rq;
-                               ide_drive_t *drive;
-                               int i;
-
-                               /* ERROR_RESET and drive->crc_count are needed
-                                * to reduce DMA transfer mode in retry process.
-                                */
-                               if (rq)
-                                       rq->errors |= ERROR_RESET;
-
-                               ide_port_for_each_dev(i, drive, hwif)
-                                       drive->crc_count++;
-                       }
-               }
-       }
-
-       while (1) {
-               reg = in_be32((void __iomem *)intsts_port);
-
-               if (reg & INTSTS_SERROR) {
-                       printk(KERN_WARNING "%s: SERROR\n", SCC_PATA_NAME);
-                       out_be32((void __iomem *)intsts_port, INTSTS_SERROR|INTSTS_BMSINT);
-
-                       out_be32(dma_base, in_be32(dma_base) & ~QCHCD_IOS_SS);
-                       continue;
-               }
-
-               if (reg & INTSTS_PRERR) {
-                       u32 maea0, maec0;
-                       unsigned long ctl_base = hwif->config_data;
-
-                       maea0 = in_be32((void __iomem *)(ctl_base + 0xF50));
-                       maec0 = in_be32((void __iomem *)(ctl_base + 0xF54));
-
-                       printk(KERN_WARNING "%s: PRERR [addr:%x cmd:%x]\n", SCC_PATA_NAME, maea0, maec0);
-
-                       out_be32((void __iomem *)intsts_port, INTSTS_PRERR|INTSTS_BMSINT);
-
-                       out_be32(dma_base, in_be32(dma_base) & ~QCHCD_IOS_SS);
-                       continue;
-               }
-
-               if (reg & INTSTS_RERR) {
-                       printk(KERN_WARNING "%s: Response Error\n", SCC_PATA_NAME);
-                       out_be32((void __iomem *)intsts_port, INTSTS_RERR|INTSTS_BMSINT);
-
-                       out_be32(dma_base, in_be32(dma_base) & ~QCHCD_IOS_SS);
-                       continue;
-               }
-
-               if (reg & INTSTS_ICERR) {
-                       out_be32(dma_base, in_be32(dma_base) & ~QCHCD_IOS_SS);
-
-                       printk(KERN_WARNING "%s: Illegal Configuration\n", SCC_PATA_NAME);
-                       out_be32((void __iomem *)intsts_port, INTSTS_ICERR|INTSTS_BMSINT);
-                       continue;
-               }
-
-               if (reg & INTSTS_BMSINT) {
-                       printk(KERN_WARNING "%s: Internal Bus Error\n", SCC_PATA_NAME);
-                       out_be32((void __iomem *)intsts_port, INTSTS_BMSINT);
-
-                       ide_do_reset(drive);
-                       continue;
-               }
-
-               if (reg & INTSTS_BMHE) {
-                       out_be32((void __iomem *)intsts_port, INTSTS_BMHE);
-                       continue;
-               }
-
-               if (reg & INTSTS_ACTEINT) {
-                       out_be32((void __iomem *)intsts_port, INTSTS_ACTEINT);
-                       continue;
-               }
-
-               if (reg & INTSTS_IOIRQS) {
-                       out_be32((void __iomem *)intsts_port, INTSTS_IOIRQS);
-                       continue;
-               }
-               break;
-       }
-
-       dma_stat = __scc_dma_end(drive);
-       if (data_loss)
-               dma_stat |= 2; /* emulate DMA error (to retry command) */
-       return dma_stat;
-}
-
-/* returns 1 if dma irq issued, 0 otherwise */
-static int scc_dma_test_irq(ide_drive_t *drive)
-{
-       ide_hwif_t *hwif = drive->hwif;
-       u32 int_stat = in_be32((void __iomem *)hwif->dma_base + 0x014);
-
-       /* SCC errata A252,A308 workaround: Step4 */
-       if ((in_be32((void __iomem *)hwif->io_ports.ctl_addr)
-            & ATA_ERR) &&
-           (int_stat & INTSTS_INTRQ))
-               return 1;
-
-       /* SCC errata A308 workaround: Step5 (polling IOIRQS) */
-       if (int_stat & INTSTS_IOIRQS)
-               return 1;
-
-       return 0;
-}
-
-static u8 scc_udma_filter(ide_drive_t *drive)
-{
-       ide_hwif_t *hwif = drive->hwif;
-       u8 mask = hwif->ultra_mask;
-
-       /* errata A308 workaround: limit non ide_disk drive to UDMA4 */
-       if ((drive->media != ide_disk) && (mask & 0xE0)) {
-               printk(KERN_INFO "%s: limit %s to UDMA4\n",
-                      SCC_PATA_NAME, drive->name);
-               mask = ATA_UDMA4;
-       }
-
-       return mask;
-}
-
-/**
- *     setup_mmio_scc  -       map CTRL/BMID region
- *     @dev: PCI device we are configuring
- *     @name: device name
- *
- */
-
-static int setup_mmio_scc (struct pci_dev *dev, const char *name)
-{
-       void __iomem *ctl_addr;
-       void __iomem *dma_addr;
-       int i, ret;
-
-       for (i = 0; i < MAX_HWIFS; i++) {
-               if (scc_ports[i].ctl == 0)
-                       break;
-       }
-       if (i >= MAX_HWIFS)
-               return -ENOMEM;
-
-       ret = pci_request_selected_regions(dev, (1 << 2) - 1, name);
-       if (ret < 0) {
-               printk(KERN_ERR "%s: can't reserve resources\n", name);
-               return ret;
-       }
-
-       ctl_addr = pci_ioremap_bar(dev, 0);
-       if (!ctl_addr)
-               goto fail_0;
-
-       dma_addr = pci_ioremap_bar(dev, 1);
-       if (!dma_addr)
-               goto fail_1;
-
-       pci_set_master(dev);
-       scc_ports[i].ctl = (unsigned long)ctl_addr;
-       scc_ports[i].dma = (unsigned long)dma_addr;
-       pci_set_drvdata(dev, (void *) &scc_ports[i]);
-
-       return 1;
-
- fail_1:
-       iounmap(ctl_addr);
- fail_0:
-       return -ENOMEM;
-}
-
-static int scc_ide_setup_pci_device(struct pci_dev *dev,
-                                   const struct ide_port_info *d)
-{
-       struct scc_ports *ports = pci_get_drvdata(dev);
-       struct ide_host *host;
-       struct ide_hw hw, *hws[] = { &hw };
-       int i, rc;
-
-       memset(&hw, 0, sizeof(hw));
-       for (i = 0; i <= 8; i++)
-               hw.io_ports_array[i] = ports->dma + 0x20 + i * 4;
-       hw.irq = dev->irq;
-       hw.dev = &dev->dev;
-
-       rc = ide_host_add(d, hws, 1, &host);
-       if (rc)
-               return rc;
-
-       ports->host = host;
-
-       return 0;
-}
-
-/**
- *     init_setup_scc  -       set up an SCC PATA Controller
- *     @dev: PCI device
- *     @d: IDE port info
- *
- *     Perform the initial set up for this device.
- */
-
-static int init_setup_scc(struct pci_dev *dev, const struct ide_port_info *d)
-{
-       unsigned long ctl_base;
-       unsigned long dma_base;
-       unsigned long cckctrl_port;
-       unsigned long intmask_port;
-       unsigned long mode_port;
-       unsigned long ecmode_port;
-       u32 reg = 0;
-       struct scc_ports *ports;
-       int rc;
-
-       rc = pci_enable_device(dev);
-       if (rc)
-               goto end;
-
-       rc = setup_mmio_scc(dev, d->name);
-       if (rc < 0)
-               goto end;
-
-       ports = pci_get_drvdata(dev);
-       ctl_base = ports->ctl;
-       dma_base = ports->dma;
-       cckctrl_port = ctl_base + 0xff0;
-       intmask_port = dma_base + 0x010;
-       mode_port = ctl_base + 0x024;
-       ecmode_port = ctl_base + 0xf00;
-
-       /* controller initialization */
-       reg = 0;
-       out_be32((void*)cckctrl_port, reg);
-       reg |= CCKCTRL_ATACLKOEN;
-       out_be32((void*)cckctrl_port, reg);
-       reg |= CCKCTRL_LCLKEN | CCKCTRL_OCLKEN;
-       out_be32((void*)cckctrl_port, reg);
-       reg |= CCKCTRL_CRST;
-       out_be32((void*)cckctrl_port, reg);
-
-       for (;;) {
-               reg = in_be32((void*)cckctrl_port);
-               if (reg & CCKCTRL_CRST)
-                       break;
-               udelay(5000);
-       }
-
-       reg |= CCKCTRL_ATARESET;
-       out_be32((void*)cckctrl_port, reg);
-
-       out_be32((void*)ecmode_port, ECMODE_VALUE);
-       out_be32((void*)mode_port, MODE_JCUSFEN);
-       out_be32((void*)intmask_port, INTMASK_MSK);
-
-       rc = scc_ide_setup_pci_device(dev, d);
-
- end:
-       return rc;
-}
-
-static void scc_tf_load(ide_drive_t *drive, struct ide_taskfile *tf, u8 valid)
-{
-       struct ide_io_ports *io_ports = &drive->hwif->io_ports;
-
-       if (valid & IDE_VALID_FEATURE)
-               scc_ide_outb(tf->feature, io_ports->feature_addr);
-       if (valid & IDE_VALID_NSECT)
-               scc_ide_outb(tf->nsect, io_ports->nsect_addr);
-       if (valid & IDE_VALID_LBAL)
-               scc_ide_outb(tf->lbal, io_ports->lbal_addr);
-       if (valid & IDE_VALID_LBAM)
-               scc_ide_outb(tf->lbam, io_ports->lbam_addr);
-       if (valid & IDE_VALID_LBAH)
-               scc_ide_outb(tf->lbah, io_ports->lbah_addr);
-       if (valid & IDE_VALID_DEVICE)
-               scc_ide_outb(tf->device, io_ports->device_addr);
-}
-
-static void scc_tf_read(ide_drive_t *drive, struct ide_taskfile *tf, u8 valid)
-{
-       struct ide_io_ports *io_ports = &drive->hwif->io_ports;
-
-       if (valid & IDE_VALID_ERROR)
-               tf->error  = scc_ide_inb(io_ports->feature_addr);
-       if (valid & IDE_VALID_NSECT)
-               tf->nsect  = scc_ide_inb(io_ports->nsect_addr);
-       if (valid & IDE_VALID_LBAL)
-               tf->lbal   = scc_ide_inb(io_ports->lbal_addr);
-       if (valid & IDE_VALID_LBAM)
-               tf->lbam   = scc_ide_inb(io_ports->lbam_addr);
-       if (valid & IDE_VALID_LBAH)
-               tf->lbah   = scc_ide_inb(io_ports->lbah_addr);
-       if (valid & IDE_VALID_DEVICE)
-               tf->device = scc_ide_inb(io_ports->device_addr);
-}
-
-static void scc_input_data(ide_drive_t *drive, struct ide_cmd *cmd,
-                          void *buf, unsigned int len)
-{
-       unsigned long data_addr = drive->hwif->io_ports.data_addr;
-
-       len++;
-
-       if (drive->io_32bit) {
-               scc_ide_insl(data_addr, buf, len / 4);
-
-               if ((len & 3) >= 2)
-                       scc_ide_insw(data_addr, (u8 *)buf + (len & ~3), 1);
-       } else
-               scc_ide_insw(data_addr, buf, len / 2);
-}
-
-static void scc_output_data(ide_drive_t *drive,  struct ide_cmd *cmd,
-                           void *buf, unsigned int len)
-{
-       unsigned long data_addr = drive->hwif->io_ports.data_addr;
-
-       len++;
-
-       if (drive->io_32bit) {
-               scc_ide_outsl(data_addr, buf, len / 4);
-
-               if ((len & 3) >= 2)
-                       scc_ide_outsw(data_addr, (u8 *)buf + (len & ~3), 1);
-       } else
-               scc_ide_outsw(data_addr, buf, len / 2);
-}
-
-/**
- *     init_mmio_iops_scc      -       set up the iops for MMIO
- *     @hwif: interface to set up
- *
- */
-
-static void init_mmio_iops_scc(ide_hwif_t *hwif)
-{
-       struct pci_dev *dev = to_pci_dev(hwif->dev);
-       struct scc_ports *ports = pci_get_drvdata(dev);
-       unsigned long dma_base = ports->dma;
-
-       ide_set_hwifdata(hwif, ports);
-
-       hwif->dma_base = dma_base;
-       hwif->config_data = ports->ctl;
-}
-
-/**
- *     init_iops_scc   -       set up iops
- *     @hwif: interface to set up
- *
- *     Do the basic setup for the SCC hardware interface
- *     and then do the MMIO setup.
- */
-
-static void init_iops_scc(ide_hwif_t *hwif)
-{
-       struct pci_dev *dev = to_pci_dev(hwif->dev);
-
-       hwif->hwif_data = NULL;
-       if (pci_get_drvdata(dev) == NULL)
-               return;
-       init_mmio_iops_scc(hwif);
-}
-
-static int scc_init_dma(ide_hwif_t *hwif, const struct ide_port_info *d)
-{
-       return ide_allocate_dma_engine(hwif);
-}
-
-static u8 scc_cable_detect(ide_hwif_t *hwif)
-{
-       return ATA_CBL_PATA80;
-}
-
-/**
- *     init_hwif_scc   -       set up hwif
- *     @hwif: interface to set up
- *
- *     We do the basic set up of the interface structure. The SCC
- *     requires several custom handlers so we override the default
- *     ide DMA handlers appropriately.
- */
-
-static void init_hwif_scc(ide_hwif_t *hwif)
-{
-       /* PTERADD */
-       out_be32((void __iomem *)(hwif->dma_base + 0x018), hwif->dmatable_dma);
-
-       if (in_be32((void __iomem *)(hwif->config_data + 0xff0)) & CCKCTRL_ATACLKOEN)
-               hwif->ultra_mask = ATA_UDMA6; /* 133MHz */
-       else
-               hwif->ultra_mask = ATA_UDMA5; /* 100MHz */
-}
-
-static const struct ide_tp_ops scc_tp_ops = {
-       .exec_command           = scc_exec_command,
-       .read_status            = scc_read_status,
-       .read_altstatus         = scc_read_altstatus,
-       .write_devctl           = scc_write_devctl,
-
-       .dev_select             = ide_dev_select,
-       .tf_load                = scc_tf_load,
-       .tf_read                = scc_tf_read,
-
-       .input_data             = scc_input_data,
-       .output_data            = scc_output_data,
-};
-
-static const struct ide_port_ops scc_port_ops = {
-       .set_pio_mode           = scc_set_pio_mode,
-       .set_dma_mode           = scc_set_dma_mode,
-       .udma_filter            = scc_udma_filter,
-       .cable_detect           = scc_cable_detect,
-};
-
-static const struct ide_dma_ops scc_dma_ops = {
-       .dma_host_set           = scc_dma_host_set,
-       .dma_setup              = scc_dma_setup,
-       .dma_start              = scc_dma_start,
-       .dma_end                = scc_dma_end,
-       .dma_test_irq           = scc_dma_test_irq,
-       .dma_lost_irq           = ide_dma_lost_irq,
-       .dma_timer_expiry       = ide_dma_sff_timer_expiry,
-       .dma_sff_read_status    = scc_dma_sff_read_status,
-};
-
-static const struct ide_port_info scc_chipset = {
-       .name           = "sccIDE",
-       .init_iops      = init_iops_scc,
-       .init_dma       = scc_init_dma,
-       .init_hwif      = init_hwif_scc,
-       .tp_ops         = &scc_tp_ops,
-       .port_ops       = &scc_port_ops,
-       .dma_ops        = &scc_dma_ops,
-       .host_flags     = IDE_HFLAG_SINGLE,
-       .irq_flags      = IRQF_SHARED,
-       .pio_mask       = ATA_PIO4,
-       .chipset        = ide_pci,
-};
-
-/**
- *     scc_init_one    -       pci layer discovery entry
- *     @dev: PCI device
- *     @id: ident table entry
- *
- *     Called by the PCI code when it finds an SCC PATA controller.
- *     We then use the IDE PCI generic helper to do most of the work.
- */
-
-static int scc_init_one(struct pci_dev *dev, const struct pci_device_id *id)
-{
-       return init_setup_scc(dev, &scc_chipset);
-}
-
-/**
- *     scc_remove      -       pci layer remove entry
- *     @dev: PCI device
- *
- *     Called by the PCI code when it removes an SCC PATA controller.
- */
-
-static void scc_remove(struct pci_dev *dev)
-{
-       struct scc_ports *ports = pci_get_drvdata(dev);
-       struct ide_host *host = ports->host;
-
-       ide_host_remove(host);
-
-       iounmap((void*)ports->dma);
-       iounmap((void*)ports->ctl);
-       pci_release_selected_regions(dev, (1 << 2) - 1);
-       memset(ports, 0, sizeof(*ports));
-}
-
-static const struct pci_device_id scc_pci_tbl[] = {
-       { PCI_VDEVICE(TOSHIBA_2, PCI_DEVICE_ID_TOSHIBA_SCC_ATA), 0 },
-       { 0, },
-};
-MODULE_DEVICE_TABLE(pci, scc_pci_tbl);
-
-static struct pci_driver scc_pci_driver = {
-       .name = "SCC IDE",
-       .id_table = scc_pci_tbl,
-       .probe = scc_init_one,
-       .remove = scc_remove,
-};
-
-static int __init scc_ide_init(void)
-{
-       return ide_pci_register_driver(&scc_pci_driver);
-}
-
-static void __exit scc_ide_exit(void)
-{
-       pci_unregister_driver(&scc_pci_driver);
-}
-
-module_init(scc_ide_init);
-module_exit(scc_ide_exit);
-
-MODULE_DESCRIPTION("PCI driver module for Toshiba SCC IDE");
-MODULE_LICENSE("GPL");
index 7f55a6d7cd035d5e7d2fbad512ce60f3465508e2..c6d5a3a40b609c9044fb57846fca951eabfe199b 100644 (file)
@@ -389,7 +389,12 @@ int mma9551_read_config_words(struct i2c_client *client, u8 app_id,
 {
        int ret, i;
        int len_words = len / sizeof(u16);
-       __be16 be_buf[MMA9551_MAX_MAILBOX_DATA_REGS];
+       __be16 be_buf[MMA9551_MAX_MAILBOX_DATA_REGS / 2];
+
+       if (len_words > ARRAY_SIZE(be_buf)) {
+               dev_err(&client->dev, "Invalid buffer size %d\n", len);
+               return -EINVAL;
+       }
 
        ret = mma9551_transfer(client, app_id, MMA9551_CMD_READ_CONFIG,
                               reg, NULL, 0, (u8 *) be_buf, len);
@@ -424,7 +429,12 @@ int mma9551_read_status_words(struct i2c_client *client, u8 app_id,
 {
        int ret, i;
        int len_words = len / sizeof(u16);
-       __be16 be_buf[MMA9551_MAX_MAILBOX_DATA_REGS];
+       __be16 be_buf[MMA9551_MAX_MAILBOX_DATA_REGS / 2];
+
+       if (len_words > ARRAY_SIZE(be_buf)) {
+               dev_err(&client->dev, "Invalid buffer size %d\n", len);
+               return -EINVAL;
+       }
 
        ret = mma9551_transfer(client, app_id, MMA9551_CMD_READ_STATUS,
                               reg, NULL, 0, (u8 *) be_buf, len);
@@ -459,7 +469,12 @@ int mma9551_write_config_words(struct i2c_client *client, u8 app_id,
 {
        int i;
        int len_words = len / sizeof(u16);
-       __be16 be_buf[MMA9551_MAX_MAILBOX_DATA_REGS];
+       __be16 be_buf[(MMA9551_MAX_MAILBOX_DATA_REGS - 1) / 2];
+
+       if (len_words > ARRAY_SIZE(be_buf)) {
+               dev_err(&client->dev, "Invalid buffer size %d\n", len);
+               return -EINVAL;
+       }
 
        for (i = 0; i < len_words; i++)
                be_buf[i] = cpu_to_be16(buf[i]);
index 2df1af7d43fc6df34b87f80373e413152e33a739..365a109aaaefe8f5367c8de6a1f0e2ccfc9bf463 100644 (file)
@@ -54,6 +54,7 @@
 #define MMA9553_MASK_CONF_STEPCOALESCE         GENMASK(7, 0)
 
 #define MMA9553_REG_CONF_ACTTHD                        0x0E
+#define MMA9553_MAX_ACTTHD                     GENMASK(15, 0)
 
 /* Pedometer status registers (R-only) */
 #define MMA9553_REG_STATUS                     0x00
@@ -316,22 +317,19 @@ static int mma9553_set_config(struct mma9553_data *data, u16 reg,
 static int mma9553_read_activity_stepcnt(struct mma9553_data *data,
                                         u8 *activity, u16 *stepcnt)
 {
-       u32 status_stepcnt;
-       u16 status;
+       u16 buf[2];
        int ret;
 
        ret = mma9551_read_status_words(data->client, MMA9551_APPID_PEDOMETER,
-                                       MMA9553_REG_STATUS, sizeof(u32),
-                                       (u16 *) &status_stepcnt);
+                                       MMA9553_REG_STATUS, sizeof(u32), buf);
        if (ret < 0) {
                dev_err(&data->client->dev,
                        "error reading status and stepcnt\n");
                return ret;
        }
 
-       status = status_stepcnt & MMA9553_MASK_CONF_WORD;
-       *activity = mma9553_get_bits(status, MMA9553_MASK_STATUS_ACTIVITY);
-       *stepcnt = status_stepcnt >> 16;
+       *activity = mma9553_get_bits(buf[0], MMA9553_MASK_STATUS_ACTIVITY);
+       *stepcnt = buf[1];
 
        return 0;
 }
@@ -872,6 +870,9 @@ static int mma9553_write_event_value(struct iio_dev *indio_dev,
        case IIO_EV_INFO_PERIOD:
                switch (chan->type) {
                case IIO_ACTIVITY:
+                       if (val < 0 || val > MMA9553_ACTIVITY_THD_TO_SEC(
+                           MMA9553_MAX_ACTTHD))
+                               return -EINVAL;
                        mutex_lock(&data->mutex);
                        ret = mma9553_set_config(data, MMA9553_REG_CONF_ACTTHD,
                                                 &data->conf.actthd,
@@ -971,7 +972,8 @@ static const struct iio_chan_spec_ext_info mma9553_ext_info[] = {
        .modified = 1,                                                  \
        .channel2 = _chan2,                                             \
        .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),             \
-       .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_CALIBHEIGHT),     \
+       .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_CALIBHEIGHT) |    \
+                                   BIT(IIO_CHAN_INFO_ENABLE),          \
        .event_spec = mma9553_activity_events,                          \
        .num_event_specs = ARRAY_SIZE(mma9553_activity_events),         \
        .ext_info = mma9553_ext_info,                                   \
index 58d1d13d552ae8cf336061f93603e4dd07b222ac..211b13271c61566c5d3f3d4e9990bcd3c7470823 100644 (file)
@@ -546,6 +546,7 @@ int st_accel_common_probe(struct iio_dev *indio_dev)
 
        indio_dev->modes = INDIO_DIRECT_MODE;
        indio_dev->info = &accel_info;
+       mutex_init(&adata->tb.buf_lock);
 
        st_sensors_power_enable(indio_dev);
 
index 08bcfb061ca5617505a47d9fa96b5f762b867f63..56008a86b78f854229943769307ce2fd2c328201 100644 (file)
@@ -53,39 +53,42 @@ static const struct iio_chan_spec const axp288_adc_channels[] = {
                .channel = 0,
                .address = AXP288_TS_ADC_H,
                .datasheet_name = "TS_PIN",
+               .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
        }, {
                .indexed = 1,
                .type = IIO_TEMP,
                .channel = 1,
                .address = AXP288_PMIC_ADC_H,
                .datasheet_name = "PMIC_TEMP",
+               .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
        }, {
                .indexed = 1,
                .type = IIO_TEMP,
                .channel = 2,
                .address = AXP288_GP_ADC_H,
                .datasheet_name = "GPADC",
+               .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
        }, {
                .indexed = 1,
                .type = IIO_CURRENT,
                .channel = 3,
                .address = AXP20X_BATT_CHRG_I_H,
                .datasheet_name = "BATT_CHG_I",
-               .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
+               .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
        }, {
                .indexed = 1,
                .type = IIO_CURRENT,
                .channel = 4,
                .address = AXP20X_BATT_DISCHRG_I_H,
                .datasheet_name = "BATT_DISCHRG_I",
-               .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
+               .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
        }, {
                .indexed = 1,
                .type = IIO_VOLTAGE,
                .channel = 5,
                .address = AXP20X_BATT_V_H,
                .datasheet_name = "BATT_V",
-               .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
+               .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
        },
 };
 
@@ -151,9 +154,6 @@ static int axp288_adc_read_raw(struct iio_dev *indio_dev,
                                                chan->address))
                        dev_err(&indio_dev->dev, "TS pin restore\n");
                break;
-       case IIO_CHAN_INFO_PROCESSED:
-               ret = axp288_adc_read_channel(val, chan->address, info->regmap);
-               break;
        default:
                ret = -EINVAL;
        }
index 51e2a83c9404ca3ddc0a24d64ffa47f6090500ba..115f6e99a7fa7c603ca9655d04759545c48e5932 100644 (file)
@@ -35,8 +35,9 @@
 #define CC10001_ADC_EOC_SET            BIT(0)
 
 #define CC10001_ADC_CHSEL_SAMPLED      0x0c
-#define CC10001_ADC_POWER_UP           0x10
-#define CC10001_ADC_POWER_UP_SET       BIT(0)
+#define CC10001_ADC_POWER_DOWN         0x10
+#define CC10001_ADC_POWER_DOWN_SET     BIT(0)
+
 #define CC10001_ADC_DEBUG              0x14
 #define CC10001_ADC_DATA_COUNT         0x20
 
@@ -62,7 +63,6 @@ struct cc10001_adc_device {
        u16 *buf;
 
        struct mutex lock;
-       unsigned long channel_map;
        unsigned int start_delay_ns;
        unsigned int eoc_delay_ns;
 };
@@ -79,6 +79,18 @@ static inline u32 cc10001_adc_read_reg(struct cc10001_adc_device *adc_dev,
        return readl(adc_dev->reg_base + reg);
 }
 
+static void cc10001_adc_power_up(struct cc10001_adc_device *adc_dev)
+{
+       cc10001_adc_write_reg(adc_dev, CC10001_ADC_POWER_DOWN, 0);
+       ndelay(adc_dev->start_delay_ns);
+}
+
+static void cc10001_adc_power_down(struct cc10001_adc_device *adc_dev)
+{
+       cc10001_adc_write_reg(adc_dev, CC10001_ADC_POWER_DOWN,
+                             CC10001_ADC_POWER_DOWN_SET);
+}
+
 static void cc10001_adc_start(struct cc10001_adc_device *adc_dev,
                              unsigned int channel)
 {
@@ -88,6 +100,7 @@ static void cc10001_adc_start(struct cc10001_adc_device *adc_dev,
        val = (channel & CC10001_ADC_CH_MASK) | CC10001_ADC_MODE_SINGLE_CONV;
        cc10001_adc_write_reg(adc_dev, CC10001_ADC_CONFIG, val);
 
+       udelay(1);
        val = cc10001_adc_read_reg(adc_dev, CC10001_ADC_CONFIG);
        val = val | CC10001_ADC_START_CONV;
        cc10001_adc_write_reg(adc_dev, CC10001_ADC_CONFIG, val);
@@ -129,6 +142,7 @@ static irqreturn_t cc10001_adc_trigger_h(int irq, void *p)
        struct iio_dev *indio_dev;
        unsigned int delay_ns;
        unsigned int channel;
+       unsigned int scan_idx;
        bool sample_invalid;
        u16 *data;
        int i;
@@ -139,20 +153,17 @@ static irqreturn_t cc10001_adc_trigger_h(int irq, void *p)
 
        mutex_lock(&adc_dev->lock);
 
-       cc10001_adc_write_reg(adc_dev, CC10001_ADC_POWER_UP,
-                             CC10001_ADC_POWER_UP_SET);
-
-       /* Wait for 8 (6+2) clock cycles before activating START */
-       ndelay(adc_dev->start_delay_ns);
+       cc10001_adc_power_up(adc_dev);
 
        /* Calculate delay step for eoc and sampled data */
        delay_ns = adc_dev->eoc_delay_ns / CC10001_MAX_POLL_COUNT;
 
        i = 0;
        sample_invalid = false;
-       for_each_set_bit(channel, indio_dev->active_scan_mask,
+       for_each_set_bit(scan_idx, indio_dev->active_scan_mask,
                                  indio_dev->masklength) {
 
+               channel = indio_dev->channels[scan_idx].channel;
                cc10001_adc_start(adc_dev, channel);
 
                data[i] = cc10001_adc_poll_done(indio_dev, channel, delay_ns);
@@ -166,7 +177,7 @@ static irqreturn_t cc10001_adc_trigger_h(int irq, void *p)
        }
 
 done:
-       cc10001_adc_write_reg(adc_dev, CC10001_ADC_POWER_UP, 0);
+       cc10001_adc_power_down(adc_dev);
 
        mutex_unlock(&adc_dev->lock);
 
@@ -185,11 +196,7 @@ static u16 cc10001_adc_read_raw_voltage(struct iio_dev *indio_dev,
        unsigned int delay_ns;
        u16 val;
 
-       cc10001_adc_write_reg(adc_dev, CC10001_ADC_POWER_UP,
-                             CC10001_ADC_POWER_UP_SET);
-
-       /* Wait for 8 (6+2) clock cycles before activating START */
-       ndelay(adc_dev->start_delay_ns);
+       cc10001_adc_power_up(adc_dev);
 
        /* Calculate delay step for eoc and sampled data */
        delay_ns = adc_dev->eoc_delay_ns / CC10001_MAX_POLL_COUNT;
@@ -198,7 +205,7 @@ static u16 cc10001_adc_read_raw_voltage(struct iio_dev *indio_dev,
 
        val = cc10001_adc_poll_done(indio_dev, chan->channel, delay_ns);
 
-       cc10001_adc_write_reg(adc_dev, CC10001_ADC_POWER_UP, 0);
+       cc10001_adc_power_down(adc_dev);
 
        return val;
 }
@@ -224,7 +231,7 @@ static int cc10001_adc_read_raw(struct iio_dev *indio_dev,
 
        case IIO_CHAN_INFO_SCALE:
                ret = regulator_get_voltage(adc_dev->reg);
-               if (ret)
+               if (ret < 0)
                        return ret;
 
                *val = ret / 1000;
@@ -255,22 +262,22 @@ static const struct iio_info cc10001_adc_info = {
        .update_scan_mode = &cc10001_update_scan_mode,
 };
 
-static int cc10001_adc_channel_init(struct iio_dev *indio_dev)
+static int cc10001_adc_channel_init(struct iio_dev *indio_dev,
+                                   unsigned long channel_map)
 {
-       struct cc10001_adc_device *adc_dev = iio_priv(indio_dev);
        struct iio_chan_spec *chan_array, *timestamp;
        unsigned int bit, idx = 0;
 
-       indio_dev->num_channels = bitmap_weight(&adc_dev->channel_map,
-                                               CC10001_ADC_NUM_CHANNELS);
+       indio_dev->num_channels = bitmap_weight(&channel_map,
+                                               CC10001_ADC_NUM_CHANNELS) + 1;
 
-       chan_array = devm_kcalloc(&indio_dev->dev, indio_dev->num_channels + 1,
+       chan_array = devm_kcalloc(&indio_dev->dev, indio_dev->num_channels,
                                  sizeof(struct iio_chan_spec),
                                  GFP_KERNEL);
        if (!chan_array)
                return -ENOMEM;
 
-       for_each_set_bit(bit, &adc_dev->channel_map, CC10001_ADC_NUM_CHANNELS) {
+       for_each_set_bit(bit, &channel_map, CC10001_ADC_NUM_CHANNELS) {
                struct iio_chan_spec *chan = &chan_array[idx];
 
                chan->type = IIO_VOLTAGE;
@@ -305,6 +312,7 @@ static int cc10001_adc_probe(struct platform_device *pdev)
        unsigned long adc_clk_rate;
        struct resource *res;
        struct iio_dev *indio_dev;
+       unsigned long channel_map;
        int ret;
 
        indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*adc_dev));
@@ -313,9 +321,9 @@ static int cc10001_adc_probe(struct platform_device *pdev)
 
        adc_dev = iio_priv(indio_dev);
 
-       adc_dev->channel_map = GENMASK(CC10001_ADC_NUM_CHANNELS - 1, 0);
+       channel_map = GENMASK(CC10001_ADC_NUM_CHANNELS - 1, 0);
        if (!of_property_read_u32(node, "adc-reserved-channels", &ret))
-               adc_dev->channel_map &= ~ret;
+               channel_map &= ~ret;
 
        adc_dev->reg = devm_regulator_get(&pdev->dev, "vref");
        if (IS_ERR(adc_dev->reg))
@@ -361,7 +369,7 @@ static int cc10001_adc_probe(struct platform_device *pdev)
        adc_dev->start_delay_ns = adc_dev->eoc_delay_ns * CC10001_WAIT_CYCLES;
 
        /* Setup the ADC channels available on the device */
-       ret = cc10001_adc_channel_init(indio_dev);
+       ret = cc10001_adc_channel_init(indio_dev, channel_map);
        if (ret < 0)
                goto err_disable_clk;
 
index efbfd12a4bfdd9f764732d976a2650719408552c..8d9c9b9215ddc1ef5530df512d475a618cb71d8f 100644 (file)
@@ -60,12 +60,12 @@ struct mcp320x {
        struct spi_message msg;
        struct spi_transfer transfer[2];
 
-       u8 tx_buf;
-       u8 rx_buf[2];
-
        struct regulator *reg;
        struct mutex lock;
        const struct mcp320x_chip_info *chip_info;
+
+       u8 tx_buf ____cacheline_aligned;
+       u8 rx_buf[2];
 };
 
 static int mcp320x_channel_to_tx_data(int device_index,
index 3211729bcb0bd2fa3a53629c4e78c2c9c37579a2..0c4618b4d51549cb7bfe8fead1e3ce61c1882366 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/iio/iio.h>
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
+#include <linux/math64.h>
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/platform_device.h>
@@ -471,11 +472,11 @@ static s32 vadc_calibrate(struct vadc_priv *vadc,
                          const struct vadc_channel_prop *prop, u16 adc_code)
 {
        const struct vadc_prescale_ratio *prescale;
-       s32 voltage;
+       s64 voltage;
 
        voltage = adc_code - vadc->graph[prop->calibration].gnd;
        voltage *= vadc->graph[prop->calibration].dx;
-       voltage = voltage / vadc->graph[prop->calibration].dy;
+       voltage = div64_s64(voltage, vadc->graph[prop->calibration].dy);
 
        if (prop->calibration == VADC_CALIB_ABSOLUTE)
                voltage += vadc->graph[prop->calibration].dx;
@@ -487,7 +488,7 @@ static s32 vadc_calibrate(struct vadc_priv *vadc,
 
        voltage = voltage * prescale->den;
 
-       return voltage / prescale->num;
+       return div64_s64(voltage, prescale->num);
 }
 
 static int vadc_decimation_from_dt(u32 value)
index a221f7329b7914449492f7a287f6524d4770a4c3..ce93bd8e3f68b82fec81b31f8f1885b908ef0b45 100644 (file)
@@ -856,6 +856,7 @@ static int xadc_read_raw(struct iio_dev *indio_dev,
                        switch (chan->address) {
                        case XADC_REG_VCCINT:
                        case XADC_REG_VCCAUX:
+                       case XADC_REG_VREFP:
                        case XADC_REG_VCCBRAM:
                        case XADC_REG_VCCPINT:
                        case XADC_REG_VCCPAUX:
@@ -996,7 +997,7 @@ static const struct iio_event_spec xadc_voltage_events[] = {
        .num_event_specs = (_alarm) ? ARRAY_SIZE(xadc_voltage_events) : 0, \
        .scan_index = (_scan_index), \
        .scan_type = { \
-               .sign = 'u', \
+               .sign = ((_addr) == XADC_REG_VREFN) ? 's' : 'u', \
                .realbits = 12, \
                .storagebits = 16, \
                .shift = 4, \
@@ -1008,7 +1009,7 @@ static const struct iio_event_spec xadc_voltage_events[] = {
 static const struct iio_chan_spec xadc_channels[] = {
        XADC_CHAN_TEMP(0, 8, XADC_REG_TEMP),
        XADC_CHAN_VOLTAGE(0, 9, XADC_REG_VCCINT, "vccint", true),
-       XADC_CHAN_VOLTAGE(1, 10, XADC_REG_VCCINT, "vccaux", true),
+       XADC_CHAN_VOLTAGE(1, 10, XADC_REG_VCCAUX, "vccaux", true),
        XADC_CHAN_VOLTAGE(2, 14, XADC_REG_VCCBRAM, "vccbram", true),
        XADC_CHAN_VOLTAGE(3, 5, XADC_REG_VCCPINT, "vccpint", true),
        XADC_CHAN_VOLTAGE(4, 6, XADC_REG_VCCPAUX, "vccpaux", true),
index c7487e8d7f809f24b5616365408c5301fea196ad..54adc5087210bb173afd62bfa36712e4a014eafb 100644 (file)
@@ -145,9 +145,9 @@ static inline int xadc_write_adc_reg(struct xadc *xadc, unsigned int reg,
 #define XADC_REG_MAX_VCCPINT   0x28
 #define XADC_REG_MAX_VCCPAUX   0x29
 #define XADC_REG_MAX_VCCO_DDR  0x2a
-#define XADC_REG_MIN_VCCPINT   0x2b
-#define XADC_REG_MIN_VCCPAUX   0x2c
-#define XADC_REG_MIN_VCCO_DDR  0x2d
+#define XADC_REG_MIN_VCCPINT   0x2c
+#define XADC_REG_MIN_VCCPAUX   0x2d
+#define XADC_REG_MIN_VCCO_DDR  0x2e
 
 #define XADC_REG_CONF0         0x40
 #define XADC_REG_CONF1         0x41
index edd13d2b4121f7834c2e90eaca02e7a4f70c51b7..8dd0477e201c192bed10a8c5384f012bfe083ff8 100644 (file)
@@ -304,8 +304,6 @@ int st_sensors_init_sensor(struct iio_dev *indio_dev,
        struct st_sensors_platform_data *of_pdata;
        int err = 0;
 
-       mutex_init(&sdata->tb.buf_lock);
-
        /* If OF/DT pdata exists, it will take precedence of anything else */
        of_pdata = st_sensors_of_probe(indio_dev->dev.parent, pdata);
        if (of_pdata)
index 21395f26d2276548567dfd118f37c22087a0d1ce..ffe96642b6d049569d73356a1df541782657a912 100644 (file)
@@ -400,6 +400,7 @@ int st_gyro_common_probe(struct iio_dev *indio_dev)
 
        indio_dev->modes = INDIO_DIRECT_MODE;
        indio_dev->info = &gyro_info;
+       mutex_init(&gdata->tb.buf_lock);
 
        st_sensors_power_enable(indio_dev);
 
index 847ca561afe014e83707d04eaef02054f9b2bbfa..55c267bbfd2f9293340fa2851bcf5cb245b22cc9 100644 (file)
@@ -38,7 +38,8 @@ static int iio_request_update_kfifo(struct iio_buffer *r)
                kfifo_free(&buf->kf);
                ret = __iio_allocate_kfifo(buf, buf->buffer.bytes_per_datum,
                                   buf->buffer.length);
-               buf->update_needed = false;
+               if (ret >= 0)
+                       buf->update_needed = false;
        } else {
                kfifo_reset_out(&buf->kf);
        }
index 91ecc46ffeaa0b9e5ecf25d3575d8ab364e4abe8..ef60bae738e344c510d529578051f7767eba7916 100644 (file)
@@ -43,8 +43,6 @@ struct prox_state {
 static const struct iio_chan_spec prox_channels[] = {
        {
                .type = IIO_PROXIMITY,
-               .modified = 1,
-               .channel2 = IIO_NO_MOD,
                .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
                .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
                BIT(IIO_CHAN_INFO_SCALE) |
@@ -253,7 +251,6 @@ static int hid_prox_probe(struct platform_device *pdev)
        struct iio_dev *indio_dev;
        struct prox_state *prox_state;
        struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data;
-       struct iio_chan_spec *channels;
 
        indio_dev = devm_iio_device_alloc(&pdev->dev,
                                sizeof(struct prox_state));
@@ -272,20 +269,21 @@ static int hid_prox_probe(struct platform_device *pdev)
                return ret;
        }
 
-       channels = kmemdup(prox_channels, sizeof(prox_channels), GFP_KERNEL);
-       if (!channels) {
+       indio_dev->channels = kmemdup(prox_channels, sizeof(prox_channels),
+                                     GFP_KERNEL);
+       if (!indio_dev->channels) {
                dev_err(&pdev->dev, "failed to duplicate channels\n");
                return -ENOMEM;
        }
 
-       ret = prox_parse_report(pdev, hsdev, channels,
+       ret = prox_parse_report(pdev, hsdev,
+                               (struct iio_chan_spec *)indio_dev->channels,
                                HID_USAGE_SENSOR_PROX, prox_state);
        if (ret) {
                dev_err(&pdev->dev, "failed to setup attributes\n");
                goto error_free_dev_mem;
        }
 
-       indio_dev->channels = channels;
        indio_dev->num_channels =
                                ARRAY_SIZE(prox_channels);
        indio_dev->dev.parent = &pdev->dev;
index 8ade473f99fee3ab35cb224eab0f69afebe2bf70..2e56f812a644d67a73f0e9bdccd0992c39777a25 100644 (file)
@@ -369,6 +369,7 @@ int st_magn_common_probe(struct iio_dev *indio_dev)
 
        indio_dev->modes = INDIO_DIRECT_MODE;
        indio_dev->info = &magn_info;
+       mutex_init(&mdata->tb.buf_lock);
 
        st_sensors_power_enable(indio_dev);
 
index 7c623e2bd6336c0968254e73547de8945efe4a42..a2602d8dd6d5ceea974cb1fdada67ddde7a2f129 100644 (file)
@@ -172,6 +172,7 @@ static s32 bmp280_compensate_temp(struct bmp280_data *data,
        var2 = (((((adc_temp >> 4) - ((s32)le16_to_cpu(buf[T1]))) *
                  ((adc_temp >> 4) - ((s32)le16_to_cpu(buf[T1])))) >> 12) *
                ((s32)(s16)le16_to_cpu(buf[T3]))) >> 14;
+       data->t_fine = var1 + var2;
 
        return (data->t_fine * 5 + 128) >> 8;
 }
index 7bb8d4c1f7df4922279dd328ddfc83fba1b113c4..3cf0bd67d24ca8001224f960513bbd93b45be1e5 100644 (file)
@@ -47,8 +47,6 @@ struct press_state {
 static const struct iio_chan_spec press_channels[] = {
        {
                .type = IIO_PRESSURE,
-               .modified = 1,
-               .channel2 = IIO_NO_MOD,
                .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
                .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
                BIT(IIO_CHAN_INFO_SCALE) |
index 97baf40d424bd599687b124062081364f94b487e..e881fa6291e9228a56cc0a7f3d6cf3ee51621855 100644 (file)
@@ -417,6 +417,7 @@ int st_press_common_probe(struct iio_dev *indio_dev)
 
        indio_dev->modes = INDIO_DIRECT_MODE;
        indio_dev->info = &press_info;
+       mutex_init(&press_data->tb.buf_lock);
 
        st_sensors_power_enable(indio_dev);
 
index 0c1419105ff083ce40bb576e60f03911dee91270..0271608a51c40ff2ade721f94b710997ffbe5c2d 100644 (file)
@@ -861,6 +861,7 @@ static void cm_destroy_id(struct ib_cm_id *cm_id, int err)
                cm_reject_sidr_req(cm_id_priv, IB_SIDR_REJECT);
                break;
        case IB_CM_REQ_SENT:
+       case IB_CM_MRA_REQ_RCVD:
                ib_cancel_mad(cm_id_priv->av.port->mad_agent, cm_id_priv->msg);
                spin_unlock_irq(&cm_id_priv->lock);
                ib_send_cm_rej(cm_id, IB_CM_REJ_TIMEOUT,
@@ -879,7 +880,6 @@ static void cm_destroy_id(struct ib_cm_id *cm_id, int err)
                                       NULL, 0, NULL, 0);
                }
                break;
-       case IB_CM_MRA_REQ_RCVD:
        case IB_CM_REP_SENT:
        case IB_CM_MRA_REP_RCVD:
                ib_cancel_mad(cm_id_priv->av.port->mad_agent, cm_id_priv->msg);
index 06441a43c3aacd1c6aecb22e15a17529b4a890a8..38ffe098150351aef9ff2ac650726ae7926f6856 100644 (file)
@@ -845,18 +845,26 @@ static void cma_save_ib_info(struct rdma_cm_id *id, struct rdma_cm_id *listen_id
        listen_ib = (struct sockaddr_ib *) &listen_id->route.addr.src_addr;
        ib = (struct sockaddr_ib *) &id->route.addr.src_addr;
        ib->sib_family = listen_ib->sib_family;
-       ib->sib_pkey = path->pkey;
-       ib->sib_flowinfo = path->flow_label;
-       memcpy(&ib->sib_addr, &path->sgid, 16);
+       if (path) {
+               ib->sib_pkey = path->pkey;
+               ib->sib_flowinfo = path->flow_label;
+               memcpy(&ib->sib_addr, &path->sgid, 16);
+       } else {
+               ib->sib_pkey = listen_ib->sib_pkey;
+               ib->sib_flowinfo = listen_ib->sib_flowinfo;
+               ib->sib_addr = listen_ib->sib_addr;
+       }
        ib->sib_sid = listen_ib->sib_sid;
        ib->sib_sid_mask = cpu_to_be64(0xffffffffffffffffULL);
        ib->sib_scope_id = listen_ib->sib_scope_id;
 
-       ib = (struct sockaddr_ib *) &id->route.addr.dst_addr;
-       ib->sib_family = listen_ib->sib_family;
-       ib->sib_pkey = path->pkey;
-       ib->sib_flowinfo = path->flow_label;
-       memcpy(&ib->sib_addr, &path->dgid, 16);
+       if (path) {
+               ib = (struct sockaddr_ib *) &id->route.addr.dst_addr;
+               ib->sib_family = listen_ib->sib_family;
+               ib->sib_pkey = path->pkey;
+               ib->sib_flowinfo = path->flow_label;
+               memcpy(&ib->sib_addr, &path->dgid, 16);
+       }
 }
 
 static __be16 ss_get_port(const struct sockaddr_storage *ss)
@@ -905,9 +913,11 @@ static int cma_save_net_info(struct rdma_cm_id *id, struct rdma_cm_id *listen_id
 {
        struct cma_hdr *hdr;
 
-       if ((listen_id->route.addr.src_addr.ss_family == AF_IB) &&
-           (ib_event->event == IB_CM_REQ_RECEIVED)) {
-               cma_save_ib_info(id, listen_id, ib_event->param.req_rcvd.primary_path);
+       if (listen_id->route.addr.src_addr.ss_family == AF_IB) {
+               if (ib_event->event == IB_CM_REQ_RECEIVED)
+                       cma_save_ib_info(id, listen_id, ib_event->param.req_rcvd.primary_path);
+               else if (ib_event->event == IB_CM_SIDR_REQ_RECEIVED)
+                       cma_save_ib_info(id, listen_id, NULL);
                return 0;
        }
 
index ab081702566fc47fd3fbbfe26a6ca7ef6bef58bc..e6ffa2e66c1ac54b7a2645f59bbb28c00bc91cc3 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "iwpm_util.h"
 
-static const char iwpm_ulib_name[] = "iWarpPortMapperUser";
+static const char iwpm_ulib_name[IWPM_ULIBNAME_SIZE] = "iWarpPortMapperUser";
 static int iwpm_ulib_version = 3;
 static int iwpm_user_pid = IWPM_PID_UNDEFINED;
 static atomic_t echo_nlmsg_seq;
index bb95a6c0477bb434cdcfd0e5e8f4408f6ec9e963..3ad8dc798f52c9101261882ac19138efb3905b94 100644 (file)
@@ -583,18 +583,18 @@ static void c4iw_record_pm_msg(struct c4iw_ep *ep,
                sizeof(ep->com.mapped_remote_addr));
 }
 
-static int get_remote_addr(struct c4iw_ep *ep)
+static int get_remote_addr(struct c4iw_ep *parent_ep, struct c4iw_ep *child_ep)
 {
        int ret;
 
-       print_addr(&ep->com, __func__, "get_remote_addr");
+       print_addr(&parent_ep->com, __func__, "get_remote_addr parent_ep ");
+       print_addr(&child_ep->com, __func__, "get_remote_addr child_ep ");
 
-       ret = iwpm_get_remote_info(&ep->com.mapped_local_addr,
-                                  &ep->com.mapped_remote_addr,
-                                  &ep->com.remote_addr, RDMA_NL_C4IW);
+       ret = iwpm_get_remote_info(&parent_ep->com.mapped_local_addr,
+                                  &child_ep->com.mapped_remote_addr,
+                                  &child_ep->com.remote_addr, RDMA_NL_C4IW);
        if (ret)
-               pr_info(MOD "Unable to find remote peer addr info - err %d\n",
-                       ret);
+               PDBG("Unable to find remote peer addr info - err %d\n", ret);
 
        return ret;
 }
@@ -2420,7 +2420,7 @@ static int pass_accept_req(struct c4iw_dev *dev, struct sk_buff *skb)
        }
        memcpy(&child_ep->com.remote_addr, &child_ep->com.mapped_remote_addr,
               sizeof(child_ep->com.remote_addr));
-       get_remote_addr(child_ep);
+       get_remote_addr(parent_ep, child_ep);
 
        c4iw_get_ep(&parent_ep->com);
        child_ep->parent_ep = parent_ep;
index cf54d6922dc47d18135253ffaf7d194bd1e39cc4..7e895d714b19e35a49ddd69f5a3432af5bcf1f71 100644 (file)
@@ -1386,7 +1386,7 @@ static void recover_lost_dbs(struct uld_ctx *ctx, struct qp_list *qp_list)
                                          t4_sq_host_wq_pidx(&qp->wq),
                                          t4_sq_wq_size(&qp->wq));
                if (ret) {
-                       pr_err(KERN_ERR MOD "%s: Fatal error - "
+                       pr_err(MOD "%s: Fatal error - "
                               "DB overflow recovery failed - "
                               "error syncing SQ qid %u\n",
                               pci_name(ctx->lldi.pdev), qp->wq.sq.qid);
@@ -1402,7 +1402,7 @@ static void recover_lost_dbs(struct uld_ctx *ctx, struct qp_list *qp_list)
                                          t4_rq_wq_size(&qp->wq));
 
                if (ret) {
-                       pr_err(KERN_ERR MOD "%s: Fatal error - "
+                       pr_err(MOD "%s: Fatal error - "
                               "DB overflow recovery failed - "
                               "error syncing RQ qid %u\n",
                               pci_name(ctx->lldi.pdev), qp->wq.rq.qid);
index 120aedf9f989a7a34839046a360dd9ad53816d64..cec1815329245cfa6573f39ce3f44f628175fea7 100644 (file)
@@ -77,7 +77,7 @@ int ehca_attach_mcast(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
                return -EINVAL;
        }
 
-       memcpy(&my_gid.raw, gid->raw, sizeof(union ib_gid));
+       memcpy(&my_gid, gid->raw, sizeof(union ib_gid));
 
        subnet_prefix = be64_to_cpu(my_gid.global.subnet_prefix);
        interface_id = be64_to_cpu(my_gid.global.interface_id);
@@ -114,7 +114,7 @@ int ehca_detach_mcast(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
                return -EINVAL;
        }
 
-       memcpy(&my_gid.raw, gid->raw, sizeof(union ib_gid));
+       memcpy(&my_gid, gid->raw, sizeof(union ib_gid));
 
        subnet_prefix = be64_to_cpu(my_gid.global.subnet_prefix);
        interface_id = be64_to_cpu(my_gid.global.interface_id);
index 57070c529dfb5ca038e2118212684dc54bb3d21b..cc64400d41ace3005c8a878b4c6811b0506726f9 100644 (file)
@@ -1569,8 +1569,7 @@ static void reset_gids_task(struct work_struct *work)
                               MLX4_CMD_TIME_CLASS_B,
                               MLX4_CMD_WRAPPED);
                if (err)
-                       pr_warn(KERN_WARNING
-                               "set port %d command failed\n", gw->port);
+                       pr_warn("set port %d command failed\n", gw->port);
        }
 
        mlx4_free_cmd_mailbox(dev, mailbox);
index 4d7024b899cb091a12aacfa9450af1e7750d4f45..d35f62d4f4c58ecce848cfb2d0544500c62dbfd3 100644 (file)
@@ -1392,7 +1392,7 @@ static int mlx5_set_path(struct mlx5_ib_dev *dev, const struct ib_ah_attr *ah,
 
        if (ah->ah_flags & IB_AH_GRH) {
                if (ah->grh.sgid_index >= gen->port[port - 1].gid_table_len) {
-                       pr_err(KERN_ERR "sgid_index (%u) too large. max is %d\n",
+                       pr_err("sgid_index (%u) too large. max is %d\n",
                               ah->grh.sgid_index, gen->port[port - 1].gid_table_len);
                        return -EINVAL;
                }
index c9780d919769a6ef9a0020b7e710afa7e7ce2497..b396344fae16af33153f0625104d95c17f488a8d 100644 (file)
@@ -40,7 +40,7 @@
 #include <be_roce.h>
 #include "ocrdma_sli.h"
 
-#define OCRDMA_ROCE_DRV_VERSION "10.4.205.0u"
+#define OCRDMA_ROCE_DRV_VERSION "10.6.0.0"
 
 #define OCRDMA_ROCE_DRV_DESC "Emulex OneConnect RoCE Driver"
 #define OCRDMA_NODE_DESC "Emulex OneConnect RoCE HCA"
@@ -515,6 +515,8 @@ static inline int ocrdma_resolve_dmac(struct ocrdma_dev *dev,
        memcpy(&in6, ah_attr->grh.dgid.raw, sizeof(in6));
        if (rdma_is_multicast_addr(&in6))
                rdma_get_mcast_mac(&in6, mac_addr);
+       else if (rdma_link_local_addr(&in6))
+               rdma_get_ll_mac(&in6, mac_addr);
        else
                memcpy(mac_addr, ah_attr->dmac, ETH_ALEN);
        return 0;
index d812904f398473d1502bb979d6d822c04b55f2b8..f5a5ea836dbdc9fe4f12e6f26e1acca5dac3c6d1 100644 (file)
@@ -56,7 +56,13 @@ static inline int set_av_attr(struct ocrdma_dev *dev, struct ocrdma_ah *ah,
        vlan_tag = attr->vlan_id;
        if (!vlan_tag || (vlan_tag > 0xFFF))
                vlan_tag = dev->pvid;
-       if (vlan_tag && (vlan_tag < 0x1000)) {
+       if (vlan_tag || dev->pfc_state) {
+               if (!vlan_tag) {
+                       pr_err("ocrdma%d:Using VLAN with PFC is recommended\n",
+                               dev->id);
+                       pr_err("ocrdma%d:Using VLAN 0 for this connection\n",
+                               dev->id);
+               }
                eth.eth_type = cpu_to_be16(0x8100);
                eth.roce_eth_type = cpu_to_be16(OCRDMA_ROCE_ETH_TYPE);
                vlan_tag |= (dev->sl & 0x07) << OCRDMA_VID_PCP_SHIFT;
@@ -121,7 +127,9 @@ struct ib_ah *ocrdma_create_ah(struct ib_pd *ibpd, struct ib_ah_attr *attr)
                goto av_conf_err;
        }
 
-       if (pd->uctx) {
+       if ((pd->uctx) &&
+           (!rdma_is_multicast_addr((struct in6_addr *)attr->grh.dgid.raw)) &&
+           (!rdma_link_local_addr((struct in6_addr *)attr->grh.dgid.raw))) {
                status = rdma_addr_find_dmac_by_grh(&sgid, &attr->grh.dgid,
                                         attr->dmac, &attr->vlan_id);
                if (status) {
index 0c9e95909a64651e931f4768e88f97e266c8379e..47615ff33bc6a1fb8c0c703b9f975acc6afe79c2 100644 (file)
@@ -933,12 +933,18 @@ static irqreturn_t ocrdma_irq_handler(int irq, void *handle)
        struct ocrdma_eqe eqe;
        struct ocrdma_eqe *ptr;
        u16 cq_id;
+       u8 mcode;
        int budget = eq->cq_cnt;
 
        do {
                ptr = ocrdma_get_eqe(eq);
                eqe = *ptr;
                ocrdma_le32_to_cpu(&eqe, sizeof(eqe));
+               mcode = (eqe.id_valid & OCRDMA_EQE_MAJOR_CODE_MASK)
+                               >> OCRDMA_EQE_MAJOR_CODE_SHIFT;
+               if (mcode == OCRDMA_MAJOR_CODE_SENTINAL)
+                       pr_err("EQ full on eqid = 0x%x, eqe = 0x%x\n",
+                              eq->q.id, eqe.id_valid);
                if ((eqe.id_valid & OCRDMA_EQE_VALID_MASK) == 0)
                        break;
 
@@ -1434,27 +1440,30 @@ static int ocrdma_mbx_alloc_pd_range(struct ocrdma_dev *dev)
        struct ocrdma_alloc_pd_range_rsp *rsp;
 
        /* Pre allocate the DPP PDs */
-       cmd = ocrdma_init_emb_mqe(OCRDMA_CMD_ALLOC_PD_RANGE, sizeof(*cmd));
-       if (!cmd)
-               return -ENOMEM;
-       cmd->pd_count = dev->attr.max_dpp_pds;
-       cmd->enable_dpp_rsvd |= OCRDMA_ALLOC_PD_ENABLE_DPP;
-       status = ocrdma_mbx_cmd(dev, (struct ocrdma_mqe *)cmd);
-       if (status)
-               goto mbx_err;
-       rsp = (struct ocrdma_alloc_pd_range_rsp *)cmd;
-
-       if ((rsp->dpp_page_pdid & OCRDMA_ALLOC_PD_RSP_DPP) && rsp->pd_count) {
-               dev->pd_mgr->dpp_page_index = rsp->dpp_page_pdid >>
-                               OCRDMA_ALLOC_PD_RSP_DPP_PAGE_SHIFT;
-               dev->pd_mgr->pd_dpp_start = rsp->dpp_page_pdid &
-                               OCRDMA_ALLOC_PD_RNG_RSP_START_PDID_MASK;
-               dev->pd_mgr->max_dpp_pd = rsp->pd_count;
-               pd_bitmap_size = BITS_TO_LONGS(rsp->pd_count) * sizeof(long);
-               dev->pd_mgr->pd_dpp_bitmap = kzalloc(pd_bitmap_size,
-                                                    GFP_KERNEL);
+       if (dev->attr.max_dpp_pds) {
+               cmd = ocrdma_init_emb_mqe(OCRDMA_CMD_ALLOC_PD_RANGE,
+                                         sizeof(*cmd));
+               if (!cmd)
+                       return -ENOMEM;
+               cmd->pd_count = dev->attr.max_dpp_pds;
+               cmd->enable_dpp_rsvd |= OCRDMA_ALLOC_PD_ENABLE_DPP;
+               status = ocrdma_mbx_cmd(dev, (struct ocrdma_mqe *)cmd);
+               rsp = (struct ocrdma_alloc_pd_range_rsp *)cmd;
+
+               if (!status && (rsp->dpp_page_pdid & OCRDMA_ALLOC_PD_RSP_DPP) &&
+                   rsp->pd_count) {
+                       dev->pd_mgr->dpp_page_index = rsp->dpp_page_pdid >>
+                                       OCRDMA_ALLOC_PD_RSP_DPP_PAGE_SHIFT;
+                       dev->pd_mgr->pd_dpp_start = rsp->dpp_page_pdid &
+                                       OCRDMA_ALLOC_PD_RNG_RSP_START_PDID_MASK;
+                       dev->pd_mgr->max_dpp_pd = rsp->pd_count;
+                       pd_bitmap_size =
+                               BITS_TO_LONGS(rsp->pd_count) * sizeof(long);
+                       dev->pd_mgr->pd_dpp_bitmap = kzalloc(pd_bitmap_size,
+                                                            GFP_KERNEL);
+               }
+               kfree(cmd);
        }
-       kfree(cmd);
 
        cmd = ocrdma_init_emb_mqe(OCRDMA_CMD_ALLOC_PD_RANGE, sizeof(*cmd));
        if (!cmd)
@@ -1462,10 +1471,8 @@ static int ocrdma_mbx_alloc_pd_range(struct ocrdma_dev *dev)
 
        cmd->pd_count = dev->attr.max_pd - dev->attr.max_dpp_pds;
        status = ocrdma_mbx_cmd(dev, (struct ocrdma_mqe *)cmd);
-       if (status)
-               goto mbx_err;
        rsp = (struct ocrdma_alloc_pd_range_rsp *)cmd;
-       if (rsp->pd_count) {
+       if (!status && rsp->pd_count) {
                dev->pd_mgr->pd_norm_start = rsp->dpp_page_pdid &
                                        OCRDMA_ALLOC_PD_RNG_RSP_START_PDID_MASK;
                dev->pd_mgr->max_normal_pd = rsp->pd_count;
@@ -1473,15 +1480,13 @@ static int ocrdma_mbx_alloc_pd_range(struct ocrdma_dev *dev)
                dev->pd_mgr->pd_norm_bitmap = kzalloc(pd_bitmap_size,
                                                      GFP_KERNEL);
        }
+       kfree(cmd);
 
        if (dev->pd_mgr->pd_norm_bitmap || dev->pd_mgr->pd_dpp_bitmap) {
                /* Enable PD resource manager */
                dev->pd_mgr->pd_prealloc_valid = true;
-       } else {
-               return -ENOMEM;
+               return 0;
        }
-mbx_err:
-       kfree(cmd);
        return status;
 }
 
@@ -2406,7 +2411,7 @@ int ocrdma_mbx_query_qp(struct ocrdma_dev *dev, struct ocrdma_qp *qp,
        struct ocrdma_query_qp *cmd;
        struct ocrdma_query_qp_rsp *rsp;
 
-       cmd = ocrdma_init_emb_mqe(OCRDMA_CMD_QUERY_QP, sizeof(*cmd));
+       cmd = ocrdma_init_emb_mqe(OCRDMA_CMD_QUERY_QP, sizeof(*rsp));
        if (!cmd)
                return status;
        cmd->qp_id = qp->id;
@@ -2428,7 +2433,7 @@ static int ocrdma_set_av_params(struct ocrdma_qp *qp,
        int status;
        struct ib_ah_attr *ah_attr = &attrs->ah_attr;
        union ib_gid sgid, zgid;
-       u32 vlan_id;
+       u32 vlan_id = 0xFFFF;
        u8 mac_addr[6];
        struct ocrdma_dev *dev = get_ocrdma_dev(qp->ibqp.device);
 
@@ -2468,12 +2473,22 @@ static int ocrdma_set_av_params(struct ocrdma_qp *qp,
        cmd->params.vlan_dmac_b4_to_b5 = mac_addr[4] | (mac_addr[5] << 8);
        if (attr_mask & IB_QP_VID) {
                vlan_id = attrs->vlan_id;
+       } else if (dev->pfc_state) {
+               vlan_id = 0;
+               pr_err("ocrdma%d:Using VLAN with PFC is recommended\n",
+                       dev->id);
+               pr_err("ocrdma%d:Using VLAN 0 for this connection\n",
+                       dev->id);
+       }
+
+       if (vlan_id < 0x1000) {
                cmd->params.vlan_dmac_b4_to_b5 |=
                    vlan_id << OCRDMA_QP_PARAMS_VLAN_SHIFT;
                cmd->flags |= OCRDMA_QP_PARA_VLAN_EN_VALID;
                cmd->params.rnt_rc_sl_fl |=
                        (dev->sl & 0x07) << OCRDMA_QP_PARAMS_SL_SHIFT;
        }
+
        return 0;
 }
 
@@ -2519,8 +2534,10 @@ static int ocrdma_set_qp_params(struct ocrdma_qp *qp,
                cmd->flags |= OCRDMA_QP_PARA_DST_QPN_VALID;
        }
        if (attr_mask & IB_QP_PATH_MTU) {
-               if (attrs->path_mtu < IB_MTU_256 ||
+               if (attrs->path_mtu < IB_MTU_512 ||
                    attrs->path_mtu > IB_MTU_4096) {
+                       pr_err("ocrdma%d: IB MTU %d is not supported\n",
+                              dev->id, ib_mtu_enum_to_int(attrs->path_mtu));
                        status = -EINVAL;
                        goto pmtu_err;
                }
@@ -3147,9 +3164,9 @@ void ocrdma_cleanup_hw(struct ocrdma_dev *dev)
        ocrdma_free_pd_pool(dev);
        ocrdma_mbx_delete_ah_tbl(dev);
 
-       /* cleanup the eqs */
-       ocrdma_destroy_eqs(dev);
-
        /* cleanup the control path */
        ocrdma_destroy_mq(dev);
+
+       /* cleanup the eqs */
+       ocrdma_destroy_eqs(dev);
 }
index 243c87c8bd65d09026f46ee12e3ee3b9109ce155..02ad0aee99afc0c5e9449c4f58353e57d38903f1 100644 (file)
@@ -1176,6 +1176,8 @@ struct ocrdma_query_qp_rsp {
        struct ocrdma_mqe_hdr hdr;
        struct ocrdma_mbx_rsp rsp;
        struct ocrdma_qp_params params;
+       u32 dpp_credits_cqid;
+       u32 rbq_id;
 };
 
 enum {
@@ -1624,12 +1626,19 @@ struct ocrdma_delete_ah_tbl_rsp {
 enum {
        OCRDMA_EQE_VALID_SHIFT          = 0,
        OCRDMA_EQE_VALID_MASK           = BIT(0),
+       OCRDMA_EQE_MAJOR_CODE_MASK      = 0x0E,
+       OCRDMA_EQE_MAJOR_CODE_SHIFT     = 0x01,
        OCRDMA_EQE_FOR_CQE_MASK         = 0xFFFE,
        OCRDMA_EQE_RESOURCE_ID_SHIFT    = 16,
        OCRDMA_EQE_RESOURCE_ID_MASK     = 0xFFFF <<
                                OCRDMA_EQE_RESOURCE_ID_SHIFT,
 };
 
+enum major_code {
+       OCRDMA_MAJOR_CODE_COMPLETION    = 0x00,
+       OCRDMA_MAJOR_CODE_SENTINAL      = 0x01
+};
+
 struct ocrdma_eqe {
        u32 id_valid;
 };
index 877175563634df79a889ed8a428405258b9df1e4..9dcb66077d6cbf9cd37bdaaa594414aadee4c96f 100644 (file)
@@ -365,7 +365,7 @@ static struct ocrdma_pd *_ocrdma_alloc_pd(struct ocrdma_dev *dev,
        if (!pd)
                return ERR_PTR(-ENOMEM);
 
-       if (udata && uctx) {
+       if (udata && uctx && dev->attr.max_dpp_pds) {
                pd->dpp_enabled =
                        ocrdma_get_asic_type(dev) == OCRDMA_ASIC_GEN_SKH_R;
                pd->num_dpp_qp =
@@ -1721,18 +1721,20 @@ int ocrdma_destroy_qp(struct ib_qp *ibqp)
        struct ocrdma_qp *qp;
        struct ocrdma_dev *dev;
        struct ib_qp_attr attrs;
-       int attr_mask = IB_QP_STATE;
+       int attr_mask;
        unsigned long flags;
 
        qp = get_ocrdma_qp(ibqp);
        dev = get_ocrdma_dev(ibqp->device);
 
-       attrs.qp_state = IB_QPS_ERR;
        pd = qp->pd;
 
        /* change the QP state to ERROR */
-       _ocrdma_modify_qp(ibqp, &attrs, attr_mask);
-
+       if (qp->state != OCRDMA_QPS_RST) {
+               attrs.qp_state = IB_QPS_ERR;
+               attr_mask = IB_QP_STATE;
+               _ocrdma_modify_qp(ibqp, &attrs, attr_mask);
+       }
        /* ensure that CQEs for newly created QP (whose id may be same with
         * one which just getting destroyed are same), dont get
         * discarded until the old CQEs are discarded.
index ba5173e249738cb123560a29701bdacb496e9fc8..7df16f74bb4585e971e1208dd348911d142f78fb 100644 (file)
@@ -903,7 +903,7 @@ struct qib_devdata {
        /* PCI Device ID (here for NodeInfo) */
        u16 deviceid;
        /* for write combining settings */
-       unsigned long wc_cookie;
+       int wc_cookie;
        unsigned long wc_base;
        unsigned long wc_len;
 
index 6d61ef98721cb02f6b4baeead132cbe1d399753c..edd0ddbd44815d8e48ed49d3dec46e37545aa031 100644 (file)
@@ -118,7 +118,8 @@ int qib_enable_wc(struct qib_devdata *dd)
        if (!ret) {
                dd->wc_cookie = arch_phys_wc_add(pioaddr, piolen);
                if (dd->wc_cookie < 0)
-                       ret = -EINVAL;
+                       /* use error from routine */
+                       ret = dd->wc_cookie;
        }
 
        return ret;
index f362883c94e37ce828d18938b7d25790135cf2d1..1d247bcf2ae25b20508f734d72b4904f704987d8 100644 (file)
@@ -747,6 +747,63 @@ static void joydev_cleanup(struct joydev *joydev)
                input_close_device(handle);
 }
 
+static bool joydev_dev_is_absolute_mouse(struct input_dev *dev)
+{
+       DECLARE_BITMAP(jd_scratch, KEY_CNT);
+
+       BUILD_BUG_ON(ABS_CNT > KEY_CNT || EV_CNT > KEY_CNT);
+
+       /*
+        * Virtualization (VMware, etc) and remote management (HP
+        * ILO2) solutions use absolute coordinates for their virtual
+        * pointing devices so that there is one-to-one relationship
+        * between pointer position on the host screen and virtual
+        * guest screen, and so their mice use ABS_X, ABS_Y and 3
+        * primary button events. This clashes with what joydev
+        * considers to be joysticks (a device with at minimum ABS_X
+        * axis).
+        *
+        * Here we are trying to separate absolute mice from
+        * joysticks. A device is, for joystick detection purposes,
+        * considered to be an absolute mouse if the following is
+        * true:
+        *
+        * 1) Event types are exactly EV_ABS, EV_KEY and EV_SYN.
+        * 2) Absolute events are exactly ABS_X and ABS_Y.
+        * 3) Keys are exactly BTN_LEFT, BTN_RIGHT and BTN_MIDDLE.
+        * 4) Device is not on "Amiga" bus.
+        */
+
+       bitmap_zero(jd_scratch, EV_CNT);
+       __set_bit(EV_ABS, jd_scratch);
+       __set_bit(EV_KEY, jd_scratch);
+       __set_bit(EV_SYN, jd_scratch);
+       if (!bitmap_equal(jd_scratch, dev->evbit, EV_CNT))
+               return false;
+
+       bitmap_zero(jd_scratch, ABS_CNT);
+       __set_bit(ABS_X, jd_scratch);
+       __set_bit(ABS_Y, jd_scratch);
+       if (!bitmap_equal(dev->absbit, jd_scratch, ABS_CNT))
+               return false;
+
+       bitmap_zero(jd_scratch, KEY_CNT);
+       __set_bit(BTN_LEFT, jd_scratch);
+       __set_bit(BTN_RIGHT, jd_scratch);
+       __set_bit(BTN_MIDDLE, jd_scratch);
+
+       if (!bitmap_equal(dev->keybit, jd_scratch, KEY_CNT))
+               return false;
+
+       /*
+        * Amiga joystick (amijoy) historically uses left/middle/right
+        * button events.
+        */
+       if (dev->id.bustype == BUS_AMIGA)
+               return false;
+
+       return true;
+}
 
 static bool joydev_match(struct input_handler *handler, struct input_dev *dev)
 {
@@ -758,6 +815,10 @@ static bool joydev_match(struct input_handler *handler, struct input_dev *dev)
        if (test_bit(EV_KEY, dev->evbit) && test_bit(BTN_DIGI, dev->keybit))
                return false;
 
+       /* Avoid absolute mice */
+       if (joydev_dev_is_absolute_mouse(dev))
+               return false;
+
        return true;
 }
 
index 7462d2fc8cfed8d4bf11d77fb2bb5e853d9f00eb..d7820d1152d2ef2d78f39c16281a9c316906e7ae 100644 (file)
@@ -156,7 +156,7 @@ config MOUSE_PS2_VMMOUSE
          Say Y here if you are running under control of VMware hypervisor
          (ESXi, Workstation or Fusion). Also make sure that when you enable
          this option, you remove the xf86-input-vmmouse user-space driver
-         or upgrade it to at least xf86-input-vmmouse 13.0.1, which doesn't
+         or upgrade it to at least xf86-input-vmmouse 13.1.0, which doesn't
          load in the presence of an in-kernel vmmouse driver.
 
          If unsure, say N.
index e6708f6efb4db7189dccdc1ed1fc0b3ca117a6ef..7752bd59d4b7d529218dad186c155a91a9922ad1 100644 (file)
@@ -941,6 +941,11 @@ static void alps_get_finger_coordinate_v7(struct input_mt_pos *mt,
        case V7_PACKET_ID_TWO:
                mt[1].x &= ~0x000F;
                mt[1].y |= 0x000F;
+               /* Detect false-postive touches where x & y report max value */
+               if (mt[1].y == 0x7ff && mt[1].x == 0xff0) {
+                       mt[1].x = 0;
+                       /* y gets set to 0 at the end of this function */
+               }
                break;
 
        case V7_PACKET_ID_MULTI:
index 991dc6b20a58594cbc28ee1dfc8f45d677497fe5..79363b6871959ec2b74c24f4b9e9b89b172d950d 100644 (file)
@@ -315,7 +315,7 @@ static void elantech_report_semi_mt_data(struct input_dev *dev,
                                         unsigned int x2, unsigned int y2)
 {
        elantech_set_slot(dev, 0, num_fingers != 0, x1, y1);
-       elantech_set_slot(dev, 1, num_fingers == 2, x2, y2);
+       elantech_set_slot(dev, 1, num_fingers >= 2, x2, y2);
 }
 
 /*
index 2d5ff86b343fbc30f1abf9e363333164311bfec6..e4c31256a74dbeddb70c74ec628ed856065cdff4 100644 (file)
@@ -164,7 +164,7 @@ static irqreturn_t stmpe_ts_handler(int irq, void *data)
                        STMPE_TSC_CTRL_TSC_EN, STMPE_TSC_CTRL_TSC_EN);
 
        /* start polling for touch_det to detect release */
-       schedule_delayed_work(&ts->work, HZ / 50);
+       schedule_delayed_work(&ts->work, msecs_to_jiffies(50));
 
        return IRQ_HANDLED;
 }
index aecb9ad2e7016885cda6ee2a7c08af1e461c9980..642f4a53de509f2f240f4cd5279ce2749d235455 100644 (file)
@@ -187,7 +187,7 @@ static int sx8654_probe(struct i2c_client *client,
                return -ENOMEM;
 
        input = devm_input_allocate_device(&client->dev);
-       if (!sx8654)
+       if (!input)
                return -ENOMEM;
 
        input->name = "SX8654 I2C Touchscreen";
index a1cbba9056fdba15b1334bd923714c65957fc20c..3465faf1809e4cb1d6630e5cdc8f87cd4e405bd2 100644 (file)
@@ -266,6 +266,7 @@ static void put_pasid_state(struct pasid_state *pasid_state)
 
 static void put_pasid_state_wait(struct pasid_state *pasid_state)
 {
+       atomic_dec(&pasid_state->count);
        wait_event(pasid_state->wq, !atomic_read(&pasid_state->count));
        free_pasid_state(pasid_state);
 }
index 9f7e1d34a32bc8ec75c6470260c66f839419f502..66a803b9dd3af928024d853995ed31383e0a8dd2 100644 (file)
 #define RESUME_TERMINATE               (1 << 0)
 
 #define TTBCR2_SEP_SHIFT               15
-#define TTBCR2_SEP_MASK                        0x7
-
-#define TTBCR2_ADDR_32                 0
-#define TTBCR2_ADDR_36                 1
-#define TTBCR2_ADDR_40                 2
-#define TTBCR2_ADDR_42                 3
-#define TTBCR2_ADDR_44                 4
-#define TTBCR2_ADDR_48                 5
+#define TTBCR2_SEP_UPSTREAM            (0x7 << TTBCR2_SEP_SHIFT)
 
 #define TTBRn_HI_ASID_SHIFT            16
 
@@ -793,26 +786,7 @@ static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain,
                writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBCR);
                if (smmu->version > ARM_SMMU_V1) {
                        reg = pgtbl_cfg->arm_lpae_s1_cfg.tcr >> 32;
-                       switch (smmu->va_size) {
-                       case 32:
-                               reg |= (TTBCR2_ADDR_32 << TTBCR2_SEP_SHIFT);
-                               break;
-                       case 36:
-                               reg |= (TTBCR2_ADDR_36 << TTBCR2_SEP_SHIFT);
-                               break;
-                       case 40:
-                               reg |= (TTBCR2_ADDR_40 << TTBCR2_SEP_SHIFT);
-                               break;
-                       case 42:
-                               reg |= (TTBCR2_ADDR_42 << TTBCR2_SEP_SHIFT);
-                               break;
-                       case 44:
-                               reg |= (TTBCR2_ADDR_44 << TTBCR2_SEP_SHIFT);
-                               break;
-                       case 48:
-                               reg |= (TTBCR2_ADDR_48 << TTBCR2_SEP_SHIFT);
-                               break;
-                       }
+                       reg |= TTBCR2_SEP_UPSTREAM;
                        writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBCR2);
                }
        } else {
index 4015560bf486db22e82f1652799731b90277b864..cab214544237cf6f89754c3878f0e57f66ba360d 100644 (file)
@@ -1004,20 +1004,18 @@ static int rk_iommu_remove(struct platform_device *pdev)
        return 0;
 }
 
-#ifdef CONFIG_OF
 static const struct of_device_id rk_iommu_dt_ids[] = {
        { .compatible = "rockchip,iommu" },
        { /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, rk_iommu_dt_ids);
-#endif
 
 static struct platform_driver rk_iommu_driver = {
        .probe = rk_iommu_probe,
        .remove = rk_iommu_remove,
        .driver = {
                   .name = "rk_iommu",
-                  .of_match_table = of_match_ptr(rk_iommu_dt_ids),
+                  .of_match_table = rk_iommu_dt_ids,
        },
 };
 
index 9687f8afebffbb865256ba6677663e6c76702aa1..1b7e155869f6c1a5f9ff361f246b6fd71539dadc 100644 (file)
@@ -828,7 +828,14 @@ static int its_alloc_tables(struct its_node *its)
                        u64 typer = readq_relaxed(its->base + GITS_TYPER);
                        u32 ids = GITS_TYPER_DEVBITS(typer);
 
-                       order = get_order((1UL << ids) * entry_size);
+                       /*
+                        * 'order' was initialized earlier to the default page
+                        * granule of the the ITS.  We can't have an allocation
+                        * smaller than that.  If the requested allocation
+                        * is smaller, round up to the default page granule.
+                        */
+                       order = max(get_order((1UL << ids) * entry_size),
+                                   order);
                        if (order >= MAX_ORDER) {
                                order = MAX_ORDER - 1;
                                pr_warn("%s: Device Table too large, reduce its page order to %u\n",
index 51c485d9a87736bcf06cfdf67c089f81288bc8d8..f67bbd80433e8c90527a9b911a2656987b800b96 100644 (file)
@@ -264,7 +264,7 @@ static int tegra_ictlr_domain_alloc(struct irq_domain *domain,
 
                irq_domain_set_hwirq_and_chip(domain, virq + i, hwirq + i,
                                              &tegra_ictlr_chip,
-                                             &info->base[ictlr]);
+                                             info->base[ictlr]);
        }
 
        parent_args = *args;
index 7dc93aa004c86cfa988993d53164ea1d665aff97..312ffd3d00177ca5a5e21393377c760e9bdec91e 100644 (file)
@@ -173,7 +173,7 @@ static void unmap_switcher(void)
 bool lguest_address_ok(const struct lguest *lg,
                       unsigned long addr, unsigned long len)
 {
-       return (addr+len) / PAGE_SIZE < lg->pfn_limit && (addr+len >= addr);
+       return addr+len <= lg->pfn_limit * PAGE_SIZE && (addr+len >= addr);
 }
 
 /*
index 2bc56e2a35262141859f8da21d09a54dec852e52..135a0907e9de413d140e9fb9b793a91b638a1606 100644 (file)
@@ -177,11 +177,16 @@ static struct md_rdev *next_active_rdev(struct md_rdev *rdev, struct mddev *mdde
         * nr_pending is 0 and In_sync is clear, the entries we return will
         * still be in the same position on the list when we re-enter
         * list_for_each_entry_continue_rcu.
+        *
+        * Note that if entered with 'rdev == NULL' to start at the
+        * beginning, we temporarily assign 'rdev' to an address which
+        * isn't really an rdev, but which can be used by
+        * list_for_each_entry_continue_rcu() to find the first entry.
         */
        rcu_read_lock();
        if (rdev == NULL)
                /* start at the beginning */
-               rdev = list_entry_rcu(&mddev->disks, struct md_rdev, same_set);
+               rdev = list_entry(&mddev->disks, struct md_rdev, same_set);
        else {
                /* release the previous rdev and start from there. */
                rdev_dec_pending(rdev, mddev);
index 593a02476c781a2b5ee7e491b9188a108630b506..27506302eb7aa42557bfc01547274957ccbace50 100644 (file)
@@ -4211,12 +4211,12 @@ action_store(struct mddev *mddev, const char *page, size_t len)
        if (!mddev->pers || !mddev->pers->sync_request)
                return -EINVAL;
 
-       if (cmd_match(page, "frozen"))
-               set_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
-       else
-               clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
 
        if (cmd_match(page, "idle") || cmd_match(page, "frozen")) {
+               if (cmd_match(page, "frozen"))
+                       set_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
+               else
+                       clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
                flush_workqueue(md_misc_wq);
                if (mddev->sync_thread) {
                        set_bit(MD_RECOVERY_INTR, &mddev->recovery);
@@ -4229,16 +4229,17 @@ action_store(struct mddev *mddev, const char *page, size_t len)
                   test_bit(MD_RECOVERY_NEEDED, &mddev->recovery))
                return -EBUSY;
        else if (cmd_match(page, "resync"))
-               set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
+               clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
        else if (cmd_match(page, "recover")) {
+               clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
                set_bit(MD_RECOVERY_RECOVER, &mddev->recovery);
-               set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
        } else if (cmd_match(page, "reshape")) {
                int err;
                if (mddev->pers->start_reshape == NULL)
                        return -EINVAL;
                err = mddev_lock(mddev);
                if (!err) {
+                       clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
                        err = mddev->pers->start_reshape(mddev);
                        mddev_unlock(mddev);
                }
@@ -4250,6 +4251,7 @@ action_store(struct mddev *mddev, const char *page, size_t len)
                        set_bit(MD_RECOVERY_CHECK, &mddev->recovery);
                else if (!cmd_match(page, "repair"))
                        return -EINVAL;
+               clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
                set_bit(MD_RECOVERY_REQUESTED, &mddev->recovery);
                set_bit(MD_RECOVERY_SYNC, &mddev->recovery);
        }
index 2cb59a641cd24417d996df89c2e2c81cc9eb087b..efb654eb53992fc45da9a6e08572779496083c3f 100644 (file)
@@ -188,8 +188,9 @@ static int create_strip_zones(struct mddev *mddev, struct r0conf **private_conf)
                }
                dev[j] = rdev1;
 
-               disk_stack_limits(mddev->gendisk, rdev1->bdev,
-                                 rdev1->data_offset << 9);
+               if (mddev->queue)
+                       disk_stack_limits(mddev->gendisk, rdev1->bdev,
+                                         rdev1->data_offset << 9);
 
                if (rdev1->bdev->bd_disk->queue->merge_bvec_fn)
                        conf->has_merge_bvec = 1;
@@ -523,6 +524,9 @@ static void raid0_make_request(struct mddev *mddev, struct bio *bio)
                         ? (sector & (chunk_sects-1))
                         : sector_div(sector, chunk_sects));
 
+               /* Restore due to sector_div */
+               sector = bio->bi_iter.bi_sector;
+
                if (sectors < bio_sectors(bio)) {
                        split = bio_split(bio, sectors, GFP_NOIO, fs_bio_set);
                        bio_chain(split, bio);
@@ -530,7 +534,6 @@ static void raid0_make_request(struct mddev *mddev, struct bio *bio)
                        split = bio;
                }
 
-               sector = bio->bi_iter.bi_sector;
                zone = find_zone(mddev->private, &sector);
                tmp_dev = map_sector(mddev, zone, sector, &sector);
                split->bi_bdev = tmp_dev->bdev;
index 77dfd720aaa00ebc55d14234cd40b6e9b65bae5f..553d54b870528f0917e7518a9a783a28636d884a 100644 (file)
@@ -749,6 +749,7 @@ static void unlock_two_stripes(struct stripe_head *sh1, struct stripe_head *sh2)
 static bool stripe_can_batch(struct stripe_head *sh)
 {
        return test_bit(STRIPE_BATCH_READY, &sh->state) &&
+               !test_bit(STRIPE_BITMAP_PENDING, &sh->state) &&
                is_full_stripe_write(sh);
 }
 
@@ -837,6 +838,15 @@ static void stripe_add_to_batch_list(struct r5conf *conf, struct stripe_head *sh
                    < IO_THRESHOLD)
                        md_wakeup_thread(conf->mddev->thread);
 
+       if (test_and_clear_bit(STRIPE_BIT_DELAY, &sh->state)) {
+               int seq = sh->bm_seq;
+               if (test_bit(STRIPE_BIT_DELAY, &sh->batch_head->state) &&
+                   sh->batch_head->bm_seq > seq)
+                       seq = sh->batch_head->bm_seq;
+               set_bit(STRIPE_BIT_DELAY, &sh->batch_head->state);
+               sh->batch_head->bm_seq = seq;
+       }
+
        atomic_inc(&sh->count);
 unlock_out:
        unlock_two_stripes(head, sh);
@@ -1078,9 +1088,6 @@ static void ops_run_io(struct stripe_head *sh, struct stripe_head_state *s)
                        pr_debug("skip op %ld on disc %d for sector %llu\n",
                                bi->bi_rw, i, (unsigned long long)sh->sector);
                        clear_bit(R5_LOCKED, &sh->dev[i].flags);
-                       if (sh->batch_head)
-                               set_bit(STRIPE_BATCH_ERR,
-                                       &sh->batch_head->state);
                        set_bit(STRIPE_HANDLE, &sh->state);
                }
 
@@ -1825,7 +1832,7 @@ ops_run_reconstruct6(struct stripe_head *sh, struct raid5_percpu *percpu,
        } else
                init_async_submit(&submit, 0, tx, NULL, NULL,
                                  to_addr_conv(sh, percpu, j));
-       async_gen_syndrome(blocks, 0, count+2, STRIPE_SIZE,  &submit);
+       tx = async_gen_syndrome(blocks, 0, count+2, STRIPE_SIZE,  &submit);
        if (!last_stripe) {
                j++;
                sh = list_first_entry(&sh->batch_list, struct stripe_head,
@@ -1971,17 +1978,30 @@ static void raid_run_ops(struct stripe_head *sh, unsigned long ops_request)
        put_cpu();
 }
 
+static struct stripe_head *alloc_stripe(struct kmem_cache *sc, gfp_t gfp)
+{
+       struct stripe_head *sh;
+
+       sh = kmem_cache_zalloc(sc, gfp);
+       if (sh) {
+               spin_lock_init(&sh->stripe_lock);
+               spin_lock_init(&sh->batch_lock);
+               INIT_LIST_HEAD(&sh->batch_list);
+               INIT_LIST_HEAD(&sh->lru);
+               atomic_set(&sh->count, 1);
+       }
+       return sh;
+}
 static int grow_one_stripe(struct r5conf *conf, gfp_t gfp)
 {
        struct stripe_head *sh;
-       sh = kmem_cache_zalloc(conf->slab_cache, gfp);
+
+       sh = alloc_stripe(conf->slab_cache, gfp);
        if (!sh)
                return 0;
 
        sh->raid_conf = conf;
 
-       spin_lock_init(&sh->stripe_lock);
-
        if (grow_buffers(sh, gfp)) {
                shrink_buffers(sh);
                kmem_cache_free(conf->slab_cache, sh);
@@ -1990,13 +2010,8 @@ static int grow_one_stripe(struct r5conf *conf, gfp_t gfp)
        sh->hash_lock_index =
                conf->max_nr_stripes % NR_STRIPE_HASH_LOCKS;
        /* we just created an active stripe so... */
-       atomic_set(&sh->count, 1);
        atomic_inc(&conf->active_stripes);
-       INIT_LIST_HEAD(&sh->lru);
 
-       spin_lock_init(&sh->batch_lock);
-       INIT_LIST_HEAD(&sh->batch_list);
-       sh->batch_head = NULL;
        release_stripe(sh);
        conf->max_nr_stripes++;
        return 1;
@@ -2060,6 +2075,35 @@ static struct flex_array *scribble_alloc(int num, int cnt, gfp_t flags)
        return ret;
 }
 
+static int resize_chunks(struct r5conf *conf, int new_disks, int new_sectors)
+{
+       unsigned long cpu;
+       int err = 0;
+
+       mddev_suspend(conf->mddev);
+       get_online_cpus();
+       for_each_present_cpu(cpu) {
+               struct raid5_percpu *percpu;
+               struct flex_array *scribble;
+
+               percpu = per_cpu_ptr(conf->percpu, cpu);
+               scribble = scribble_alloc(new_disks,
+                                         new_sectors / STRIPE_SECTORS,
+                                         GFP_NOIO);
+
+               if (scribble) {
+                       flex_array_free(percpu->scribble);
+                       percpu->scribble = scribble;
+               } else {
+                       err = -ENOMEM;
+                       break;
+               }
+       }
+       put_online_cpus();
+       mddev_resume(conf->mddev);
+       return err;
+}
+
 static int resize_stripes(struct r5conf *conf, int newsize)
 {
        /* Make all the stripes able to hold 'newsize' devices.
@@ -2088,7 +2132,6 @@ static int resize_stripes(struct r5conf *conf, int newsize)
        struct stripe_head *osh, *nsh;
        LIST_HEAD(newstripes);
        struct disk_info *ndisks;
-       unsigned long cpu;
        int err;
        struct kmem_cache *sc;
        int i;
@@ -2109,13 +2152,11 @@ static int resize_stripes(struct r5conf *conf, int newsize)
                return -ENOMEM;
 
        for (i = conf->max_nr_stripes; i; i--) {
-               nsh = kmem_cache_zalloc(sc, GFP_KERNEL);
+               nsh = alloc_stripe(sc, GFP_KERNEL);
                if (!nsh)
                        break;
 
                nsh->raid_conf = conf;
-               spin_lock_init(&nsh->stripe_lock);
-
                list_add(&nsh->lru, &newstripes);
        }
        if (i) {
@@ -2142,13 +2183,11 @@ static int resize_stripes(struct r5conf *conf, int newsize)
                                    lock_device_hash_lock(conf, hash));
                osh = get_free_stripe(conf, hash);
                unlock_device_hash_lock(conf, hash);
-               atomic_set(&nsh->count, 1);
+
                for(i=0; i<conf->pool_size; i++) {
                        nsh->dev[i].page = osh->dev[i].page;
                        nsh->dev[i].orig_page = osh->dev[i].page;
                }
-               for( ; i<newsize; i++)
-                       nsh->dev[i].page = NULL;
                nsh->hash_lock_index = hash;
                kmem_cache_free(conf->slab_cache, osh);
                cnt++;
@@ -2174,25 +2213,6 @@ static int resize_stripes(struct r5conf *conf, int newsize)
        } else
                err = -ENOMEM;
 
-       get_online_cpus();
-       for_each_present_cpu(cpu) {
-               struct raid5_percpu *percpu;
-               struct flex_array *scribble;
-
-               percpu = per_cpu_ptr(conf->percpu, cpu);
-               scribble = scribble_alloc(newsize, conf->chunk_sectors /
-                       STRIPE_SECTORS, GFP_NOIO);
-
-               if (scribble) {
-                       flex_array_free(percpu->scribble);
-                       percpu->scribble = scribble;
-               } else {
-                       err = -ENOMEM;
-                       break;
-               }
-       }
-       put_online_cpus();
-
        /* Step 4, return new stripes to service */
        while(!list_empty(&newstripes)) {
                nsh = list_entry(newstripes.next, struct stripe_head, lru);
@@ -2212,7 +2232,8 @@ static int resize_stripes(struct r5conf *conf, int newsize)
 
        conf->slab_cache = sc;
        conf->active_name = 1-conf->active_name;
-       conf->pool_size = newsize;
+       if (!err)
+               conf->pool_size = newsize;
        return err;
 }
 
@@ -2434,7 +2455,7 @@ static void raid5_end_write_request(struct bio *bi, int error)
        }
        rdev_dec_pending(rdev, conf->mddev);
 
-       if (sh->batch_head && !uptodate)
+       if (sh->batch_head && !uptodate && !replacement)
                set_bit(STRIPE_BATCH_ERR, &sh->batch_head->state);
 
        if (!test_and_clear_bit(R5_DOUBLE_LOCKED, &sh->dev[i].flags))
@@ -2976,14 +2997,32 @@ static int add_stripe_bio(struct stripe_head *sh, struct bio *bi, int dd_idx,
        pr_debug("added bi b#%llu to stripe s#%llu, disk %d.\n",
                (unsigned long long)(*bip)->bi_iter.bi_sector,
                (unsigned long long)sh->sector, dd_idx);
-       spin_unlock_irq(&sh->stripe_lock);
 
        if (conf->mddev->bitmap && firstwrite) {
+               /* Cannot hold spinlock over bitmap_startwrite,
+                * but must ensure this isn't added to a batch until
+                * we have added to the bitmap and set bm_seq.
+                * So set STRIPE_BITMAP_PENDING to prevent
+                * batching.
+                * If multiple add_stripe_bio() calls race here they
+                * much all set STRIPE_BITMAP_PENDING.  So only the first one
+                * to complete "bitmap_startwrite" gets to set
+                * STRIPE_BIT_DELAY.  This is important as once a stripe
+                * is added to a batch, STRIPE_BIT_DELAY cannot be changed
+                * any more.
+                */
+               set_bit(STRIPE_BITMAP_PENDING, &sh->state);
+               spin_unlock_irq(&sh->stripe_lock);
                bitmap_startwrite(conf->mddev->bitmap, sh->sector,
                                  STRIPE_SECTORS, 0);
-               sh->bm_seq = conf->seq_flush+1;
-               set_bit(STRIPE_BIT_DELAY, &sh->state);
+               spin_lock_irq(&sh->stripe_lock);
+               clear_bit(STRIPE_BITMAP_PENDING, &sh->state);
+               if (!sh->batch_head) {
+                       sh->bm_seq = conf->seq_flush+1;
+                       set_bit(STRIPE_BIT_DELAY, &sh->state);
+               }
        }
+       spin_unlock_irq(&sh->stripe_lock);
 
        if (stripe_can_batch(sh))
                stripe_add_to_batch_list(conf, sh);
@@ -3278,7 +3317,9 @@ static int need_this_block(struct stripe_head *sh, struct stripe_head_state *s,
                /* reconstruct-write isn't being forced */
                return 0;
        for (i = 0; i < s->failed; i++) {
-               if (!test_bit(R5_UPTODATE, &fdev[i]->flags) &&
+               if (s->failed_num[i] != sh->pd_idx &&
+                   s->failed_num[i] != sh->qd_idx &&
+                   !test_bit(R5_UPTODATE, &fdev[i]->flags) &&
                    !test_bit(R5_OVERWRITE, &fdev[i]->flags))
                        return 1;
        }
@@ -3298,6 +3339,7 @@ static int fetch_block(struct stripe_head *sh, struct stripe_head_state *s,
                 */
                BUG_ON(test_bit(R5_Wantcompute, &dev->flags));
                BUG_ON(test_bit(R5_Wantread, &dev->flags));
+               BUG_ON(sh->batch_head);
                if ((s->uptodate == disks - 1) &&
                    (s->failed && (disk_idx == s->failed_num[0] ||
                                   disk_idx == s->failed_num[1]))) {
@@ -3366,7 +3408,6 @@ static void handle_stripe_fill(struct stripe_head *sh,
 {
        int i;
 
-       BUG_ON(sh->batch_head);
        /* look for blocks to read/compute, skip this if a compute
         * is already in flight, or if the stripe contents are in the
         * midst of changing due to a write
@@ -3379,6 +3420,8 @@ static void handle_stripe_fill(struct stripe_head *sh,
        set_bit(STRIPE_HANDLE, &sh->state);
 }
 
+static void break_stripe_batch_list(struct stripe_head *head_sh,
+                                   unsigned long handle_flags);
 /* handle_stripe_clean_event
  * any written block on an uptodate or failed drive can be returned.
  * Note that if we 'wrote' to a failed drive, it will be UPTODATE, but
@@ -3392,7 +3435,6 @@ static void handle_stripe_clean_event(struct r5conf *conf,
        int discard_pending = 0;
        struct stripe_head *head_sh = sh;
        bool do_endio = false;
-       int wakeup_nr = 0;
 
        for (i = disks; i--; )
                if (sh->dev[i].written) {
@@ -3481,44 +3523,8 @@ static void handle_stripe_clean_event(struct r5conf *conf,
                if (atomic_dec_and_test(&conf->pending_full_writes))
                        md_wakeup_thread(conf->mddev->thread);
 
-       if (!head_sh->batch_head || !do_endio)
-               return;
-       for (i = 0; i < head_sh->disks; i++) {
-               if (test_and_clear_bit(R5_Overlap, &head_sh->dev[i].flags))
-                       wakeup_nr++;
-       }
-       while (!list_empty(&head_sh->batch_list)) {
-               int i;
-               sh = list_first_entry(&head_sh->batch_list,
-                                     struct stripe_head, batch_list);
-               list_del_init(&sh->batch_list);
-
-               set_mask_bits(&sh->state, ~STRIPE_EXPAND_SYNC_FLAG,
-                             head_sh->state & ~((1 << STRIPE_ACTIVE) |
-                                                (1 << STRIPE_PREREAD_ACTIVE) |
-                                                STRIPE_EXPAND_SYNC_FLAG));
-               sh->check_state = head_sh->check_state;
-               sh->reconstruct_state = head_sh->reconstruct_state;
-               for (i = 0; i < sh->disks; i++) {
-                       if (test_and_clear_bit(R5_Overlap, &sh->dev[i].flags))
-                               wakeup_nr++;
-                       sh->dev[i].flags = head_sh->dev[i].flags;
-               }
-
-               spin_lock_irq(&sh->stripe_lock);
-               sh->batch_head = NULL;
-               spin_unlock_irq(&sh->stripe_lock);
-               if (sh->state & STRIPE_EXPAND_SYNC_FLAG)
-                       set_bit(STRIPE_HANDLE, &sh->state);
-               release_stripe(sh);
-       }
-
-       spin_lock_irq(&head_sh->stripe_lock);
-       head_sh->batch_head = NULL;
-       spin_unlock_irq(&head_sh->stripe_lock);
-       wake_up_nr(&conf->wait_for_overlap, wakeup_nr);
-       if (head_sh->state & STRIPE_EXPAND_SYNC_FLAG)
-               set_bit(STRIPE_HANDLE, &head_sh->state);
+       if (head_sh->batch_head && do_endio)
+               break_stripe_batch_list(head_sh, STRIPE_EXPAND_SYNC_FLAGS);
 }
 
 static void handle_stripe_dirtying(struct r5conf *conf,
@@ -4159,9 +4165,13 @@ static void analyse_stripe(struct stripe_head *sh, struct stripe_head_state *s)
 
 static int clear_batch_ready(struct stripe_head *sh)
 {
+       /* Return '1' if this is a member of batch, or
+        * '0' if it is a lone stripe or a head which can now be
+        * handled.
+        */
        struct stripe_head *tmp;
        if (!test_and_clear_bit(STRIPE_BATCH_READY, &sh->state))
-               return 0;
+               return (sh->batch_head && sh->batch_head != sh);
        spin_lock(&sh->stripe_lock);
        if (!sh->batch_head) {
                spin_unlock(&sh->stripe_lock);
@@ -4189,46 +4199,65 @@ static int clear_batch_ready(struct stripe_head *sh)
        return 0;
 }
 
-static void check_break_stripe_batch_list(struct stripe_head *sh)
+static void break_stripe_batch_list(struct stripe_head *head_sh,
+                                   unsigned long handle_flags)
 {
-       struct stripe_head *head_sh, *next;
+       struct stripe_head *sh, *next;
        int i;
+       int do_wakeup = 0;
 
-       if (!test_and_clear_bit(STRIPE_BATCH_ERR, &sh->state))
-               return;
+       list_for_each_entry_safe(sh, next, &head_sh->batch_list, batch_list) {
 
-       head_sh = sh;
-       do {
-               sh = list_first_entry(&sh->batch_list,
-                                     struct stripe_head, batch_list);
-               BUG_ON(sh == head_sh);
-       } while (!test_bit(STRIPE_DEGRADED, &sh->state));
-
-       while (sh != head_sh) {
-               next = list_first_entry(&sh->batch_list,
-                                       struct stripe_head, batch_list);
                list_del_init(&sh->batch_list);
 
-               set_mask_bits(&sh->state, ~STRIPE_EXPAND_SYNC_FLAG,
-                             head_sh->state & ~((1 << STRIPE_ACTIVE) |
-                                                (1 << STRIPE_PREREAD_ACTIVE) |
-                                                (1 << STRIPE_DEGRADED) |
-                                                STRIPE_EXPAND_SYNC_FLAG));
+               WARN_ON_ONCE(sh->state & ((1 << STRIPE_ACTIVE) |
+                                         (1 << STRIPE_SYNCING) |
+                                         (1 << STRIPE_REPLACED) |
+                                         (1 << STRIPE_PREREAD_ACTIVE) |
+                                         (1 << STRIPE_DELAYED) |
+                                         (1 << STRIPE_BIT_DELAY) |
+                                         (1 << STRIPE_FULL_WRITE) |
+                                         (1 << STRIPE_BIOFILL_RUN) |
+                                         (1 << STRIPE_COMPUTE_RUN)  |
+                                         (1 << STRIPE_OPS_REQ_PENDING) |
+                                         (1 << STRIPE_DISCARD) |
+                                         (1 << STRIPE_BATCH_READY) |
+                                         (1 << STRIPE_BATCH_ERR) |
+                                         (1 << STRIPE_BITMAP_PENDING)));
+               WARN_ON_ONCE(head_sh->state & ((1 << STRIPE_DISCARD) |
+                                             (1 << STRIPE_REPLACED)));
+
+               set_mask_bits(&sh->state, ~(STRIPE_EXPAND_SYNC_FLAGS |
+                                           (1 << STRIPE_DEGRADED)),
+                             head_sh->state & (1 << STRIPE_INSYNC));
+
                sh->check_state = head_sh->check_state;
                sh->reconstruct_state = head_sh->reconstruct_state;
-               for (i = 0; i < sh->disks; i++)
+               for (i = 0; i < sh->disks; i++) {
+                       if (test_and_clear_bit(R5_Overlap, &sh->dev[i].flags))
+                               do_wakeup = 1;
                        sh->dev[i].flags = head_sh->dev[i].flags &
                                (~((1 << R5_WriteError) | (1 << R5_Overlap)));
-
+               }
                spin_lock_irq(&sh->stripe_lock);
                sh->batch_head = NULL;
                spin_unlock_irq(&sh->stripe_lock);
-
-               set_bit(STRIPE_HANDLE, &sh->state);
+               if (handle_flags == 0 ||
+                   sh->state & handle_flags)
+                       set_bit(STRIPE_HANDLE, &sh->state);
                release_stripe(sh);
-
-               sh = next;
        }
+       spin_lock_irq(&head_sh->stripe_lock);
+       head_sh->batch_head = NULL;
+       spin_unlock_irq(&head_sh->stripe_lock);
+       for (i = 0; i < head_sh->disks; i++)
+               if (test_and_clear_bit(R5_Overlap, &head_sh->dev[i].flags))
+                       do_wakeup = 1;
+       if (head_sh->state & handle_flags)
+               set_bit(STRIPE_HANDLE, &head_sh->state);
+
+       if (do_wakeup)
+               wake_up(&head_sh->raid_conf->wait_for_overlap);
 }
 
 static void handle_stripe(struct stripe_head *sh)
@@ -4253,7 +4282,8 @@ static void handle_stripe(struct stripe_head *sh)
                return;
        }
 
-       check_break_stripe_batch_list(sh);
+       if (test_and_clear_bit(STRIPE_BATCH_ERR, &sh->state))
+               break_stripe_batch_list(sh, 0);
 
        if (test_bit(STRIPE_SYNC_REQUESTED, &sh->state) && !sh->batch_head) {
                spin_lock(&sh->stripe_lock);
@@ -4307,6 +4337,7 @@ static void handle_stripe(struct stripe_head *sh)
        if (s.failed > conf->max_degraded) {
                sh->check_state = 0;
                sh->reconstruct_state = 0;
+               break_stripe_batch_list(sh, 0);
                if (s.to_read+s.to_write+s.written)
                        handle_failed_stripe(conf, sh, &s, disks, &s.return_bi);
                if (s.syncing + s.replacing)
@@ -6221,8 +6252,11 @@ static int alloc_scratch_buffer(struct r5conf *conf, struct raid5_percpu *percpu
                percpu->spare_page = alloc_page(GFP_KERNEL);
        if (!percpu->scribble)
                percpu->scribble = scribble_alloc(max(conf->raid_disks,
-                       conf->previous_raid_disks), conf->chunk_sectors /
-                       STRIPE_SECTORS, GFP_KERNEL);
+                                                     conf->previous_raid_disks),
+                                                 max(conf->chunk_sectors,
+                                                     conf->prev_chunk_sectors)
+                                                  / STRIPE_SECTORS,
+                                                 GFP_KERNEL);
 
        if (!percpu->scribble || (conf->level == 6 && !percpu->spare_page)) {
                free_scratch_buffer(conf, percpu);
@@ -7198,6 +7232,15 @@ static int check_reshape(struct mddev *mddev)
        if (!check_stripe_cache(mddev))
                return -ENOSPC;
 
+       if (mddev->new_chunk_sectors > mddev->chunk_sectors ||
+           mddev->delta_disks > 0)
+               if (resize_chunks(conf,
+                                 conf->previous_raid_disks
+                                 + max(0, mddev->delta_disks),
+                                 max(mddev->new_chunk_sectors,
+                                     mddev->chunk_sectors)
+                           ) < 0)
+                       return -ENOMEM;
        return resize_stripes(conf, (conf->previous_raid_disks
                                     + mddev->delta_disks));
 }
index 7dc0dd86074b1702276ccb51ba166a38d5d0f7e3..896d603ad0da964d2c45f22039d8b733f0bef26e 100644 (file)
@@ -337,9 +337,12 @@ enum {
        STRIPE_ON_RELEASE_LIST,
        STRIPE_BATCH_READY,
        STRIPE_BATCH_ERR,
+       STRIPE_BITMAP_PENDING,  /* Being added to bitmap, don't add
+                                * to batch yet.
+                                */
 };
 
-#define STRIPE_EXPAND_SYNC_FLAG \
+#define STRIPE_EXPAND_SYNC_FLAGS \
        ((1 << STRIPE_EXPAND_SOURCE) |\
        (1 << STRIPE_EXPAND_READY) |\
        (1 << STRIPE_EXPANDING) |\
index ae498b53ee4042ef3e39e6f77a7272cffe4abe74..46e3840c7a37392402deb53a7a9eb2cb7b8b27b6 100644 (file)
@@ -431,6 +431,10 @@ int da9052_adc_read_temp(struct da9052 *da9052)
 EXPORT_SYMBOL_GPL(da9052_adc_read_temp);
 
 static const struct mfd_cell da9052_subdev_info[] = {
+       {
+               .name = "da9052-regulator",
+               .id = 0,
+       },
        {
                .name = "da9052-regulator",
                .id = 1,
@@ -483,10 +487,6 @@ static const struct mfd_cell da9052_subdev_info[] = {
                .name = "da9052-regulator",
                .id = 13,
        },
-       {
-               .name = "da9052-regulator",
-               .id = 14,
-       },
        {
                .name = "da9052-onkey",
        },
index 03d7c7521d9712e051cd83579ef26d1938368469..9a39e0b7e583625e7fa8a3f24dab0179e3da880a 100644 (file)
@@ -1304,7 +1304,7 @@ static void atmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 
        if (ios->clock) {
                unsigned int clock_min = ~0U;
-               u32 clkdiv;
+               int clkdiv;
 
                spin_lock_bh(&host->lock);
                if (!host->mode_reg) {
@@ -1328,7 +1328,12 @@ static void atmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
                /* Calculate clock divider */
                if (host->caps.has_odd_clk_div) {
                        clkdiv = DIV_ROUND_UP(host->bus_hz, clock_min) - 2;
-                       if (clkdiv > 511) {
+                       if (clkdiv < 0) {
+                               dev_warn(&mmc->class_dev,
+                                        "clock %u too fast; using %lu\n",
+                                        clock_min, host->bus_hz / 2);
+                               clkdiv = 0;
+                       } else if (clkdiv > 511) {
                                dev_warn(&mmc->class_dev,
                                         "clock %u too slow; using %lu\n",
                                         clock_min, host->bus_hz / (511 + 2));
index 7c8b1694a134da91cbeb5b4764922c8e7d8d06c2..3af137f49ac9aa49c0c58ad59977b53b9d81f358 100644 (file)
@@ -223,7 +223,7 @@ static int m25p_probe(struct spi_device *spi)
         */
        if (data && data->type)
                flash_name = data->type;
-       else if (!strcmp(spi->modalias, "nor-jedec"))
+       else if (!strcmp(spi->modalias, "spi-nor"))
                flash_name = NULL; /* auto-detect */
        else
                flash_name = spi->modalias;
@@ -255,7 +255,7 @@ static int m25p_remove(struct spi_device *spi)
  * since most of these flash are compatible to some extent, and their
  * differences can often be differentiated by the JEDEC read-ID command, we
  * encourage new users to add support to the spi-nor library, and simply bind
- * against a generic string here (e.g., "nor-jedec").
+ * against a generic string here (e.g., "jedec,spi-nor").
  *
  * Many flash names are kept here in this list (as well as in spi-nor.c) to
  * keep them available as module aliases for existing platforms.
@@ -305,7 +305,7 @@ static const struct spi_device_id m25p_ids[] = {
         * Generic support for SPI NOR that can be identified by the JEDEC READ
         * ID opcode (0x9F). Use this, if possible.
         */
-       {"nor-jedec"},
+       {"spi-nor"},
        { },
 };
 MODULE_DEVICE_TABLE(spi, m25p_ids);
index a3196b750a220663b22f866fbf8173ca6fe81d4a..58df07acdbdb5f4c397511834265c233c3a7f62d 100644 (file)
@@ -191,9 +191,11 @@ static int __init mtd_readtest_init(void)
                                err = ret;
                }
 
-               err = mtdtest_relax();
-               if (err)
+               ret = mtdtest_relax();
+               if (ret) {
+                       err = ret;
                        goto out;
+               }
        }
 
        if (err)
index db2c05b6fe7facc9f07a565d40ad6ee507e3da6e..c9eb78f10a0db829ca396539ccf49331c9f06a1e 100644 (file)
@@ -310,6 +310,8 @@ static void ubiblock_do_work(struct work_struct *work)
        blk_rq_map_sg(req->q, req, pdu->usgl.sg);
 
        ret = ubiblock_read(pdu);
+       rq_flush_dcache_pages(req);
+
        blk_mq_end_request(req, ret);
 }
 
index 4df28943d2229035166d2bb4a72ec11c8f9671c5..e8d3c1d35453d1e182cd4b82388978f580abe946 100644 (file)
@@ -624,7 +624,7 @@ int __bond_opt_set(struct bonding *bond,
 out:
        if (ret)
                bond_opt_error_interpret(bond, opt, ret, val);
-       else
+       else if (bond->dev->reg_state == NETREG_REGISTERED)
                call_netdevice_notifiers(NETDEV_CHANGEINFODATA, bond->dev);
 
        return ret;
index 6bddfe062b516467b6cc2be75a53c17c2040b2d7..fc55e8e0351dfe5f3ca436d8aed64bf6d660db84 100644 (file)
@@ -509,10 +509,11 @@ static int xcan_rx(struct net_device *ndev)
                        cf->can_id |= CAN_RTR_FLAG;
        }
 
-       if (!(id_xcan & XCAN_IDR_SRR_MASK)) {
-               data[0] = priv->read_reg(priv, XCAN_RXFIFO_DW1_OFFSET);
-               data[1] = priv->read_reg(priv, XCAN_RXFIFO_DW2_OFFSET);
+       /* DW1/DW2 must always be read to remove message from RXFIFO */
+       data[0] = priv->read_reg(priv, XCAN_RXFIFO_DW1_OFFSET);
+       data[1] = priv->read_reg(priv, XCAN_RXFIFO_DW2_OFFSET);
 
+       if (!(cf->can_id & CAN_RTR_FLAG)) {
                /* Change Xilinx CAN data format to socketCAN data format */
                if (cf->can_dlc > 0)
                        *(__be32 *)(cf->data) = cpu_to_be32(data[0]);
index af639ab4c55b64fd886df0413d090afd2fe618ba..cf309aa92802623ec0532b56b1dd10a88a234af1 100644 (file)
@@ -1469,6 +1469,9 @@ static void __exit mv88e6xxx_cleanup(void)
 #if IS_ENABLED(CONFIG_NET_DSA_MV88E6171)
        unregister_switch_driver(&mv88e6171_switch_driver);
 #endif
+#if IS_ENABLED(CONFIG_NET_DSA_MV88E6352)
+       unregister_switch_driver(&mv88e6352_switch_driver);
+#endif
 #if IS_ENABLED(CONFIG_NET_DSA_MV88E6123_61_65)
        unregister_switch_driver(&mv88e6123_61_65_switch_driver);
 #endif
index 089c269637b725da7876db7e4988baa77b5ec171..426916036151649ca3a2cef4e69eb00735826c05 100644 (file)
@@ -180,6 +180,7 @@ config SUNLANCE
 config AMD_XGBE
        tristate "AMD 10GbE Ethernet driver"
        depends on (OF_NET || ACPI) && HAS_IOMEM && HAS_DMA
+       depends on ARM64 || COMPILE_TEST
        select PHYLIB
        select AMD_XGBE_PHY
        select BITREVERSE
index f4054d242f3c7ac6e52437c5cb795cac8e3da2dd..19e38afbc5ee3f5a015fd55ecba813c26a9bca1a 100644 (file)
@@ -1,6 +1,7 @@
 config NET_XGENE
        tristate "APM X-Gene SoC Ethernet Driver"
        depends on HAS_DMA
+       depends on ARCH_XGENE || COMPILE_TEST
        select PHYLIB
        help
          This is the Ethernet driver for the on-chip ethernet interface on the
index a8bb8f664d3d7f9a031158d5cac82820fbed7d6d..ec56a9b65dc3a313e1b0571e8a58047c161f6507 100644 (file)
@@ -4786,6 +4786,11 @@ int bnx2x_change_mtu(struct net_device *dev, int new_mtu)
 {
        struct bnx2x *bp = netdev_priv(dev);
 
+       if (pci_num_vf(bp->pdev)) {
+               DP(BNX2X_MSG_IOV, "VFs are enabled, can not change MTU\n");
+               return -EPERM;
+       }
+
        if (bp->recovery_state != BNX2X_RECOVERY_DONE) {
                BNX2X_ERR("Can't perform change MTU during parity recovery\n");
                return -EAGAIN;
@@ -4938,11 +4943,6 @@ int bnx2x_resume(struct pci_dev *pdev)
        }
        bp = netdev_priv(dev);
 
-       if (pci_num_vf(bp->pdev)) {
-               DP(BNX2X_MSG_IOV, "VFs are enabled, can not change MTU\n");
-               return -EPERM;
-       }
-
        if (bp->recovery_state != BNX2X_RECOVERY_DONE) {
                BNX2X_ERR("Handling parity error recovery. Try again later\n");
                return -EAGAIN;
index 556dcc162a6252a36fe550110b4abbb3d1bbcf60..fd52ce95127ef98b7c0687594024357b05c1a848 100644 (file)
@@ -13371,8 +13371,13 @@ static int bnx2x_init_one(struct pci_dev *pdev,
        /* Management FW 'remembers' living interfaces. Allow it some time
         * to forget previously living interfaces, allowing a proper re-load.
         */
-       if (is_kdump_kernel())
-               msleep(5000);
+       if (is_kdump_kernel()) {
+               ktime_t now = ktime_get_boottime();
+               ktime_t fw_ready_time = ktime_set(5, 0);
+
+               if (ktime_before(now, fw_ready_time))
+                       msleep(ktime_ms_delta(fw_ready_time, now));
+       }
 
        /* An estimated maximum supported CoS number according to the chip
         * version.
index 4104d49f005d4a825eb14b99efeb5f158ab456d5..fc646a41d5481406400bb4013ced8f96cf236092 100644 (file)
@@ -350,6 +350,9 @@ static int macb_mii_probe(struct net_device *dev)
        else
                phydev->supported &= PHY_BASIC_FEATURES;
 
+       if (bp->caps & MACB_CAPS_NO_GIGABIT_HALF)
+               phydev->supported &= ~SUPPORTED_1000baseT_Half;
+
        phydev->advertising = phydev->supported;
 
        bp->link = 0;
@@ -981,7 +984,7 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id)
        struct macb_queue *queue = dev_id;
        struct macb *bp = queue->bp;
        struct net_device *dev = bp->dev;
-       u32 status;
+       u32 status, ctrl;
 
        status = queue_readl(queue, ISR);
 
@@ -1037,6 +1040,21 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id)
                 * add that if/when we get our hands on a full-blown MII PHY.
                 */
 
+               /* There is a hardware issue under heavy load where DMA can
+                * stop, this causes endless "used buffer descriptor read"
+                * interrupts but it can be cleared by re-enabling RX. See
+                * the at91 manual, section 41.3.1 or the Zynq manual
+                * section 16.7.4 for details.
+                */
+               if (status & MACB_BIT(RXUBR)) {
+                       ctrl = macb_readl(bp, NCR);
+                       macb_writel(bp, NCR, ctrl & ~MACB_BIT(RE));
+                       macb_writel(bp, NCR, ctrl | MACB_BIT(RE));
+
+                       if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE)
+                               macb_writel(bp, ISR, MACB_BIT(RXUBR));
+               }
+
                if (status & MACB_BIT(ISR_ROVR)) {
                        /* We missed at least one packet */
                        if (macb_is_gem(bp))
@@ -2684,6 +2702,14 @@ static const struct macb_config emac_config = {
        .init = at91ether_init,
 };
 
+static const struct macb_config zynq_config = {
+       .caps = MACB_CAPS_SG_DISABLED | MACB_CAPS_GIGABIT_MODE_AVAILABLE |
+               MACB_CAPS_NO_GIGABIT_HALF,
+       .dma_burst_length = 16,
+       .clk_init = macb_clk_init,
+       .init = macb_init,
+};
+
 static const struct of_device_id macb_dt_ids[] = {
        { .compatible = "cdns,at32ap7000-macb" },
        { .compatible = "cdns,at91sam9260-macb", .data = &at91sam9260_config },
@@ -2694,6 +2720,7 @@ static const struct of_device_id macb_dt_ids[] = {
        { .compatible = "atmel,sama5d4-gem", .data = &sama5d4_config },
        { .compatible = "cdns,at91rm9200-emac", .data = &emac_config },
        { .compatible = "cdns,emac", .data = &emac_config },
+       { .compatible = "cdns,zynq-gem", .data = &zynq_config },
        { /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, macb_dt_ids);
index eb7d76f7bf6aaf983e97408ced9b359b54c8ddc3..24b1d9bcd8654d5aba2401b7b6a85b563f09d9cc 100644 (file)
 #define MACB_CAPS_ISR_CLEAR_ON_WRITE           0x00000001
 #define MACB_CAPS_USRIO_HAS_CLKEN              0x00000002
 #define MACB_CAPS_USRIO_DEFAULT_IS_MII         0x00000004
+#define MACB_CAPS_NO_GIGABIT_HALF              0x00000008
 #define MACB_CAPS_FIFO_MODE                    0x10000000
 #define MACB_CAPS_GIGABIT_MODE_AVAILABLE       0x20000000
 #define MACB_CAPS_SG_DISABLED                  0x40000000
index de79193221903edee02810fe657ac44815e877ca..b9df0cbd0a3833321d1f73bc74258b50b137f225 100644 (file)
@@ -2084,12 +2084,8 @@ static void emac_ethtool_get_pauseparam(struct net_device *ndev,
 
 static int emac_get_regs_len(struct emac_instance *dev)
 {
-       if (emac_has_feature(dev, EMAC_FTR_EMAC4))
-               return sizeof(struct emac_ethtool_regs_subhdr) +
-                       EMAC4_ETHTOOL_REGS_SIZE(dev);
-       else
                return sizeof(struct emac_ethtool_regs_subhdr) +
-                       EMAC_ETHTOOL_REGS_SIZE(dev);
+                       sizeof(struct emac_regs);
 }
 
 static int emac_ethtool_get_regs_len(struct net_device *ndev)
@@ -2114,15 +2110,15 @@ static void *emac_dump_regs(struct emac_instance *dev, void *buf)
        struct emac_ethtool_regs_subhdr *hdr = buf;
 
        hdr->index = dev->cell_index;
-       if (emac_has_feature(dev, EMAC_FTR_EMAC4)) {
+       if (emac_has_feature(dev, EMAC_FTR_EMAC4SYNC)) {
+               hdr->version = EMAC4SYNC_ETHTOOL_REGS_VER;
+       } else if (emac_has_feature(dev, EMAC_FTR_EMAC4)) {
                hdr->version = EMAC4_ETHTOOL_REGS_VER;
-               memcpy_fromio(hdr + 1, dev->emacp, EMAC4_ETHTOOL_REGS_SIZE(dev));
-               return (void *)(hdr + 1) + EMAC4_ETHTOOL_REGS_SIZE(dev);
        } else {
                hdr->version = EMAC_ETHTOOL_REGS_VER;
-               memcpy_fromio(hdr + 1, dev->emacp, EMAC_ETHTOOL_REGS_SIZE(dev));
-               return (void *)(hdr + 1) + EMAC_ETHTOOL_REGS_SIZE(dev);
        }
+       memcpy_fromio(hdr + 1, dev->emacp, sizeof(struct emac_regs));
+       return (void *)(hdr + 1) + sizeof(struct emac_regs);
 }
 
 static void emac_ethtool_get_regs(struct net_device *ndev,
index 67f342a9f65e46fe8dd015b921fd144e30db286b..28df37420da963d5d8f3b3234e4f584442537121 100644 (file)
@@ -461,10 +461,7 @@ struct emac_ethtool_regs_subhdr {
 };
 
 #define EMAC_ETHTOOL_REGS_VER          0
-#define EMAC_ETHTOOL_REGS_SIZE(dev)    ((dev)->rsrc_regs.end - \
-                                        (dev)->rsrc_regs.start + 1)
-#define EMAC4_ETHTOOL_REGS_VER         1
-#define EMAC4_ETHTOOL_REGS_SIZE(dev)   ((dev)->rsrc_regs.end - \
-                                        (dev)->rsrc_regs.start + 1)
+#define EMAC4_ETHTOOL_REGS_VER         1
+#define EMAC4SYNC_ETHTOOL_REGS_VER     2
 
 #endif /* __IBM_NEWEMAC_CORE_H */
index 5d9ceb17b4cbad4f7e89cf0bb050e915f5b8d285..0abc942c966e4a377af222c1d876af6983edb91a 100644 (file)
@@ -40,6 +40,7 @@
 #include <linux/ptp_classify.h>
 #include <linux/mii.h>
 #include <linux/mdio.h>
+#include <linux/pm_qos.h>
 #include "hw.h"
 
 struct e1000_info;
index 1b0661e3573b78d73804ed59177420a4d6fde147..c754b2027281f8a2c0b18c079b31c2b7420eedbf 100644 (file)
@@ -610,7 +610,7 @@ static bool fm10k_clean_rx_irq(struct fm10k_q_vector *q_vector,
        unsigned int total_bytes = 0, total_packets = 0;
        u16 cleaned_count = fm10k_desc_unused(rx_ring);
 
-       do {
+       while (likely(total_packets < budget)) {
                union fm10k_rx_desc *rx_desc;
 
                /* return some buffers to hardware, one at a time is too slow */
@@ -659,7 +659,7 @@ static bool fm10k_clean_rx_irq(struct fm10k_q_vector *q_vector,
 
                /* update budget accounting */
                total_packets++;
-       } while (likely(total_packets < budget));
+       }
 
        /* place incomplete frames back on ring for completion */
        rx_ring->skb = skb;
index 8457d0306e3a76107c18ed524a3000d47b3ead6e..a0a9b1fcb5e8efcf4f7ebfe980459f64056e896f 100644 (file)
@@ -1036,7 +1036,7 @@ static void igb_reset_q_vector(struct igb_adapter *adapter, int v_idx)
                adapter->tx_ring[q_vector->tx.ring->queue_index] = NULL;
 
        if (q_vector->rx.ring)
-               adapter->tx_ring[q_vector->rx.ring->queue_index] = NULL;
+               adapter->rx_ring[q_vector->rx.ring->queue_index] = NULL;
 
        netif_napi_del(&q_vector->napi);
 
@@ -1207,6 +1207,8 @@ static int igb_alloc_q_vector(struct igb_adapter *adapter,
        q_vector = adapter->q_vector[v_idx];
        if (!q_vector)
                q_vector = kzalloc(size, GFP_KERNEL);
+       else
+               memset(q_vector, 0, size);
        if (!q_vector)
                return -ENOMEM;
 
index a16d267fbce4b0f6883c8cf5d43db1ad3bf7e458..e71cdde9cb017aecab834d2f2d9c5d4821c3d42e 100644 (file)
@@ -3612,7 +3612,7 @@ static int ixgbevf_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
        u8 *dst_mac = skb_header_pointer(skb, 0, 0, NULL);
 
        if (!dst_mac || is_link_local_ether_addr(dst_mac)) {
-               dev_kfree_skb(skb);
+               dev_kfree_skb_any(skb);
                return NETDEV_TX_OK;
        }
 
index 4f7dc044601e2751ad625e4c011aa3a1c328e62f..529ef0594b902ebaf2838cf478ef914a0b69d5b7 100644 (file)
@@ -714,8 +714,13 @@ static int mlx4_cmd_wait(struct mlx4_dev *dev, u64 in_param, u64 *out_param,
                                         msecs_to_jiffies(timeout))) {
                mlx4_warn(dev, "command 0x%x timed out (go bit not cleared)\n",
                          op);
-               err = -EIO;
-               goto out_reset;
+               if (op == MLX4_CMD_NOP) {
+                       err = -EBUSY;
+                       goto out;
+               } else {
+                       err = -EIO;
+                       goto out_reset;
+               }
        }
 
        err = context->result;
index 54f0e5ab2e55ca87dc66a2ef8b4e27062a634ce4..0a56f010c8468d0734c3afd791605843d373b91a 100644 (file)
@@ -139,7 +139,7 @@ static unsigned long en_stats_adder(__be64 *start, __be64 *next, int num)
        int i;
        int offset = next - start;
 
-       for (i = 0; i <= num; i++) {
+       for (i = 0; i < num; i++) {
                ret += be64_to_cpu(*curr);
                curr += offset;
        }
index c7f28bf4b8e21436cc927c8212c5cc6b57706e51..bafe2180cf0c413c4d971f8043e401a018dc8100 100644 (file)
@@ -2845,7 +2845,7 @@ int mlx4_SW2HW_EQ_wrapper(struct mlx4_dev *dev, int slave,
 {
        int err;
        int eqn = vhcr->in_modifier;
-       int res_id = (slave << 8) | eqn;
+       int res_id = (slave << 10) | eqn;
        struct mlx4_eq_context *eqc = inbox->buf;
        int mtt_base = eq_get_mtt_addr(eqc) / dev->caps.mtt_entry_sz;
        int mtt_size = eq_get_mtt_size(eqc);
@@ -3051,7 +3051,7 @@ int mlx4_HW2SW_EQ_wrapper(struct mlx4_dev *dev, int slave,
                          struct mlx4_cmd_info *cmd)
 {
        int eqn = vhcr->in_modifier;
-       int res_id = eqn | (slave << 8);
+       int res_id = eqn | (slave << 10);
        struct res_eq *eq;
        int err;
 
@@ -3108,7 +3108,7 @@ int mlx4_GEN_EQE(struct mlx4_dev *dev, int slave, struct mlx4_eqe *eqe)
                return 0;
 
        mutex_lock(&priv->mfunc.master.gen_eqe_mutex[slave]);
-       res_id = (slave << 8) | event_eq->eqn;
+       res_id = (slave << 10) | event_eq->eqn;
        err = get_res(dev, slave, res_id, RES_EQ, &req);
        if (err)
                goto unlock;
@@ -3131,7 +3131,7 @@ int mlx4_GEN_EQE(struct mlx4_dev *dev, int slave, struct mlx4_eqe *eqe)
 
        memcpy(mailbox->buf, (u8 *) eqe, 28);
 
-       in_modifier = (slave & 0xff) | ((event_eq->eqn & 0xff) << 16);
+       in_modifier = (slave & 0xff) | ((event_eq->eqn & 0x3ff) << 16);
 
        err = mlx4_cmd(dev, mailbox->dma, in_modifier, 0,
                       MLX4_CMD_GEN_EQE, MLX4_CMD_TIME_CLASS_B,
@@ -3157,7 +3157,7 @@ int mlx4_QUERY_EQ_wrapper(struct mlx4_dev *dev, int slave,
                          struct mlx4_cmd_info *cmd)
 {
        int eqn = vhcr->in_modifier;
-       int res_id = eqn | (slave << 8);
+       int res_id = eqn | (slave << 10);
        struct res_eq *eq;
        int err;
 
@@ -3187,7 +3187,7 @@ int mlx4_SW2HW_CQ_wrapper(struct mlx4_dev *dev, int slave,
        int cqn = vhcr->in_modifier;
        struct mlx4_cq_context *cqc = inbox->buf;
        int mtt_base = cq_get_mtt_addr(cqc) / dev->caps.mtt_entry_sz;
-       struct res_cq *cq;
+       struct res_cq *cq = NULL;
        struct res_mtt *mtt;
 
        err = cq_res_start_move_to(dev, slave, cqn, RES_CQ_HW, &cq);
@@ -3223,7 +3223,7 @@ int mlx4_HW2SW_CQ_wrapper(struct mlx4_dev *dev, int slave,
 {
        int err;
        int cqn = vhcr->in_modifier;
-       struct res_cq *cq;
+       struct res_cq *cq = NULL;
 
        err = cq_res_start_move_to(dev, slave, cqn, RES_CQ_ALLOCATED, &cq);
        if (err)
@@ -3362,7 +3362,7 @@ int mlx4_SW2HW_SRQ_wrapper(struct mlx4_dev *dev, int slave,
        int err;
        int srqn = vhcr->in_modifier;
        struct res_mtt *mtt;
-       struct res_srq *srq;
+       struct res_srq *srq = NULL;
        struct mlx4_srq_context *srqc = inbox->buf;
        int mtt_base = srq_get_mtt_addr(srqc) / dev->caps.mtt_entry_sz;
 
@@ -3406,7 +3406,7 @@ int mlx4_HW2SW_SRQ_wrapper(struct mlx4_dev *dev, int slave,
 {
        int err;
        int srqn = vhcr->in_modifier;
-       struct res_srq *srq;
+       struct res_srq *srq = NULL;
 
        err = srq_res_start_move_to(dev, slave, srqn, RES_SRQ_ALLOCATED, &srq);
        if (err)
@@ -4714,13 +4714,13 @@ static void rem_slave_eqs(struct mlx4_dev *dev, int slave)
                                        break;
 
                                case RES_EQ_HW:
-                                       err = mlx4_cmd(dev, slave, eqn & 0xff,
+                                       err = mlx4_cmd(dev, slave, eqn & 0x3ff,
                                                       1, MLX4_CMD_HW2SW_EQ,
                                                       MLX4_CMD_TIME_CLASS_A,
                                                       MLX4_CMD_NATIVE);
                                        if (err)
                                                mlx4_dbg(dev, "rem_slave_eqs: failed to move slave %d eqs %d to SW ownership\n",
-                                                        slave, eqn);
+                                                        slave, eqn & 0x3ff);
                                        atomic_dec(&eq->mtt->ref_count);
                                        state = RES_EQ_RESERVED;
                                        break;
index 8da7c3faf8178c05576c74833fc828f197104f52..7b43a3b4abdcbc7bc1cdfd4d13c611563e2760a2 100644 (file)
@@ -1764,7 +1764,7 @@ int netxen_process_cmd_ring(struct netxen_adapter *adapter)
        int done = 0;
        struct nx_host_tx_ring *tx_ring = adapter->tx_ring;
 
-       if (!spin_trylock(&adapter->tx_clean_lock))
+       if (!spin_trylock_bh(&adapter->tx_clean_lock))
                return 1;
 
        sw_consumer = tx_ring->sw_consumer;
@@ -1819,7 +1819,7 @@ int netxen_process_cmd_ring(struct netxen_adapter *adapter)
         */
        hw_consumer = le32_to_cpu(*(tx_ring->hw_consumer));
        done = (sw_consumer == hw_consumer);
-       spin_unlock(&adapter->tx_clean_lock);
+       spin_unlock_bh(&adapter->tx_clean_lock);
 
        return done;
 }
index e0c31e3947d1091371bfa742fbea5cee9743002d..6409a06bbdf633b0ce440bf817aabfe69311dd1e 100644 (file)
@@ -3025,9 +3025,9 @@ netxen_sysfs_read_dimm(struct file *filp, struct kobject *kobj,
        u8 dw, rows, cols, banks, ranks;
        u32 val;
 
-       if (size != sizeof(struct netxen_dimm_cfg)) {
+       if (size < attr->size) {
                netdev_err(netdev, "Invalid size\n");
-               return -1;
+               return -EINVAL;
        }
 
        memset(&dimm, 0, sizeof(struct netxen_dimm_cfg));
@@ -3137,7 +3137,7 @@ netxen_sysfs_read_dimm(struct file *filp, struct kobject *kobj,
 
 static struct bin_attribute bin_attr_dimm = {
        .attr = { .name = "dimm", .mode = (S_IRUGO | S_IWUSR) },
-       .size = 0,
+       .size = sizeof(struct netxen_dimm_cfg),
        .read = netxen_sysfs_read_dimm,
 };
 
index f66641d961e3bc18ae15a301323497ff9fb265e8..6af028d5f9bcbdcc3aae303a114fd64d87986eed 100644 (file)
@@ -912,6 +912,8 @@ qca_spi_probe(struct spi_device *spi_device)
        qca->spi_dev = spi_device;
        qca->legacy_mode = legacy_mode;
 
+       spi_set_drvdata(spi_device, qcaspi_devs);
+
        mac = of_get_mac_address(spi_device->dev.of_node);
 
        if (mac)
@@ -944,8 +946,6 @@ qca_spi_probe(struct spi_device *spi_device)
                return -EFAULT;
        }
 
-       spi_set_drvdata(spi_device, qcaspi_devs);
-
        qcaspi_init_device_debugfs(qca);
 
        return 0;
index c70ab40d86989974d54c9161bf7acd8558d93c74..3df51faf18ae3ba8ce6bb7f49e6f51e4da1be738 100644 (file)
@@ -6884,7 +6884,7 @@ static void r8169_csum_workaround(struct rtl8169_private *tp,
                        rtl8169_start_xmit(nskb, tp->dev);
                } while (segs);
 
-               dev_kfree_skb(skb);
+               dev_consume_skb_any(skb);
        } else if (skb->ip_summed == CHECKSUM_PARTIAL) {
                if (skb_checksum_help(skb) < 0)
                        goto drop;
@@ -6896,7 +6896,7 @@ static void r8169_csum_workaround(struct rtl8169_private *tp,
 drop:
                stats = &tp->dev->stats;
                stats->tx_dropped++;
-               dev_kfree_skb(skb);
+               dev_kfree_skb_any(skb);
        }
 }
 
index ec251531bd9f8ecd1e64295b4f1f5c35fe475b79..cf98cc9bbc8dc9d57545bbbe25592f6878fcf324 100644 (file)
@@ -2921,10 +2921,11 @@ static int rocker_port_ipv4_resolve(struct rocker_port *rocker_port,
        struct neighbour *n = __ipv4_neigh_lookup(dev, (__force u32)ip_addr);
        int err = 0;
 
-       if (!n)
+       if (!n) {
                n = neigh_create(&arp_tbl, &ip_addr, dev);
-       if (!n)
-               return -ENOMEM;
+               if (IS_ERR(n))
+                       return IS_ERR(n);
+       }
 
        /* If the neigh is already resolved, then go ahead and
         * install the entry, otherwise start the ARP process to
@@ -2936,6 +2937,7 @@ static int rocker_port_ipv4_resolve(struct rocker_port *rocker_port,
        else
                neigh_event_send(n, NULL);
 
+       neigh_release(n);
        return err;
 }
 
index 14b363a25c023c70f13b73e9c485bf28e9d533e2..630f0b7800e47e085c5ffb2db6ac23efef9ad08c 100644 (file)
@@ -2238,9 +2238,10 @@ static int smc_drv_probe(struct platform_device *pdev)
        const struct of_device_id *match = NULL;
        struct smc_local *lp;
        struct net_device *ndev;
-       struct resource *res, *ires;
+       struct resource *res;
        unsigned int __iomem *addr;
        unsigned long irq_flags = SMC_IRQ_FLAGS;
+       unsigned long irq_resflags;
        int ret;
 
        ndev = alloc_etherdev(sizeof(struct smc_local));
@@ -2332,16 +2333,19 @@ static int smc_drv_probe(struct platform_device *pdev)
                goto out_free_netdev;
        }
 
-       ires = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-       if (!ires) {
+       ndev->irq = platform_get_irq(pdev, 0);
+       if (ndev->irq <= 0) {
                ret = -ENODEV;
                goto out_release_io;
        }
-
-       ndev->irq = ires->start;
-
-       if (irq_flags == -1 || ires->flags & IRQF_TRIGGER_MASK)
-               irq_flags = ires->flags & IRQF_TRIGGER_MASK;
+       /*
+        * If this platform does not specify any special irqflags, or if
+        * the resource supplies a trigger, override the irqflags with
+        * the trigger flags from the resource.
+        */
+       irq_resflags = irqd_get_trigger_type(irq_get_irq_data(ndev->irq));
+       if (irq_flags == -1 || irq_resflags & IRQF_TRIGGER_MASK)
+               irq_flags = irq_resflags & IRQF_TRIGGER_MASK;
 
        ret = smc_request_attrib(pdev, ndev);
        if (ret)
index 41047c9143d0a66cde1441311fb5feb3ce0796d0..959aeeade0c97b8cbf5ee27024ecda185c6258b2 100644 (file)
@@ -2418,9 +2418,9 @@ static int smsc911x_drv_probe(struct platform_device *pdev)
        struct net_device *dev;
        struct smsc911x_data *pdata;
        struct smsc911x_platform_config *config = dev_get_platdata(&pdev->dev);
-       struct resource *res, *irq_res;
+       struct resource *res;
        unsigned int intcfg = 0;
-       int res_size, irq_flags;
+       int res_size, irq, irq_flags;
        int retval;
 
        res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
@@ -2434,8 +2434,8 @@ static int smsc911x_drv_probe(struct platform_device *pdev)
        }
        res_size = resource_size(res);
 
-       irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-       if (!irq_res) {
+       irq = platform_get_irq(pdev, 0);
+       if (irq <= 0) {
                pr_warn("Could not allocate irq resource\n");
                retval = -ENODEV;
                goto out_0;
@@ -2455,8 +2455,8 @@ static int smsc911x_drv_probe(struct platform_device *pdev)
        SET_NETDEV_DEV(dev, &pdev->dev);
 
        pdata = netdev_priv(dev);
-       dev->irq = irq_res->start;
-       irq_flags = irq_res->flags & IRQF_TRIGGER_MASK;
+       dev->irq = irq;
+       irq_flags = irq_get_trigger_type(irq);
        pdata->ioaddr = ioremap_nocache(res->start, res_size);
 
        pdata->dev = dev;
index 2ac9552d1fa385953e261ff3797c74b8d5ad4add..73bab983edd96a47169bf4b1957e5fd13c28a3a0 100644 (file)
@@ -117,6 +117,12 @@ struct stmmac_priv {
        int use_riwt;
        int irq_wake;
        spinlock_t ptp_lock;
+
+#ifdef CONFIG_DEBUG_FS
+       struct dentry *dbgfs_dir;
+       struct dentry *dbgfs_rings_status;
+       struct dentry *dbgfs_dma_cap;
+#endif
 };
 
 int stmmac_mdio_unregister(struct net_device *ndev);
index 05c146f718a36551c4fe4ada4871f2612f16571d..2c5ce2baca8712790d51096a53868b84466f7dde 100644 (file)
@@ -118,7 +118,7 @@ static irqreturn_t stmmac_interrupt(int irq, void *dev_id);
 
 #ifdef CONFIG_DEBUG_FS
 static int stmmac_init_fs(struct net_device *dev);
-static void stmmac_exit_fs(void);
+static void stmmac_exit_fs(struct net_device *dev);
 #endif
 
 #define STMMAC_COAL_TIMER(x) (jiffies + usecs_to_jiffies(x))
@@ -1916,7 +1916,7 @@ static int stmmac_release(struct net_device *dev)
        netif_carrier_off(dev);
 
 #ifdef CONFIG_DEBUG_FS
-       stmmac_exit_fs();
+       stmmac_exit_fs(dev);
 #endif
 
        stmmac_release_ptp(priv);
@@ -2508,8 +2508,6 @@ static int stmmac_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 
 #ifdef CONFIG_DEBUG_FS
 static struct dentry *stmmac_fs_dir;
-static struct dentry *stmmac_rings_status;
-static struct dentry *stmmac_dma_cap;
 
 static void sysfs_display_ring(void *head, int size, int extend_desc,
                               struct seq_file *seq)
@@ -2648,36 +2646,39 @@ static const struct file_operations stmmac_dma_cap_fops = {
 
 static int stmmac_init_fs(struct net_device *dev)
 {
-       /* Create debugfs entries */
-       stmmac_fs_dir = debugfs_create_dir(STMMAC_RESOURCE_NAME, NULL);
+       struct stmmac_priv *priv = netdev_priv(dev);
+
+       /* Create per netdev entries */
+       priv->dbgfs_dir = debugfs_create_dir(dev->name, stmmac_fs_dir);
 
-       if (!stmmac_fs_dir || IS_ERR(stmmac_fs_dir)) {
-               pr_err("ERROR %s, debugfs create directory failed\n",
-                      STMMAC_RESOURCE_NAME);
+       if (!priv->dbgfs_dir || IS_ERR(priv->dbgfs_dir)) {
+               pr_err("ERROR %s/%s, debugfs create directory failed\n",
+                      STMMAC_RESOURCE_NAME, dev->name);
 
                return -ENOMEM;
        }
 
        /* Entry to report DMA RX/TX rings */
-       stmmac_rings_status = debugfs_create_file("descriptors_status",
-                                                 S_IRUGO, stmmac_fs_dir, dev,
-                                                 &stmmac_rings_status_fops);
+       priv->dbgfs_rings_status =
+               debugfs_create_file("descriptors_status", S_IRUGO,
+                                   priv->dbgfs_dir, dev,
+                                   &stmmac_rings_status_fops);
 
-       if (!stmmac_rings_status || IS_ERR(stmmac_rings_status)) {
+       if (!priv->dbgfs_rings_status || IS_ERR(priv->dbgfs_rings_status)) {
                pr_info("ERROR creating stmmac ring debugfs file\n");
-               debugfs_remove(stmmac_fs_dir);
+               debugfs_remove_recursive(priv->dbgfs_dir);
 
                return -ENOMEM;
        }
 
        /* Entry to report the DMA HW features */
-       stmmac_dma_cap = debugfs_create_file("dma_cap", S_IRUGO, stmmac_fs_dir,
-                                            dev, &stmmac_dma_cap_fops);
+       priv->dbgfs_dma_cap = debugfs_create_file("dma_cap", S_IRUGO,
+                                           priv->dbgfs_dir,
+                                           dev, &stmmac_dma_cap_fops);
 
-       if (!stmmac_dma_cap || IS_ERR(stmmac_dma_cap)) {
+       if (!priv->dbgfs_dma_cap || IS_ERR(priv->dbgfs_dma_cap)) {
                pr_info("ERROR creating stmmac MMC debugfs file\n");
-               debugfs_remove(stmmac_rings_status);
-               debugfs_remove(stmmac_fs_dir);
+               debugfs_remove_recursive(priv->dbgfs_dir);
 
                return -ENOMEM;
        }
@@ -2685,11 +2686,11 @@ static int stmmac_init_fs(struct net_device *dev)
        return 0;
 }
 
-static void stmmac_exit_fs(void)
+static void stmmac_exit_fs(struct net_device *dev)
 {
-       debugfs_remove(stmmac_rings_status);
-       debugfs_remove(stmmac_dma_cap);
-       debugfs_remove(stmmac_fs_dir);
+       struct stmmac_priv *priv = netdev_priv(dev);
+
+       debugfs_remove_recursive(priv->dbgfs_dir);
 }
 #endif /* CONFIG_DEBUG_FS */
 
@@ -3149,6 +3150,35 @@ static int __init stmmac_cmdline_opt(char *str)
 __setup("stmmaceth=", stmmac_cmdline_opt);
 #endif /* MODULE */
 
+static int __init stmmac_init(void)
+{
+#ifdef CONFIG_DEBUG_FS
+       /* Create debugfs main directory if it doesn't exist yet */
+       if (!stmmac_fs_dir) {
+               stmmac_fs_dir = debugfs_create_dir(STMMAC_RESOURCE_NAME, NULL);
+
+               if (!stmmac_fs_dir || IS_ERR(stmmac_fs_dir)) {
+                       pr_err("ERROR %s, debugfs create directory failed\n",
+                              STMMAC_RESOURCE_NAME);
+
+                       return -ENOMEM;
+               }
+       }
+#endif
+
+       return 0;
+}
+
+static void __exit stmmac_exit(void)
+{
+#ifdef CONFIG_DEBUG_FS
+       debugfs_remove_recursive(stmmac_fs_dir);
+#endif
+}
+
+module_init(stmmac_init)
+module_exit(stmmac_exit)
+
 MODULE_DESCRIPTION("STMMAC 10/100/1000 Ethernet device driver");
 MODULE_AUTHOR("Giuseppe Cavallaro <peppe.cavallaro@st.com>");
 MODULE_LICENSE("GPL");
index 705bbdf9394058944927fd575d1dfc47cdb283d5..68aec5c460db46c1378cdf122c3ad8f4eba15e86 100644 (file)
@@ -23,6 +23,7 @@
 *******************************************************************************/
 
 #include <linux/platform_device.h>
+#include <linux/module.h>
 #include <linux/io.h>
 #include <linux/of.h>
 #include <linux/of_net.h>
index 690a4c36b3166c76b4d8ed63f9d21574ecac8bb3..af2694dc6f90146fc2afe9073a0dde7058731f59 100644 (file)
@@ -707,8 +707,8 @@ static int temac_start_xmit(struct sk_buff *skb, struct net_device *ndev)
 
        cur_p->app0 |= STS_CTRL_APP0_SOP;
        cur_p->len = skb_headlen(skb);
-       cur_p->phys = dma_map_single(ndev->dev.parent, skb->data, skb->len,
-                                    DMA_TO_DEVICE);
+       cur_p->phys = dma_map_single(ndev->dev.parent, skb->data,
+                                    skb_headlen(skb), DMA_TO_DEVICE);
        cur_p->app4 = (unsigned long)skb;
 
        for (ii = 0; ii < num_frag; ii++) {
index 2d9ef533cc4837c5bd7b46c96958f9f1b9eda323..ea091bc5ff09dad379fde915fbb7ec073c613aa1 100644 (file)
@@ -826,7 +826,6 @@ int netvsc_send(struct hv_device *device,
        u16 q_idx = packet->q_idx;
        u32 pktlen = packet->total_data_buflen, msd_len = 0;
        unsigned int section_index = NETVSC_INVALID_INDEX;
-       struct sk_buff *skb = NULL;
        unsigned long flag;
        struct multi_send_data *msdp;
        struct hv_netvsc_packet *msd_send = NULL, *cur_send = NULL;
@@ -924,12 +923,8 @@ int netvsc_send(struct hv_device *device,
        if (cur_send)
                ret = netvsc_send_pkt(cur_send, net_device);
 
-       if (ret != 0) {
-               if (section_index != NETVSC_INVALID_INDEX)
-                       netvsc_free_send_slot(net_device, section_index);
-       } else if (skb) {
-               dev_kfree_skb_any(skb);
-       }
+       if (ret != 0 && section_index != NETVSC_INVALID_INDEX)
+               netvsc_free_send_slot(net_device, section_index);
 
        return ret;
 }
index 38026650c0387ecb101d085e24273bf24ded2783..67d00fbc2e0e29e7bd426ed8f7d21b22bf6772fc 100644 (file)
@@ -85,6 +85,7 @@ struct at86rf230_local {
        struct ieee802154_hw *hw;
        struct at86rf2xx_chip_data *data;
        struct regmap *regmap;
+       int slp_tr;
 
        struct completion state_complete;
        struct at86rf230_state_change state;
@@ -95,163 +96,164 @@ struct at86rf230_local {
        unsigned long cal_timeout;
        s8 max_frame_retries;
        bool is_tx;
+       bool is_tx_from_off;
        u8 tx_retry;
        struct sk_buff *tx_skb;
        struct at86rf230_state_change tx;
 };
 
-#define        RG_TRX_STATUS   (0x01)
-#define        SR_TRX_STATUS           0x01, 0x1f, 0
-#define        SR_RESERVED_01_3        0x01, 0x20, 5
-#define        SR_CCA_STATUS           0x01, 0x40, 6
-#define        SR_CCA_DONE             0x01, 0x80, 7
-#define        RG_TRX_STATE    (0x02)
-#define        SR_TRX_CMD              0x02, 0x1f, 0
-#define        SR_TRAC_STATUS          0x02, 0xe0, 5
-#define        RG_TRX_CTRL_0   (0x03)
-#define        SR_CLKM_CTRL            0x03, 0x07, 0
-#define        SR_CLKM_SHA_SEL         0x03, 0x08, 3
-#define        SR_PAD_IO_CLKM          0x03, 0x30, 4
-#define        SR_PAD_IO               0x03, 0xc0, 6
-#define        RG_TRX_CTRL_1   (0x04)
-#define        SR_IRQ_POLARITY         0x04, 0x01, 0
-#define        SR_IRQ_MASK_MODE        0x04, 0x02, 1
-#define        SR_SPI_CMD_MODE         0x04, 0x0c, 2
-#define        SR_RX_BL_CTRL           0x04, 0x10, 4
-#define        SR_TX_AUTO_CRC_ON       0x04, 0x20, 5
-#define        SR_IRQ_2_EXT_EN         0x04, 0x40, 6
-#define        SR_PA_EXT_EN            0x04, 0x80, 7
-#define        RG_PHY_TX_PWR   (0x05)
-#define        SR_TX_PWR               0x05, 0x0f, 0
-#define        SR_PA_LT                0x05, 0x30, 4
-#define        SR_PA_BUF_LT            0x05, 0xc0, 6
-#define        RG_PHY_RSSI     (0x06)
-#define        SR_RSSI                 0x06, 0x1f, 0
-#define        SR_RND_VALUE            0x06, 0x60, 5
-#define        SR_RX_CRC_VALID         0x06, 0x80, 7
-#define        RG_PHY_ED_LEVEL (0x07)
-#define        SR_ED_LEVEL             0x07, 0xff, 0
-#define        RG_PHY_CC_CCA   (0x08)
-#define        SR_CHANNEL              0x08, 0x1f, 0
-#define        SR_CCA_MODE             0x08, 0x60, 5
-#define        SR_CCA_REQUEST          0x08, 0x80, 7
-#define        RG_CCA_THRES    (0x09)
-#define        SR_CCA_ED_THRES         0x09, 0x0f, 0
-#define        SR_RESERVED_09_1        0x09, 0xf0, 4
-#define        RG_RX_CTRL      (0x0a)
-#define        SR_PDT_THRES            0x0a, 0x0f, 0
-#define        SR_RESERVED_0a_1        0x0a, 0xf0, 4
-#define        RG_SFD_VALUE    (0x0b)
-#define        SR_SFD_VALUE            0x0b, 0xff, 0
-#define        RG_TRX_CTRL_2   (0x0c)
-#define        SR_OQPSK_DATA_RATE      0x0c, 0x03, 0
-#define        SR_SUB_MODE             0x0c, 0x04, 2
-#define        SR_BPSK_QPSK            0x0c, 0x08, 3
-#define        SR_OQPSK_SUB1_RC_EN     0x0c, 0x10, 4
-#define        SR_RESERVED_0c_5        0x0c, 0x60, 5
-#define        SR_RX_SAFE_MODE         0x0c, 0x80, 7
-#define        RG_ANT_DIV      (0x0d)
-#define        SR_ANT_CTRL             0x0d, 0x03, 0
-#define        SR_ANT_EXT_SW_EN        0x0d, 0x04, 2
-#define        SR_ANT_DIV_EN           0x0d, 0x08, 3
-#define        SR_RESERVED_0d_2        0x0d, 0x70, 4
-#define        SR_ANT_SEL              0x0d, 0x80, 7
-#define        RG_IRQ_MASK     (0x0e)
-#define        SR_IRQ_MASK             0x0e, 0xff, 0
-#define        RG_IRQ_STATUS   (0x0f)
-#define        SR_IRQ_0_PLL_LOCK       0x0f, 0x01, 0
-#define        SR_IRQ_1_PLL_UNLOCK     0x0f, 0x02, 1
-#define        SR_IRQ_2_RX_START       0x0f, 0x04, 2
-#define        SR_IRQ_3_TRX_END        0x0f, 0x08, 3
-#define        SR_IRQ_4_CCA_ED_DONE    0x0f, 0x10, 4
-#define        SR_IRQ_5_AMI            0x0f, 0x20, 5
-#define        SR_IRQ_6_TRX_UR         0x0f, 0x40, 6
-#define        SR_IRQ_7_BAT_LOW        0x0f, 0x80, 7
-#define        RG_VREG_CTRL    (0x10)
-#define        SR_RESERVED_10_6        0x10, 0x03, 0
-#define        SR_DVDD_OK              0x10, 0x04, 2
-#define        SR_DVREG_EXT            0x10, 0x08, 3
-#define        SR_RESERVED_10_3        0x10, 0x30, 4
-#define        SR_AVDD_OK              0x10, 0x40, 6
-#define        SR_AVREG_EXT            0x10, 0x80, 7
-#define        RG_BATMON       (0x11)
-#define        SR_BATMON_VTH           0x11, 0x0f, 0
-#define        SR_BATMON_HR            0x11, 0x10, 4
-#define        SR_BATMON_OK            0x11, 0x20, 5
-#define        SR_RESERVED_11_1        0x11, 0xc0, 6
-#define        RG_XOSC_CTRL    (0x12)
-#define        SR_XTAL_TRIM            0x12, 0x0f, 0
-#define        SR_XTAL_MODE            0x12, 0xf0, 4
-#define        RG_RX_SYN       (0x15)
-#define        SR_RX_PDT_LEVEL         0x15, 0x0f, 0
-#define        SR_RESERVED_15_2        0x15, 0x70, 4
-#define        SR_RX_PDT_DIS           0x15, 0x80, 7
-#define        RG_XAH_CTRL_1   (0x17)
-#define        SR_RESERVED_17_8        0x17, 0x01, 0
-#define        SR_AACK_PROM_MODE       0x17, 0x02, 1
-#define        SR_AACK_ACK_TIME        0x17, 0x04, 2
-#define        SR_RESERVED_17_5        0x17, 0x08, 3
-#define        SR_AACK_UPLD_RES_FT     0x17, 0x10, 4
-#define        SR_AACK_FLTR_RES_FT     0x17, 0x20, 5
-#define        SR_CSMA_LBT_MODE        0x17, 0x40, 6
-#define        SR_RESERVED_17_1        0x17, 0x80, 7
-#define        RG_FTN_CTRL     (0x18)
-#define        SR_RESERVED_18_2        0x18, 0x7f, 0
-#define        SR_FTN_START            0x18, 0x80, 7
-#define        RG_PLL_CF       (0x1a)
-#define        SR_RESERVED_1a_2        0x1a, 0x7f, 0
-#define        SR_PLL_CF_START         0x1a, 0x80, 7
-#define        RG_PLL_DCU      (0x1b)
-#define        SR_RESERVED_1b_3        0x1b, 0x3f, 0
-#define        SR_RESERVED_1b_2        0x1b, 0x40, 6
-#define        SR_PLL_DCU_START        0x1b, 0x80, 7
-#define        RG_PART_NUM     (0x1c)
-#define        SR_PART_NUM             0x1c, 0xff, 0
-#define        RG_VERSION_NUM  (0x1d)
-#define        SR_VERSION_NUM          0x1d, 0xff, 0
-#define        RG_MAN_ID_0     (0x1e)
-#define        SR_MAN_ID_0             0x1e, 0xff, 0
-#define        RG_MAN_ID_1     (0x1f)
-#define        SR_MAN_ID_1             0x1f, 0xff, 0
-#define        RG_SHORT_ADDR_0 (0x20)
-#define        SR_SHORT_ADDR_0         0x20, 0xff, 0
-#define        RG_SHORT_ADDR_1 (0x21)
-#define        SR_SHORT_ADDR_1         0x21, 0xff, 0
-#define        RG_PAN_ID_0     (0x22)
-#define        SR_PAN_ID_0             0x22, 0xff, 0
-#define        RG_PAN_ID_1     (0x23)
-#define        SR_PAN_ID_1             0x23, 0xff, 0
-#define        RG_IEEE_ADDR_0  (0x24)
-#define        SR_IEEE_ADDR_0          0x24, 0xff, 0
-#define        RG_IEEE_ADDR_1  (0x25)
-#define        SR_IEEE_ADDR_1          0x25, 0xff, 0
-#define        RG_IEEE_ADDR_2  (0x26)
-#define        SR_IEEE_ADDR_2          0x26, 0xff, 0
-#define        RG_IEEE_ADDR_3  (0x27)
-#define        SR_IEEE_ADDR_3          0x27, 0xff, 0
-#define        RG_IEEE_ADDR_4  (0x28)
-#define        SR_IEEE_ADDR_4          0x28, 0xff, 0
-#define        RG_IEEE_ADDR_5  (0x29)
-#define        SR_IEEE_ADDR_5          0x29, 0xff, 0
-#define        RG_IEEE_ADDR_6  (0x2a)
-#define        SR_IEEE_ADDR_6          0x2a, 0xff, 0
-#define        RG_IEEE_ADDR_7  (0x2b)
-#define        SR_IEEE_ADDR_7          0x2b, 0xff, 0
-#define        RG_XAH_CTRL_0   (0x2c)
-#define        SR_SLOTTED_OPERATION    0x2c, 0x01, 0
-#define        SR_MAX_CSMA_RETRIES     0x2c, 0x0e, 1
-#define        SR_MAX_FRAME_RETRIES    0x2c, 0xf0, 4
-#define        RG_CSMA_SEED_0  (0x2d)
-#define        SR_CSMA_SEED_0          0x2d, 0xff, 0
-#define        RG_CSMA_SEED_1  (0x2e)
-#define        SR_CSMA_SEED_1          0x2e, 0x07, 0
-#define        SR_AACK_I_AM_COORD      0x2e, 0x08, 3
-#define        SR_AACK_DIS_ACK         0x2e, 0x10, 4
-#define        SR_AACK_SET_PD          0x2e, 0x20, 5
-#define        SR_AACK_FVN_MODE        0x2e, 0xc0, 6
-#define        RG_CSMA_BE      (0x2f)
-#define        SR_MIN_BE               0x2f, 0x0f, 0
-#define        SR_MAX_BE               0x2f, 0xf0, 4
+#define RG_TRX_STATUS  (0x01)
+#define SR_TRX_STATUS          0x01, 0x1f, 0
+#define SR_RESERVED_01_3       0x01, 0x20, 5
+#define SR_CCA_STATUS          0x01, 0x40, 6
+#define SR_CCA_DONE            0x01, 0x80, 7
+#define RG_TRX_STATE   (0x02)
+#define SR_TRX_CMD             0x02, 0x1f, 0
+#define SR_TRAC_STATUS         0x02, 0xe0, 5
+#define RG_TRX_CTRL_0  (0x03)
+#define SR_CLKM_CTRL           0x03, 0x07, 0
+#define SR_CLKM_SHA_SEL                0x03, 0x08, 3
+#define SR_PAD_IO_CLKM         0x03, 0x30, 4
+#define SR_PAD_IO              0x03, 0xc0, 6
+#define RG_TRX_CTRL_1  (0x04)
+#define SR_IRQ_POLARITY                0x04, 0x01, 0
+#define SR_IRQ_MASK_MODE       0x04, 0x02, 1
+#define SR_SPI_CMD_MODE                0x04, 0x0c, 2
+#define SR_RX_BL_CTRL          0x04, 0x10, 4
+#define SR_TX_AUTO_CRC_ON      0x04, 0x20, 5
+#define SR_IRQ_2_EXT_EN                0x04, 0x40, 6
+#define SR_PA_EXT_EN           0x04, 0x80, 7
+#define RG_PHY_TX_PWR  (0x05)
+#define SR_TX_PWR              0x05, 0x0f, 0
+#define SR_PA_LT               0x05, 0x30, 4
+#define SR_PA_BUF_LT           0x05, 0xc0, 6
+#define RG_PHY_RSSI    (0x06)
+#define SR_RSSI                        0x06, 0x1f, 0
+#define SR_RND_VALUE           0x06, 0x60, 5
+#define SR_RX_CRC_VALID                0x06, 0x80, 7
+#define RG_PHY_ED_LEVEL        (0x07)
+#define SR_ED_LEVEL            0x07, 0xff, 0
+#define RG_PHY_CC_CCA  (0x08)
+#define SR_CHANNEL             0x08, 0x1f, 0
+#define SR_CCA_MODE            0x08, 0x60, 5
+#define SR_CCA_REQUEST         0x08, 0x80, 7
+#define RG_CCA_THRES   (0x09)
+#define SR_CCA_ED_THRES                0x09, 0x0f, 0
+#define SR_RESERVED_09_1       0x09, 0xf0, 4
+#define RG_RX_CTRL     (0x0a)
+#define SR_PDT_THRES           0x0a, 0x0f, 0
+#define SR_RESERVED_0a_1       0x0a, 0xf0, 4
+#define RG_SFD_VALUE   (0x0b)
+#define SR_SFD_VALUE           0x0b, 0xff, 0
+#define RG_TRX_CTRL_2  (0x0c)
+#define SR_OQPSK_DATA_RATE     0x0c, 0x03, 0
+#define SR_SUB_MODE            0x0c, 0x04, 2
+#define SR_BPSK_QPSK           0x0c, 0x08, 3
+#define SR_OQPSK_SUB1_RC_EN    0x0c, 0x10, 4
+#define SR_RESERVED_0c_5       0x0c, 0x60, 5
+#define SR_RX_SAFE_MODE                0x0c, 0x80, 7
+#define RG_ANT_DIV     (0x0d)
+#define SR_ANT_CTRL            0x0d, 0x03, 0
+#define SR_ANT_EXT_SW_EN       0x0d, 0x04, 2
+#define SR_ANT_DIV_EN          0x0d, 0x08, 3
+#define SR_RESERVED_0d_2       0x0d, 0x70, 4
+#define SR_ANT_SEL             0x0d, 0x80, 7
+#define RG_IRQ_MASK    (0x0e)
+#define SR_IRQ_MASK            0x0e, 0xff, 0
+#define RG_IRQ_STATUS  (0x0f)
+#define SR_IRQ_0_PLL_LOCK      0x0f, 0x01, 0
+#define SR_IRQ_1_PLL_UNLOCK    0x0f, 0x02, 1
+#define SR_IRQ_2_RX_START      0x0f, 0x04, 2
+#define SR_IRQ_3_TRX_END       0x0f, 0x08, 3
+#define SR_IRQ_4_CCA_ED_DONE   0x0f, 0x10, 4
+#define SR_IRQ_5_AMI           0x0f, 0x20, 5
+#define SR_IRQ_6_TRX_UR                0x0f, 0x40, 6
+#define SR_IRQ_7_BAT_LOW       0x0f, 0x80, 7
+#define RG_VREG_CTRL   (0x10)
+#define SR_RESERVED_10_6       0x10, 0x03, 0
+#define SR_DVDD_OK             0x10, 0x04, 2
+#define SR_DVREG_EXT           0x10, 0x08, 3
+#define SR_RESERVED_10_3       0x10, 0x30, 4
+#define SR_AVDD_OK             0x10, 0x40, 6
+#define SR_AVREG_EXT           0x10, 0x80, 7
+#define RG_BATMON      (0x11)
+#define SR_BATMON_VTH          0x11, 0x0f, 0
+#define SR_BATMON_HR           0x11, 0x10, 4
+#define SR_BATMON_OK           0x11, 0x20, 5
+#define SR_RESERVED_11_1       0x11, 0xc0, 6
+#define RG_XOSC_CTRL   (0x12)
+#define SR_XTAL_TRIM           0x12, 0x0f, 0
+#define SR_XTAL_MODE           0x12, 0xf0, 4
+#define RG_RX_SYN      (0x15)
+#define SR_RX_PDT_LEVEL                0x15, 0x0f, 0
+#define SR_RESERVED_15_2       0x15, 0x70, 4
+#define SR_RX_PDT_DIS          0x15, 0x80, 7
+#define RG_XAH_CTRL_1  (0x17)
+#define SR_RESERVED_17_8       0x17, 0x01, 0
+#define SR_AACK_PROM_MODE      0x17, 0x02, 1
+#define SR_AACK_ACK_TIME       0x17, 0x04, 2
+#define SR_RESERVED_17_5       0x17, 0x08, 3
+#define SR_AACK_UPLD_RES_FT    0x17, 0x10, 4
+#define SR_AACK_FLTR_RES_FT    0x17, 0x20, 5
+#define SR_CSMA_LBT_MODE       0x17, 0x40, 6
+#define SR_RESERVED_17_1       0x17, 0x80, 7
+#define RG_FTN_CTRL    (0x18)
+#define SR_RESERVED_18_2       0x18, 0x7f, 0
+#define SR_FTN_START           0x18, 0x80, 7
+#define RG_PLL_CF      (0x1a)
+#define SR_RESERVED_1a_2       0x1a, 0x7f, 0
+#define SR_PLL_CF_START                0x1a, 0x80, 7
+#define RG_PLL_DCU     (0x1b)
+#define SR_RESERVED_1b_3       0x1b, 0x3f, 0
+#define SR_RESERVED_1b_2       0x1b, 0x40, 6
+#define SR_PLL_DCU_START       0x1b, 0x80, 7
+#define RG_PART_NUM    (0x1c)
+#define SR_PART_NUM            0x1c, 0xff, 0
+#define RG_VERSION_NUM (0x1d)
+#define SR_VERSION_NUM         0x1d, 0xff, 0
+#define RG_MAN_ID_0    (0x1e)
+#define SR_MAN_ID_0            0x1e, 0xff, 0
+#define RG_MAN_ID_1    (0x1f)
+#define SR_MAN_ID_1            0x1f, 0xff, 0
+#define RG_SHORT_ADDR_0        (0x20)
+#define SR_SHORT_ADDR_0                0x20, 0xff, 0
+#define RG_SHORT_ADDR_1        (0x21)
+#define SR_SHORT_ADDR_1                0x21, 0xff, 0
+#define RG_PAN_ID_0    (0x22)
+#define SR_PAN_ID_0            0x22, 0xff, 0
+#define RG_PAN_ID_1    (0x23)
+#define SR_PAN_ID_1            0x23, 0xff, 0
+#define RG_IEEE_ADDR_0 (0x24)
+#define SR_IEEE_ADDR_0         0x24, 0xff, 0
+#define RG_IEEE_ADDR_1 (0x25)
+#define SR_IEEE_ADDR_1         0x25, 0xff, 0
+#define RG_IEEE_ADDR_2 (0x26)
+#define SR_IEEE_ADDR_2         0x26, 0xff, 0
+#define RG_IEEE_ADDR_3 (0x27)
+#define SR_IEEE_ADDR_3         0x27, 0xff, 0
+#define RG_IEEE_ADDR_4 (0x28)
+#define SR_IEEE_ADDR_4         0x28, 0xff, 0
+#define RG_IEEE_ADDR_5 (0x29)
+#define SR_IEEE_ADDR_5         0x29, 0xff, 0
+#define RG_IEEE_ADDR_6 (0x2a)
+#define SR_IEEE_ADDR_6         0x2a, 0xff, 0
+#define RG_IEEE_ADDR_7 (0x2b)
+#define SR_IEEE_ADDR_7         0x2b, 0xff, 0
+#define RG_XAH_CTRL_0  (0x2c)
+#define SR_SLOTTED_OPERATION   0x2c, 0x01, 0
+#define SR_MAX_CSMA_RETRIES    0x2c, 0x0e, 1
+#define SR_MAX_FRAME_RETRIES   0x2c, 0xf0, 4
+#define RG_CSMA_SEED_0 (0x2d)
+#define SR_CSMA_SEED_0         0x2d, 0xff, 0
+#define RG_CSMA_SEED_1 (0x2e)
+#define SR_CSMA_SEED_1         0x2e, 0x07, 0
+#define SR_AACK_I_AM_COORD     0x2e, 0x08, 3
+#define SR_AACK_DIS_ACK                0x2e, 0x10, 4
+#define SR_AACK_SET_PD         0x2e, 0x20, 5
+#define SR_AACK_FVN_MODE       0x2e, 0xc0, 6
+#define RG_CSMA_BE     (0x2f)
+#define SR_MIN_BE              0x2f, 0x0f, 0
+#define SR_MAX_BE              0x2f, 0xf0, 4
 
 #define CMD_REG                0x80
 #define CMD_REG_MASK   0x3f
@@ -292,6 +294,8 @@ struct at86rf230_local {
 #define STATE_BUSY_RX_AACK_NOCLK 0x1E
 #define STATE_TRANSITION_IN_PROGRESS 0x1F
 
+#define TRX_STATE_MASK         (0x1F)
+
 #define AT86RF2XX_NUMREGS 0x3F
 
 static void
@@ -336,6 +340,14 @@ at86rf230_write_subreg(struct at86rf230_local *lp,
        return regmap_update_bits(lp->regmap, addr, mask, data << shift);
 }
 
+static inline void
+at86rf230_slp_tr_rising_edge(struct at86rf230_local *lp)
+{
+       gpio_set_value(lp->slp_tr, 1);
+       udelay(1);
+       gpio_set_value(lp->slp_tr, 0);
+}
+
 static bool
 at86rf230_reg_writeable(struct device *dev, unsigned int reg)
 {
@@ -509,7 +521,7 @@ at86rf230_async_state_assert(void *context)
        struct at86rf230_state_change *ctx = context;
        struct at86rf230_local *lp = ctx->lp;
        const u8 *buf = ctx->buf;
-       const u8 trx_state = buf[1] & 0x1f;
+       const u8 trx_state = buf[1] & TRX_STATE_MASK;
 
        /* Assert state change */
        if (trx_state != ctx->to_state) {
@@ -609,11 +621,17 @@ at86rf230_async_state_delay(void *context)
                switch (ctx->to_state) {
                case STATE_RX_AACK_ON:
                        tim = ktime_set(0, c->t_off_to_aack * NSEC_PER_USEC);
+                       /* state change from TRX_OFF to RX_AACK_ON to do a
+                        * calibration, we need to reset the timeout for the
+                        * next one.
+                        */
+                       lp->cal_timeout = jiffies + AT86RF2XX_CAL_LOOP_TIMEOUT;
                        goto change;
+               case STATE_TX_ARET_ON:
                case STATE_TX_ON:
                        tim = ktime_set(0, c->t_off_to_tx_on * NSEC_PER_USEC);
-                       /* state change from TRX_OFF to TX_ON to do a
-                        * calibration, we need to reset the timeout for the
+                       /* state change from TRX_OFF to TX_ON or ARET_ON to do
+                        * calibration, we need to reset the timeout for the
                         * next one.
                         */
                        lp->cal_timeout = jiffies + AT86RF2XX_CAL_LOOP_TIMEOUT;
@@ -667,7 +685,7 @@ at86rf230_async_state_change_start(void *context)
        struct at86rf230_state_change *ctx = context;
        struct at86rf230_local *lp = ctx->lp;
        u8 *buf = ctx->buf;
-       const u8 trx_state = buf[1] & 0x1f;
+       const u8 trx_state = buf[1] & TRX_STATE_MASK;
        int rc;
 
        /* Check for "possible" STATE_TRANSITION_IN_PROGRESS */
@@ -772,16 +790,6 @@ at86rf230_tx_on(void *context)
                                     at86rf230_tx_complete, true);
 }
 
-static void
-at86rf230_tx_trac_error(void *context)
-{
-       struct at86rf230_state_change *ctx = context;
-       struct at86rf230_local *lp = ctx->lp;
-
-       at86rf230_async_state_change(lp, ctx, STATE_TX_ON,
-                                    at86rf230_tx_on, true);
-}
-
 static void
 at86rf230_tx_trac_check(void *context)
 {
@@ -791,12 +799,12 @@ at86rf230_tx_trac_check(void *context)
        const u8 trac = (buf[1] & 0xe0) >> 5;
 
        /* If trac status is different than zero we need to do a state change
-        * to STATE_FORCE_TRX_OFF then STATE_TX_ON to recover the transceiver
-        * state to TX_ON.
+        * to STATE_FORCE_TRX_OFF then STATE_RX_AACK_ON to recover the
+        * transceiver.
         */
        if (trac)
                at86rf230_async_state_change(lp, ctx, STATE_FORCE_TRX_OFF,
-                                            at86rf230_tx_trac_error, true);
+                                            at86rf230_tx_on, true);
        else
                at86rf230_tx_on(context);
 }
@@ -941,13 +949,18 @@ at86rf230_write_frame_complete(void *context)
        u8 *buf = ctx->buf;
        int rc;
 
-       buf[0] = (RG_TRX_STATE & CMD_REG_MASK) | CMD_REG | CMD_WRITE;
-       buf[1] = STATE_BUSY_TX;
        ctx->trx.len = 2;
-       ctx->msg.complete = NULL;
-       rc = spi_async(lp->spi, &ctx->msg);
-       if (rc)
-               at86rf230_async_error(lp, ctx, rc);
+
+       if (gpio_is_valid(lp->slp_tr)) {
+               at86rf230_slp_tr_rising_edge(lp);
+       } else {
+               buf[0] = (RG_TRX_STATE & CMD_REG_MASK) | CMD_REG | CMD_WRITE;
+               buf[1] = STATE_BUSY_TX;
+               ctx->msg.complete = NULL;
+               rc = spi_async(lp->spi, &ctx->msg);
+               if (rc)
+                       at86rf230_async_error(lp, ctx, rc);
+       }
 }
 
 static void
@@ -993,12 +1006,21 @@ at86rf230_xmit_start(void *context)
         * are in STATE_TX_ON. The pfad differs here, so we change
         * the complete handler.
         */
-       if (lp->tx_aret)
-               at86rf230_async_state_change(lp, ctx, STATE_TX_ON,
-                                            at86rf230_xmit_tx_on, false);
-       else
+       if (lp->tx_aret) {
+               if (lp->is_tx_from_off) {
+                       lp->is_tx_from_off = false;
+                       at86rf230_async_state_change(lp, ctx, STATE_TX_ARET_ON,
+                                                    at86rf230_xmit_tx_on,
+                                                    false);
+               } else {
+                       at86rf230_async_state_change(lp, ctx, STATE_TX_ON,
+                                                    at86rf230_xmit_tx_on,
+                                                    false);
+               }
+       } else {
                at86rf230_async_state_change(lp, ctx, STATE_TX_ON,
                                             at86rf230_write_frame, false);
+       }
 }
 
 static int
@@ -1017,11 +1039,13 @@ at86rf230_xmit(struct ieee802154_hw *hw, struct sk_buff *skb)
         * to TX_ON, the lp->cal_timeout should be reinit by state_delay
         * function then to start in the next 5 minutes.
         */
-       if (time_is_before_jiffies(lp->cal_timeout))
+       if (time_is_before_jiffies(lp->cal_timeout)) {
+               lp->is_tx_from_off = true;
                at86rf230_async_state_change(lp, ctx, STATE_TRX_OFF,
                                             at86rf230_xmit_start, false);
-       else
+       } else {
                at86rf230_xmit_start(ctx);
+       }
 
        return 0;
 }
@@ -1037,9 +1061,6 @@ at86rf230_ed(struct ieee802154_hw *hw, u8 *level)
 static int
 at86rf230_start(struct ieee802154_hw *hw)
 {
-       struct at86rf230_local *lp = hw->priv;
-
-       lp->cal_timeout = jiffies + AT86RF2XX_CAL_LOOP_TIMEOUT;
        return at86rf230_sync_state_change(hw->priv, STATE_RX_AACK_ON);
 }
 
@@ -1673,6 +1694,7 @@ static int at86rf230_probe(struct spi_device *spi)
        lp = hw->priv;
        lp->hw = hw;
        lp->spi = spi;
+       lp->slp_tr = slp_tr;
        hw->parent = &spi->dev;
        hw->vif_data_size = sizeof(*lp);
        ieee802154_random_extended_addr(&hw->phy->perm_extended_addr);
index b227a13f6473404a5082a0a99d4e7067b3daeaf7..9f59f17dc317a254641bdc48973ce78e089761bc 100644 (file)
@@ -599,10 +599,18 @@ static int macvlan_open(struct net_device *dev)
                        goto del_unicast;
        }
 
+       if (dev->flags & IFF_PROMISC) {
+               err = dev_set_promiscuity(lowerdev, 1);
+               if (err < 0)
+                       goto clear_multi;
+       }
+
 hash_add:
        macvlan_hash_add(vlan);
        return 0;
 
+clear_multi:
+       dev_set_allmulti(lowerdev, -1);
 del_unicast:
        dev_uc_del(lowerdev, dev->dev_addr);
 out:
@@ -638,6 +646,9 @@ static int macvlan_stop(struct net_device *dev)
        if (dev->flags & IFF_ALLMULTI)
                dev_set_allmulti(lowerdev, -1);
 
+       if (dev->flags & IFF_PROMISC)
+               dev_set_promiscuity(lowerdev, -1);
+
        dev_uc_del(lowerdev, dev->dev_addr);
 
 hash_del:
@@ -696,6 +707,10 @@ static void macvlan_change_rx_flags(struct net_device *dev, int change)
        if (dev->flags & IFF_UP) {
                if (change & IFF_ALLMULTI)
                        dev_set_allmulti(lowerdev, dev->flags & IFF_ALLMULTI ? 1 : -1);
+               if (change & IFF_PROMISC)
+                       dev_set_promiscuity(lowerdev,
+                                           dev->flags & IFF_PROMISC ? 1 : -1);
+
        }
 }
 
index 8fadaa14b9f0fbd97b689d7bab562eccd30d17bf..70641d2c042957e7e154b4a1d265f39fe3ffa386 100644 (file)
@@ -27,6 +27,7 @@ config AMD_PHY
 config AMD_XGBE_PHY
        tristate "Driver for the AMD 10GbE (amd-xgbe) PHYs"
        depends on (OF || ACPI) && HAS_IOMEM
+       depends on ARM64 || COMPILE_TEST
        ---help---
          Currently supports the AMD 10GbE PHY
 
index fb276f64cd6400cc7617c2586582c378eb2e9c53..34a75cba3b739ce5b4f28e1549915e19502fb4cc 100644 (file)
@@ -755,6 +755,45 @@ static int amd_xgbe_phy_set_mode(struct phy_device *phydev,
        return ret;
 }
 
+static bool amd_xgbe_phy_use_xgmii_mode(struct phy_device *phydev)
+{
+       if (phydev->autoneg == AUTONEG_ENABLE) {
+               if (phydev->advertising & ADVERTISED_10000baseKR_Full)
+                       return true;
+       } else {
+               if (phydev->speed == SPEED_10000)
+                       return true;
+       }
+
+       return false;
+}
+
+static bool amd_xgbe_phy_use_gmii_2500_mode(struct phy_device *phydev)
+{
+       if (phydev->autoneg == AUTONEG_ENABLE) {
+               if (phydev->advertising & ADVERTISED_2500baseX_Full)
+                       return true;
+       } else {
+               if (phydev->speed == SPEED_2500)
+                       return true;
+       }
+
+       return false;
+}
+
+static bool amd_xgbe_phy_use_gmii_mode(struct phy_device *phydev)
+{
+       if (phydev->autoneg == AUTONEG_ENABLE) {
+               if (phydev->advertising & ADVERTISED_1000baseKX_Full)
+                       return true;
+       } else {
+               if (phydev->speed == SPEED_1000)
+                       return true;
+       }
+
+       return false;
+}
+
 static int amd_xgbe_phy_set_an(struct phy_device *phydev, bool enable,
                               bool restart)
 {
@@ -1235,11 +1274,11 @@ static int amd_xgbe_phy_config_init(struct phy_device *phydev)
        /* Set initial mode - call the mode setting routines
         * directly to insure we are properly configured
         */
-       if (phydev->advertising & SUPPORTED_10000baseKR_Full)
+       if (amd_xgbe_phy_use_xgmii_mode(phydev))
                ret = amd_xgbe_phy_xgmii_mode(phydev);
-       else if (phydev->advertising & SUPPORTED_1000baseKX_Full)
+       else if (amd_xgbe_phy_use_gmii_mode(phydev))
                ret = amd_xgbe_phy_gmii_mode(phydev);
-       else if (phydev->advertising & SUPPORTED_2500baseX_Full)
+       else if (amd_xgbe_phy_use_gmii_2500_mode(phydev))
                ret = amd_xgbe_phy_gmii_2500_mode(phydev);
        else
                ret = -EINVAL;
index 64c74c6a482806bfc5d2bb4f821b4b1ef085adfd..b5dc59de094eef06838d4601cacd9dbeaba04a6a 100644 (file)
@@ -404,7 +404,7 @@ static struct phy_driver bcm7xxx_driver[] = {
        .name           = "Broadcom BCM7425",
        .features       = PHY_GBIT_FEATURES |
                          SUPPORTED_Pause | SUPPORTED_Asym_Pause,
-       .flags          = 0,
+       .flags          = PHY_IS_INTERNAL,
        .config_init    = bcm7xxx_config_init,
        .config_aneg    = genphy_config_aneg,
        .read_status    = genphy_read_status,
index 496e02f961d37039ff56d5e45a8aa28aa0f44b91..00cb41e713123689803e5dddfa527c3ebaee26ae 100644 (file)
@@ -47,7 +47,7 @@
 #define PSF_TX         0x1000
 #define EXT_EVENT      1
 #define CAL_EVENT      7
-#define CAL_TRIGGER    7
+#define CAL_TRIGGER    1
 #define DP83640_N_PINS 12
 
 #define MII_DP83640_MICR 0x11
@@ -496,7 +496,9 @@ static int ptp_dp83640_enable(struct ptp_clock_info *ptp,
                        else
                                evnt |= EVNT_RISE;
                }
+               mutex_lock(&clock->extreg_lock);
                ext_write(0, phydev, PAGE5, PTP_EVNT, evnt);
+               mutex_unlock(&clock->extreg_lock);
                return 0;
 
        case PTP_CLK_REQ_PEROUT:
@@ -532,6 +534,8 @@ static u8 status_frame_src[6] = { 0x08, 0x00, 0x17, 0x0B, 0x6B, 0x0F };
 
 static void enable_status_frames(struct phy_device *phydev, bool on)
 {
+       struct dp83640_private *dp83640 = phydev->priv;
+       struct dp83640_clock *clock = dp83640->clock;
        u16 cfg0 = 0, ver;
 
        if (on)
@@ -539,9 +543,13 @@ static void enable_status_frames(struct phy_device *phydev, bool on)
 
        ver = (PSF_PTPVER & VERSIONPTP_MASK) << VERSIONPTP_SHIFT;
 
+       mutex_lock(&clock->extreg_lock);
+
        ext_write(0, phydev, PAGE5, PSF_CFG0, cfg0);
        ext_write(0, phydev, PAGE6, PSF_CFG1, ver);
 
+       mutex_unlock(&clock->extreg_lock);
+
        if (!phydev->attached_dev) {
                pr_warn("expected to find an attached netdevice\n");
                return;
@@ -838,7 +846,7 @@ static void decode_rxts(struct dp83640_private *dp83640,
        list_del_init(&rxts->list);
        phy2rxts(phy_rxts, rxts);
 
-       spin_lock_irqsave(&dp83640->rx_queue.lock, flags);
+       spin_lock(&dp83640->rx_queue.lock);
        skb_queue_walk(&dp83640->rx_queue, skb) {
                struct dp83640_skb_info *skb_info;
 
@@ -853,7 +861,7 @@ static void decode_rxts(struct dp83640_private *dp83640,
                        break;
                }
        }
-       spin_unlock_irqrestore(&dp83640->rx_queue.lock, flags);
+       spin_unlock(&dp83640->rx_queue.lock);
 
        if (!shhwtstamps)
                list_add_tail(&rxts->list, &dp83640->rxts);
@@ -1173,11 +1181,18 @@ static int dp83640_config_init(struct phy_device *phydev)
 
        if (clock->chosen && !list_empty(&clock->phylist))
                recalibrate(clock);
-       else
+       else {
+               mutex_lock(&clock->extreg_lock);
                enable_broadcast(phydev, clock->page, 1);
+               mutex_unlock(&clock->extreg_lock);
+       }
 
        enable_status_frames(phydev, true);
+
+       mutex_lock(&clock->extreg_lock);
        ext_write(0, phydev, PAGE4, PTP_CTL, PTP_ENABLE);
+       mutex_unlock(&clock->extreg_lock);
+
        return 0;
 }
 
index c9cb486c753d053c8b6da529a0c078d89f9c2a2f..53d18150f4e291bb4bb047a18a9877d3a82a08f4 100644 (file)
@@ -168,7 +168,10 @@ static struct mii_bus *mdio_gpio_bus_init(struct device *dev,
                if (!new_bus->irq[i])
                        new_bus->irq[i] = PHY_POLL;
 
-       snprintf(new_bus->id, MII_BUS_ID_SIZE, "gpio-%x", bus_id);
+       if (bus_id != -1)
+               snprintf(new_bus->id, MII_BUS_ID_SIZE, "gpio-%x", bus_id);
+       else
+               strncpy(new_bus->id, "gpio", MII_BUS_ID_SIZE);
 
        if (devm_gpio_request(dev, bitbang->mdc, "mdc"))
                goto out_free_bus;
index 1190fd8f008862bc8f70f271575839d280a8f906..ebdc357c513167515baef710ba56d8b6b8e57cb9 100644 (file)
@@ -548,7 +548,8 @@ static int kszphy_probe(struct phy_device *phydev)
        }
 
        clk = devm_clk_get(&phydev->dev, "rmii-ref");
-       if (!IS_ERR(clk)) {
+       /* NOTE: clk may be NULL if building without CONFIG_HAVE_CLK */
+       if (!IS_ERR_OR_NULL(clk)) {
                unsigned long rate = clk_get_rate(clk);
                bool rmii_ref_clk_sel_25_mhz;
 
index 52cd8db2c57daad2767dec72149f4cdabbcf6917..47cd578052fc2328169fcc9df304be79e7af9ac5 100644 (file)
@@ -742,6 +742,9 @@ EXPORT_SYMBOL(phy_stop);
  */
 void phy_start(struct phy_device *phydev)
 {
+       bool do_resume = false;
+       int err = 0;
+
        mutex_lock(&phydev->lock);
 
        switch (phydev->state) {
@@ -752,11 +755,22 @@ void phy_start(struct phy_device *phydev)
                phydev->state = PHY_UP;
                break;
        case PHY_HALTED:
+               /* make sure interrupts are re-enabled for the PHY */
+               err = phy_enable_interrupts(phydev);
+               if (err < 0)
+                       break;
+
                phydev->state = PHY_RESUMING;
+               do_resume = true;
+               break;
        default:
                break;
        }
        mutex_unlock(&phydev->lock);
+
+       /* if phy was suspended, bring the physical link up again */
+       if (do_resume)
+               phy_resume(phydev);
 }
 EXPORT_SYMBOL(phy_start);
 
@@ -769,7 +783,7 @@ void phy_state_machine(struct work_struct *work)
        struct delayed_work *dwork = to_delayed_work(work);
        struct phy_device *phydev =
                        container_of(dwork, struct phy_device, state_queue);
-       bool needs_aneg = false, do_suspend = false, do_resume = false;
+       bool needs_aneg = false, do_suspend = false;
        int err = 0;
 
        mutex_lock(&phydev->lock);
@@ -888,14 +902,6 @@ void phy_state_machine(struct work_struct *work)
                }
                break;
        case PHY_RESUMING:
-               err = phy_clear_interrupt(phydev);
-               if (err)
-                       break;
-
-               err = phy_config_interrupt(phydev, PHY_INTERRUPT_ENABLED);
-               if (err)
-                       break;
-
                if (AUTONEG_ENABLE == phydev->autoneg) {
                        err = phy_aneg_done(phydev);
                        if (err < 0)
@@ -933,7 +939,6 @@ void phy_state_machine(struct work_struct *work)
                        }
                        phydev->adjust_link(phydev->attached_dev);
                }
-               do_resume = true;
                break;
        }
 
@@ -943,8 +948,6 @@ void phy_state_machine(struct work_struct *work)
                err = phy_start_aneg(phydev);
        else if (do_suspend)
                phy_suspend(phydev);
-       else if (do_resume)
-               phy_resume(phydev);
 
        if (err < 0)
                phy_error(phydev);
@@ -1053,13 +1056,14 @@ int phy_init_eee(struct phy_device *phydev, bool clk_stop_enable)
 {
        /* According to 802.3az,the EEE is supported only in full duplex-mode.
         * Also EEE feature is active when core is operating with MII, GMII
-        * or RGMII. Internal PHYs are also allowed to proceed and should
-        * return an error if they do not support EEE.
+        * or RGMII (all kinds). Internal PHYs are also allowed to proceed and
+        * should return an error if they do not support EEE.
         */
        if ((phydev->duplex == DUPLEX_FULL) &&
            ((phydev->interface == PHY_INTERFACE_MODE_MII) ||
            (phydev->interface == PHY_INTERFACE_MODE_GMII) ||
-           (phydev->interface == PHY_INTERFACE_MODE_RGMII) ||
+           (phydev->interface >= PHY_INTERFACE_MODE_RGMII &&
+            phydev->interface <= PHY_INTERFACE_MODE_RGMII_TXID) ||
             phy_is_internal(phydev))) {
                int eee_lp, eee_cap, eee_adv;
                u32 lp, cap, adv;
index aa1dd926623ad622e3a15f905733e3d585aca871..b62a5e3a1c652d27e2bbb0d2a8a88990c3fef027 100644 (file)
@@ -465,6 +465,10 @@ static void pppoe_unbind_sock_work(struct work_struct *work)
        struct sock *sk = sk_pppox(po);
 
        lock_sock(sk);
+       if (po->pppoe_dev) {
+               dev_put(po->pppoe_dev);
+               po->pppoe_dev = NULL;
+       }
        pppox_unbind_sock(sk);
        release_sock(sk);
        sock_put(sk);
index c3e4da9e79ca071a06082e965a3aec5bb206a77e..8067b8fbb0eea42b106cc56ffe6bc216ae01f85a 100644 (file)
@@ -1182,7 +1182,7 @@ cdc_ncm_fill_tx_frame(struct usbnet *dev, struct sk_buff *skb, __le32 sign)
         * payload data instead.
         */
        usbnet_set_skb_tx_stats(skb_out, n,
-                               ctx->tx_curr_frame_payload - skb_out->len);
+                               (long)ctx->tx_curr_frame_payload - skb_out->len);
 
        return skb_out;
 
index ac4d03b328b130ab918175b1fa5c8fe55a0cbc7b..aafa1a1898e43de0d3d06e7d8367751473f25142 100644 (file)
@@ -4116,6 +4116,7 @@ static struct usb_device_id rtl8152_table[] = {
        {REALTEK_USB_DEVICE(VENDOR_ID_REALTEK, 0x8153)},
        {REALTEK_USB_DEVICE(VENDOR_ID_SAMSUNG, 0xa101)},
        {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO,  0x7205)},
+       {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO,  0x304f)},
        {}
 };
 
index 733f4feb2ef3c5f11bbf99af962ecbb77253314b..3c86b107275a899f3748e4cfee82ab2bb43aff6b 100644 (file)
@@ -1285,7 +1285,7 @@ netdev_tx_t usbnet_start_xmit (struct sk_buff *skb,
                                     struct net_device *net)
 {
        struct usbnet           *dev = netdev_priv(net);
-       int                     length;
+       unsigned int                    length;
        struct urb              *urb = NULL;
        struct skb_data         *entry;
        struct driver_info      *info = dev->driver_info;
@@ -1413,7 +1413,7 @@ netdev_tx_t usbnet_start_xmit (struct sk_buff *skb,
                }
        } else
                netif_dbg(dev, tx_queued, dev->net,
-                         "> tx, len %d, type 0x%x\n", length, skb->protocol);
+                         "> tx, len %u, type 0x%x\n", length, skb->protocol);
 #ifdef CONFIG_PM
 deferred:
 #endif
index 27a5f954f8e999cc809dc5ed0bad08d2e06e0f18..21a0fbf1ed947a83506de920f7f61501457bfe68 100644 (file)
@@ -2961,7 +2961,7 @@ static void __net_exit vxlan_exit_net(struct net *net)
                 * to the list by the previous loop.
                 */
                if (!net_eq(dev_net(vxlan->dev), net))
-                       unregister_netdevice_queue(dev, &list);
+                       unregister_netdevice_queue(vxlan->dev, &list);
        }
 
        unregister_netdevice_many(&list);
index 0acd079ba96bd3d2f60602ebf5f889f36da9f908..3ad79bb4f2c21c94b6c41c526a7e033e0937ed77 100644 (file)
@@ -1103,28 +1103,14 @@ static u8 ath_get_rate_txpower(struct ath_softc *sc, struct ath_buf *bf,
        struct sk_buff *skb;
        struct ath_frame_info *fi;
        struct ieee80211_tx_info *info;
-       struct ieee80211_vif *vif;
        struct ath_hw *ah = sc->sc_ah;
 
        if (sc->tx99_state || !ah->tpc_enabled)
                return MAX_RATE_POWER;
 
        skb = bf->bf_mpdu;
-       info = IEEE80211_SKB_CB(skb);
-       vif = info->control.vif;
-
-       if (!vif) {
-               max_power = sc->cur_chan->cur_txpower;
-               goto out;
-       }
-
-       if (vif->bss_conf.txpower_type != NL80211_TX_POWER_LIMITED) {
-               max_power = min_t(u8, sc->cur_chan->cur_txpower,
-                                 2 * vif->bss_conf.txpower);
-               goto out;
-       }
-
        fi = get_frame_info(skb);
+       info = IEEE80211_SKB_CB(skb);
 
        if (!AR_SREV_9300_20_OR_LATER(ah)) {
                int txpower = fi->tx_power;
@@ -1161,25 +1147,26 @@ static u8 ath_get_rate_txpower(struct ath_softc *sc, struct ath_buf *bf,
                        txpower -= 2;
 
                txpower = max(txpower, 0);
-               max_power = min_t(u8, ah->tx_power[rateidx],
-                                 2 * vif->bss_conf.txpower);
-               max_power = min_t(u8, max_power, txpower);
+               max_power = min_t(u8, ah->tx_power[rateidx], txpower);
+
+               /* XXX: clamp minimum TX power at 1 for AR9160 since if
+                * max_power is set to 0, frames are transmitted at max
+                * TX power
+                */
+               if (!max_power && !AR_SREV_9280_20_OR_LATER(ah))
+                       max_power = 1;
        } else if (!bf->bf_state.bfs_paprd) {
                if (rateidx < 8 && (info->flags & IEEE80211_TX_CTL_STBC))
                        max_power = min_t(u8, ah->tx_power_stbc[rateidx],
-                                         2 * vif->bss_conf.txpower);
+                                         fi->tx_power);
                else
                        max_power = min_t(u8, ah->tx_power[rateidx],
-                                         2 * vif->bss_conf.txpower);
-               max_power = min(max_power, fi->tx_power);
+                                         fi->tx_power);
        } else {
                max_power = ah->paprd_training_power;
        }
-out:
-       /* XXX: clamp minimum TX power at 1 for AR9160 since if max_power
-        * is set to 0, frames are transmitted at max TX power
-        */
-       return (!max_power && !AR_SREV_9280_20_OR_LATER(ah)) ? 1 : max_power;
+
+       return max_power;
 }
 
 static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf,
@@ -2129,6 +2116,7 @@ static void setup_frame_info(struct ieee80211_hw *hw,
        struct ath_node *an = NULL;
        enum ath9k_key_type keytype;
        bool short_preamble = false;
+       u8 txpower;
 
        /*
         * We check if Short Preamble is needed for the CTS rate by
@@ -2145,6 +2133,16 @@ static void setup_frame_info(struct ieee80211_hw *hw,
        if (sta)
                an = (struct ath_node *) sta->drv_priv;
 
+       if (tx_info->control.vif) {
+               struct ieee80211_vif *vif = tx_info->control.vif;
+
+               txpower = 2 * vif->bss_conf.txpower;
+       } else {
+               struct ath_softc *sc = hw->priv;
+
+               txpower = sc->cur_chan->cur_txpower;
+       }
+
        memset(fi, 0, sizeof(*fi));
        fi->txq = -1;
        if (hw_key)
@@ -2155,7 +2153,7 @@ static void setup_frame_info(struct ieee80211_hw *hw,
                fi->keyix = ATH9K_TXKEYIX_INVALID;
        fi->keytype = keytype;
        fi->framelen = framelen;
-       fi->tx_power = MAX_RATE_POWER;
+       fi->tx_power = txpower;
 
        if (!rate)
                return;
index ab019b45551b9ea9bef61a1861feba7601897a5f..f89f446e5c8ae32b5dccc42cae6234ad75283ff8 100644 (file)
@@ -21,6 +21,7 @@ config IWLWIFI
                Intel 7260 Wi-Fi Adapter
                Intel 3160 Wi-Fi Adapter
                Intel 7265 Wi-Fi Adapter
+               Intel 3165 Wi-Fi Adapter
 
 
          This driver uses the kernel's mac80211 subsystem.
index 36e786f0387bd42593fe3c8ec523831694483bea..74ad278116be3feb18b3a2a98e4034aa3145a6a1 100644 (file)
 
 /* Highest firmware API version supported */
 #define IWL7260_UCODE_API_MAX  13
-#define IWL3160_UCODE_API_MAX  13
 
 /* Oldest version we won't warn about */
 #define IWL7260_UCODE_API_OK   12
-#define IWL3160_UCODE_API_OK   12
+#define IWL3165_UCODE_API_OK   13
 
 /* Lowest firmware API version supported */
 #define IWL7260_UCODE_API_MIN  10
-#define IWL3160_UCODE_API_MIN  10
+#define IWL3165_UCODE_API_MIN  13
 
 /* NVM versions */
 #define IWL7260_NVM_VERSION            0x0a1d
 #define IWL3160_FW_PRE "iwlwifi-3160-"
 #define IWL3160_MODULE_FIRMWARE(api) IWL3160_FW_PRE __stringify(api) ".ucode"
 
-#define IWL3165_FW_PRE "iwlwifi-3165-"
-#define IWL3165_MODULE_FIRMWARE(api) IWL3165_FW_PRE __stringify(api) ".ucode"
-
 #define IWL7265_FW_PRE "iwlwifi-7265-"
 #define IWL7265_MODULE_FIRMWARE(api) IWL7265_FW_PRE __stringify(api) ".ucode"
 
@@ -248,8 +244,13 @@ static const struct iwl_ht_params iwl7265_ht_params = {
 
 const struct iwl_cfg iwl3165_2ac_cfg = {
        .name = "Intel(R) Dual Band Wireless AC 3165",
-       .fw_name_pre = IWL3165_FW_PRE,
+       .fw_name_pre = IWL7265D_FW_PRE,
        IWL_DEVICE_7000,
+       /* sparse doens't like the re-assignment but it is safe */
+#ifndef __CHECKER__
+       .ucode_api_ok = IWL3165_UCODE_API_OK,
+       .ucode_api_min = IWL3165_UCODE_API_MIN,
+#endif
        .ht_params = &iwl7000_ht_params,
        .nvm_ver = IWL3165_NVM_VERSION,
        .nvm_calib_ver = IWL3165_TX_POWER_VERSION,
@@ -325,6 +326,5 @@ const struct iwl_cfg iwl7265d_n_cfg = {
 
 MODULE_FIRMWARE(IWL7260_MODULE_FIRMWARE(IWL7260_UCODE_API_OK));
 MODULE_FIRMWARE(IWL3160_MODULE_FIRMWARE(IWL3160_UCODE_API_OK));
-MODULE_FIRMWARE(IWL3165_MODULE_FIRMWARE(IWL3160_UCODE_API_OK));
 MODULE_FIRMWARE(IWL7265_MODULE_FIRMWARE(IWL7260_UCODE_API_OK));
 MODULE_FIRMWARE(IWL7265D_MODULE_FIRMWARE(IWL7260_UCODE_API_OK));
index 41ff85de73343b0a5686bfd175164807e8dc4684..21302b6f2bfd79a8e8617a345e3771f6608c0145 100644 (file)
@@ -6,6 +6,7 @@
  * GPL LICENSE SUMMARY
  *
  * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
+ * Copyright(c) 2015 Intel Mobile Communications GmbH
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -31,6 +32,7 @@
  * BSD LICENSE
  *
  * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
+ * Copyright(c) 2015 Intel Mobile Communications GmbH
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -748,6 +750,9 @@ void iwl_init_ht_hw_capab(const struct iwl_cfg *cfg,
                return;
        }
 
+       if (data->sku_cap_mimo_disabled)
+               rx_chains = 1;
+
        ht_info->ht_supported = true;
        ht_info->cap = IEEE80211_HT_CAP_DSSSCCK40;
 
index 5234a0bf11e4e3286b740c22518f4a039e224e94..750c8c9ee70d0352e5828049ff4b138e31a3ae6c 100644 (file)
@@ -6,6 +6,7 @@
  * GPL LICENSE SUMMARY
  *
  * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
+ * Copyright(c) 2015 Intel Mobile Communications GmbH
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -31,6 +32,7 @@
  * BSD LICENSE
  *
  * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
+ * Copyright(c) 2015 Intel Mobile Communications GmbH
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -84,6 +86,7 @@ struct iwl_nvm_data {
        bool sku_cap_11ac_enable;
        bool sku_cap_amt_enable;
        bool sku_cap_ipan_enable;
+       bool sku_cap_mimo_disabled;
 
        u16 radio_cfg_type;
        u8 radio_cfg_step;
index bfdf3faa6c470dafbd9a66672b2f55e38b0872bc..62db2e5e45ebd51793c372e54832b21511057c58 100644 (file)
@@ -244,6 +244,7 @@ enum iwl_ucode_tlv_flag {
  *     longer than the passive one, which is essential for fragmented scan.
  * @IWL_UCODE_TLV_API_WIFI_MCC_UPDATE: ucode supports MCC updates with source.
  * IWL_UCODE_TLV_API_HDC_PHASE_0: ucode supports finer configuration of LTR
+ * @IWL_UCODE_TLV_API_TX_POWER_DEV: new API for tx power.
  * @IWL_UCODE_TLV_API_BASIC_DWELL: use only basic dwell time in scan command,
  *     regardless of the band or the number of the probes. FW will calculate
  *     the actual dwell time.
@@ -260,6 +261,7 @@ enum iwl_ucode_tlv_api {
        IWL_UCODE_TLV_API_FRAGMENTED_SCAN       = BIT(8),
        IWL_UCODE_TLV_API_WIFI_MCC_UPDATE       = BIT(9),
        IWL_UCODE_TLV_API_HDC_PHASE_0           = BIT(10),
+       IWL_UCODE_TLV_API_TX_POWER_DEV          = BIT(11),
        IWL_UCODE_TLV_API_BASIC_DWELL           = BIT(13),
        IWL_UCODE_TLV_API_SCD_CFG               = BIT(15),
        IWL_UCODE_TLV_API_SINGLE_SCAN_EBS       = BIT(16),
index 83903a5025c2e69779554e7bcf980aff48b3d080..75e96db6626b185684c93687e5f4d020b60dc50e 100644 (file)
@@ -6,7 +6,7 @@
  * GPL LICENSE SUMMARY
  *
  * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
- * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
+ * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -32,7 +32,7 @@
  * BSD LICENSE
  *
  * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
- * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
+ * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -116,10 +116,11 @@ enum family_8000_nvm_offsets {
 
 /* SKU Capabilities (actual values from NVM definition) */
 enum nvm_sku_bits {
-       NVM_SKU_CAP_BAND_24GHZ  = BIT(0),
-       NVM_SKU_CAP_BAND_52GHZ  = BIT(1),
-       NVM_SKU_CAP_11N_ENABLE  = BIT(2),
-       NVM_SKU_CAP_11AC_ENABLE = BIT(3),
+       NVM_SKU_CAP_BAND_24GHZ          = BIT(0),
+       NVM_SKU_CAP_BAND_52GHZ          = BIT(1),
+       NVM_SKU_CAP_11N_ENABLE          = BIT(2),
+       NVM_SKU_CAP_11AC_ENABLE         = BIT(3),
+       NVM_SKU_CAP_MIMO_DISABLE        = BIT(5),
 };
 
 /*
@@ -368,6 +369,11 @@ static void iwl_init_vht_hw_capab(const struct iwl_cfg *cfg,
        if (cfg->ht_params->ldpc)
                vht_cap->cap |= IEEE80211_VHT_CAP_RXLDPC;
 
+       if (data->sku_cap_mimo_disabled) {
+               num_rx_ants = 1;
+               num_tx_ants = 1;
+       }
+
        if (num_tx_ants > 1)
                vht_cap->cap |= IEEE80211_VHT_CAP_TXSTBC;
        else
@@ -527,6 +533,10 @@ static void iwl_set_hw_address_family_8000(struct device *dev,
        const u8 *hw_addr;
 
        if (mac_override) {
+               static const u8 reserved_mac[] = {
+                       0x02, 0xcc, 0xaa, 0xff, 0xee, 0x00
+               };
+
                hw_addr = (const u8 *)(mac_override +
                                 MAC_ADDRESS_OVERRIDE_FAMILY_8000);
 
@@ -538,7 +548,12 @@ static void iwl_set_hw_address_family_8000(struct device *dev,
                data->hw_addr[4] = hw_addr[5];
                data->hw_addr[5] = hw_addr[4];
 
-               if (is_valid_ether_addr(data->hw_addr))
+               /*
+                * Force the use of the OTP MAC address in case of reserved MAC
+                * address in the NVM, or if address is given but invalid.
+                */
+               if (is_valid_ether_addr(data->hw_addr) &&
+                   memcmp(reserved_mac, hw_addr, ETH_ALEN) != 0)
                        return;
 
                IWL_ERR_DEV(dev,
@@ -610,6 +625,7 @@ iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg,
                data->sku_cap_11n_enable = false;
        data->sku_cap_11ac_enable = data->sku_cap_11n_enable &&
                                    (sku & NVM_SKU_CAP_11AC_ENABLE);
+       data->sku_cap_mimo_disabled = sku & NVM_SKU_CAP_MIMO_DISABLE;
 
        data->n_hw_addrs = iwl_get_n_hw_addrs(cfg, nvm_sw);
 
index 6dfed1259260f06d23feb544d78ce6484c01fb36..56254a837214ffad421a7b7a14a9eaec3d7dc029 100644 (file)
@@ -6,7 +6,7 @@
  * GPL LICENSE SUMMARY
  *
  * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved.
- * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
+ * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -32,7 +32,7 @@
  * BSD LICENSE
  *
  * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
- * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
+ * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -421,8 +421,9 @@ struct iwl_trans_txq_scd_cfg {
  *
  * All the handlers MUST be implemented
  *
- * @start_hw: starts the HW- from that point on, the HW can send interrupts
- *     May sleep
+ * @start_hw: starts the HW. If low_power is true, the NIC needs to be taken
+ *     out of a low power state. From that point on, the HW can send
+ *     interrupts. May sleep.
  * @op_mode_leave: Turn off the HW RF kill indication if on
  *     May sleep
  * @start_fw: allocates and inits all the resources for the transport
@@ -432,10 +433,11 @@ struct iwl_trans_txq_scd_cfg {
  *     the SCD base address in SRAM, then provide it here, or 0 otherwise.
  *     May sleep
  * @stop_device: stops the whole device (embedded CPU put to reset) and stops
- *     the HW. From that point on, the HW will be in low power but will still
- *     issue interrupt if the HW RF kill is triggered. This callback must do
- *     the right thing and not crash even if start_hw() was called but not
- *     start_fw(). May sleep
+ *     the HW. If low_power is true, the NIC will be put in low power state.
+ *     From that point on, the HW will be stopped but will still issue an
+ *     interrupt if the HW RF kill switch is triggered.
+ *     This callback must do the right thing and not crash even if %start_hw()
+ *     was called but not &start_fw(). May sleep.
  * @d3_suspend: put the device into the correct mode for WoWLAN during
  *     suspend. This is optional, if not implemented WoWLAN will not be
  *     supported. This callback may sleep.
@@ -491,14 +493,14 @@ struct iwl_trans_txq_scd_cfg {
  */
 struct iwl_trans_ops {
 
-       int (*start_hw)(struct iwl_trans *iwl_trans);
+       int (*start_hw)(struct iwl_trans *iwl_trans, bool low_power);
        void (*op_mode_leave)(struct iwl_trans *iwl_trans);
        int (*start_fw)(struct iwl_trans *trans, const struct fw_img *fw,
                        bool run_in_rfkill);
        int (*update_sf)(struct iwl_trans *trans,
                         struct iwl_sf_region *st_fwrd_space);
        void (*fw_alive)(struct iwl_trans *trans, u32 scd_addr);
-       void (*stop_device)(struct iwl_trans *trans);
+       void (*stop_device)(struct iwl_trans *trans, bool low_power);
 
        void (*d3_suspend)(struct iwl_trans *trans, bool test);
        int (*d3_resume)(struct iwl_trans *trans, enum iwl_d3_status *status,
@@ -652,11 +654,16 @@ static inline void iwl_trans_configure(struct iwl_trans *trans,
        trans->ops->configure(trans, trans_cfg);
 }
 
-static inline int iwl_trans_start_hw(struct iwl_trans *trans)
+static inline int _iwl_trans_start_hw(struct iwl_trans *trans, bool low_power)
 {
        might_sleep();
 
-       return trans->ops->start_hw(trans);
+       return trans->ops->start_hw(trans, low_power);
+}
+
+static inline int iwl_trans_start_hw(struct iwl_trans *trans)
+{
+       return trans->ops->start_hw(trans, true);
 }
 
 static inline void iwl_trans_op_mode_leave(struct iwl_trans *trans)
@@ -703,15 +710,21 @@ static inline int iwl_trans_update_sf(struct iwl_trans *trans,
        return 0;
 }
 
-static inline void iwl_trans_stop_device(struct iwl_trans *trans)
+static inline void _iwl_trans_stop_device(struct iwl_trans *trans,
+                                         bool low_power)
 {
        might_sleep();
 
-       trans->ops->stop_device(trans);
+       trans->ops->stop_device(trans, low_power);
 
        trans->state = IWL_TRANS_NO_FW;
 }
 
+static inline void iwl_trans_stop_device(struct iwl_trans *trans)
+{
+       _iwl_trans_stop_device(trans, true);
+}
+
 static inline void iwl_trans_d3_suspend(struct iwl_trans *trans, bool test)
 {
        might_sleep();
index d954591e0be58528d138f8738b2cb2325db1fed3..6ac6de2af9779982231d1efb4c6186fad4442f5d 100644 (file)
@@ -776,7 +776,7 @@ static int iwl_mvm_bt_coex_reduced_txp(struct iwl_mvm *mvm, u8 sta_id,
        struct iwl_host_cmd cmd = {
                .id = BT_CONFIG,
                .len = { sizeof(*bt_cmd), },
-               .dataflags = { IWL_HCMD_DFL_NOCOPY, },
+               .dataflags = { IWL_HCMD_DFL_DUP, },
                .flags = CMD_ASYNC,
        };
        struct iwl_mvm_sta *mvmsta;
index a6c48c7b1e1683fdbdcb99fd0e4f971cf6ad66d2..4310cf102d78ecd4f3e7baffa13570d878153cb4 100644 (file)
@@ -1726,7 +1726,7 @@ iwl_mvm_netdetect_query_results(struct iwl_mvm *mvm,
        results->matched_profiles = le32_to_cpu(query->matched_profiles);
        memcpy(results->matches, query->matches, sizeof(results->matches));
 
-#ifdef CPTCFG_IWLWIFI_DEBUGFS
+#ifdef CONFIG_IWLWIFI_DEBUGFS
        mvm->last_netdetect_scans = le32_to_cpu(query->n_scans_done);
 #endif
 
@@ -1750,8 +1750,10 @@ static void iwl_mvm_query_netdetect_reasons(struct iwl_mvm *mvm,
        int i, j, n_matches, ret;
 
        fw_status = iwl_mvm_get_wakeup_status(mvm, vif);
-       if (!IS_ERR_OR_NULL(fw_status))
+       if (!IS_ERR_OR_NULL(fw_status)) {
                reasons = le32_to_cpu(fw_status->wakeup_reasons);
+               kfree(fw_status);
+       }
 
        if (reasons & IWL_WOWLAN_WAKEUP_BY_RFKILL_DEASSERTED)
                wakeup.rfkill_release = true;
@@ -1868,15 +1870,15 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test)
        /* get the BSS vif pointer again */
        vif = iwl_mvm_get_bss_vif(mvm);
        if (IS_ERR_OR_NULL(vif))
-               goto out_unlock;
+               goto err;
 
        ret = iwl_trans_d3_resume(mvm->trans, &d3_status, test);
        if (ret)
-               goto out_unlock;
+               goto err;
 
        if (d3_status != IWL_D3_STATUS_ALIVE) {
                IWL_INFO(mvm, "Device was reset during suspend\n");
-               goto out_unlock;
+               goto err;
        }
 
        /* query SRAM first in case we want event logging */
@@ -1902,7 +1904,8 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test)
                goto out_iterate;
        }
 
- out_unlock:
+err:
+       iwl_mvm_free_nd(mvm);
        mutex_unlock(&mvm->mutex);
 
 out_iterate:
@@ -1915,6 +1918,14 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test)
        /* return 1 to reconfigure the device */
        set_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status);
        set_bit(IWL_MVM_STATUS_D3_RECONFIG, &mvm->status);
+
+       /* We always return 1, which causes mac80211 to do a reconfig
+        * with IEEE80211_RECONFIG_TYPE_RESTART.  This type of
+        * reconfig calls iwl_mvm_restart_complete(), where we unref
+        * the IWL_MVM_REF_UCODE_DOWN, so we need to take the
+        * reference here.
+        */
+       iwl_mvm_ref(mvm, IWL_MVM_REF_UCODE_DOWN);
        return 1;
 }
 
@@ -2021,7 +2032,6 @@ static int iwl_mvm_d3_test_release(struct inode *inode, struct file *file)
        __iwl_mvm_resume(mvm, true);
        rtnl_unlock();
        iwl_abort_notification_waits(&mvm->notif_wait);
-       iwl_mvm_ref(mvm, IWL_MVM_REF_UCODE_DOWN);
        ieee80211_restart_hw(mvm->hw);
 
        /* wait for restart and disconnect all interfaces */
index 4fc0938b3fb6d6c92464f63b3f206cbc798f92b7..b1baa33cc19b3228a8534af71ab69c7dede40520 100644 (file)
@@ -297,6 +297,40 @@ struct iwl_uapsd_misbehaving_ap_notif {
        u8 reserved[3];
 } __packed;
 
+/**
+ * struct iwl_reduce_tx_power_cmd - TX power reduction command
+ * REDUCE_TX_POWER_CMD = 0x9f
+ * @flags: (reserved for future implementation)
+ * @mac_context_id: id of the mac ctx for which we are reducing TX power.
+ * @pwr_restriction: TX power restriction in dBms.
+ */
+struct iwl_reduce_tx_power_cmd {
+       u8 flags;
+       u8 mac_context_id;
+       __le16 pwr_restriction;
+} __packed; /* TX_REDUCED_POWER_API_S_VER_1 */
+
+/**
+ * struct iwl_dev_tx_power_cmd - TX power reduction command
+ * REDUCE_TX_POWER_CMD = 0x9f
+ * @set_mode: 0 - MAC tx power, 1 - device tx power
+ * @mac_context_id: id of the mac ctx for which we are reducing TX power.
+ * @pwr_restriction: TX power restriction in 1/8 dBms.
+ * @dev_24: device TX power restriction in 1/8 dBms
+ * @dev_52_low: device TX power restriction upper band - low
+ * @dev_52_high: device TX power restriction upper band - high
+ */
+struct iwl_dev_tx_power_cmd {
+       __le32 set_mode;
+       __le32 mac_context_id;
+       __le16 pwr_restriction;
+       __le16 dev_24;
+       __le16 dev_52_low;
+       __le16 dev_52_high;
+} __packed; /* TX_REDUCED_POWER_API_S_VER_2 */
+
+#define IWL_DEV_MAX_TX_POWER 0x7FFF
+
 /**
  * struct iwl_beacon_filter_cmd
  * REPLY_BEACON_FILTERING_CMD = 0xd2 (command)
index 4f81dcf57a736e7409087f4b3193809c3570db6f..d6cced47d561b9601a59166296a229facfd9014e 100644 (file)
@@ -122,46 +122,6 @@ enum iwl_scan_complete_status {
        SCAN_COMP_STATUS_ERR_ALLOC_TE = 0x0C,
 };
 
-/**
- * struct iwl_scan_results_notif - scan results for one channel
- * ( SCAN_RESULTS_NOTIFICATION = 0x83 )
- * @channel: which channel the results are from
- * @band: 0 for 5.2 GHz, 1 for 2.4 GHz
- * @probe_status: SCAN_PROBE_STATUS_*, indicates success of probe request
- * @num_probe_not_sent: # of request that weren't sent due to not enough time
- * @duration: duration spent in channel, in usecs
- * @statistics: statistics gathered for this channel
- */
-struct iwl_scan_results_notif {
-       u8 channel;
-       u8 band;
-       u8 probe_status;
-       u8 num_probe_not_sent;
-       __le32 duration;
-       __le32 statistics[SCAN_RESULTS_STATISTICS];
-} __packed; /* SCAN_RESULT_NTF_API_S_VER_2 */
-
-/**
- * struct iwl_scan_complete_notif - notifies end of scanning (all channels)
- * ( SCAN_COMPLETE_NOTIFICATION = 0x84 )
- * @scanned_channels: number of channels scanned (and number of valid results)
- * @status: one of SCAN_COMP_STATUS_*
- * @bt_status: BT on/off status
- * @last_channel: last channel that was scanned
- * @tsf_low: TSF timer (lower half) in usecs
- * @tsf_high: TSF timer (higher half) in usecs
- * @results: array of scan results, only "scanned_channels" of them are valid
- */
-struct iwl_scan_complete_notif {
-       u8 scanned_channels;
-       u8 status;
-       u8 bt_status;
-       u8 last_channel;
-       __le32 tsf_low;
-       __le32 tsf_high;
-       struct iwl_scan_results_notif results[];
-} __packed; /* SCAN_COMPLETE_NTF_API_S_VER_2 */
-
 /* scan offload */
 #define IWL_SCAN_MAX_BLACKLIST_LEN     64
 #define IWL_SCAN_SHORT_BLACKLIST_LEN   16
@@ -554,7 +514,7 @@ struct iwl_scan_req_unified_lmac {
 } __packed;
 
 /**
- * struct iwl_lmac_scan_results_notif - scan results for one channel -
+ * struct iwl_scan_results_notif - scan results for one channel -
  *     SCAN_RESULT_NTF_API_S_VER_3
  * @channel: which channel the results are from
  * @band: 0 for 5.2 GHz, 1 for 2.4 GHz
@@ -562,7 +522,7 @@ struct iwl_scan_req_unified_lmac {
  * @num_probe_not_sent: # of request that weren't sent due to not enough time
  * @duration: duration spent in channel, in usecs
  */
-struct iwl_lmac_scan_results_notif {
+struct iwl_scan_results_notif {
        u8 channel;
        u8 band;
        u8 probe_status;
index aab68cbae754d547a9e1fe514c4c88de6877777f..01b1da6ad35977b349fc79336c15238706ca9078 100644 (file)
@@ -281,19 +281,6 @@ struct iwl_tx_ant_cfg_cmd {
        __le32 valid;
 } __packed;
 
-/**
- * struct iwl_reduce_tx_power_cmd - TX power reduction command
- * REDUCE_TX_POWER_CMD = 0x9f
- * @flags: (reserved for future implementation)
- * @mac_context_id: id of the mac ctx for which we are reducing TX power.
- * @pwr_restriction: TX power restriction in dBms.
- */
-struct iwl_reduce_tx_power_cmd {
-       u8 flags;
-       u8 mac_context_id;
-       __le16 pwr_restriction;
-} __packed; /* TX_REDUCED_POWER_API_S_VER_1 */
-
 /*
  * Calibration control struct.
  * Sent as part of the phy configuration command.
index bc5eac4960e18a79a211da2a2bf6492b1a39e570..df869633f4dd976c9404e036ecf8a49a855fd0b4 100644 (file)
@@ -6,7 +6,7 @@
  * GPL LICENSE SUMMARY
  *
  * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
- * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
+ * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -32,7 +32,7 @@
  * BSD LICENSE
  *
  * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
- * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
+ * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -322,7 +322,7 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
 
        lockdep_assert_held(&mvm->mutex);
 
-       if (WARN_ON_ONCE(mvm->init_ucode_complete || mvm->calibrating))
+       if (WARN_ON_ONCE(mvm->calibrating))
                return 0;
 
        iwl_init_notification_wait(&mvm->notif_wait,
@@ -396,8 +396,6 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
         */
        ret = iwl_wait_notification(&mvm->notif_wait, &calib_wait,
                        MVM_UCODE_CALIB_TIMEOUT);
-       if (!ret)
-               mvm->init_ucode_complete = true;
 
        if (ret && iwl_mvm_is_radio_killed(mvm)) {
                IWL_DEBUG_RF_KILL(mvm, "RFKILL while calibrating.\n");
@@ -494,15 +492,6 @@ int iwl_mvm_fw_dbg_collect_desc(struct iwl_mvm *mvm,
 
        mvm->fw_dump_desc = desc;
 
-       /* stop recording */
-       if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000) {
-               iwl_set_bits_prph(mvm->trans, MON_BUFF_SAMPLE_CTL, 0x100);
-       } else {
-               iwl_write_prph(mvm->trans, DBGC_IN_SAMPLE, 0);
-               /* wait before we collect the data till the DBGC stop */
-               udelay(100);
-       }
-
        queue_delayed_work(system_wq, &mvm->fw_dump_wk, delay);
 
        return 0;
@@ -658,25 +647,24 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
         * module loading, load init ucode now
         * (for example, if we were in RFKILL)
         */
-       if (!mvm->init_ucode_complete) {
-               ret = iwl_run_init_mvm_ucode(mvm, false);
-               if (ret && !iwlmvm_mod_params.init_dbg) {
-                       IWL_ERR(mvm, "Failed to run INIT ucode: %d\n", ret);
-                       /* this can't happen */
-                       if (WARN_ON(ret > 0))
-                               ret = -ERFKILL;
-                       goto error;
-               }
-               if (!iwlmvm_mod_params.init_dbg) {
-                       /*
-                        * should stop and start HW since that INIT
-                        * image just loaded
-                        */
-                       iwl_trans_stop_device(mvm->trans);
-                       ret = iwl_trans_start_hw(mvm->trans);
-                       if (ret)
-                               return ret;
-               }
+       ret = iwl_run_init_mvm_ucode(mvm, false);
+       if (ret && !iwlmvm_mod_params.init_dbg) {
+               IWL_ERR(mvm, "Failed to run INIT ucode: %d\n", ret);
+               /* this can't happen */
+               if (WARN_ON(ret > 0))
+                       ret = -ERFKILL;
+               goto error;
+       }
+       if (!iwlmvm_mod_params.init_dbg) {
+               /*
+                * Stop and start the transport without entering low power
+                * mode. This will save the state of other components on the
+                * device that are triggered by the INIT firwmare (MFUART).
+                */
+               _iwl_trans_stop_device(mvm->trans, false);
+               _iwl_trans_start_hw(mvm->trans, false);
+               if (ret)
+                       return ret;
        }
 
        if (iwlmvm_mod_params.init_dbg)
index 84555170b6f751bb4f0925bf5c85319de76293b6..dda9f7b5f3423173e668f507719e47c3540b27d0 100644 (file)
@@ -1322,7 +1322,7 @@ static void iwl_mvm_restart_complete(struct iwl_mvm *mvm)
 
        clear_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status);
        iwl_mvm_d0i3_enable_tx(mvm, NULL);
-       ret = iwl_mvm_update_quotas(mvm, false, NULL);
+       ret = iwl_mvm_update_quotas(mvm, true, NULL);
        if (ret)
                IWL_ERR(mvm, "Failed to update quotas after restart (%d)\n",
                        ret);
@@ -1471,8 +1471,8 @@ static struct iwl_mvm_phy_ctxt *iwl_mvm_get_free_phy_ctxt(struct iwl_mvm *mvm)
        return NULL;
 }
 
-static int iwl_mvm_set_tx_power(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
-                               s8 tx_power)
+static int iwl_mvm_set_tx_power_old(struct iwl_mvm *mvm,
+                                   struct ieee80211_vif *vif, s8 tx_power)
 {
        /* FW is in charge of regulatory enforcement */
        struct iwl_reduce_tx_power_cmd reduce_txpwr_cmd = {
@@ -1485,6 +1485,26 @@ static int iwl_mvm_set_tx_power(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
                                    &reduce_txpwr_cmd);
 }
 
+static int iwl_mvm_set_tx_power(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
+                               s16 tx_power)
+{
+       struct iwl_dev_tx_power_cmd cmd = {
+               .set_mode = 0,
+               .mac_context_id =
+                       cpu_to_le32(iwl_mvm_vif_from_mac80211(vif)->id),
+               .pwr_restriction = cpu_to_le16(8 * tx_power),
+       };
+
+       if (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_TX_POWER_DEV))
+               return iwl_mvm_set_tx_power_old(mvm, vif, tx_power);
+
+       if (tx_power == IWL_DEFAULT_MAX_TX_POWER)
+               cmd.pwr_restriction = cpu_to_le16(IWL_DEV_MAX_TX_POWER);
+
+       return iwl_mvm_send_cmd_pdu(mvm, REDUCE_TX_POWER_CMD, 0,
+                                   sizeof(cmd), &cmd);
+}
+
 static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
                                     struct ieee80211_vif *vif)
 {
@@ -3975,9 +3995,6 @@ static void iwl_mvm_mac_event_callback(struct ieee80211_hw *hw,
        if (!iwl_fw_dbg_trigger_enabled(mvm->fw, FW_DBG_TRIGGER_MLME))
                return;
 
-       if (event->u.mlme.status == MLME_SUCCESS)
-               return;
-
        trig = iwl_fw_dbg_get_trigger(mvm->fw, FW_DBG_TRIGGER_MLME);
        trig_mlme = (void *)trig->data;
        if (!iwl_fw_dbg_trigger_check_stop(mvm, vif, trig))
index d5522a16124292cd6cab36159851a8446b5e2d95..cf70f681d1acb7e271717091684ca805749e13ab 100644 (file)
@@ -603,7 +603,6 @@ struct iwl_mvm {
 
        enum iwl_ucode_type cur_ucode;
        bool ucode_loaded;
-       bool init_ucode_complete;
        bool calibrating;
        u32 error_event_table;
        u32 log_event_table;
index a08b03d58d4bf0f3ebd4773a7fdb6e07cc8406b8..2ea01238754eb8d1c2470156f0293a2e15988fd6 100644 (file)
@@ -865,6 +865,16 @@ static void iwl_mvm_fw_error_dump_wk(struct work_struct *work)
                return;
 
        mutex_lock(&mvm->mutex);
+
+       /* stop recording */
+       if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000) {
+               iwl_set_bits_prph(mvm->trans, MON_BUFF_SAMPLE_CTL, 0x100);
+       } else {
+               iwl_write_prph(mvm->trans, DBGC_IN_SAMPLE, 0);
+               /* wait before we collect the data till the DBGC stop */
+               udelay(100);
+       }
+
        iwl_mvm_fw_error_dump(mvm);
 
        /* start recording again if the firmware is not crashed */
@@ -1253,11 +1263,13 @@ static void iwl_mvm_d0i3_exit_work(struct work_struct *wk)
                ieee80211_iterate_active_interfaces(
                        mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
                        iwl_mvm_d0i3_disconnect_iter, mvm);
-
-       iwl_free_resp(&get_status_cmd);
 out:
        iwl_mvm_d0i3_enable_tx(mvm, qos_seq);
 
+       /* qos_seq might point inside resp_pkt, so free it only now */
+       if (get_status_cmd.resp_pkt)
+               iwl_free_resp(&get_status_cmd);
+
        /* the FW might have updated the regdomain */
        iwl_mvm_update_changed_regdom(mvm);
 
index f9928f2c125f726bbf89474096bd47990bfb86eb..33cd68ae7bf9362539fa1a99e34686e0cca3de2b 100644 (file)
@@ -180,6 +180,9 @@ static bool rs_mimo_allow(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
        if (iwl_mvm_vif_low_latency(mvmvif) && mvmsta->vif->p2p)
                return false;
 
+       if (mvm->nvm_data->sku_cap_mimo_disabled)
+               return false;
+
        return true;
 }
 
index 78ec7db64ba59e886e2a7b18a3df64f70a4ea29c..d6314ddf57b5d9638fcfd2fcf6ba917bb136779f 100644 (file)
@@ -478,6 +478,11 @@ static void iwl_mvm_stat_iterator(void *_data, u8 *mac,
        if (vif->type != NL80211_IFTYPE_STATION)
                return;
 
+       if (sig == 0) {
+               IWL_DEBUG_RX(mvm, "RSSI is 0 - skip signal based decision\n");
+               return;
+       }
+
        mvmvif->bf_data.ave_beacon_signal = sig;
 
        /* BT Coex */
index 74e1c86289dcbcedc1f5c7b963e468095de7cf25..1075a213bd6a87156e44ab410ac566cf18bdacc3 100644 (file)
@@ -319,7 +319,7 @@ int iwl_mvm_rx_scan_offload_iter_complete_notif(struct iwl_mvm *mvm,
                                                struct iwl_device_cmd *cmd)
 {
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
-       struct iwl_scan_complete_notif *notif = (void *)pkt->data;
+       struct iwl_lmac_scan_complete_notif *notif = (void *)pkt->data;
 
        IWL_DEBUG_SCAN(mvm,
                       "Scan offload iteration complete: status=0x%x scanned channels=%d\n",
index 2de8fbfe4edf4d6c6997307fb91052177fd7e6e4..d6f6515fe663707c3127f9c1db97c3143a9c0bd8 100644 (file)
@@ -5,8 +5,8 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved.
- * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
+ * Copyright(c) 2007 - 2015 Intel Corporation. All rights reserved.
+ * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -31,8 +31,8 @@
  *
  * BSD LICENSE
  *
- * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
- * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
+ * Copyright(c) 2005 - 2015 Intel Corporation. All rights reserved.
+ * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -104,7 +104,7 @@ static void iwl_pcie_free_fw_monitor(struct iwl_trans *trans)
 static void iwl_pcie_alloc_fw_monitor(struct iwl_trans *trans)
 {
        struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
-       struct page *page;
+       struct page *page = NULL;
        dma_addr_t phys;
        u32 size;
        u8 power;
@@ -131,6 +131,7 @@ static void iwl_pcie_alloc_fw_monitor(struct iwl_trans *trans)
                                    DMA_FROM_DEVICE);
                if (dma_mapping_error(trans->dev, phys)) {
                        __free_pages(page, order);
+                       page = NULL;
                        continue;
                }
                IWL_INFO(trans,
@@ -1020,7 +1021,7 @@ static void iwl_trans_pcie_fw_alive(struct iwl_trans *trans, u32 scd_addr)
        iwl_pcie_tx_start(trans, scd_addr);
 }
 
-static void iwl_trans_pcie_stop_device(struct iwl_trans *trans)
+static void iwl_trans_pcie_stop_device(struct iwl_trans *trans, bool low_power)
 {
        struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
        bool hw_rfkill, was_hw_rfkill;
@@ -1048,9 +1049,11 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans)
                iwl_pcie_rx_stop(trans);
 
                /* Power-down device's busmaster DMA clocks */
-               iwl_write_prph(trans, APMG_CLK_DIS_REG,
-                              APMG_CLK_VAL_DMA_CLK_RQT);
-               udelay(5);
+               if (trans->cfg->device_family != IWL_DEVICE_FAMILY_8000) {
+                       iwl_write_prph(trans, APMG_CLK_DIS_REG,
+                                      APMG_CLK_VAL_DMA_CLK_RQT);
+                       udelay(5);
+               }
        }
 
        /* Make sure (redundant) we've released our request to stay awake */
@@ -1115,7 +1118,7 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans)
 void iwl_trans_pcie_rf_kill(struct iwl_trans *trans, bool state)
 {
        if (iwl_op_mode_hw_rf_kill(trans->op_mode, state))
-               iwl_trans_pcie_stop_device(trans);
+               iwl_trans_pcie_stop_device(trans, true);
 }
 
 static void iwl_trans_pcie_d3_suspend(struct iwl_trans *trans, bool test)
@@ -1200,7 +1203,7 @@ static int iwl_trans_pcie_d3_resume(struct iwl_trans *trans,
        return 0;
 }
 
-static int iwl_trans_pcie_start_hw(struct iwl_trans *trans)
+static int iwl_trans_pcie_start_hw(struct iwl_trans *trans, bool low_power)
 {
        bool hw_rfkill;
        int err;
index f0188c83c79f7d6027bdee6372768d3657347a2a..2721cf89fb160f0d3f4e6106474c5da101707a18 100644 (file)
@@ -126,7 +126,7 @@ static int _usbctrl_vendorreq_sync_read(struct usb_device *udev, u8 request,
 
        do {
                status = usb_control_msg(udev, pipe, request, reqtype, value,
-                                        index, pdata, len, 0); /*max. timeout*/
+                                        index, pdata, len, 1000);
                if (status < 0) {
                        /* firmware download is checksumed, don't retry */
                        if ((value >= FW_8192C_START_ADDRESS &&
index 3d8dbf5f2d396aa8dde8745afe98d8b4f9febd67..fee02414529e0b951d67ea458107b50f87c9b1d8 100644 (file)
@@ -793,6 +793,7 @@ static void connect(struct backend_info *be)
                        goto err;
                }
 
+               queue->credit_bytes = credit_bytes;
                queue->remaining_credit = credit_bytes;
                queue->credit_usec = credit_usec;
 
index 3f45afd4382e164053dac1231978e91a5af6dbe0..e031c943286ef3f7765e42640397626d7555607c 100644 (file)
@@ -1698,6 +1698,7 @@ static void xennet_destroy_queues(struct netfront_info *info)
 
                if (netif_running(info->netdev))
                        napi_disable(&queue->napi);
+               del_timer_sync(&queue->rx_refill_timer);
                netif_napi_del(&queue->napi);
        }
 
@@ -2102,9 +2103,6 @@ static const struct attribute_group xennet_dev_group = {
 static int xennet_remove(struct xenbus_device *dev)
 {
        struct netfront_info *info = dev_get_drvdata(&dev->dev);
-       unsigned int num_queues = info->netdev->real_num_tx_queues;
-       struct netfront_queue *queue = NULL;
-       unsigned int i = 0;
 
        dev_dbg(&dev->dev, "%s\n", dev->nodename);
 
@@ -2112,16 +2110,7 @@ static int xennet_remove(struct xenbus_device *dev)
 
        unregister_netdev(info->netdev);
 
-       for (i = 0; i < num_queues; ++i) {
-               queue = &info->queues[i];
-               del_timer_sync(&queue->rx_refill_timer);
-       }
-
-       if (num_queues) {
-               kfree(info->queues);
-               info->queues = NULL;
-       }
-
+       xennet_destroy_queues(info);
        xennet_free_netdev(info->netdev);
 
        return 0;
index 8be2096c842390f5ecefc24186267e9ce4f61e2b..deeaed54422246dceb236f0a604696d5cddb2549 100644 (file)
@@ -348,7 +348,7 @@ int superio_fixup_irq(struct pci_dev *pcidev)
                BUG();
                return -1;
        }
-       printk("superio_fixup_irq(%s) ven 0x%x dev 0x%x from %pf\n",
+       printk(KERN_DEBUG "superio_fixup_irq(%s) ven 0x%x dev 0x%x from %ps\n",
                pci_name(pcidev),
                pcidev->vendor, pcidev->device,
                __builtin_return_address(0));
index 4ad5c1a996e3e906023bbe246c98a258ec3bba23..e406e3d8c1c71713e08ceb440e43900fbbb5b8be 100644 (file)
@@ -643,7 +643,9 @@ static const struct cygnus_gpio_pin_range cygnus_gpio_pintable[] = {
        CYGNUS_PINRANGE(87, 104, 12),
        CYGNUS_PINRANGE(99, 102, 2),
        CYGNUS_PINRANGE(101, 90, 4),
-       CYGNUS_PINRANGE(105, 116, 10),
+       CYGNUS_PINRANGE(105, 116, 6),
+       CYGNUS_PINRANGE(111, 100, 2),
+       CYGNUS_PINRANGE(113, 122, 4),
        CYGNUS_PINRANGE(123, 11, 1),
        CYGNUS_PINRANGE(124, 38, 4),
        CYGNUS_PINRANGE(128, 43, 1),
index 82f691eeeec4d82cd5e75b7a96be719befbcd57f..732ff757a95fe12fe7b5ddca1714a8e527017e90 100644 (file)
@@ -1292,6 +1292,49 @@ static void chv_gpio_irq_unmask(struct irq_data *d)
        chv_gpio_irq_mask_unmask(d, false);
 }
 
+static unsigned chv_gpio_irq_startup(struct irq_data *d)
+{
+       /*
+        * Check if the interrupt has been requested with 0 as triggering
+        * type. In that case it is assumed that the current values
+        * programmed to the hardware are used (e.g BIOS configured
+        * defaults).
+        *
+        * In that case ->irq_set_type() will never be called so we need to
+        * read back the values from hardware now, set correct flow handler
+        * and update mappings before the interrupt is being used.
+        */
+       if (irqd_get_trigger_type(d) == IRQ_TYPE_NONE) {
+               struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+               struct chv_pinctrl *pctrl = gpiochip_to_pinctrl(gc);
+               unsigned offset = irqd_to_hwirq(d);
+               int pin = chv_gpio_offset_to_pin(pctrl, offset);
+               irq_flow_handler_t handler;
+               unsigned long flags;
+               u32 intsel, value;
+
+               intsel = readl(chv_padreg(pctrl, pin, CHV_PADCTRL0));
+               intsel &= CHV_PADCTRL0_INTSEL_MASK;
+               intsel >>= CHV_PADCTRL0_INTSEL_SHIFT;
+
+               value = readl(chv_padreg(pctrl, pin, CHV_PADCTRL1));
+               if (value & CHV_PADCTRL1_INTWAKECFG_LEVEL)
+                       handler = handle_level_irq;
+               else
+                       handler = handle_edge_irq;
+
+               spin_lock_irqsave(&pctrl->lock, flags);
+               if (!pctrl->intr_lines[intsel]) {
+                       __irq_set_handler_locked(d->irq, handler);
+                       pctrl->intr_lines[intsel] = offset;
+               }
+               spin_unlock_irqrestore(&pctrl->lock, flags);
+       }
+
+       chv_gpio_irq_unmask(d);
+       return 0;
+}
+
 static int chv_gpio_irq_type(struct irq_data *d, unsigned type)
 {
        struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
@@ -1357,6 +1400,7 @@ static int chv_gpio_irq_type(struct irq_data *d, unsigned type)
 
 static struct irq_chip chv_gpio_irqchip = {
        .name = "chv-gpio",
+       .irq_startup = chv_gpio_irq_startup,
        .irq_ack = chv_gpio_irq_ack,
        .irq_mask = chv_gpio_irq_mask,
        .irq_unmask = chv_gpio_irq_unmask,
index edcd140e089968e0f7b95fef4ffcd82f157f8294..a70a5fe79d44d343b0e1830ccd36fe7b6384d314 100644 (file)
@@ -569,7 +569,7 @@ static int meson_gpiolib_register(struct meson_pinctrl *pc)
                domain->chip.direction_output = meson_gpio_direction_output;
                domain->chip.get = meson_gpio_get;
                domain->chip.set = meson_gpio_set;
-               domain->chip.base = -1;
+               domain->chip.base = domain->data->pin_base;
                domain->chip.ngpio = domain->data->num_pins;
                domain->chip.can_sleep = false;
                domain->chip.of_node = domain->of_node;
index 2f7ea62298801c2a5b9b87605a3fe5fbb0ca00bd..9677807db364d70ee4512799e26449bccba56a08 100644 (file)
@@ -876,13 +876,13 @@ static struct meson_domain_data meson8b_domain_data[] = {
                .banks          = meson8b_banks,
                .num_banks      = ARRAY_SIZE(meson8b_banks),
                .pin_base       = 0,
-               .num_pins       = 83,
+               .num_pins       = 130,
        },
        {
                .name           = "ao-bank",
                .banks          = meson8b_ao_banks,
                .num_banks      = ARRAY_SIZE(meson8b_ao_banks),
-               .pin_base       = 83,
+               .pin_base       = 130,
                .num_pins       = 16,
        },
 };
index 9bb9ad6d4a1b1b1c3600cd283f240d2479a80841..28f328136f0df78fe3253d6996ae9108229f87e5 100644 (file)
@@ -2897,7 +2897,7 @@ static ssize_t hotkey_wakeup_reason_show(struct device *dev,
        return snprintf(buf, PAGE_SIZE, "%d\n", hotkey_wakeup_reason);
 }
 
-static DEVICE_ATTR_RO(hotkey_wakeup_reason);
+static DEVICE_ATTR(wakeup_reason, S_IRUGO, hotkey_wakeup_reason_show, NULL);
 
 static void hotkey_wakeup_reason_notify_change(void)
 {
@@ -2913,7 +2913,8 @@ static ssize_t hotkey_wakeup_hotunplug_complete_show(struct device *dev,
        return snprintf(buf, PAGE_SIZE, "%d\n", hotkey_autosleep_ack);
 }
 
-static DEVICE_ATTR_RO(hotkey_wakeup_hotunplug_complete);
+static DEVICE_ATTR(wakeup_hotunplug_complete, S_IRUGO,
+                  hotkey_wakeup_hotunplug_complete_show, NULL);
 
 static void hotkey_wakeup_hotunplug_complete_notify_change(void)
 {
@@ -2978,8 +2979,8 @@ static struct attribute *hotkey_attributes[] __initdata = {
        &dev_attr_hotkey_enable.attr,
        &dev_attr_hotkey_bios_enabled.attr,
        &dev_attr_hotkey_bios_mask.attr,
-       &dev_attr_hotkey_wakeup_reason.attr,
-       &dev_attr_hotkey_wakeup_hotunplug_complete.attr,
+       &dev_attr_wakeup_reason.attr,
+       &dev_attr_wakeup_hotunplug_complete.attr,
        &dev_attr_hotkey_mask.attr,
        &dev_attr_hotkey_all_mask.attr,
        &dev_attr_hotkey_recommended_mask.attr,
@@ -4393,12 +4394,13 @@ static ssize_t wan_enable_store(struct device *dev,
                        attr, buf, count);
 }
 
-static DEVICE_ATTR_RW(wan_enable);
+static DEVICE_ATTR(wwan_enable, S_IWUSR | S_IRUGO,
+                  wan_enable_show, wan_enable_store);
 
 /* --------------------------------------------------------------------- */
 
 static struct attribute *wan_attributes[] = {
-       &dev_attr_wan_enable.attr,
+       &dev_attr_wwan_enable.attr,
        NULL
 };
 
@@ -8138,7 +8140,8 @@ static ssize_t fan_pwm1_enable_store(struct device *dev,
        return count;
 }
 
-static DEVICE_ATTR_RW(fan_pwm1_enable);
+static DEVICE_ATTR(pwm1_enable, S_IWUSR | S_IRUGO,
+                  fan_pwm1_enable_show, fan_pwm1_enable_store);
 
 /* sysfs fan pwm1 ------------------------------------------------------ */
 static ssize_t fan_pwm1_show(struct device *dev,
@@ -8198,7 +8201,7 @@ static ssize_t fan_pwm1_store(struct device *dev,
        return (rc) ? rc : count;
 }
 
-static DEVICE_ATTR_RW(fan_pwm1);
+static DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, fan_pwm1_show, fan_pwm1_store);
 
 /* sysfs fan fan1_input ------------------------------------------------ */
 static ssize_t fan_fan1_input_show(struct device *dev,
@@ -8215,7 +8218,7 @@ static ssize_t fan_fan1_input_show(struct device *dev,
        return snprintf(buf, PAGE_SIZE, "%u\n", speed);
 }
 
-static DEVICE_ATTR_RO(fan_fan1_input);
+static DEVICE_ATTR(fan1_input, S_IRUGO, fan_fan1_input_show, NULL);
 
 /* sysfs fan fan2_input ------------------------------------------------ */
 static ssize_t fan_fan2_input_show(struct device *dev,
@@ -8232,7 +8235,7 @@ static ssize_t fan_fan2_input_show(struct device *dev,
        return snprintf(buf, PAGE_SIZE, "%u\n", speed);
 }
 
-static DEVICE_ATTR_RO(fan_fan2_input);
+static DEVICE_ATTR(fan2_input, S_IRUGO, fan_fan2_input_show, NULL);
 
 /* sysfs fan fan_watchdog (hwmon driver) ------------------------------- */
 static ssize_t fan_fan_watchdog_show(struct device_driver *drv,
@@ -8265,8 +8268,8 @@ static DRIVER_ATTR(fan_watchdog, S_IWUSR | S_IRUGO,
 
 /* --------------------------------------------------------------------- */
 static struct attribute *fan_attributes[] = {
-       &dev_attr_fan_pwm1_enable.attr, &dev_attr_fan_pwm1.attr,
-       &dev_attr_fan_fan1_input.attr,
+       &dev_attr_pwm1_enable.attr, &dev_attr_pwm1.attr,
+       &dev_attr_fan1_input.attr,
        NULL, /* for fan2_input */
        NULL
 };
@@ -8400,7 +8403,7 @@ static int __init fan_init(struct ibm_init_struct *iibm)
                if (tp_features.second_fan) {
                        /* attach second fan tachometer */
                        fan_attributes[ARRAY_SIZE(fan_attributes)-2] =
-                                       &dev_attr_fan_fan2_input.attr;
+                                       &dev_attr_fan2_input.attr;
                }
                rc = sysfs_create_group(&tpacpi_sensors_pdev->dev.kobj,
                                         &fan_attr_group);
@@ -8848,7 +8851,7 @@ static ssize_t thinkpad_acpi_pdev_name_show(struct device *dev,
        return snprintf(buf, PAGE_SIZE, "%s\n", TPACPI_NAME);
 }
 
-static DEVICE_ATTR_RO(thinkpad_acpi_pdev_name);
+static DEVICE_ATTR(name, S_IRUGO, thinkpad_acpi_pdev_name_show, NULL);
 
 /* --------------------------------------------------------------------- */
 
@@ -9390,8 +9393,7 @@ static void thinkpad_acpi_module_exit(void)
                hwmon_device_unregister(tpacpi_hwmon);
 
        if (tp_features.sensors_pdev_attrs_registered)
-               device_remove_file(&tpacpi_sensors_pdev->dev,
-                                  &dev_attr_thinkpad_acpi_pdev_name);
+               device_remove_file(&tpacpi_sensors_pdev->dev, &dev_attr_name);
        if (tpacpi_sensors_pdev)
                platform_device_unregister(tpacpi_sensors_pdev);
        if (tpacpi_pdev)
@@ -9512,8 +9514,7 @@ static int __init thinkpad_acpi_module_init(void)
                thinkpad_acpi_module_exit();
                return ret;
        }
-       ret = device_create_file(&tpacpi_sensors_pdev->dev,
-                                &dev_attr_thinkpad_acpi_pdev_name);
+       ret = device_create_file(&tpacpi_sensors_pdev->dev, &dev_attr_name);
        if (ret) {
                pr_err("unable to create sysfs hwmon device attributes\n");
                thinkpad_acpi_module_exit();
index ca1cc5a47eb1e02b9acd38f1aeff2abf93bbf6ac..bd1dbfee2515dda65c54176d9b2e547cb4e3beca 100644 (file)
@@ -1149,6 +1149,7 @@ static struct platform_driver axp288_fuel_gauge_driver = {
 
 module_platform_driver(axp288_fuel_gauge_driver);
 
+MODULE_AUTHOR("Ramakrishna Pallala <ramakrishna.pallala@intel.com>");
 MODULE_AUTHOR("Todd Brandt <todd.e.brandt@linux.intel.com>");
 MODULE_DESCRIPTION("Xpower AXP288 Fuel Gauge Driver");
 MODULE_LICENSE("GPL");
index a57433de5c249fa33e6fb4f59e7c2dbf3190208b..b6b98378faa32b50c0e1900c76ca4e26da3bd6c1 100644 (file)
@@ -1109,6 +1109,14 @@ static void __exit bq27x00_battery_exit(void)
 }
 module_exit(bq27x00_battery_exit);
 
+#ifdef CONFIG_BATTERY_BQ27X00_PLATFORM
+MODULE_ALIAS("platform:bq27000-battery");
+#endif
+
+#ifdef CONFIG_BATTERY_BQ27X00_I2C
+MODULE_ALIAS("i2c:bq27000-battery");
+#endif
+
 MODULE_AUTHOR("Rodolfo Giometti <giometti@linux.it>");
 MODULE_DESCRIPTION("BQ27x00 battery monitor driver");
 MODULE_LICENSE("GPL");
index 2da9ed8ccbb5391f50c7137866b3fad5669dd2d7..8a971b3dbe583f0dc2640ddfa867f33c3e2c0ef4 100644 (file)
@@ -347,7 +347,7 @@ static int collie_bat_probe(struct ucb1x00_dev *dev)
                goto err_psy_reg_main;
        }
 
-       psy_main_cfg.drv_data = &collie_bat_bu;
+       psy_bu_cfg.drv_data = &collie_bat_bu;
        collie_bat_bu.psy = power_supply_register(&dev->ucb->dev,
                                                  &collie_bat_bu_desc,
                                                  &psy_bu_cfg);
index aad9c3318c02a271a864da8866b9b38c4623768c..17d93a73c5136e53ab2955d7aba02a7ef0c85d1f 100644 (file)
@@ -41,6 +41,7 @@ config POWER_RESET_AXXIA
 config POWER_RESET_BRCMSTB
        bool "Broadcom STB reset driver"
        depends on ARM || MIPS || COMPILE_TEST
+       depends on MFD_SYSCON
        default ARCH_BRCMSTB
        help
          This driver provides restart support for Broadcom STB boards.
index 01c7055c4200e3d9a7333ac7c0bcaccc3ac2d4a5..ca461ebc7ae8f73338059d6ce9547b850c269f1b 100644 (file)
@@ -212,9 +212,9 @@ static int at91_reset_platform_probe(struct platform_device *pdev)
                res = platform_get_resource(pdev, IORESOURCE_MEM, idx + 1 );
                at91_ramc_base[idx] = devm_ioremap(&pdev->dev, res->start,
                                                   resource_size(res));
-               if (IS_ERR(at91_ramc_base[idx])) {
+               if (!at91_ramc_base[idx]) {
                        dev_err(&pdev->dev, "Could not map ram controller address\n");
-                       return PTR_ERR(at91_ramc_base[idx]);
+                       return -ENOMEM;
                }
        }
 
index 7ef193b6f7fe81451c504797cec9bb4932879ee8..1e08195551fe7d505511a6dd92b07d1ab4300911 100644 (file)
@@ -120,18 +120,7 @@ static enum hrtimer_restart ltc2952_poweroff_timer_wde(struct hrtimer *timer)
 
 static void ltc2952_poweroff_start_wde(struct ltc2952_poweroff *data)
 {
-       if (hrtimer_start(&data->timer_wde, data->wde_interval,
-                         HRTIMER_MODE_REL)) {
-               /*
-                * The device will not toggle the watchdog reset,
-                * thus shut down is only safe if the PowerPath controller
-                * has a long enough time-off before triggering a hardware
-                * power-off.
-                *
-                * Only sending a warning as the system will power-off anyway
-                */
-               dev_err(data->dev, "unable to start the timer\n");
-       }
+       hrtimer_start(&data->timer_wde, data->wde_interval, HRTIMER_MODE_REL);
 }
 
 static enum hrtimer_restart
@@ -165,9 +154,8 @@ static irqreturn_t ltc2952_poweroff_handler(int irq, void *dev_id)
        }
 
        if (gpiod_get_value(data->gpio_trigger)) {
-               if (hrtimer_start(&data->timer_trigger, data->trigger_delay,
-                                 HRTIMER_MODE_REL))
-                       dev_err(data->dev, "unable to start the wait timer\n");
+               hrtimer_start(&data->timer_trigger, data->trigger_delay,
+                             HRTIMER_MODE_REL);
        } else {
                hrtimer_cancel(&data->timer_trigger);
                /* omitting return value check, timer should have been valid */
index 476171a768d61def6d1f1e476ebc6db78c60839b..8a029f9bc18cb0f0c2c95bc7ea4d9167164326be 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/mfd/syscon.h>
 #include <linux/module.h>
 #include <linux/of.h>
+#include <linux/of_device.h>
 #include <linux/platform_device.h>
 #include <linux/pwm.h>
 #include <linux/regmap.h>
 #define PERIP_PWM_PDM_CONTROL_CH_MASK          0x1
 #define PERIP_PWM_PDM_CONTROL_CH_SHIFT(ch)     ((ch) * 4)
 
-#define MAX_TMBASE_STEPS                       65536
+/*
+ * PWM period is specified with a timebase register,
+ * in number of step periods. The PWM duty cycle is also
+ * specified in step periods, in the [0, $timebase] range.
+ * In other words, the timebase imposes the duty cycle
+ * resolution. Therefore, let's constraint the timebase to
+ * a minimum value to allow a sane range of duty cycle values.
+ * Imposing a minimum timebase, will impose a maximum PWM frequency.
+ *
+ * The value chosen is completely arbitrary.
+ */
+#define MIN_TMBASE_STEPS                       16
+
+struct img_pwm_soc_data {
+       u32 max_timebase;
+};
 
 struct img_pwm_chip {
        struct device   *dev;
@@ -47,6 +63,9 @@ struct img_pwm_chip {
        struct clk      *sys_clk;
        void __iomem    *base;
        struct regmap   *periph_regs;
+       int             max_period_ns;
+       int             min_period_ns;
+       const struct img_pwm_soc_data   *data;
 };
 
 static inline struct img_pwm_chip *to_img_pwm_chip(struct pwm_chip *chip)
@@ -72,24 +91,31 @@ static int img_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
        u32 val, div, duty, timebase;
        unsigned long mul, output_clk_hz, input_clk_hz;
        struct img_pwm_chip *pwm_chip = to_img_pwm_chip(chip);
+       unsigned int max_timebase = pwm_chip->data->max_timebase;
+
+       if (period_ns < pwm_chip->min_period_ns ||
+           period_ns > pwm_chip->max_period_ns) {
+               dev_err(chip->dev, "configured period not in range\n");
+               return -ERANGE;
+       }
 
        input_clk_hz = clk_get_rate(pwm_chip->pwm_clk);
        output_clk_hz = DIV_ROUND_UP(NSEC_PER_SEC, period_ns);
 
        mul = DIV_ROUND_UP(input_clk_hz, output_clk_hz);
-       if (mul <= MAX_TMBASE_STEPS) {
+       if (mul <= max_timebase) {
                div = PWM_CTRL_CFG_NO_SUB_DIV;
                timebase = DIV_ROUND_UP(mul, 1);
-       } else if (mul <= MAX_TMBASE_STEPS * 8) {
+       } else if (mul <= max_timebase * 8) {
                div = PWM_CTRL_CFG_SUB_DIV0;
                timebase = DIV_ROUND_UP(mul, 8);
-       } else if (mul <= MAX_TMBASE_STEPS * 64) {
+       } else if (mul <= max_timebase * 64) {
                div = PWM_CTRL_CFG_SUB_DIV1;
                timebase = DIV_ROUND_UP(mul, 64);
-       } else if (mul <= MAX_TMBASE_STEPS * 512) {
+       } else if (mul <= max_timebase * 512) {
                div = PWM_CTRL_CFG_SUB_DIV0_DIV1;
                timebase = DIV_ROUND_UP(mul, 512);
-       } else if (mul > MAX_TMBASE_STEPS * 512) {
+       } else if (mul > max_timebase * 512) {
                dev_err(chip->dev,
                        "failed to configure timebase steps/divider value\n");
                return -EINVAL;
@@ -143,11 +169,27 @@ static const struct pwm_ops img_pwm_ops = {
        .owner = THIS_MODULE,
 };
 
+static const struct img_pwm_soc_data pistachio_pwm = {
+       .max_timebase = 255,
+};
+
+static const struct of_device_id img_pwm_of_match[] = {
+       {
+               .compatible = "img,pistachio-pwm",
+               .data = &pistachio_pwm,
+       },
+       { }
+};
+MODULE_DEVICE_TABLE(of, img_pwm_of_match);
+
 static int img_pwm_probe(struct platform_device *pdev)
 {
        int ret;
+       u64 val;
+       unsigned long clk_rate;
        struct resource *res;
        struct img_pwm_chip *pwm;
+       const struct of_device_id *of_dev_id;
 
        pwm = devm_kzalloc(&pdev->dev, sizeof(*pwm), GFP_KERNEL);
        if (!pwm)
@@ -160,6 +202,11 @@ static int img_pwm_probe(struct platform_device *pdev)
        if (IS_ERR(pwm->base))
                return PTR_ERR(pwm->base);
 
+       of_dev_id = of_match_device(img_pwm_of_match, &pdev->dev);
+       if (!of_dev_id)
+               return -ENODEV;
+       pwm->data = of_dev_id->data;
+
        pwm->periph_regs = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
                                                           "img,cr-periph");
        if (IS_ERR(pwm->periph_regs))
@@ -189,6 +236,17 @@ static int img_pwm_probe(struct platform_device *pdev)
                goto disable_sysclk;
        }
 
+       clk_rate = clk_get_rate(pwm->pwm_clk);
+
+       /* The maximum input clock divider is 512 */
+       val = (u64)NSEC_PER_SEC * 512 * pwm->data->max_timebase;
+       do_div(val, clk_rate);
+       pwm->max_period_ns = val;
+
+       val = (u64)NSEC_PER_SEC * MIN_TMBASE_STEPS;
+       do_div(val, clk_rate);
+       pwm->min_period_ns = val;
+
        pwm->chip.dev = &pdev->dev;
        pwm->chip.ops = &img_pwm_ops;
        pwm->chip.base = -1;
@@ -228,12 +286,6 @@ static int img_pwm_remove(struct platform_device *pdev)
        return pwmchip_remove(&pwm_chip->chip);
 }
 
-static const struct of_device_id img_pwm_of_match[] = {
-       { .compatible = "img,pistachio-pwm", },
-       { }
-};
-MODULE_DEVICE_TABLE(of, img_pwm_of_match);
-
 static struct platform_driver img_pwm_driver = {
        .driver = {
                .name = "img-pwm",
index 8a4df7a1f2eecc879a679711d13d64885397af39..e628d4c2f2ae43de1955aac857f745ec2d3d0357 100644 (file)
@@ -394,6 +394,7 @@ static inline struct da9052_regulator_info *find_regulator_info(u8 chip_id,
 
 static int da9052_regulator_probe(struct platform_device *pdev)
 {
+       const struct mfd_cell *cell = mfd_get_cell(pdev);
        struct regulator_config config = { };
        struct da9052_regulator *regulator;
        struct da9052 *da9052;
@@ -409,7 +410,7 @@ static int da9052_regulator_probe(struct platform_device *pdev)
        regulator->da9052 = da9052;
 
        regulator->info = find_regulator_info(regulator->da9052->chip_id,
-                                             pdev->id);
+                                             cell->id);
        if (regulator->info == NULL) {
                dev_err(&pdev->dev, "invalid regulator ID specified\n");
                return -EINVAL;
@@ -419,7 +420,7 @@ static int da9052_regulator_probe(struct platform_device *pdev)
        config.driver_data = regulator;
        config.regmap = da9052->regmap;
        if (pdata && pdata->regulators) {
-               config.init_data = pdata->regulators[pdev->id];
+               config.init_data = pdata->regulators[cell->id];
        } else {
 #ifdef CONFIG_OF
                struct device_node *nproot = da9052->dev->of_node;
index cb70ced7e0db19771699a7b362d63b7c49e06d31..4b62d1a875e43eb09bf4631f7695f31dda9bfa6d 100644 (file)
@@ -64,7 +64,7 @@ static void rtc_delayed_write(u32 val, struct armada38x_rtc *rtc, int offset)
 static int armada38x_rtc_read_time(struct device *dev, struct rtc_time *tm)
 {
        struct armada38x_rtc *rtc = dev_get_drvdata(dev);
-       unsigned long time, time_check, flags;
+       unsigned long time, time_check;
 
        mutex_lock(&rtc->mutex_time);
        time = readl(rtc->regs + RTC_TIME);
index f0b9871a4bbd3ff209d77e56f28818fdbcce25e6..3ba61141975914aa25ef42658471686756fdefb5 100644 (file)
@@ -1158,11 +1158,12 @@ static ssize_t poll_timeout_store(struct bus_type *bus, const char *buf,
        poll_timeout = time;
        hr_time = ktime_set(0, poll_timeout);
 
-       if (!hrtimer_is_queued(&ap_poll_timer) ||
-           !hrtimer_forward(&ap_poll_timer, hrtimer_get_expires(&ap_poll_timer), hr_time)) {
-               hrtimer_set_expires(&ap_poll_timer, hr_time);
-               hrtimer_start_expires(&ap_poll_timer, HRTIMER_MODE_ABS);
-       }
+       spin_lock_bh(&ap_poll_timer_lock);
+       hrtimer_cancel(&ap_poll_timer);
+       hrtimer_set_expires(&ap_poll_timer, hr_time);
+       hrtimer_start_expires(&ap_poll_timer, HRTIMER_MODE_ABS);
+       spin_unlock_bh(&ap_poll_timer_lock);
+
        return count;
 }
 
@@ -1528,14 +1529,11 @@ static inline void __ap_schedule_poll_timer(void)
        ktime_t hr_time;
 
        spin_lock_bh(&ap_poll_timer_lock);
-       if (hrtimer_is_queued(&ap_poll_timer) || ap_suspend_flag)
-               goto out;
-       if (ktime_to_ns(hrtimer_expires_remaining(&ap_poll_timer)) <= 0) {
+       if (!hrtimer_is_queued(&ap_poll_timer) && !ap_suspend_flag) {
                hr_time = ktime_set(0, poll_timeout);
                hrtimer_forward_now(&ap_poll_timer, hr_time);
                hrtimer_restart(&ap_poll_timer);
        }
-out:
        spin_unlock_bh(&ap_poll_timer_lock);
 }
 
@@ -1952,7 +1950,7 @@ static void ap_reset_domain(void)
 {
        int i;
 
-       if (ap_domain_index != -1)
+       if ((ap_domain_index != -1) && (ap_test_config_domain(ap_domain_index)))
                for (i = 0; i < AP_DEVICES; i++)
                        ap_reset_queue(AP_MKQID(i, ap_domain_index));
 }
@@ -2097,7 +2095,6 @@ void ap_module_exit(void)
        hrtimer_cancel(&ap_poll_timer);
        destroy_workqueue(ap_work_queue);
        tasklet_kill(&ap_tasklet);
-       root_device_unregister(ap_root_device);
        while ((dev = bus_find_device(&ap_bus_type, NULL, NULL,
                    __ap_match_all)))
        {
@@ -2106,6 +2103,7 @@ void ap_module_exit(void)
        }
        for (i = 0; ap_bus_attrs[i]; i++)
                bus_remove_file(&ap_bus_type, ap_bus_attrs[i]);
+       root_device_unregister(ap_root_device);
        bus_unregister(&ap_bus_type);
        unregister_reset_call(&ap_reset_call);
        if (ap_using_interrupts())
index 81e83a65a1936cb897a2a0bbfc4bcfabb957b276..32070099c33356d6dca288330337df8eba5e5fa6 100644 (file)
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2005 - 2014 Emulex
+ * Copyright (C) 2005 - 2015 Avago Technologies
  * All rights reserved.
  *
  * This program is free software; you can redistribute it and/or
@@ -8,9 +8,9 @@
  * Public License is included in this distribution in the file called COPYING.
  *
  * Contact Information:
- * linux-drivers@emulex.com
+ * linux-drivers@avagotech.com
  *
- * Emulex
+ * Avago Technologies
  * 3333 Susan Street
  * Costa Mesa, CA 92626
  */
index 1028760b8a22145e792de569862641d627d5b89f..447cf7ce606ec6e3cf8b0540ba4f455c41aec2d5 100644 (file)
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2005 - 2014 Emulex
+ * Copyright (C) 2005 - 2015 Avago Technologies
  * All rights reserved.
  *
  * This program is free software; you can redistribute it and/or
@@ -8,9 +8,9 @@
  * Public License is included in this distribution in the file called COPYING.
  *
  * Contact Information:
- * linux-drivers@emulex.com
+ * linux-drivers@avagotech.com
  *
- * Emulex
+ * Avago Technologies
  * 3333 Susan Street
  * Costa Mesa, CA 92626
  */
index 98897434bcb4580c23e6939f35b6e8344002f7a3..f11d325fe6963f191424b52d6f0c16d69ddef671 100644 (file)
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2005 - 2014 Emulex
+ * Copyright (C) 2005 - 2015 Avago Technologies
  * All rights reserved.
  *
  * This program is free software; you can redistribute it and/or
@@ -8,9 +8,9 @@
  * Public License is included in this distribution in the file called COPYING.
  *
  * Contact Information:
- * linux-drivers@emulex.com
+ * linux-drivers@avagotech.com
  *
- * Emulex
+ * Avago Technologies
  * 3333 Susan Street
  * Costa Mesa, CA 92626
  */
index b7391a3f9f0ba1d3e1f9ba96649d7ca8a9e2af16..2f0700796842004812a12c6307487747f2868e63 100644 (file)
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2005 - 2014 Emulex
+ * Copyright (C) 2005 - 2015 Avago Technologies
  * All rights reserved.
  *
  * This program is free software; you can redistribute it and/or
@@ -7,12 +7,12 @@
  * as published by the Free Software Foundation.  The full GNU General
  * Public License is included in this distribution in the file called COPYING.
  *
- * Written by: Jayamohan Kallickal (jayamohan.kallickal@emulex.com)
+ * Written by: Jayamohan Kallickal (jayamohan.kallickal@avagotech.com)
  *
  * Contact Information:
- * linux-drivers@emulex.com
+ * linux-drivers@avagotech.com
  *
- * Emulex
+ * Avago Technologies
  * 3333 Susan Street
  * Costa Mesa, CA 92626
  */
index e0b3b2d1f27a64e9b5ee1eba4b558046847c0375..0c84e1c0763acc98e04003be5b966fd2f277f450 100644 (file)
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2005 - 2014 Emulex
+ * Copyright (C) 2005 - 2015 Avago Technologies
  * All rights reserved.
  *
  * This program is free software; you can redistribute it and/or
@@ -7,12 +7,12 @@
  * as published by the Free Software Foundation.  The full GNU General
  * Public License is included in this distribution in the file called COPYING.
  *
- * Written by: Jayamohan Kallickal (jayamohan.kallickal@emulex.com)
+ * Written by: Jayamohan Kallickal (jayamohan.kallickal@avagotech.com)
  *
  * Contact Information:
- * linux-drivers@emulex.com
+ * linux-drivers@avagotech.com
  *
- * Emulex
+ * Avago Technologies
  * 3333 Susan Street
  * Costa Mesa, CA 92626
  */
index 923a2b5a24395547212207312588b125f19de3a2..1f74760ce86cb27db2308f4dbe1d9ba25f10bcaa 100644 (file)
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2005 - 2014 Emulex
+ * Copyright (C) 2005 - 2015 Avago Technologies
  * All rights reserved.
  *
  * This program is free software; you can redistribute it and/or
@@ -7,12 +7,12 @@
  * as published by the Free Software Foundation.  The full GNU General
  * Public License is included in this distribution in the file called COPYING.
  *
- * Written by: Jayamohan Kallickal (jayamohan.kallickal@emulex.com)
+ * Written by: Jayamohan Kallickal (jayamohan.kallickal@avagotech.com)
  *
  * Contact Information:
- * linux-drivers@emulex.com
+ * linux-drivers@avagotech.com
  *
- * Emulex
+ * Avago Technologies
  * 3333 Susan Street
  * Costa Mesa, CA 92626
  */
@@ -50,7 +50,7 @@ static unsigned int enable_msix = 1;
 
 MODULE_DESCRIPTION(DRV_DESC " " BUILD_STR);
 MODULE_VERSION(BUILD_STR);
-MODULE_AUTHOR("Emulex Corporation");
+MODULE_AUTHOR("Avago Technologies");
 MODULE_LICENSE("GPL");
 module_param(be_iopoll_budget, int, 0);
 module_param(enable_msix, int, 0);
@@ -552,7 +552,7 @@ MODULE_DEVICE_TABLE(pci, beiscsi_pci_id_table);
 
 static struct scsi_host_template beiscsi_sht = {
        .module = THIS_MODULE,
-       .name = "Emulex 10Gbe open-iscsi Initiator Driver",
+       .name = "Avago Technologies 10Gbe open-iscsi Initiator Driver",
        .proc_name = DRV_NAME,
        .queuecommand = iscsi_queuecommand,
        .change_queue_depth = scsi_change_queue_depth,
index 7ee0ffc3851468ad19b5defe60b36b71266a6980..e70ea26bbc2b0fff8a82c540edd4aceab371da45 100644 (file)
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2005 - 2014 Emulex
+ * Copyright (C) 2005 - 2015 Avago Technologies
  * All rights reserved.
  *
  * This program is free software; you can redistribute it and/or
@@ -7,12 +7,12 @@
  * as published by the Free Software Foundation.  The full GNU General
  * Public License is included in this distribution in the file called COPYING.
  *
- * Written by: Jayamohan Kallickal (jayamohan.kallickal@emulex.com)
+ * Written by: Jayamohan Kallickal (jayamohan.kallickal@avagotech.com)
  *
  * Contact Information:
- * linux-drivers@emulex.com
+ * linux-drivers@avagotech.com
  *
- * Emulex
+ * Avago Technologies
  * 3333 Susan Street
  * Costa Mesa, CA 92626
  */
@@ -37,7 +37,7 @@
 
 #define DRV_NAME               "be2iscsi"
 #define BUILD_STR              "10.4.114.0"
-#define BE_NAME                        "Emulex OneConnect" \
+#define BE_NAME                        "Avago Technologies OneConnect" \
                                "Open-iSCSI Driver version" BUILD_STR
 #define DRV_DESC               BE_NAME " " "Driver"
 
index 681d4e8f003ab6d6873cf9d4bc35c2c87d81aa35..c2c4d6975fb7b22b2a4db35adf6ca69d2ea06547 100644 (file)
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2005 - 2014 Emulex
+ * Copyright (C) 2005 - 2015 Avago Technologies
  * All rights reserved.
  *
  * This program is free software; you can redistribute it and/or
@@ -7,12 +7,12 @@
  * as published by the Free Software Foundation.  The full GNU General
  * Public License is included in this distribution in the file called COPYING.
  *
- * Written by: Jayamohan Kallickal (jayamohan.kallickal@emulex.com)
+ * Written by: Jayamohan Kallickal (jayamohan.kallickal@avagotech.com)
  *
  * Contact Information:
- * linux-drivers@emulex.com
+ * linux-drivers@avagotech.com
  *
- * Emulex
+ * Avago Technologies
  * 3333 Susan Street
  * Costa Mesa, CA 92626
  */
index bd81446936fc34c5ecbc77cdd013416a0f1224f2..9356b9a86b66fcc7d640361aab6670d64315244f 100644 (file)
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2005 - 2014 Emulex
+ * Copyright (C) 2005 - 2015 Avago Technologies
  * All rights reserved.
  *
  * This program is free software; you can redistribute it and/or
@@ -7,12 +7,12 @@
  * as published by the Free Software Foundation.  The full GNU General
  * Public License is included in this distribution in the file called COPYING.
  *
- * Written by: Jayamohan Kallickal (jayamohan.kallickal@emulex.com)
+ * Written by: Jayamohan Kallickal (jayamohan.kallickal@avagotech.com)
  *
  * Contact Information:
- * linux-drivers@emulex.com
+ * linux-drivers@avagotech.com
  *
- * Emulex
+ * Avago Technologies
  * 3333 Susan Street
  * Costa Mesa, CA 92626
  */
index cb73cf9e9ba5c9a7d16c2b069ef649663cf067f8..c140f99772caa5963b15a67456b32d9194373927 100644 (file)
@@ -1129,25 +1129,6 @@ lpfc_release_scsi_buf(struct lpfc_hba *phba, struct lpfc_scsi_buf *psb)
        phba->lpfc_release_scsi_buf(phba, psb);
 }
 
-/**
- * lpfc_fcpcmd_to_iocb - copy the fcp_cmd data into the IOCB
- * @data: A pointer to the immediate command data portion of the IOCB.
- * @fcp_cmnd: The FCP Command that is provided by the SCSI layer.
- *
- * The routine copies the entire FCP command from @fcp_cmnd to @data while
- * byte swapping the data to big endian format for transmission on the wire.
- **/
-static void
-lpfc_fcpcmd_to_iocb(uint8_t *data, struct fcp_cmnd *fcp_cmnd)
-{
-       int i, j;
-
-       for (i = 0, j = 0; i < sizeof(struct fcp_cmnd);
-            i += sizeof(uint32_t), j++) {
-               ((uint32_t *)data)[j] = cpu_to_be32(((uint32_t *)fcp_cmnd)[j]);
-       }
-}
-
 /**
  * lpfc_scsi_prep_dma_buf_s3 - DMA mapping for scsi buffer to SLI3 IF spec
  * @phba: The Hba for which this call is being executed.
@@ -1283,7 +1264,6 @@ lpfc_scsi_prep_dma_buf_s3(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd)
         * we need to set word 4 of IOCB here
         */
        iocb_cmd->un.fcpi.fcpi_parm = scsi_bufflen(scsi_cmnd);
-       lpfc_fcpcmd_to_iocb(iocb_cmd->unsli3.fcp_ext.icd, fcp_cmnd);
        return 0;
 }
 
@@ -4146,6 +4126,24 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,
        lpfc_release_scsi_buf(phba, lpfc_cmd);
 }
 
+/**
+ * lpfc_fcpcmd_to_iocb - copy the fcp_cmd data into the IOCB
+ * @data: A pointer to the immediate command data portion of the IOCB.
+ * @fcp_cmnd: The FCP Command that is provided by the SCSI layer.
+ *
+ * The routine copies the entire FCP command from @fcp_cmnd to @data while
+ * byte swapping the data to big endian format for transmission on the wire.
+ **/
+static void
+lpfc_fcpcmd_to_iocb(uint8_t *data, struct fcp_cmnd *fcp_cmnd)
+{
+       int i, j;
+       for (i = 0, j = 0; i < sizeof(struct fcp_cmnd);
+            i += sizeof(uint32_t), j++) {
+               ((uint32_t *)data)[j] = cpu_to_be32(((uint32_t *)fcp_cmnd)[j]);
+       }
+}
+
 /**
  * lpfc_scsi_prep_cmnd - Wrapper func for convert scsi cmnd to FCP info unit
  * @vport: The virtual port for which this call is being executed.
@@ -4225,6 +4223,9 @@ lpfc_scsi_prep_cmnd(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd,
                fcp_cmnd->fcpCntl3 = 0;
                phba->fc4ControlRequests++;
        }
+       if (phba->sli_rev == 3 &&
+           !(phba->sli3_options & LPFC_SLI3_BG_ENABLED))
+               lpfc_fcpcmd_to_iocb(iocb_cmd->unsli3.fcp_ext.icd, fcp_cmnd);
        /*
         * Finish initializing those IOCB fields that are independent
         * of the scsi_cmnd request_buffer
index 79beebf53302e591bc0661372335561c65d3e006..7f9d65fe4fd9a441c1aa00f602f3dac14c866563 100644 (file)
@@ -1600,6 +1600,7 @@ static unsigned int sd_completed_bytes(struct scsi_cmnd *scmd)
 {
        u64 start_lba = blk_rq_pos(scmd->request);
        u64 end_lba = blk_rq_pos(scmd->request) + (scsi_bufflen(scmd) / 512);
+       u64 factor = scmd->device->sector_size / 512;
        u64 bad_lba;
        int info_valid;
        /*
@@ -1621,16 +1622,9 @@ static unsigned int sd_completed_bytes(struct scsi_cmnd *scmd)
        if (scsi_bufflen(scmd) <= scmd->device->sector_size)
                return 0;
 
-       if (scmd->device->sector_size < 512) {
-               /* only legitimate sector_size here is 256 */
-               start_lba <<= 1;
-               end_lba <<= 1;
-       } else {
-               /* be careful ... don't want any overflows */
-               unsigned int factor = scmd->device->sector_size / 512;
-               do_div(start_lba, factor);
-               do_div(end_lba, factor);
-       }
+       /* be careful ... don't want any overflows */
+       do_div(start_lba, factor);
+       do_div(end_lba, factor);
 
        /* The bad lba was reported incorrectly, we have no idea where
         * the error is.
@@ -2188,8 +2182,7 @@ sd_read_capacity(struct scsi_disk *sdkp, unsigned char *buffer)
        if (sector_size != 512 &&
            sector_size != 1024 &&
            sector_size != 2048 &&
-           sector_size != 4096 &&
-           sector_size != 256) {
+           sector_size != 4096) {
                sd_printk(KERN_NOTICE, sdkp, "Unsupported sector size %d.\n",
                          sector_size);
                /*
@@ -2244,8 +2237,6 @@ sd_read_capacity(struct scsi_disk *sdkp, unsigned char *buffer)
                sdkp->capacity <<= 2;
        else if (sector_size == 1024)
                sdkp->capacity <<= 1;
-       else if (sector_size == 256)
-               sdkp->capacity >>= 1;
 
        blk_queue_physical_block_size(sdp->request_queue,
                                      sdkp->physical_block_size);
index d9dad90344d545a18185ecf0736fa79a4b6a212b..3c6584ff65c1979b6119c4edce15e6d35eb3957f 100644 (file)
@@ -1600,8 +1600,7 @@ static int storvsc_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scmnd)
                break;
        default:
                vm_srb->data_in = UNKNOWN_TYPE;
-               vm_srb->win8_extension.srb_flags |= (SRB_FLAGS_DATA_IN |
-                                                    SRB_FLAGS_DATA_OUT);
+               vm_srb->win8_extension.srb_flags |= SRB_FLAGS_NO_DATA_TRANSFER;
                break;
        }
 
index 198f96b7fb45dab78845ba1fcde123ea680e2082..72b059081559356100aa68dea2c021b056b492e5 100644 (file)
@@ -78,6 +78,7 @@ config SPI_ATMEL
 config SPI_BCM2835
        tristate "BCM2835 SPI controller"
        depends on ARCH_BCM2835 || COMPILE_TEST
+       depends on GPIOLIB
        help
          This selects a driver for the Broadcom BCM2835 SPI master.
 
@@ -302,7 +303,7 @@ config SPI_FSL_SPI
 config SPI_FSL_DSPI
        tristate "Freescale DSPI controller"
        select REGMAP_MMIO
-       depends on SOC_VF610 || COMPILE_TEST
+       depends on SOC_VF610 || SOC_LS1021A || COMPILE_TEST
        help
          This enables support for the Freescale DSPI controller in master
          mode. VF610 platform uses the controller.
index f63864a893c520c40d9c79f1c8ca838b15dedc8c..37875cf942f7b928c5d31f44345b5c060f182b36 100644 (file)
@@ -164,13 +164,12 @@ static int bcm2835_spi_transfer_one_poll(struct spi_master *master,
                                         unsigned long xfer_time_us)
 {
        struct bcm2835_spi *bs = spi_master_get_devdata(master);
-       unsigned long timeout = jiffies +
-               max(4 * xfer_time_us * HZ / 1000000, 2uL);
+       /* set timeout to 1 second of maximum polling */
+       unsigned long timeout = jiffies + HZ;
 
        /* enable HW block without interrupts */
        bcm2835_wr(bs, BCM2835_SPI_CS, cs | BCM2835_SPI_CS_TA);
 
-       /* set timeout to 4x the expected time, or 2 jiffies */
        /* loop until finished the transfer */
        while (bs->rx_len) {
                /* read from fifo as much as possible */
index 5ef6638d5e8a2698a6c8e85fad41c46d1f03fd06..840a4984d3650e27dcf98713235a67e040b8ca1a 100644 (file)
@@ -180,7 +180,6 @@ int spi_bitbang_setup(struct spi_device *spi)
 {
        struct spi_bitbang_cs   *cs = spi->controller_state;
        struct spi_bitbang      *bitbang;
-       int                     retval;
        unsigned long           flags;
 
        bitbang = spi_master_get_devdata(spi->master);
@@ -197,9 +196,11 @@ int spi_bitbang_setup(struct spi_device *spi)
        if (!cs->txrx_word)
                return -EINVAL;
 
-       retval = bitbang->setup_transfer(spi, NULL);
-       if (retval < 0)
-               return retval;
+       if (bitbang->setup_transfer) {
+               int retval = bitbang->setup_transfer(spi, NULL);
+               if (retval < 0)
+                       return retval;
+       }
 
        dev_dbg(&spi->dev, "%s, %u nsec/bit\n", __func__, 2 * cs->nsecs);
 
@@ -295,9 +296,11 @@ static int spi_bitbang_transfer_one(struct spi_master *master,
 
                /* init (-1) or override (1) transfer params */
                if (do_setup != 0) {
-                       status = bitbang->setup_transfer(spi, t);
-                       if (status < 0)
-                               break;
+                       if (bitbang->setup_transfer) {
+                               status = bitbang->setup_transfer(spi, t);
+                               if (status < 0)
+                                       break;
+                       }
                        if (do_setup == -1)
                                do_setup = 0;
                }
index 9c46a3058743b75228256f55e64b8419b49c1f3d..896add8cfd3b6c6bba311a335072e63a4060a3a4 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/of_address.h>
 #include <linux/spi/spi.h>
 #include <linux/types.h>
+#include <linux/platform_device.h>
 
 #include "spi-fsl-cpm.h"
 #include "spi-fsl-lib.h"
@@ -269,17 +270,6 @@ static unsigned long fsl_spi_cpm_get_pram(struct mpc8xxx_spi *mspi)
        if (mspi->flags & SPI_CPM2) {
                pram_ofs = cpm_muram_alloc(SPI_PRAM_SIZE, 64);
                out_be16(spi_base, pram_ofs);
-       } else {
-               struct spi_pram __iomem *pram = spi_base;
-               u16 rpbase = in_be16(&pram->rpbase);
-
-               /* Microcode relocation patch applied? */
-               if (rpbase) {
-                       pram_ofs = rpbase;
-               } else {
-                       pram_ofs = cpm_muram_alloc(SPI_PRAM_SIZE, 64);
-                       out_be16(spi_base, pram_ofs);
-               }
        }
 
        iounmap(spi_base);
@@ -292,7 +282,6 @@ int fsl_spi_cpm_init(struct mpc8xxx_spi *mspi)
        struct device_node *np = dev->of_node;
        const u32 *iprop;
        int size;
-       unsigned long pram_ofs;
        unsigned long bds_ofs;
 
        if (!(mspi->flags & SPI_CPM_MODE))
@@ -319,8 +308,26 @@ int fsl_spi_cpm_init(struct mpc8xxx_spi *mspi)
                }
        }
 
-       pram_ofs = fsl_spi_cpm_get_pram(mspi);
-       if (IS_ERR_VALUE(pram_ofs)) {
+       if (mspi->flags & SPI_CPM1) {
+               struct resource *res;
+               void *pram;
+
+               res = platform_get_resource(to_platform_device(dev),
+                                           IORESOURCE_MEM, 1);
+               pram = devm_ioremap_resource(dev, res);
+               if (IS_ERR(pram))
+                       mspi->pram = NULL;
+               else
+                       mspi->pram = pram;
+       } else {
+               unsigned long pram_ofs = fsl_spi_cpm_get_pram(mspi);
+
+               if (IS_ERR_VALUE(pram_ofs))
+                       mspi->pram = NULL;
+               else
+                       mspi->pram = cpm_muram_addr(pram_ofs);
+       }
+       if (mspi->pram == NULL) {
                dev_err(dev, "can't allocate spi parameter ram\n");
                goto err_pram;
        }
@@ -346,8 +353,6 @@ int fsl_spi_cpm_init(struct mpc8xxx_spi *mspi)
                goto err_dummy_rx;
        }
 
-       mspi->pram = cpm_muram_addr(pram_ofs);
-
        mspi->tx_bd = cpm_muram_addr(bds_ofs);
        mspi->rx_bd = cpm_muram_addr(bds_ofs + sizeof(*mspi->tx_bd));
 
@@ -375,7 +380,8 @@ int fsl_spi_cpm_init(struct mpc8xxx_spi *mspi)
 err_dummy_tx:
        cpm_muram_free(bds_ofs);
 err_bds:
-       cpm_muram_free(pram_ofs);
+       if (!(mspi->flags & SPI_CPM1))
+               cpm_muram_free(cpm_muram_offset(mspi->pram));
 err_pram:
        fsl_spi_free_dummy_rx();
        return -ENOMEM;
index d0a73a09a9bd3e02371a30bc4b5ceb34f6b52e4e..80d245ac846fa366abf8d2b7511a1fb4ac25c03e 100644 (file)
@@ -359,14 +359,16 @@ static void fsl_espi_rw_trans(struct spi_message *m,
                                struct fsl_espi_transfer *trans, u8 *rx_buff)
 {
        struct fsl_espi_transfer *espi_trans = trans;
-       unsigned int n_tx = espi_trans->n_tx;
-       unsigned int n_rx = espi_trans->n_rx;
+       unsigned int total_len = espi_trans->len;
        struct spi_transfer *t;
        u8 *local_buf;
        u8 *rx_buf = rx_buff;
        unsigned int trans_len;
        unsigned int addr;
-       int i, pos, loop;
+       unsigned int tx_only;
+       unsigned int rx_pos = 0;
+       unsigned int pos;
+       int i, loop;
 
        local_buf = kzalloc(SPCOM_TRANLEN_MAX, GFP_KERNEL);
        if (!local_buf) {
@@ -374,36 +376,48 @@ static void fsl_espi_rw_trans(struct spi_message *m,
                return;
        }
 
-       for (pos = 0, loop = 0; pos < n_rx; pos += trans_len, loop++) {
-               trans_len = n_rx - pos;
-               if (trans_len > SPCOM_TRANLEN_MAX - n_tx)
-                       trans_len = SPCOM_TRANLEN_MAX - n_tx;
+       for (pos = 0, loop = 0; pos < total_len; pos += trans_len, loop++) {
+               trans_len = total_len - pos;
 
                i = 0;
+               tx_only = 0;
                list_for_each_entry(t, &m->transfers, transfer_list) {
                        if (t->tx_buf) {
                                memcpy(local_buf + i, t->tx_buf, t->len);
                                i += t->len;
+                               if (!t->rx_buf)
+                                       tx_only += t->len;
                        }
                }
 
+               /* Add additional TX bytes to compensate SPCOM_TRANLEN_MAX */
+               if (loop > 0)
+                       trans_len += tx_only;
+
+               if (trans_len > SPCOM_TRANLEN_MAX)
+                       trans_len = SPCOM_TRANLEN_MAX;
+
+               /* Update device offset */
                if (pos > 0) {
                        addr = fsl_espi_cmd2addr(local_buf);
-                       addr += pos;
+                       addr += rx_pos;
                        fsl_espi_addr2cmd(addr, local_buf);
                }
 
-               espi_trans->n_tx = n_tx;
-               espi_trans->n_rx = trans_len;
-               espi_trans->len = trans_len + n_tx;
+               espi_trans->len = trans_len;
                espi_trans->tx_buf = local_buf;
                espi_trans->rx_buf = local_buf;
                fsl_espi_do_trans(m, espi_trans);
 
-               memcpy(rx_buf + pos, espi_trans->rx_buf + n_tx, trans_len);
+               /* If there is at least one RX byte then copy it to rx_buf */
+               if (tx_only < SPCOM_TRANLEN_MAX)
+                       memcpy(rx_buf + rx_pos, espi_trans->rx_buf + tx_only,
+                                       trans_len - tx_only);
+
+               rx_pos += trans_len - tx_only;
 
                if (loop > 0)
-                       espi_trans->actual_length += espi_trans->len - n_tx;
+                       espi_trans->actual_length += espi_trans->len - tx_only;
                else
                        espi_trans->actual_length += espi_trans->len;
        }
@@ -418,6 +432,7 @@ static int fsl_espi_do_one_msg(struct spi_master *master,
        u8 *rx_buf = NULL;
        unsigned int n_tx = 0;
        unsigned int n_rx = 0;
+       unsigned int xfer_len = 0;
        struct fsl_espi_transfer espi_trans;
 
        list_for_each_entry(t, &m->transfers, transfer_list) {
@@ -427,11 +442,13 @@ static int fsl_espi_do_one_msg(struct spi_master *master,
                        n_rx += t->len;
                        rx_buf = t->rx_buf;
                }
+               if ((t->tx_buf) || (t->rx_buf))
+                       xfer_len += t->len;
        }
 
        espi_trans.n_tx = n_tx;
        espi_trans.n_rx = n_rx;
-       espi_trans.len = n_tx + n_rx;
+       espi_trans.len = xfer_len;
        espi_trans.actual_length = 0;
        espi_trans.status = 0;
 
index 4df8942058deed3928e61a4b2bc4061c56eec7d7..d1a5b9fc3eba22edaafd6155a5292ee108d97ac7 100644 (file)
@@ -1210,6 +1210,7 @@ static int omap2_mcspi_transfer_one_message(struct spi_master *master,
        struct omap2_mcspi      *mcspi;
        struct omap2_mcspi_dma  *mcspi_dma;
        struct spi_transfer     *t;
+       int status;
 
        spi = m->spi;
        mcspi = spi_master_get_devdata(master);
@@ -1229,7 +1230,8 @@ static int omap2_mcspi_transfer_one_message(struct spi_master *master,
                                        tx_buf ? "tx" : "",
                                        rx_buf ? "rx" : "",
                                        t->bits_per_word);
-                       return -EINVAL;
+                       status = -EINVAL;
+                       goto out;
                }
 
                if (m->is_dma_mapped || len < DMA_MIN_BYTES)
@@ -1241,7 +1243,8 @@ static int omap2_mcspi_transfer_one_message(struct spi_master *master,
                        if (dma_mapping_error(mcspi->dev, t->tx_dma)) {
                                dev_dbg(mcspi->dev, "dma %cX %d bytes error\n",
                                                'T', len);
-                               return -EINVAL;
+                               status = -EINVAL;
+                               goto out;
                        }
                }
                if (mcspi_dma->dma_rx && rx_buf != NULL) {
@@ -1253,14 +1256,19 @@ static int omap2_mcspi_transfer_one_message(struct spi_master *master,
                                if (tx_buf != NULL)
                                        dma_unmap_single(mcspi->dev, t->tx_dma,
                                                        len, DMA_TO_DEVICE);
-                               return -EINVAL;
+                               status = -EINVAL;
+                               goto out;
                        }
                }
        }
 
        omap2_mcspi_work(mcspi, m);
+       /* spi_finalize_current_message() changes the status inside the
+        * spi_message, save the status here. */
+       status = m->status;
+out:
        spi_finalize_current_message(master);
-       return 0;
+       return status;
 }
 
 static int omap2_mcspi_master_setup(struct omap2_mcspi *mcspi)
index d5d7d2235163f9ef8c6430d99544ec7f2c791c6b..50910d85df5af28d6f281485cc79d4b3e15bc7e5 100644 (file)
@@ -583,6 +583,15 @@ static int spi_unmap_msg(struct spi_master *master, struct spi_message *msg)
        rx_dev = master->dma_rx->device->dev;
 
        list_for_each_entry(xfer, &msg->transfers, transfer_list) {
+               /*
+                * Restore the original value of tx_buf or rx_buf if they are
+                * NULL.
+                */
+               if (xfer->tx_buf == master->dummy_tx)
+                       xfer->tx_buf = NULL;
+               if (xfer->rx_buf == master->dummy_rx)
+                       xfer->rx_buf = NULL;
+
                if (!master->can_dma(master, msg->spi, xfer))
                        continue;
 
index 15a7ee3859dd7dd74aee31593876b422093eff04..5fe1c22e289b881cacebbf081d7c245fad7d2098 100644 (file)
@@ -359,12 +359,13 @@ static void ssb_pcicore_init_hostmode(struct ssb_pcicore *pc)
 
        /*
         * Accessing PCI config without a proper delay after devices reset (not
-        * GPIO reset) was causing reboots on WRT300N v1.0.
+        * GPIO reset) was causing reboots on WRT300N v1.0 (BCM4704).
         * Tested delay 850 us lowered reboot chance to 50-80%, 1000 us fixed it
         * completely. Flushing all writes was also tested but with no luck.
+        * The same problem was reported for WRT350N v1 (BCM4705), so we just
+        * sleep here unconditionally.
         */
-       if (pc->dev->bus->chip_id == 0x4704)
-               usleep_range(1000, 2000);
+       usleep_range(1000, 2000);
 
        /* Enable PCI bridge BAR0 prefetch and burst */
        val = PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
index 8199b0a697bb5f8b672aabad8f9685c8c51a8f5e..1cf24e4edf251ca1896a72073c5fdf6df0eac336 100644 (file)
@@ -158,7 +158,7 @@ static int up_to_host(struct mux_rx *r)
        unsigned int start_flag;
        unsigned int payload_size;
        unsigned short packet_type;
-       int dummy_cnt;
+       int total_len;
        u32 packet_size_sum = r->offset;
        int index;
        int ret = TO_HOST_INVALID_PACKET;
@@ -176,10 +176,10 @@ static int up_to_host(struct mux_rx *r)
                        break;
                }
 
-               dummy_cnt = ALIGN(MUX_HEADER_SIZE + payload_size, 4);
+               total_len = ALIGN(MUX_HEADER_SIZE + payload_size, 4);
 
                if (len - packet_size_sum <
-                       MUX_HEADER_SIZE + payload_size + dummy_cnt) {
+                       total_len) {
                        pr_err("invalid payload : %d %d %04x\n",
                               payload_size, len, packet_type);
                        break;
@@ -202,7 +202,7 @@ static int up_to_host(struct mux_rx *r)
                        break;
                }
 
-               packet_size_sum += MUX_HEADER_SIZE + payload_size + dummy_cnt;
+               packet_size_sum += total_len;
                if (len - packet_size_sum <= MUX_HEADER_SIZE + 2) {
                        ret = r->callback(NULL,
                                        0,
@@ -361,7 +361,6 @@ static int gdm_mux_send(void *priv_dev, void *data, int len, int tty_index,
        struct mux_pkt_header *mux_header;
        struct mux_tx *t = NULL;
        static u32 seq_num = 1;
-       int dummy_cnt;
        int total_len;
        int ret;
        unsigned long flags;
@@ -374,9 +373,7 @@ static int gdm_mux_send(void *priv_dev, void *data, int len, int tty_index,
 
        spin_lock_irqsave(&mux_dev->write_lock, flags);
 
-       dummy_cnt = ALIGN(MUX_HEADER_SIZE + len, 4);
-
-       total_len = len + MUX_HEADER_SIZE + dummy_cnt;
+       total_len = ALIGN(MUX_HEADER_SIZE + len, 4);
 
        t = alloc_mux_tx(total_len);
        if (!t) {
@@ -392,7 +389,8 @@ static int gdm_mux_send(void *priv_dev, void *data, int len, int tty_index,
        mux_header->packet_type = __cpu_to_le16(packet_type[tty_index]);
 
        memcpy(t->buf+MUX_HEADER_SIZE, data, len);
-       memset(t->buf+MUX_HEADER_SIZE+len, 0, dummy_cnt);
+       memset(t->buf+MUX_HEADER_SIZE+len, 0, total_len - MUX_HEADER_SIZE -
+              len);
 
        t->len = total_len;
        t->callback = cb;
index 42fba3f5b593e08801a57269ede5e21da8c8841f..cb0b6387789f197dbe2d314b96728d05b6a361c9 100644 (file)
@@ -1900,23 +1900,20 @@ static int r871x_mp_ioctl_hdl(struct net_device *dev,
        struct mp_ioctl_handler *phandler;
        struct mp_ioctl_param *poidparam;
        unsigned long BytesRead, BytesWritten, BytesNeeded;
-       u8 *pparmbuf = NULL, bset;
+       u8 *pparmbuf, bset;
        u16 len;
        uint status;
        int ret = 0;
 
-       if ((!p->length) || (!p->pointer)) {
-               ret = -EINVAL;
-               goto _r871x_mp_ioctl_hdl_exit;
-       }
+       if ((!p->length) || (!p->pointer))
+               return -EINVAL;
+
        bset = (u8)(p->flags & 0xFFFF);
        len = p->length;
-       pparmbuf = NULL;
        pparmbuf = memdup_user(p->pointer, len);
-       if (IS_ERR(pparmbuf)) {
-               ret = PTR_ERR(pparmbuf);
-               goto _r871x_mp_ioctl_hdl_exit;
-       }
+       if (IS_ERR(pparmbuf))
+               return PTR_ERR(pparmbuf);
+
        poidparam = (struct mp_ioctl_param *)pparmbuf;
        if (poidparam->subcode >= MAX_MP_IOCTL_SUBCODE) {
                ret = -EINVAL;
index 3c7ea95dd9f93aa0f1619c246d3fea78d0eea155..dbbb2f879a29fb00a59e20733ee118920ff19c59 100644 (file)
@@ -1250,7 +1250,7 @@ static int lynxfb_pci_probe(struct pci_dev *pdev,
        return -ENODEV;
 }
 
-static void __exit lynxfb_pci_remove(struct pci_dev *pdev)
+static void lynxfb_pci_remove(struct pci_dev *pdev)
 {
        struct fb_info *info;
        struct lynx_share *share;
index 1cdcf49b2445094ba5270011251dfe86684766e4..e00c0605d1541556492c8ab46d5d4db8156a30f6 100644 (file)
@@ -362,12 +362,16 @@ bool CARDbSetPhyParameter(struct vnt_private *pDevice, u8 bb_type)
  * Return Value: none
  */
 bool CARDbUpdateTSF(struct vnt_private *pDevice, unsigned char byRxRate,
-                   u64 qwBSSTimestamp, u64 qwLocalTSF)
+                   u64 qwBSSTimestamp)
 {
+       u64 local_tsf;
        u64 qwTSFOffset = 0;
 
-       if (qwBSSTimestamp != qwLocalTSF) {
-               qwTSFOffset = CARDqGetTSFOffset(byRxRate, qwBSSTimestamp, qwLocalTSF);
+       CARDbGetCurrentTSF(pDevice, &local_tsf);
+
+       if (qwBSSTimestamp != local_tsf) {
+               qwTSFOffset = CARDqGetTSFOffset(byRxRate, qwBSSTimestamp,
+                                               local_tsf);
                /* adjust TSF, HW's TSF add TSF Offset reg */
                VNSvOutPortD(pDevice->PortOffset + MAC_REG_TSFOFST, (u32)qwTSFOffset);
                VNSvOutPortD(pDevice->PortOffset + MAC_REG_TSFOFST + 4, (u32)(qwTSFOffset >> 32));
index 2dfc4195227188bf48f1473cc821051739f135da..16cca49e680a3fc74bde7795b7565cfbe61bd17a 100644 (file)
@@ -83,7 +83,7 @@ bool CARDbRadioPowerOff(struct vnt_private *);
 bool CARDbRadioPowerOn(struct vnt_private *);
 bool CARDbSetPhyParameter(struct vnt_private *, u8);
 bool CARDbUpdateTSF(struct vnt_private *, unsigned char byRxRate,
-                   u64 qwBSSTimestamp, u64 qwLocalTSF);
+                   u64 qwBSSTimestamp);
 bool CARDbSetBeaconPeriod(struct vnt_private *, unsigned short wBeaconInterval);
 
 #endif /* __CARD_H__ */
index 4bb4f8ee41321a23134bcaf750ff3d2896350e82..0343ae386f0351bdff320f2f956371540eb931f3 100644 (file)
@@ -912,7 +912,11 @@ static int vnt_int_report_rate(struct vnt_private *priv,
 
        if (!(tsr1 & TSR1_TERR)) {
                info->status.rates[0].idx = idx;
-               info->flags |= IEEE80211_TX_STAT_ACK;
+
+               if (info->flags & IEEE80211_TX_CTL_NO_ACK)
+                       info->flags |= IEEE80211_TX_STAT_NOACK_TRANSMITTED;
+               else
+                       info->flags |= IEEE80211_TX_STAT_ACK;
        }
 
        return 0;
@@ -937,9 +941,6 @@ static int device_tx_srv(struct vnt_private *pDevice, unsigned int uIdx)
                /* Only the status of first TD in the chain is correct */
                if (pTD->m_td1TD1.byTCR & TCR_STP) {
                        if ((pTD->pTDInfo->byFlags & TD_FLAGS_NETIF_SKB) != 0) {
-
-                               vnt_int_report_rate(pDevice, pTD->pTDInfo, byTsr0, byTsr1);
-
                                if (!(byTsr1 & TSR1_TERR)) {
                                        if (byTsr0 != 0) {
                                                pr_debug(" Tx[%d] OK but has error. tsr1[%02X] tsr0[%02X]\n",
@@ -958,6 +959,9 @@ static int device_tx_srv(struct vnt_private *pDevice, unsigned int uIdx)
                                                 (int)uIdx, byTsr1, byTsr0);
                                }
                        }
+
+                       vnt_int_report_rate(pDevice, pTD->pTDInfo, byTsr0, byTsr1);
+
                        device_free_tx_buf(pDevice, pTD);
                        pDevice->iTDUsed[uIdx]--;
                }
@@ -989,10 +993,8 @@ static void device_free_tx_buf(struct vnt_private *pDevice, PSTxDesc pDesc)
                                 skb->len, DMA_TO_DEVICE);
        }
 
-       if (pTDInfo->byFlags & TD_FLAGS_NETIF_SKB)
+       if (skb)
                ieee80211_tx_status_irqsafe(pDevice->hw, skb);
-       else
-               dev_kfree_skb_irq(skb);
 
        pTDInfo->skb_dma = 0;
        pTDInfo->skb = NULL;
@@ -1204,14 +1206,6 @@ static int vnt_tx_packet(struct vnt_private *priv, struct sk_buff *skb)
        if (dma_idx == TYPE_AC0DMA)
                head_td->pTDInfo->byFlags = TD_FLAGS_NETIF_SKB;
 
-       priv->iTDUsed[dma_idx]++;
-
-       /* Take ownership */
-       wmb();
-       head_td->m_td0TD0.f1Owner = OWNED_BY_NIC;
-
-       /* get Next */
-       wmb();
        priv->apCurrTD[dma_idx] = head_td->next;
 
        spin_unlock_irqrestore(&priv->lock, flags);
@@ -1232,11 +1226,18 @@ static int vnt_tx_packet(struct vnt_private *priv, struct sk_buff *skb)
 
        head_td->buff_addr = cpu_to_le32(head_td->pTDInfo->skb_dma);
 
+       /* Poll Transmit the adapter */
+       wmb();
+       head_td->m_td0TD0.f1Owner = OWNED_BY_NIC;
+       wmb(); /* second memory barrier */
+
        if (head_td->pTDInfo->byFlags & TD_FLAGS_NETIF_SKB)
                MACvTransmitAC0(priv->PortOffset);
        else
                MACvTransmit0(priv->PortOffset);
 
+       priv->iTDUsed[dma_idx]++;
+
        spin_unlock_irqrestore(&priv->lock, flags);
 
        return 0;
@@ -1416,9 +1417,16 @@ static void vnt_bss_info_changed(struct ieee80211_hw *hw,
 
        priv->current_aid = conf->aid;
 
-       if (changed & BSS_CHANGED_BSSID)
+       if (changed & BSS_CHANGED_BSSID) {
+               unsigned long flags;
+
+               spin_lock_irqsave(&priv->lock, flags);
+
                MACvWriteBSSIDAddress(priv->PortOffset, (u8 *)conf->bssid);
 
+               spin_unlock_irqrestore(&priv->lock, flags);
+       }
+
        if (changed & BSS_CHANGED_BASIC_RATES) {
                priv->basic_rates = conf->basic_rates;
 
@@ -1477,7 +1485,7 @@ static void vnt_bss_info_changed(struct ieee80211_hw *hw,
        if (changed & BSS_CHANGED_ASSOC && priv->op_mode != NL80211_IFTYPE_AP) {
                if (conf->assoc) {
                        CARDbUpdateTSF(priv, conf->beacon_rate->hw_value,
-                                      conf->sync_device_ts, conf->sync_tsf);
+                                      conf->sync_tsf);
 
                        CARDbSetBeaconPeriod(priv, conf->beacon_int);
 
index f6c2cf8590c4811471a88c9e82be1d4151a11618..5c589962a1e841ad66c41fe2057df51f18cdee31 100644 (file)
@@ -805,10 +805,18 @@ int vnt_tx_packet(struct vnt_private *priv, struct sk_buff *skb)
                vnt_schedule_command(priv, WLAN_CMD_SETPOWER);
        }
 
-       if (current_rate > RATE_11M)
-               pkt_type = priv->packet_type;
-       else
+       if (current_rate > RATE_11M) {
+               if (info->band == IEEE80211_BAND_5GHZ) {
+                       pkt_type = PK_TYPE_11A;
+               } else {
+                       if (tx_rate->flags & IEEE80211_TX_RC_USE_CTS_PROTECT)
+                               pkt_type = PK_TYPE_11GB;
+                       else
+                               pkt_type = PK_TYPE_11GA;
+               }
+       } else {
                pkt_type = PK_TYPE_11B;
+       }
 
        spin_lock_irqsave(&priv->lock, flags);
 
index c2556cf5186bc75b71870ed6a304fda430b8521b..01255fd65135949ce78b7f94fde7bccc196ac75c 100644 (file)
@@ -224,9 +224,9 @@ static const struct armada_thermal_data armada380_data = {
        .is_valid_shift = 10,
        .temp_shift = 0,
        .temp_mask = 0x3ff,
-       .coef_b = 1169498786UL,
-       .coef_m = 2000000UL,
-       .coef_div = 4289,
+       .coef_b = 2931108200UL,
+       .coef_m = 5000000UL,
+       .coef_div = 10502,
        .inverted = true,
 };
 
index 12623bc02f46679674d9bd1c3f1574fc21b57c37..725718e97a0bc86f8d69d3fc112fba7670543402 100644 (file)
@@ -206,51 +206,57 @@ static void find_target_mwait(void)
 
 }
 
+struct pkg_cstate_info {
+       bool skip;
+       int msr_index;
+       int cstate_id;
+};
+
+#define PKG_CSTATE_INIT(id) {                          \
+               .msr_index = MSR_PKG_C##id##_RESIDENCY, \
+               .cstate_id = id                         \
+                       }
+
+static struct pkg_cstate_info pkg_cstates[] = {
+       PKG_CSTATE_INIT(2),
+       PKG_CSTATE_INIT(3),
+       PKG_CSTATE_INIT(6),
+       PKG_CSTATE_INIT(7),
+       PKG_CSTATE_INIT(8),
+       PKG_CSTATE_INIT(9),
+       PKG_CSTATE_INIT(10),
+       {NULL},
+};
+
 static bool has_pkg_state_counter(void)
 {
-       u64 tmp;
-       return !rdmsrl_safe(MSR_PKG_C2_RESIDENCY, &tmp) ||
-              !rdmsrl_safe(MSR_PKG_C3_RESIDENCY, &tmp) ||
-              !rdmsrl_safe(MSR_PKG_C6_RESIDENCY, &tmp) ||
-              !rdmsrl_safe(MSR_PKG_C7_RESIDENCY, &tmp);
+       u64 val;
+       struct pkg_cstate_info *info = pkg_cstates;
+
+       /* check if any one of the counter msrs exists */
+       while (info->msr_index) {
+               if (!rdmsrl_safe(info->msr_index, &val))
+                       return true;
+               info++;
+       }
+
+       return false;
 }
 
 static u64 pkg_state_counter(void)
 {
        u64 val;
        u64 count = 0;
-
-       static bool skip_c2;
-       static bool skip_c3;
-       static bool skip_c6;
-       static bool skip_c7;
-
-       if (!skip_c2) {
-               if (!rdmsrl_safe(MSR_PKG_C2_RESIDENCY, &val))
-                       count += val;
-               else
-                       skip_c2 = true;
-       }
-
-       if (!skip_c3) {
-               if (!rdmsrl_safe(MSR_PKG_C3_RESIDENCY, &val))
-                       count += val;
-               else
-                       skip_c3 = true;
-       }
-
-       if (!skip_c6) {
-               if (!rdmsrl_safe(MSR_PKG_C6_RESIDENCY, &val))
-                       count += val;
-               else
-                       skip_c6 = true;
-       }
-
-       if (!skip_c7) {
-               if (!rdmsrl_safe(MSR_PKG_C7_RESIDENCY, &val))
-                       count += val;
-               else
-                       skip_c7 = true;
+       struct pkg_cstate_info *info = pkg_cstates;
+
+       while (info->msr_index) {
+               if (!info->skip) {
+                       if (!rdmsrl_safe(info->msr_index, &val))
+                               count += val;
+                       else
+                               info->skip = true;
+               }
+               info++;
        }
 
        return count;
@@ -667,7 +673,7 @@ static struct thermal_cooling_device_ops powerclamp_cooling_ops = {
 };
 
 /* runs on Nehalem and later */
-static const struct x86_cpu_id intel_powerclamp_ids[] = {
+static const struct x86_cpu_id intel_powerclamp_ids[] __initconst = {
        { X86_VENDOR_INTEL, 6, 0x1a},
        { X86_VENDOR_INTEL, 6, 0x1c},
        { X86_VENDOR_INTEL, 6, 0x1e},
@@ -689,12 +695,13 @@ static const struct x86_cpu_id intel_powerclamp_ids[] = {
        { X86_VENDOR_INTEL, 6, 0x46},
        { X86_VENDOR_INTEL, 6, 0x4c},
        { X86_VENDOR_INTEL, 6, 0x4d},
+       { X86_VENDOR_INTEL, 6, 0x4f},
        { X86_VENDOR_INTEL, 6, 0x56},
        {}
 };
 MODULE_DEVICE_TABLE(x86cpu, intel_powerclamp_ids);
 
-static int powerclamp_probe(void)
+static int __init powerclamp_probe(void)
 {
        if (!x86_match_cpu(intel_powerclamp_ids)) {
                pr_err("Intel powerclamp does not run on family %d model %d\n",
@@ -760,7 +767,7 @@ static inline void powerclamp_create_debug_files(void)
        debugfs_remove_recursive(debug_dir);
 }
 
-static int powerclamp_init(void)
+static int __init powerclamp_init(void)
 {
        int retval;
        int bitmap_size;
@@ -809,7 +816,7 @@ static int powerclamp_init(void)
 }
 module_init(powerclamp_init);
 
-static void powerclamp_exit(void)
+static void __exit powerclamp_exit(void)
 {
        unregister_hotcpu_notifier(&powerclamp_cpu_notifier);
        end_power_clamp();
index 3aa46ac7cdbc33765a90279da09fd84507a09d6c..cd8f5f93b42c45aa4cde0f8c4aa346836006f6da 100644 (file)
@@ -529,7 +529,7 @@ static int rockchip_thermal_probe(struct platform_device *pdev)
 
        thermal->pclk = devm_clk_get(&pdev->dev, "apb_pclk");
        if (IS_ERR(thermal->pclk)) {
-               error = PTR_ERR(thermal->clk);
+               error = PTR_ERR(thermal->pclk);
                dev_err(&pdev->dev, "failed to get apb_pclk clock: %d\n",
                        error);
                return error;
index 0531c752fbbb6680c40e939ad2a14fdc1830f357..8e391812e50377664f079cb83f61c380b16e6d93 100644 (file)
@@ -103,7 +103,7 @@ static inline int of_thermal_get_ntrips(struct thermal_zone_device *tz)
 static inline bool of_thermal_is_trip_valid(struct thermal_zone_device *tz,
                                            int trip)
 {
-       return 0;
+       return false;
 }
 static inline const struct thermal_trip *
 of_thermal_get_trip_points(struct thermal_zone_device *tz)
index a4929272074f3f8a161ff7978289af475560b9eb..58b5c6694cd4361472b34fa941890e5121d3dba9 100644 (file)
@@ -420,7 +420,8 @@ const struct ti_bandgap_data dra752_data = {
                        TI_BANDGAP_FEATURE_FREEZE_BIT |
                        TI_BANDGAP_FEATURE_TALERT |
                        TI_BANDGAP_FEATURE_COUNTER_DELAY |
-                       TI_BANDGAP_FEATURE_HISTORY_BUFFER,
+                       TI_BANDGAP_FEATURE_HISTORY_BUFFER |
+                       TI_BANDGAP_FEATURE_ERRATA_814,
        .fclock_name = "l3instr_ts_gclk_div",
        .div_ck_name = "l3instr_ts_gclk_div",
        .conv_table = dra752_adc_to_temp,
index eff0c80fd4af50110cde6b4dc5cba3500787e91e..79ff70c446ba195ef893125b377567ff4ac2e58b 100644 (file)
@@ -319,7 +319,8 @@ const struct ti_bandgap_data omap5430_data = {
                        TI_BANDGAP_FEATURE_FREEZE_BIT |
                        TI_BANDGAP_FEATURE_TALERT |
                        TI_BANDGAP_FEATURE_COUNTER_DELAY |
-                       TI_BANDGAP_FEATURE_HISTORY_BUFFER,
+                       TI_BANDGAP_FEATURE_HISTORY_BUFFER |
+                       TI_BANDGAP_FEATURE_ERRATA_813,
        .fclock_name = "l3instr_ts_gclk_div",
        .div_ck_name = "l3instr_ts_gclk_div",
        .conv_table = omap5430_adc_to_temp,
index 62a5d449c38805019db7d554e6c0f7f43d215341..bc14dc874594e4d9fd37a68874bb6adb6eb4b562 100644 (file)
@@ -118,6 +118,37 @@ static int ti_bandgap_power(struct ti_bandgap *bgp, bool on)
        return ret;
 }
 
+/**
+ * ti_errata814_bandgap_read_temp() - helper function to read dra7 sensor temperature
+ * @bgp: pointer to ti_bandgap structure
+ * @reg: desired register (offset) to be read
+ *
+ * Function to read dra7 bandgap sensor temperature. This is done separately
+ * so as to workaround the errata "Bandgap Temperature read Dtemp can be
+ * corrupted" - Errata ID: i814".
+ * Read accesses to registers listed below can be corrupted due to incorrect
+ * resynchronization between clock domains.
+ * Read access to registers below can be corrupted :
+ * CTRL_CORE_DTEMP_MPU/GPU/CORE/DSPEVE/IVA_n (n = 0 to 4)
+ * CTRL_CORE_TEMP_SENSOR_MPU/GPU/CORE/DSPEVE/IVA_n
+ *
+ * Return: the register value.
+ */
+static u32 ti_errata814_bandgap_read_temp(struct ti_bandgap *bgp,  u32 reg)
+{
+       u32 val1, val2;
+
+       val1 = ti_bandgap_readl(bgp, reg);
+       val2 = ti_bandgap_readl(bgp, reg);
+
+       /* If both times we read the same value then that is right */
+       if (val1 == val2)
+               return val1;
+
+       /* if val1 and val2 are different read it third time */
+       return ti_bandgap_readl(bgp, reg);
+}
+
 /**
  * ti_bandgap_read_temp() - helper function to read sensor temperature
  * @bgp: pointer to ti_bandgap structure
@@ -148,7 +179,11 @@ static u32 ti_bandgap_read_temp(struct ti_bandgap *bgp, int id)
        }
 
        /* read temperature */
-       temp = ti_bandgap_readl(bgp, reg);
+       if (TI_BANDGAP_HAS(bgp, ERRATA_814))
+               temp = ti_errata814_bandgap_read_temp(bgp, reg);
+       else
+               temp = ti_bandgap_readl(bgp, reg);
+
        temp &= tsr->bgap_dtemp_mask;
 
        if (TI_BANDGAP_HAS(bgp, FREEZE_BIT))
@@ -410,7 +445,7 @@ static int ti_bandgap_update_alert_threshold(struct ti_bandgap *bgp, int id,
 {
        struct temp_sensor_data *ts_data = bgp->conf->sensors[id].ts_data;
        struct temp_sensor_registers *tsr;
-       u32 thresh_val, reg_val, t_hot, t_cold;
+       u32 thresh_val, reg_val, t_hot, t_cold, ctrl;
        int err = 0;
 
        tsr = bgp->conf->sensors[id].registers;
@@ -442,8 +477,47 @@ static int ti_bandgap_update_alert_threshold(struct ti_bandgap *bgp, int id,
                  ~(tsr->threshold_thot_mask | tsr->threshold_tcold_mask);
        reg_val |= (t_hot << __ffs(tsr->threshold_thot_mask)) |
                   (t_cold << __ffs(tsr->threshold_tcold_mask));
+
+       /**
+        * Errata i813:
+        * Spurious Thermal Alert: Talert can happen randomly while the device
+        * remains under the temperature limit defined for this event to trig.
+        * This spurious event is caused by a incorrect re-synchronization
+        * between clock domains. The comparison between configured threshold
+        * and current temperature value can happen while the value is
+        * transitioning (metastable), thus causing inappropriate event
+        * generation. No spurious event occurs as long as the threshold value
+        * stays unchanged. Spurious event can be generated while a thermal
+        * alert threshold is modified in
+        * CONTROL_BANDGAP_THRESHOLD_MPU/GPU/CORE/DSPEVE/IVA_n.
+        */
+
+       if (TI_BANDGAP_HAS(bgp, ERRATA_813)) {
+               /* Mask t_hot and t_cold events at the IP Level */
+               ctrl = ti_bandgap_readl(bgp, tsr->bgap_mask_ctrl);
+
+               if (hot)
+                       ctrl &= ~tsr->mask_hot_mask;
+               else
+                       ctrl &= ~tsr->mask_cold_mask;
+
+               ti_bandgap_writel(bgp, ctrl, tsr->bgap_mask_ctrl);
+       }
+
+       /* Write the threshold value */
        ti_bandgap_writel(bgp, reg_val, tsr->bgap_threshold);
 
+       if (TI_BANDGAP_HAS(bgp, ERRATA_813)) {
+               /* Unmask t_hot and t_cold events at the IP Level */
+               ctrl = ti_bandgap_readl(bgp, tsr->bgap_mask_ctrl);
+               if (hot)
+                       ctrl |= tsr->mask_hot_mask;
+               else
+                       ctrl |= tsr->mask_cold_mask;
+
+               ti_bandgap_writel(bgp, ctrl, tsr->bgap_mask_ctrl);
+       }
+
        if (err) {
                dev_err(bgp->dev, "failed to reprogram thot threshold\n");
                err = -EIO;
index b3adf72f252d310779e5014b9ee272bf2a499946..0c52f7afba00b5335adbeba60cd31f547d2256a3 100644 (file)
@@ -318,6 +318,10 @@ struct ti_temp_sensor {
  * TI_BANDGAP_FEATURE_HISTORY_BUFFER - used when the bandgap device features
  *     a history buffer of temperatures.
  *
+ * TI_BANDGAP_FEATURE_ERRATA_814 - used to workaorund when the bandgap device
+ *     has Errata 814
+ * TI_BANDGAP_FEATURE_ERRATA_813 - used to workaorund when the bandgap device
+ *     has Errata 813
  * TI_BANDGAP_HAS(b, f) - macro to check if a bandgap device is capable of a
  *      specific feature (above) or not. Return non-zero, if yes.
  */
@@ -331,6 +335,8 @@ struct ti_temp_sensor {
 #define TI_BANDGAP_FEATURE_FREEZE_BIT          BIT(7)
 #define TI_BANDGAP_FEATURE_COUNTER_DELAY       BIT(8)
 #define TI_BANDGAP_FEATURE_HISTORY_BUFFER      BIT(9)
+#define TI_BANDGAP_FEATURE_ERRATA_814          BIT(10)
+#define TI_BANDGAP_FEATURE_ERRATA_813          BIT(11)
 #define TI_BANDGAP_HAS(b, f)                   \
                        ((b)->conf->features & TI_BANDGAP_FEATURE_ ## f)
 
index 5bab1c684bb11024c2e5a7ee143c18aefc54349b..7a3d146a5f0efc0dbc3b94e854adb4d81c85da4d 100644 (file)
@@ -289,7 +289,7 @@ static int xen_initial_domain_console_init(void)
                        return -ENOMEM;
        }
 
-       info->irq = bind_virq_to_irq(VIRQ_CONSOLE, 0);
+       info->irq = bind_virq_to_irq(VIRQ_CONSOLE, 0, false);
        info->vtermno = HVC_COOKIE;
 
        spin_lock(&xencons_lock);
index 91abc00aa833b8493fe721e05024cd8368e23aa6..2c34c3249972de85f650d34fa0b25448efba3686 100644 (file)
@@ -3170,7 +3170,7 @@ static int gsmtty_break_ctl(struct tty_struct *tty, int state)
        return gsmtty_modem_update(dlci, encode);
 }
 
-static void gsmtty_remove(struct tty_driver *driver, struct tty_struct *tty)
+static void gsmtty_cleanup(struct tty_struct *tty)
 {
        struct gsm_dlci *dlci = tty->driver_data;
        struct gsm_mux *gsm = dlci->gsm;
@@ -3178,7 +3178,6 @@ static void gsmtty_remove(struct tty_driver *driver, struct tty_struct *tty)
        dlci_put(dlci);
        dlci_put(gsm->dlci[0]);
        mux_put(gsm);
-       driver->ttys[tty->index] = NULL;
 }
 
 /* Virtual ttys for the demux */
@@ -3199,7 +3198,7 @@ static const struct tty_operations gsmtty_ops = {
        .tiocmget               = gsmtty_tiocmget,
        .tiocmset               = gsmtty_tiocmset,
        .break_ctl              = gsmtty_break_ctl,
-       .remove                 = gsmtty_remove,
+       .cleanup                = gsmtty_cleanup,
 };
 
 
index 644ddb841d9f54085bb82a903034af5aaf42de45..bbc4ce66c2c18dd30fb10b80f955a4f4565225c5 100644 (file)
@@ -600,7 +600,7 @@ static ssize_t n_hdlc_tty_read(struct tty_struct *tty, struct file *file,
        add_wait_queue(&tty->read_wait, &wait);
 
        for (;;) {
-               if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) {
+               if (test_bit(TTY_OTHER_DONE, &tty->flags)) {
                        ret = -EIO;
                        break;
                }
@@ -828,7 +828,7 @@ static unsigned int n_hdlc_tty_poll(struct tty_struct *tty, struct file *filp,
                /* set bits for operations that won't block */
                if (n_hdlc->rx_buf_list.head)
                        mask |= POLLIN | POLLRDNORM;    /* readable */
-               if (test_bit(TTY_OTHER_CLOSED, &tty->flags))
+               if (test_bit(TTY_OTHER_DONE, &tty->flags))
                        mask |= POLLHUP;
                if (tty_hung_up_p(filp))
                        mask |= POLLHUP;
index cf6e0f2e1331fd46310a6834d99896e2b943ea19..cc57a3a6b02b348df95c827fd2c770e59ffca155 100644 (file)
@@ -1949,6 +1949,18 @@ static inline int input_available_p(struct tty_struct *tty, int poll)
                return ldata->commit_head - ldata->read_tail >= amt;
 }
 
+static inline int check_other_done(struct tty_struct *tty)
+{
+       int done = test_bit(TTY_OTHER_DONE, &tty->flags);
+       if (done) {
+               /* paired with cmpxchg() in check_other_closed(); ensures
+                * read buffer head index is not stale
+                */
+               smp_mb__after_atomic();
+       }
+       return done;
+}
+
 /**
  *     copy_from_read_buf      -       copy read data directly
  *     @tty: terminal device
@@ -2167,7 +2179,7 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file,
        struct n_tty_data *ldata = tty->disc_data;
        unsigned char __user *b = buf;
        DEFINE_WAIT_FUNC(wait, woken_wake_function);
-       int c;
+       int c, done;
        int minimum, time;
        ssize_t retval = 0;
        long timeout;
@@ -2235,8 +2247,10 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file,
                    ((minimum - (b - buf)) >= 1))
                        ldata->minimum_to_wake = (minimum - (b - buf));
 
+               done = check_other_done(tty);
+
                if (!input_available_p(tty, 0)) {
-                       if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) {
+                       if (done) {
                                retval = -EIO;
                                break;
                        }
@@ -2443,12 +2457,12 @@ static unsigned int n_tty_poll(struct tty_struct *tty, struct file *file,
 
        poll_wait(file, &tty->read_wait, wait);
        poll_wait(file, &tty->write_wait, wait);
+       if (check_other_done(tty))
+               mask |= POLLHUP;
        if (input_available_p(tty, 1))
                mask |= POLLIN | POLLRDNORM;
        if (tty->packet && tty->link->ctrl_status)
                mask |= POLLPRI | POLLIN | POLLRDNORM;
-       if (test_bit(TTY_OTHER_CLOSED, &tty->flags))
-               mask |= POLLHUP;
        if (tty_hung_up_p(file))
                mask |= POLLHUP;
        if (!(mask & (POLLHUP | POLLIN | POLLRDNORM))) {
index e72ee629cead1b0af93c54b96395cbfc98b69975..4d5e8409769c3cc412ba5d428e0f179b4b44fdad 100644 (file)
@@ -53,9 +53,8 @@ static void pty_close(struct tty_struct *tty, struct file *filp)
        /* Review - krefs on tty_link ?? */
        if (!tty->link)
                return;
-       tty_flush_to_ldisc(tty->link);
        set_bit(TTY_OTHER_CLOSED, &tty->link->flags);
-       wake_up_interruptible(&tty->link->read_wait);
+       tty_flip_buffer_push(tty->link->port);
        wake_up_interruptible(&tty->link->write_wait);
        if (tty->driver->subtype == PTY_TYPE_MASTER) {
                set_bit(TTY_OTHER_CLOSED, &tty->flags);
@@ -243,7 +242,9 @@ static int pty_open(struct tty_struct *tty, struct file *filp)
                goto out;
 
        clear_bit(TTY_IO_ERROR, &tty->flags);
+       /* TTY_OTHER_CLOSED must be cleared before TTY_OTHER_DONE */
        clear_bit(TTY_OTHER_CLOSED, &tty->link->flags);
+       clear_bit(TTY_OTHER_DONE, &tty->link->flags);
        set_bit(TTY_THROTTLED, &tty->flags);
        return 0;
 
index 5a4e9d579585f9c5165839db0fec8e368dfb8133..6f5a0720a8c8eead6c23f37c359c516730013cef 100644 (file)
@@ -1639,6 +1639,9 @@ static int pl011_startup(struct uart_port *port)
 
        writew(uap->vendor->ifls, uap->port.membase + UART011_IFLS);
 
+       /* Assume that TX IRQ doesn't work until we see one: */
+       uap->tx_irq_seen = 0;
+
        spin_lock_irq(&uap->port.lock);
 
        /* restore RTS and DTR */
@@ -1702,7 +1705,7 @@ static void pl011_shutdown(struct uart_port *port)
        spin_lock_irq(&uap->port.lock);
        uap->im = 0;
        writew(uap->im, uap->port.membase + UART011_IMSC);
-       writew(0xffff & ~UART011_TXIS, uap->port.membase + UART011_ICR);
+       writew(0xffff, uap->port.membase + UART011_ICR);
        spin_unlock_irq(&uap->port.lock);
 
        pl011_dma_shutdown(uap);
index 5fdc9f3ecd644d9b58a0f9a10f150296b68282d7..6dc471e30e793aaf99bfc1bac6d376387d9e21a5 100644 (file)
@@ -187,13 +187,8 @@ static int __init param_setup_earlycon(char *buf)
                return 0;
 
        err = setup_earlycon(buf);
-       if (err == -ENOENT) {
-               pr_warn("no match for %s\n", buf);
-               err = 0;
-       } else if (err == -EALREADY) {
-               pr_warn("already registered\n");
-               err = 0;
-       }
+       if (err == -ENOENT || err == -EALREADY)
+               return 0;
        return err;
 }
 early_param("earlycon", param_setup_earlycon);
index 211479aa34bb20d5375078afb103829faa5bfd84..7f49172ccd8673b316b3b82ab21282885ef983eb 100644 (file)
@@ -1735,6 +1735,8 @@ static int serial_omap_probe(struct platform_device *pdev)
 err_add_port:
        pm_runtime_put(&pdev->dev);
        pm_runtime_disable(&pdev->dev);
+       pm_qos_remove_request(&up->pm_qos_request);
+       device_init_wakeup(up->dev, false);
 err_rs485:
 err_port_line:
        return ret;
index 75661641f5fe068237e7830acd9472383964da3a..2f78b77f0f8180fa07df27ab2ab931cf73f53587 100644 (file)
 
 #define TTY_BUFFER_PAGE        (((PAGE_SIZE - sizeof(struct tty_buffer)) / 2) & ~0xFF)
 
+/*
+ * If all tty flip buffers have been processed by flush_to_ldisc() or
+ * dropped by tty_buffer_flush(), check if the linked pty has been closed.
+ * If so, wake the reader/poll to process
+ */
+static inline void check_other_closed(struct tty_struct *tty)
+{
+       unsigned long flags, old;
+
+       /* transition from TTY_OTHER_CLOSED => TTY_OTHER_DONE must be atomic */
+       for (flags = ACCESS_ONCE(tty->flags);
+            test_bit(TTY_OTHER_CLOSED, &flags);
+            ) {
+               old = flags;
+               __set_bit(TTY_OTHER_DONE, &flags);
+               flags = cmpxchg(&tty->flags, old, flags);
+               if (old == flags) {
+                       wake_up_interruptible(&tty->read_wait);
+                       break;
+               }
+       }
+}
 
 /**
  *     tty_buffer_lock_exclusive       -       gain exclusive access to buffer
@@ -229,6 +251,8 @@ void tty_buffer_flush(struct tty_struct *tty, struct tty_ldisc *ld)
        if (ld && ld->ops->flush_buffer)
                ld->ops->flush_buffer(tty);
 
+       check_other_closed(tty);
+
        atomic_dec(&buf->priority);
        mutex_unlock(&buf->lock);
 }
@@ -471,8 +495,10 @@ static void flush_to_ldisc(struct work_struct *work)
                smp_rmb();
                count = head->commit - head->read;
                if (!count) {
-                       if (next == NULL)
+                       if (next == NULL) {
+                               check_other_closed(tty);
                                break;
+                       }
                        buf->head = next;
                        tty_buffer_free(port, head);
                        continue;
@@ -488,19 +514,6 @@ static void flush_to_ldisc(struct work_struct *work)
        tty_ldisc_deref(disc);
 }
 
-/**
- *     tty_flush_to_ldisc
- *     @tty: tty to push
- *
- *     Push the terminal flip buffers to the line discipline.
- *
- *     Must not be called from IRQ context.
- */
-void tty_flush_to_ldisc(struct tty_struct *tty)
-{
-       flush_work(&tty->port->buf.work);
-}
-
 /**
  *     tty_flip_buffer_push    -       terminal
  *     @port: tty port to push
index dfb05edcdb96dbbb3b794d6faf5c799b3c031f06..5b7061a331038d36ad20b7ec3c05b2ab1f8b3efc 100644 (file)
@@ -88,9 +88,13 @@ static ssize_t ci_port_test_write(struct file *file, const char __user *ubuf,
        char buf[32];
        int ret;
 
-       if (copy_from_user(buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
+       count = min_t(size_t, sizeof(buf) - 1, count);
+       if (copy_from_user(buf, ubuf, count))
                return -EFAULT;
 
+       /* sscanf requires a zero terminated string */
+       buf[count] = '\0';
+
        if (sscanf(buf, "%u", &mode) != 1)
                return -EINVAL;
 
index 41e510ae8c837ea337135c4ec8ddbe26fccac275..d85abfed84ccaa2327820f1b35cabac11422d647 100644 (file)
@@ -106,6 +106,9 @@ static const struct usb_device_id usb_quirk_list[] = {
        { USB_DEVICE(0x04f3, 0x010c), .driver_info =
                        USB_QUIRK_DEVICE_QUALIFIER },
 
+       { USB_DEVICE(0x04f3, 0x0125), .driver_info =
+                       USB_QUIRK_DEVICE_QUALIFIER },
+
        { USB_DEVICE(0x04f3, 0x016f), .driver_info =
                        USB_QUIRK_DEVICE_QUALIFIER },
 
index edba5348be186bf33857bd7c1d47233df6d12422..6b486a36863c08dd908df48375d819602672762b 100644 (file)
@@ -65,8 +65,8 @@
 #define USBOTGSS_IRQENABLE_SET_MISC            0x003c
 #define USBOTGSS_IRQENABLE_CLR_MISC            0x0040
 #define USBOTGSS_IRQMISC_OFFSET                        0x03fc
-#define USBOTGSS_UTMI_OTG_CTRL                 0x0080
-#define USBOTGSS_UTMI_OTG_STATUS               0x0084
+#define USBOTGSS_UTMI_OTG_STATUS               0x0080
+#define USBOTGSS_UTMI_OTG_CTRL                 0x0084
 #define USBOTGSS_UTMI_OTG_OFFSET               0x0480
 #define USBOTGSS_TXFIFO_DEPTH                  0x0508
 #define USBOTGSS_RXFIFO_DEPTH                  0x050c
 #define USBOTGSS_IRQMISC_DISCHRGVBUS_FALL              (1 << 3)
 #define USBOTGSS_IRQMISC_IDPULLUP_FALL         (1 << 0)
 
-/* UTMI_OTG_CTRL REGISTER */
-#define USBOTGSS_UTMI_OTG_CTRL_DRVVBUS         (1 << 5)
-#define USBOTGSS_UTMI_OTG_CTRL_CHRGVBUS                (1 << 4)
-#define USBOTGSS_UTMI_OTG_CTRL_DISCHRGVBUS     (1 << 3)
-#define USBOTGSS_UTMI_OTG_CTRL_IDPULLUP                (1 << 0)
-
 /* UTMI_OTG_STATUS REGISTER */
-#define USBOTGSS_UTMI_OTG_STATUS_SW_MODE       (1 << 31)
-#define USBOTGSS_UTMI_OTG_STATUS_POWERPRESENT  (1 << 9)
-#define USBOTGSS_UTMI_OTG_STATUS_TXBITSTUFFENABLE (1 << 8)
-#define USBOTGSS_UTMI_OTG_STATUS_IDDIG         (1 << 4)
-#define USBOTGSS_UTMI_OTG_STATUS_SESSEND       (1 << 3)
-#define USBOTGSS_UTMI_OTG_STATUS_SESSVALID     (1 << 2)
-#define USBOTGSS_UTMI_OTG_STATUS_VBUSVALID     (1 << 1)
+#define USBOTGSS_UTMI_OTG_STATUS_DRVVBUS       (1 << 5)
+#define USBOTGSS_UTMI_OTG_STATUS_CHRGVBUS      (1 << 4)
+#define USBOTGSS_UTMI_OTG_STATUS_DISCHRGVBUS   (1 << 3)
+#define USBOTGSS_UTMI_OTG_STATUS_IDPULLUP      (1 << 0)
+
+/* UTMI_OTG_CTRL REGISTER */
+#define USBOTGSS_UTMI_OTG_CTRL_SW_MODE         (1 << 31)
+#define USBOTGSS_UTMI_OTG_CTRL_POWERPRESENT    (1 << 9)
+#define USBOTGSS_UTMI_OTG_CTRL_TXBITSTUFFENABLE (1 << 8)
+#define USBOTGSS_UTMI_OTG_CTRL_IDDIG           (1 << 4)
+#define USBOTGSS_UTMI_OTG_CTRL_SESSEND         (1 << 3)
+#define USBOTGSS_UTMI_OTG_CTRL_SESSVALID       (1 << 2)
+#define USBOTGSS_UTMI_OTG_CTRL_VBUSVALID       (1 << 1)
 
 struct dwc3_omap {
        struct device           *dev;
@@ -119,7 +119,7 @@ struct dwc3_omap {
        int                     irq;
        void __iomem            *base;
 
-       u32                     utmi_otg_status;
+       u32                     utmi_otg_ctrl;
        u32                     utmi_otg_offset;
        u32                     irqmisc_offset;
        u32                     irq_eoi_offset;
@@ -153,15 +153,15 @@ static inline void dwc3_omap_writel(void __iomem *base, u32 offset, u32 value)
        writel(value, base + offset);
 }
 
-static u32 dwc3_omap_read_utmi_status(struct dwc3_omap *omap)
+static u32 dwc3_omap_read_utmi_ctrl(struct dwc3_omap *omap)
 {
-       return dwc3_omap_readl(omap->base, USBOTGSS_UTMI_OTG_STATUS +
+       return dwc3_omap_readl(omap->base, USBOTGSS_UTMI_OTG_CTRL +
                                                        omap->utmi_otg_offset);
 }
 
-static void dwc3_omap_write_utmi_status(struct dwc3_omap *omap, u32 value)
+static void dwc3_omap_write_utmi_ctrl(struct dwc3_omap *omap, u32 value)
 {
-       dwc3_omap_writel(omap->base, USBOTGSS_UTMI_OTG_STATUS +
+       dwc3_omap_writel(omap->base, USBOTGSS_UTMI_OTG_CTRL +
                                        omap->utmi_otg_offset, value);
 
 }
@@ -235,25 +235,25 @@ static void dwc3_omap_set_mailbox(struct dwc3_omap *omap,
                        }
                }
 
-               val = dwc3_omap_read_utmi_status(omap);
-               val &= ~(USBOTGSS_UTMI_OTG_STATUS_IDDIG
-                               | USBOTGSS_UTMI_OTG_STATUS_VBUSVALID
-                               | USBOTGSS_UTMI_OTG_STATUS_SESSEND);
-               val |= USBOTGSS_UTMI_OTG_STATUS_SESSVALID
-                               | USBOTGSS_UTMI_OTG_STATUS_POWERPRESENT;
-               dwc3_omap_write_utmi_status(omap, val);
+               val = dwc3_omap_read_utmi_ctrl(omap);
+               val &= ~(USBOTGSS_UTMI_OTG_CTRL_IDDIG
+                               | USBOTGSS_UTMI_OTG_CTRL_VBUSVALID
+                               | USBOTGSS_UTMI_OTG_CTRL_SESSEND);
+               val |= USBOTGSS_UTMI_OTG_CTRL_SESSVALID
+                               | USBOTGSS_UTMI_OTG_CTRL_POWERPRESENT;
+               dwc3_omap_write_utmi_ctrl(omap, val);
                break;
 
        case OMAP_DWC3_VBUS_VALID:
                dev_dbg(omap->dev, "VBUS Connect\n");
 
-               val = dwc3_omap_read_utmi_status(omap);
-               val &= ~USBOTGSS_UTMI_OTG_STATUS_SESSEND;
-               val |= USBOTGSS_UTMI_OTG_STATUS_IDDIG
-                               | USBOTGSS_UTMI_OTG_STATUS_VBUSVALID
-                               | USBOTGSS_UTMI_OTG_STATUS_SESSVALID
-                               | USBOTGSS_UTMI_OTG_STATUS_POWERPRESENT;
-               dwc3_omap_write_utmi_status(omap, val);
+               val = dwc3_omap_read_utmi_ctrl(omap);
+               val &= ~USBOTGSS_UTMI_OTG_CTRL_SESSEND;
+               val |= USBOTGSS_UTMI_OTG_CTRL_IDDIG
+                               | USBOTGSS_UTMI_OTG_CTRL_VBUSVALID
+                               | USBOTGSS_UTMI_OTG_CTRL_SESSVALID
+                               | USBOTGSS_UTMI_OTG_CTRL_POWERPRESENT;
+               dwc3_omap_write_utmi_ctrl(omap, val);
                break;
 
        case OMAP_DWC3_ID_FLOAT:
@@ -263,13 +263,13 @@ static void dwc3_omap_set_mailbox(struct dwc3_omap *omap,
        case OMAP_DWC3_VBUS_OFF:
                dev_dbg(omap->dev, "VBUS Disconnect\n");
 
-               val = dwc3_omap_read_utmi_status(omap);
-               val &= ~(USBOTGSS_UTMI_OTG_STATUS_SESSVALID
-                               | USBOTGSS_UTMI_OTG_STATUS_VBUSVALID
-                               | USBOTGSS_UTMI_OTG_STATUS_POWERPRESENT);
-               val |= USBOTGSS_UTMI_OTG_STATUS_SESSEND
-                               | USBOTGSS_UTMI_OTG_STATUS_IDDIG;
-               dwc3_omap_write_utmi_status(omap, val);
+               val = dwc3_omap_read_utmi_ctrl(omap);
+               val &= ~(USBOTGSS_UTMI_OTG_CTRL_SESSVALID
+                               | USBOTGSS_UTMI_OTG_CTRL_VBUSVALID
+                               | USBOTGSS_UTMI_OTG_CTRL_POWERPRESENT);
+               val |= USBOTGSS_UTMI_OTG_CTRL_SESSEND
+                               | USBOTGSS_UTMI_OTG_CTRL_IDDIG;
+               dwc3_omap_write_utmi_ctrl(omap, val);
                break;
 
        default:
@@ -422,22 +422,22 @@ static void dwc3_omap_set_utmi_mode(struct dwc3_omap *omap)
        struct device_node      *node = omap->dev->of_node;
        int                     utmi_mode = 0;
 
-       reg = dwc3_omap_read_utmi_status(omap);
+       reg = dwc3_omap_read_utmi_ctrl(omap);
 
        of_property_read_u32(node, "utmi-mode", &utmi_mode);
 
        switch (utmi_mode) {
        case DWC3_OMAP_UTMI_MODE_SW:
-               reg |= USBOTGSS_UTMI_OTG_STATUS_SW_MODE;
+               reg |= USBOTGSS_UTMI_OTG_CTRL_SW_MODE;
                break;
        case DWC3_OMAP_UTMI_MODE_HW:
-               reg &= ~USBOTGSS_UTMI_OTG_STATUS_SW_MODE;
+               reg &= ~USBOTGSS_UTMI_OTG_CTRL_SW_MODE;
                break;
        default:
                dev_dbg(omap->dev, "UNKNOWN utmi mode %d\n", utmi_mode);
        }
 
-       dwc3_omap_write_utmi_status(omap, reg);
+       dwc3_omap_write_utmi_ctrl(omap, reg);
 }
 
 static int dwc3_omap_extcon_register(struct dwc3_omap *omap)
@@ -614,7 +614,7 @@ static int dwc3_omap_suspend(struct device *dev)
 {
        struct dwc3_omap        *omap = dev_get_drvdata(dev);
 
-       omap->utmi_otg_status = dwc3_omap_read_utmi_status(omap);
+       omap->utmi_otg_ctrl = dwc3_omap_read_utmi_ctrl(omap);
        dwc3_omap_disable_irqs(omap);
 
        return 0;
@@ -624,7 +624,7 @@ static int dwc3_omap_resume(struct device *dev)
 {
        struct dwc3_omap        *omap = dev_get_drvdata(dev);
 
-       dwc3_omap_write_utmi_status(omap, omap->utmi_otg_status);
+       dwc3_omap_write_utmi_ctrl(omap, omap->utmi_otg_ctrl);
        dwc3_omap_enable_irqs(omap);
 
        pm_runtime_disable(dev);
index c42765b3a060bc6b28b0f7a55f0231489afe651c..0495c94a23d7e96a9c3554b99893b6b0f63e7302 100644 (file)
@@ -1295,6 +1295,7 @@ static void purge_configs_funcs(struct gadget_info *gi)
                        }
                }
                c->next_interface_id = 0;
+               memset(c->interface, 0, sizeof(c->interface));
                c->superspeed = 0;
                c->highspeed = 0;
                c->fullspeed = 0;
index 13dfc9915b1dee679b89f83a19ab3ef56641ae34..f7f35a36c09a06eab17ef2e5af013ee3de2b5b8e 100644 (file)
@@ -437,12 +437,20 @@ static int hidg_setup(struct usb_function *f,
                  | USB_REQ_GET_DESCRIPTOR):
                switch (value >> 8) {
                case HID_DT_HID:
+               {
+                       struct hid_descriptor hidg_desc_copy = hidg_desc;
+
                        VDBG(cdev, "USB_REQ_GET_DESCRIPTOR: HID\n");
+                       hidg_desc_copy.desc[0].bDescriptorType = HID_DT_REPORT;
+                       hidg_desc_copy.desc[0].wDescriptorLength =
+                               cpu_to_le16(hidg->report_desc_length);
+
                        length = min_t(unsigned short, length,
-                                                  hidg_desc.bLength);
-                       memcpy(req->buf, &hidg_desc, length);
+                                                  hidg_desc_copy.bLength);
+                       memcpy(req->buf, &hidg_desc_copy, length);
                        goto respond;
                        break;
+               }
                case HID_DT_REPORT:
                        VDBG(cdev, "USB_REQ_GET_DESCRIPTOR: REPORT\n");
                        length = min_t(unsigned short, length,
@@ -632,6 +640,10 @@ static int hidg_bind(struct usb_configuration *c, struct usb_function *f)
        hidg_fs_in_ep_desc.wMaxPacketSize = cpu_to_le16(hidg->report_length);
        hidg_hs_out_ep_desc.wMaxPacketSize = cpu_to_le16(hidg->report_length);
        hidg_fs_out_ep_desc.wMaxPacketSize = cpu_to_le16(hidg->report_length);
+       /*
+        * We can use hidg_desc struct here but we should not relay
+        * that its content won't change after returning from this function.
+        */
        hidg_desc.desc[0].bDescriptorType = HID_DT_REPORT;
        hidg_desc.desc[0].wDescriptorLength =
                cpu_to_le16(hidg->report_desc_length);
index 89179ab20c109277a3d49c48b7d91d85eb821f4c..7ee057930ae71793bcbd2777cb275572af21c295 100644 (file)
@@ -113,6 +113,7 @@ struct gs_port {
        int write_allocated;
        struct gs_buf           port_write_buf;
        wait_queue_head_t       drain_wait;     /* wait while writes drain */
+       bool                    write_busy;
 
        /* REVISIT this state ... */
        struct usb_cdc_line_coding port_line_coding;    /* 8-N-1 etc */
@@ -363,7 +364,7 @@ __acquires(&port->port_lock)
        int                     status = 0;
        bool                    do_tty_wake = false;
 
-       while (!list_empty(pool)) {
+       while (!port->write_busy && !list_empty(pool)) {
                struct usb_request      *req;
                int                     len;
 
@@ -393,9 +394,11 @@ __acquires(&port->port_lock)
                 * NOTE that we may keep sending data for a while after
                 * the TTY closed (dev->ioport->port_tty is NULL).
                 */
+               port->write_busy = true;
                spin_unlock(&port->port_lock);
                status = usb_ep_queue(in, req, GFP_ATOMIC);
                spin_lock(&port->port_lock);
+               port->write_busy = false;
 
                if (status) {
                        pr_debug("%s: %s %s err %d\n",
index c30b7b572465d290b8cc6097915d63fd596aa79d..1194b09ae7462638d689eb99af6a15bd209c9e9e 100644 (file)
@@ -121,7 +121,7 @@ static struct usb_function *f_msg;
 /*
  * We _always_ have both ACM and mass storage functions.
  */
-static int __init acm_ms_do_config(struct usb_configuration *c)
+static int acm_ms_do_config(struct usb_configuration *c)
 {
        struct fsg_opts *opts;
        int     status;
@@ -174,7 +174,7 @@ static struct usb_configuration acm_ms_config_driver = {
 
 /*-------------------------------------------------------------------------*/
 
-static int __init acm_ms_bind(struct usb_composite_dev *cdev)
+static int acm_ms_bind(struct usb_composite_dev *cdev)
 {
        struct usb_gadget       *gadget = cdev->gadget;
        struct fsg_opts         *opts;
@@ -249,7 +249,7 @@ static int __init acm_ms_bind(struct usb_composite_dev *cdev)
        return status;
 }
 
-static int __exit acm_ms_unbind(struct usb_composite_dev *cdev)
+static int acm_ms_unbind(struct usb_composite_dev *cdev)
 {
        usb_put_function(f_msg);
        usb_put_function_instance(fi_msg);
@@ -258,13 +258,13 @@ static int __exit acm_ms_unbind(struct usb_composite_dev *cdev)
        return 0;
 }
 
-static __refdata struct usb_composite_driver acm_ms_driver = {
+static struct usb_composite_driver acm_ms_driver = {
        .name           = "g_acm_ms",
        .dev            = &device_desc,
        .max_speed      = USB_SPEED_SUPER,
        .strings        = dev_strings,
        .bind           = acm_ms_bind,
-       .unbind         = __exit_p(acm_ms_unbind),
+       .unbind         = acm_ms_unbind,
 };
 
 module_usb_composite_driver(acm_ms_driver);
index f46a3956e43d1f334d9dafd2d3055aa99eee5b58..f289caf18a45341dc613a676345bfe8eeb51ee8e 100644 (file)
@@ -167,7 +167,7 @@ static const struct usb_descriptor_header *otg_desc[] = {
 
 /*-------------------------------------------------------------------------*/
 
-static int __init audio_do_config(struct usb_configuration *c)
+static int audio_do_config(struct usb_configuration *c)
 {
        int status;
 
@@ -216,7 +216,7 @@ static struct usb_configuration audio_config_driver = {
 
 /*-------------------------------------------------------------------------*/
 
-static int __init audio_bind(struct usb_composite_dev *cdev)
+static int audio_bind(struct usb_composite_dev *cdev)
 {
 #ifndef CONFIG_GADGET_UAC1
        struct f_uac2_opts      *uac2_opts;
@@ -276,7 +276,7 @@ static int __init audio_bind(struct usb_composite_dev *cdev)
        return status;
 }
 
-static int __exit audio_unbind(struct usb_composite_dev *cdev)
+static int audio_unbind(struct usb_composite_dev *cdev)
 {
 #ifdef CONFIG_GADGET_UAC1
        if (!IS_ERR_OR_NULL(f_uac1))
@@ -292,13 +292,13 @@ static int __exit audio_unbind(struct usb_composite_dev *cdev)
        return 0;
 }
 
-static __refdata struct usb_composite_driver audio_driver = {
+static struct usb_composite_driver audio_driver = {
        .name           = "g_audio",
        .dev            = &device_desc,
        .strings        = audio_strings,
        .max_speed      = USB_SPEED_HIGH,
        .bind           = audio_bind,
-       .unbind         = __exit_p(audio_unbind),
+       .unbind         = audio_unbind,
 };
 
 module_usb_composite_driver(audio_driver);
index 2e85d947347830b5b09ddf70b43631c85b2489d8..afd3e37921a7d9f1cc879cda5fe64ac5f940b6fa 100644 (file)
@@ -104,7 +104,7 @@ static struct usb_function_instance *fi_ecm;
 /*
  * We _always_ have both CDC ECM and CDC ACM functions.
  */
-static int __init cdc_do_config(struct usb_configuration *c)
+static int cdc_do_config(struct usb_configuration *c)
 {
        int     status;
 
@@ -153,7 +153,7 @@ static struct usb_configuration cdc_config_driver = {
 
 /*-------------------------------------------------------------------------*/
 
-static int __init cdc_bind(struct usb_composite_dev *cdev)
+static int cdc_bind(struct usb_composite_dev *cdev)
 {
        struct usb_gadget       *gadget = cdev->gadget;
        struct f_ecm_opts       *ecm_opts;
@@ -211,7 +211,7 @@ static int __init cdc_bind(struct usb_composite_dev *cdev)
        return status;
 }
 
-static int __exit cdc_unbind(struct usb_composite_dev *cdev)
+static int cdc_unbind(struct usb_composite_dev *cdev)
 {
        usb_put_function(f_acm);
        usb_put_function_instance(fi_serial);
@@ -222,13 +222,13 @@ static int __exit cdc_unbind(struct usb_composite_dev *cdev)
        return 0;
 }
 
-static __refdata struct usb_composite_driver cdc_driver = {
+static struct usb_composite_driver cdc_driver = {
        .name           = "g_cdc",
        .dev            = &device_desc,
        .strings        = dev_strings,
        .max_speed      = USB_SPEED_HIGH,
        .bind           = cdc_bind,
-       .unbind         = __exit_p(cdc_unbind),
+       .unbind         = cdc_unbind,
 };
 
 module_usb_composite_driver(cdc_driver);
index 633683a72a1169d95ee9f553efde929e9bf48808..204b10b1a7e7dd08c36bc00d44205e0c6753b1c2 100644 (file)
@@ -284,7 +284,7 @@ static int dbgp_configure_endpoints(struct usb_gadget *gadget)
        return -ENODEV;
 }
 
-static int __init dbgp_bind(struct usb_gadget *gadget,
+static int dbgp_bind(struct usb_gadget *gadget,
                struct usb_gadget_driver *driver)
 {
        int err, stp;
@@ -406,7 +406,7 @@ static int dbgp_setup(struct usb_gadget *gadget,
        return err;
 }
 
-static __refdata struct usb_gadget_driver dbgp_driver = {
+static struct usb_gadget_driver dbgp_driver = {
        .function = "dbgp",
        .max_speed = USB_SPEED_HIGH,
        .bind = dbgp_bind,
index c5fdc61cdc4a6bcf1684d005fddb7f34e2971bb6..a3323dca218f9514b4c2a5e4319d9866c950d8e5 100644 (file)
@@ -222,7 +222,7 @@ static struct usb_function *f_rndis;
  * the first one present.  That's to make Microsoft's drivers happy,
  * and to follow DOCSIS 1.0 (cable modem standard).
  */
-static int __init rndis_do_config(struct usb_configuration *c)
+static int rndis_do_config(struct usb_configuration *c)
 {
        int status;
 
@@ -264,7 +264,7 @@ MODULE_PARM_DESC(use_eem, "use CDC EEM mode");
 /*
  * We _always_ have an ECM, CDC Subset, or EEM configuration.
  */
-static int __init eth_do_config(struct usb_configuration *c)
+static int eth_do_config(struct usb_configuration *c)
 {
        int status = 0;
 
@@ -318,7 +318,7 @@ static struct usb_configuration eth_config_driver = {
 
 /*-------------------------------------------------------------------------*/
 
-static int __init eth_bind(struct usb_composite_dev *cdev)
+static int eth_bind(struct usb_composite_dev *cdev)
 {
        struct usb_gadget       *gadget = cdev->gadget;
        struct f_eem_opts       *eem_opts = NULL;
@@ -447,7 +447,7 @@ static int __init eth_bind(struct usb_composite_dev *cdev)
        return status;
 }
 
-static int __exit eth_unbind(struct usb_composite_dev *cdev)
+static int eth_unbind(struct usb_composite_dev *cdev)
 {
        if (has_rndis()) {
                usb_put_function(f_rndis);
@@ -466,13 +466,13 @@ static int __exit eth_unbind(struct usb_composite_dev *cdev)
        return 0;
 }
 
-static __refdata struct usb_composite_driver eth_driver = {
+static struct usb_composite_driver eth_driver = {
        .name           = "g_ether",
        .dev            = &device_desc,
        .strings        = dev_strings,
        .max_speed      = USB_SPEED_SUPER,
        .bind           = eth_bind,
-       .unbind         = __exit_p(eth_unbind),
+       .unbind         = eth_unbind,
 };
 
 module_usb_composite_driver(eth_driver);
index b01b88e1b716a5902d5276196ef459663545a216..7b9ef7e257d236dd442226203301a59bbd59ef47 100644 (file)
@@ -163,7 +163,7 @@ static int gfs_unbind(struct usb_composite_dev *cdev);
 static int gfs_do_config(struct usb_configuration *c);
 
 
-static __refdata struct usb_composite_driver gfs_driver = {
+static struct usb_composite_driver gfs_driver = {
        .name           = DRIVER_NAME,
        .dev            = &gfs_dev_desc,
        .strings        = gfs_dev_strings,
index e02a095294ac24fe0640555839d37e57833a13bd..da19c486b61e33a5b3214830f1c5db42ed979a75 100644 (file)
@@ -118,7 +118,7 @@ static struct usb_gadget_strings *dev_strings[] = {
 static struct usb_function_instance *fi_midi;
 static struct usb_function *f_midi;
 
-static int __exit midi_unbind(struct usb_composite_dev *dev)
+static int midi_unbind(struct usb_composite_dev *dev)
 {
        usb_put_function(f_midi);
        usb_put_function_instance(fi_midi);
@@ -133,7 +133,7 @@ static struct usb_configuration midi_config = {
        .MaxPower       = CONFIG_USB_GADGET_VBUS_DRAW,
 };
 
-static int __init midi_bind_config(struct usb_configuration *c)
+static int midi_bind_config(struct usb_configuration *c)
 {
        int status;
 
@@ -150,7 +150,7 @@ static int __init midi_bind_config(struct usb_configuration *c)
        return 0;
 }
 
-static int __init midi_bind(struct usb_composite_dev *cdev)
+static int midi_bind(struct usb_composite_dev *cdev)
 {
        struct f_midi_opts *midi_opts;
        int status;
@@ -185,13 +185,13 @@ static int __init midi_bind(struct usb_composite_dev *cdev)
        return status;
 }
 
-static __refdata struct usb_composite_driver midi_driver = {
+static struct usb_composite_driver midi_driver = {
        .name           = (char *) longname,
        .dev            = &device_desc,
        .strings        = dev_strings,
        .max_speed      = USB_SPEED_HIGH,
        .bind           = midi_bind,
-       .unbind         = __exit_p(midi_unbind),
+       .unbind         = midi_unbind,
 };
 
 module_usb_composite_driver(midi_driver);
index 614b06d80b4122c0b469dc898b5a251551667e69..2baa572686c6acbd5e1350ab167b65a367482302 100644 (file)
@@ -106,7 +106,7 @@ static struct usb_gadget_strings *dev_strings[] = {
 
 /****************************** Configurations ******************************/
 
-static int __init do_config(struct usb_configuration *c)
+static int do_config(struct usb_configuration *c)
 {
        struct hidg_func_node *e, *n;
        int status = 0;
@@ -147,7 +147,7 @@ static struct usb_configuration config_driver = {
 
 /****************************** Gadget Bind ******************************/
 
-static int __init hid_bind(struct usb_composite_dev *cdev)
+static int hid_bind(struct usb_composite_dev *cdev)
 {
        struct usb_gadget *gadget = cdev->gadget;
        struct list_head *tmp;
@@ -205,7 +205,7 @@ static int __init hid_bind(struct usb_composite_dev *cdev)
        return status;
 }
 
-static int __exit hid_unbind(struct usb_composite_dev *cdev)
+static int hid_unbind(struct usb_composite_dev *cdev)
 {
        struct hidg_func_node *n;
 
@@ -216,7 +216,7 @@ static int __exit hid_unbind(struct usb_composite_dev *cdev)
        return 0;
 }
 
-static int __init hidg_plat_driver_probe(struct platform_device *pdev)
+static int hidg_plat_driver_probe(struct platform_device *pdev)
 {
        struct hidg_func_descriptor *func = dev_get_platdata(&pdev->dev);
        struct hidg_func_node *entry;
@@ -252,13 +252,13 @@ static int hidg_plat_driver_remove(struct platform_device *pdev)
 /****************************** Some noise ******************************/
 
 
-static __refdata struct usb_composite_driver hidg_driver = {
+static struct usb_composite_driver hidg_driver = {
        .name           = "g_hid",
        .dev            = &device_desc,
        .strings        = dev_strings,
        .max_speed      = USB_SPEED_HIGH,
        .bind           = hid_bind,
-       .unbind         = __exit_p(hid_unbind),
+       .unbind         = hid_unbind,
 };
 
 static struct platform_driver hidg_plat_driver = {
index 8e27a8c9644470bfa8d5b44fc95a198aeda7214f..e7bfb081f111e4b60e55bce9ae5cd5f0743dad20 100644 (file)
@@ -130,7 +130,7 @@ static int msg_thread_exits(struct fsg_common *common)
        return 0;
 }
 
-static int __init msg_do_config(struct usb_configuration *c)
+static int msg_do_config(struct usb_configuration *c)
 {
        struct fsg_opts *opts;
        int ret;
@@ -170,7 +170,7 @@ static struct usb_configuration msg_config_driver = {
 
 /****************************** Gadget Bind ******************************/
 
-static int __init msg_bind(struct usb_composite_dev *cdev)
+static int msg_bind(struct usb_composite_dev *cdev)
 {
        static const struct fsg_operations ops = {
                .thread_exits = msg_thread_exits,
@@ -248,7 +248,7 @@ static int msg_unbind(struct usb_composite_dev *cdev)
 
 /****************************** Some noise ******************************/
 
-static __refdata struct usb_composite_driver msg_driver = {
+static struct usb_composite_driver msg_driver = {
        .name           = "g_mass_storage",
        .dev            = &msg_device_desc,
        .max_speed      = USB_SPEED_SUPER,
index 39d27bb343b410fc8eae1c6aefb59bc2bb1fe0d5..b21b51f0c9fadb27bbe319791ad970502eb88aa3 100644 (file)
@@ -149,7 +149,7 @@ static struct usb_function *f_acm_rndis;
 static struct usb_function *f_rndis;
 static struct usb_function *f_msg_rndis;
 
-static __init int rndis_do_config(struct usb_configuration *c)
+static int rndis_do_config(struct usb_configuration *c)
 {
        struct fsg_opts *fsg_opts;
        int ret;
@@ -237,7 +237,7 @@ static struct usb_function *f_acm_multi;
 static struct usb_function *f_ecm;
 static struct usb_function *f_msg_multi;
 
-static __init int cdc_do_config(struct usb_configuration *c)
+static int cdc_do_config(struct usb_configuration *c)
 {
        struct fsg_opts *fsg_opts;
        int ret;
@@ -466,7 +466,7 @@ static int __ref multi_bind(struct usb_composite_dev *cdev)
        return status;
 }
 
-static int __exit multi_unbind(struct usb_composite_dev *cdev)
+static int multi_unbind(struct usb_composite_dev *cdev)
 {
 #ifdef CONFIG_USB_G_MULTI_CDC
        usb_put_function(f_msg_multi);
@@ -497,13 +497,13 @@ static int __exit multi_unbind(struct usb_composite_dev *cdev)
 /****************************** Some noise ******************************/
 
 
-static __refdata struct usb_composite_driver multi_driver = {
+static struct usb_composite_driver multi_driver = {
        .name           = "g_multi",
        .dev            = &device_desc,
        .strings        = dev_strings,
        .max_speed      = USB_SPEED_HIGH,
        .bind           = multi_bind,
-       .unbind         = __exit_p(multi_unbind),
+       .unbind         = multi_unbind,
        .needs_serial   = 1,
 };
 
index e90e23db2acba192330741b9219c5d28e6a94b38..6ce7421412e9c14d7766210ab3442d06ca8f49d6 100644 (file)
@@ -107,7 +107,7 @@ static struct usb_function *f_ncm;
 
 /*-------------------------------------------------------------------------*/
 
-static int __init ncm_do_config(struct usb_configuration *c)
+static int ncm_do_config(struct usb_configuration *c)
 {
        int status;
 
@@ -143,7 +143,7 @@ static struct usb_configuration ncm_config_driver = {
 
 /*-------------------------------------------------------------------------*/
 
-static int __init gncm_bind(struct usb_composite_dev *cdev)
+static int gncm_bind(struct usb_composite_dev *cdev)
 {
        struct usb_gadget       *gadget = cdev->gadget;
        struct f_ncm_opts       *ncm_opts;
@@ -186,7 +186,7 @@ static int __init gncm_bind(struct usb_composite_dev *cdev)
        return status;
 }
 
-static int __exit gncm_unbind(struct usb_composite_dev *cdev)
+static int gncm_unbind(struct usb_composite_dev *cdev)
 {
        if (!IS_ERR_OR_NULL(f_ncm))
                usb_put_function(f_ncm);
@@ -195,13 +195,13 @@ static int __exit gncm_unbind(struct usb_composite_dev *cdev)
        return 0;
 }
 
-static __refdata struct usb_composite_driver ncm_driver = {
+static struct usb_composite_driver ncm_driver = {
        .name           = "g_ncm",
        .dev            = &device_desc,
        .strings        = dev_strings,
        .max_speed      = USB_SPEED_HIGH,
        .bind           = gncm_bind,
-       .unbind         = __exit_p(gncm_unbind),
+       .unbind         = gncm_unbind,
 };
 
 module_usb_composite_driver(ncm_driver);
index 9b8fd701648ced489d50ab562e8a8288afaf1125..4bb498a38a1c01eb17077844bc163028c3e22b93 100644 (file)
@@ -118,7 +118,7 @@ static struct usb_function_instance *fi_obex1;
 static struct usb_function_instance *fi_obex2;
 static struct usb_function_instance *fi_phonet;
 
-static int __init nokia_bind_config(struct usb_configuration *c)
+static int nokia_bind_config(struct usb_configuration *c)
 {
        struct usb_function *f_acm;
        struct usb_function *f_phonet = NULL;
@@ -224,7 +224,7 @@ static int __init nokia_bind_config(struct usb_configuration *c)
        return status;
 }
 
-static int __init nokia_bind(struct usb_composite_dev *cdev)
+static int nokia_bind(struct usb_composite_dev *cdev)
 {
        struct usb_gadget       *gadget = cdev->gadget;
        int                     status;
@@ -307,7 +307,7 @@ static int __init nokia_bind(struct usb_composite_dev *cdev)
        return status;
 }
 
-static int __exit nokia_unbind(struct usb_composite_dev *cdev)
+static int nokia_unbind(struct usb_composite_dev *cdev)
 {
        if (!IS_ERR_OR_NULL(f_obex1_cfg2))
                usb_put_function(f_obex1_cfg2);
@@ -338,13 +338,13 @@ static int __exit nokia_unbind(struct usb_composite_dev *cdev)
        return 0;
 }
 
-static __refdata struct usb_composite_driver nokia_driver = {
+static struct usb_composite_driver nokia_driver = {
        .name           = "g_nokia",
        .dev            = &device_desc,
        .strings        = dev_strings,
        .max_speed      = USB_SPEED_HIGH,
        .bind           = nokia_bind,
-       .unbind         = __exit_p(nokia_unbind),
+       .unbind         = nokia_unbind,
 };
 
 module_usb_composite_driver(nokia_driver);
index d5b6ee725a2ac04030ac52fc4b4e9c93477a90b6..1ce7df1060a5b237ae2532f514d95e3edd63cf34 100644 (file)
@@ -126,7 +126,7 @@ static struct usb_configuration printer_cfg_driver = {
        .bmAttributes           = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
 };
 
-static int __init printer_do_config(struct usb_configuration *c)
+static int printer_do_config(struct usb_configuration *c)
 {
        struct usb_gadget       *gadget = c->cdev->gadget;
        int                     status = 0;
@@ -152,7 +152,7 @@ static int __init printer_do_config(struct usb_configuration *c)
        return status;
 }
 
-static int __init printer_bind(struct usb_composite_dev *cdev)
+static int printer_bind(struct usb_composite_dev *cdev)
 {
        struct f_printer_opts *opts;
        int ret, len;
@@ -191,7 +191,7 @@ static int __init printer_bind(struct usb_composite_dev *cdev)
        return ret;
 }
 
-static int __exit printer_unbind(struct usb_composite_dev *cdev)
+static int printer_unbind(struct usb_composite_dev *cdev)
 {
        usb_put_function(f_printer);
        usb_put_function_instance(fi_printer);
@@ -199,7 +199,7 @@ static int __exit printer_unbind(struct usb_composite_dev *cdev)
        return 0;
 }
 
-static __refdata struct usb_composite_driver printer_driver = {
+static struct usb_composite_driver printer_driver = {
        .name           = shortname,
        .dev            = &device_desc,
        .strings        = dev_strings,
index 1f5f978d35d5318be56d1e069750d42e18b6b3c5..8b7528f9b78eff02a7d20bca4122429d6294be6d 100644 (file)
@@ -174,7 +174,7 @@ static int serial_register_ports(struct usb_composite_dev *cdev,
        return ret;
 }
 
-static int __init gs_bind(struct usb_composite_dev *cdev)
+static int gs_bind(struct usb_composite_dev *cdev)
 {
        int                     status;
 
@@ -230,7 +230,7 @@ static int gs_unbind(struct usb_composite_dev *cdev)
        return 0;
 }
 
-static __refdata struct usb_composite_driver gserial_driver = {
+static struct usb_composite_driver gserial_driver = {
        .name           = "g_serial",
        .dev            = &device_desc,
        .strings        = dev_strings,
index 8b80addc4ce6a5aaae4a330f4e27abd3ea67c5f8..f9b4882fce528f7cd6fa04ec66d90109a3a12047 100644 (file)
@@ -2397,7 +2397,7 @@ static int usb_target_bind(struct usb_composite_dev *cdev)
        return 0;
 }
 
-static __refdata struct usb_composite_driver usbg_driver = {
+static struct usb_composite_driver usbg_driver = {
        .name           = "g_target",
        .dev            = &usbg_device_desc,
        .strings        = usbg_strings,
index 04a3da20f74248442f6cabdbb4853db2b0f4f3b9..72c976bf3530f595115a9536267069c50e13aeba 100644 (file)
@@ -334,7 +334,7 @@ static const struct uvc_descriptor_header * const uvc_ss_streaming_cls[] = {
  * USB configuration
  */
 
-static int __init
+static int
 webcam_config_bind(struct usb_configuration *c)
 {
        int status = 0;
@@ -358,7 +358,7 @@ static struct usb_configuration webcam_config_driver = {
        .MaxPower               = CONFIG_USB_GADGET_VBUS_DRAW,
 };
 
-static int /* __init_or_exit */
+static int
 webcam_unbind(struct usb_composite_dev *cdev)
 {
        if (!IS_ERR_OR_NULL(f_uvc))
@@ -368,7 +368,7 @@ webcam_unbind(struct usb_composite_dev *cdev)
        return 0;
 }
 
-static int __init
+static int
 webcam_bind(struct usb_composite_dev *cdev)
 {
        struct f_uvc_opts *uvc_opts;
@@ -422,7 +422,7 @@ webcam_bind(struct usb_composite_dev *cdev)
  * Driver
  */
 
-static __refdata struct usb_composite_driver webcam_driver = {
+static struct usb_composite_driver webcam_driver = {
        .name           = "g_webcam",
        .dev            = &webcam_device_descriptor,
        .strings        = webcam_device_strings,
index 5ee95152493c2b6b0be74257cc437bdb560f250b..c986e8addb90ac809428f780e04cfb9242c22a90 100644 (file)
@@ -272,7 +272,7 @@ static struct usb_function_instance *func_inst_lb;
 module_param_named(qlen, gzero_options.qlen, uint, S_IRUGO|S_IWUSR);
 MODULE_PARM_DESC(qlen, "depth of loopback queue");
 
-static int __init zero_bind(struct usb_composite_dev *cdev)
+static int zero_bind(struct usb_composite_dev *cdev)
 {
        struct f_ss_opts        *ss_opts;
        struct f_lb_opts        *lb_opts;
@@ -400,7 +400,7 @@ static int zero_unbind(struct usb_composite_dev *cdev)
        return 0;
 }
 
-static __refdata struct usb_composite_driver zero_driver = {
+static struct usb_composite_driver zero_driver = {
        .name           = "zero",
        .dev            = &device_desc,
        .strings        = dev_strings,
index 2fbedca3c2b4eb80a19325c3bcc54913df6a7c27..fc4226462f8f5da2f71741a77093b7d69343afe3 100644 (file)
@@ -1942,7 +1942,7 @@ static int at91udc_probe(struct platform_device *pdev)
        return retval;
 }
 
-static int __exit at91udc_remove(struct platform_device *pdev)
+static int at91udc_remove(struct platform_device *pdev)
 {
        struct at91_udc *udc = platform_get_drvdata(pdev);
        unsigned long   flags;
@@ -2018,7 +2018,7 @@ static int at91udc_resume(struct platform_device *pdev)
 #endif
 
 static struct platform_driver at91_udc_driver = {
-       .remove         = __exit_p(at91udc_remove),
+       .remove         = at91udc_remove,
        .shutdown       = at91udc_shutdown,
        .suspend        = at91udc_suspend,
        .resume         = at91udc_resume,
index 4c01953a0869cf67693ec2842d48b508770927a2..351d48550c332af0768e43912f0d21069fbf8ea4 100644 (file)
@@ -2186,7 +2186,7 @@ static int usba_udc_probe(struct platform_device *pdev)
        return 0;
 }
 
-static int __exit usba_udc_remove(struct platform_device *pdev)
+static int usba_udc_remove(struct platform_device *pdev)
 {
        struct usba_udc *udc;
        int i;
@@ -2258,7 +2258,7 @@ static int usba_udc_resume(struct device *dev)
 static SIMPLE_DEV_PM_OPS(usba_udc_pm_ops, usba_udc_suspend, usba_udc_resume);
 
 static struct platform_driver udc_driver = {
-       .remove         = __exit_p(usba_udc_remove),
+       .remove         = usba_udc_remove,
        .driver         = {
                .name           = "atmel_usba_udc",
                .pm             = &usba_udc_pm_ops,
index 55fcb930f92e404252620e14cd3556314287714e..c60022b46a4835b4cc2b151b7a46193fe0f5554b 100644 (file)
@@ -2525,7 +2525,7 @@ static int fsl_udc_probe(struct platform_device *pdev)
 /* Driver removal function
  * Free resources and finish pending transactions
  */
-static int __exit fsl_udc_remove(struct platform_device *pdev)
+static int fsl_udc_remove(struct platform_device *pdev)
 {
        struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        struct fsl_usb2_platform_data *pdata = dev_get_platdata(&pdev->dev);
@@ -2663,7 +2663,7 @@ static const struct platform_device_id fsl_udc_devtype[] = {
 };
 MODULE_DEVICE_TABLE(platform, fsl_udc_devtype);
 static struct platform_driver udc_driver = {
-       .remove         = __exit_p(fsl_udc_remove),
+       .remove         = fsl_udc_remove,
        /* Just for FSL i.mx SoC currently */
        .id_table       = fsl_udc_devtype,
        /* these suspend and resume are not usb suspend and resume */
index fb4df159d32d59cb81c8cdbbfd9b33b3aa1d8d89..3970f453de4903fb55c21831e4cb511b2a2afc11 100644 (file)
@@ -1342,7 +1342,7 @@ static const struct usb_gadget_ops fusb300_gadget_ops = {
        .udc_stop       = fusb300_udc_stop,
 };
 
-static int __exit fusb300_remove(struct platform_device *pdev)
+static int fusb300_remove(struct platform_device *pdev)
 {
        struct fusb300 *fusb300 = platform_get_drvdata(pdev);
 
@@ -1492,7 +1492,7 @@ static int fusb300_probe(struct platform_device *pdev)
 }
 
 static struct platform_driver fusb300_driver = {
-       .remove =       __exit_p(fusb300_remove),
+       .remove =       fusb300_remove,
        .driver         = {
                .name = (char *) udc_name,
        },
index 8c7c83c937139b084b48dba9a548683c865481d2..309706fe4bf0ab0fd61d37a492a2bef0d73deb2a 100644 (file)
@@ -1528,7 +1528,7 @@ static const struct usb_gadget_ops m66592_gadget_ops = {
        .pullup                 = m66592_pullup,
 };
 
-static int __exit m66592_remove(struct platform_device *pdev)
+static int m66592_remove(struct platform_device *pdev)
 {
        struct m66592           *m66592 = platform_get_drvdata(pdev);
 
@@ -1695,7 +1695,7 @@ static int m66592_probe(struct platform_device *pdev)
 
 /*-------------------------------------------------------------------------*/
 static struct platform_driver m66592_driver = {
-       .remove =       __exit_p(m66592_remove),
+       .remove =       m66592_remove,
        .driver         = {
                .name = (char *) udc_name,
        },
index 2495fe9c95c5855f0c18be45d6f58deb0cf21a45..0293f7169deeace9688bab19316b2bd04fa8641c 100644 (file)
@@ -1820,7 +1820,7 @@ static const struct usb_gadget_ops r8a66597_gadget_ops = {
        .set_selfpowered        = r8a66597_set_selfpowered,
 };
 
-static int __exit r8a66597_remove(struct platform_device *pdev)
+static int r8a66597_remove(struct platform_device *pdev)
 {
        struct r8a66597         *r8a66597 = platform_get_drvdata(pdev);
 
@@ -1974,7 +1974,7 @@ static int r8a66597_probe(struct platform_device *pdev)
 
 /*-------------------------------------------------------------------------*/
 static struct platform_driver r8a66597_driver = {
-       .remove =       __exit_p(r8a66597_remove),
+       .remove =       r8a66597_remove,
        .driver         = {
                .name = (char *) udc_name,
        },
index dd3e9fd31b801fbc9b8e200930f2dfe814aed2d3..1f24274477ab9352ce582f96bfbfbdd61605d07e 100644 (file)
@@ -2071,8 +2071,8 @@ static int xudc_probe(struct platform_device *pdev)
        /* Map the registers */
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        udc->addr = devm_ioremap_resource(&pdev->dev, res);
-       if (!udc->addr)
-               return -ENOMEM;
+       if (IS_ERR(udc->addr))
+               return PTR_ERR(udc->addr);
 
        irq = platform_get_irq(pdev, 0);
        if (irq < 0) {
index f5397a517c54ce5a7df00b60e4b2482a2fd8b16c..7d34cbfaf373b54826cd0ffad697ef6f5d36c096 100644 (file)
@@ -2026,8 +2026,13 @@ static int process_isoc_td(struct xhci_hcd *xhci, struct xhci_td *td,
                break;
        case COMP_DEV_ERR:
        case COMP_STALL:
+               frame->status = -EPROTO;
+               skip_td = true;
+               break;
        case COMP_TX_ERR:
                frame->status = -EPROTO;
+               if (event_trb != td->last_trb)
+                       return 0;
                skip_td = true;
                break;
        case COMP_STOP:
@@ -2640,7 +2645,7 @@ irqreturn_t xhci_irq(struct usb_hcd *hcd)
                xhci_halt(xhci);
 hw_died:
                spin_unlock(&xhci->lock);
-               return -ESHUTDOWN;
+               return IRQ_HANDLED;
        }
 
        /*
index 8e421b89632ddaa4eaf30ee34ef60f89b7ac3e2d..ea75e8ccd3c11d397dc7a6a2ff45e78ae829fd81 100644 (file)
@@ -1267,7 +1267,7 @@ union xhci_trb {
  * since the command ring is 64-byte aligned.
  * It must also be greater than 16.
  */
-#define TRBS_PER_SEGMENT       64
+#define TRBS_PER_SEGMENT       256
 /* Allow two commands + a link TRB, along with any reserved command TRBs */
 #define MAX_RSVD_CMD_TRBS      (TRBS_PER_SEGMENT - 3)
 #define TRB_SEGMENT_SIZE       (TRBS_PER_SEGMENT*16)
index 1e0e10dd6ba51904b34bb32a9155cba7a5173f8f..3af263cc0caa3760a7a1704f329803e4951e62ae 100644 (file)
@@ -94,7 +94,7 @@ struct isp1301 {
 
 #if defined(CONFIG_MACH_OMAP_H2) || defined(CONFIG_MACH_OMAP_H3)
 
-#if    defined(CONFIG_TPS65010) || defined(CONFIG_TPS65010_MODULE)
+#if    defined(CONFIG_TPS65010) || (defined(CONFIG_TPS65010_MODULE) && defined(MODULE))
 
 #include <linux/i2c/tps65010.h>
 
index 84ce2d74894c9c3b25c7bcf0185f23887492eb94..9031750e7404a566d3c08c30e0366c424dcd0b06 100644 (file)
@@ -127,6 +127,7 @@ static const struct usb_device_id id_table[] = {
        { USB_DEVICE(0x10C4, 0x88A5) }, /* Planet Innovation Ingeni ZigBee USB Device */
        { USB_DEVICE(0x10C4, 0x8946) }, /* Ketra N1 Wireless Interface */
        { USB_DEVICE(0x10C4, 0x8977) }, /* CEL MeshWorks DevKit Device */
+       { USB_DEVICE(0x10C4, 0x8998) }, /* KCF Technologies PRN */
        { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */
        { USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */
        { USB_DEVICE(0x10C4, 0xEA70) }, /* Silicon Labs factory default */
index 829604d11f3fa72a6b5bec5580f150c27c513cbf..f5257af33ecfbc30bb0989fe03fea09af215639e 100644 (file)
@@ -61,7 +61,6 @@ static const struct usb_device_id id_table[] = {
        { USB_DEVICE(DCU10_VENDOR_ID, DCU10_PRODUCT_ID) },
        { USB_DEVICE(SITECOM_VENDOR_ID, SITECOM_PRODUCT_ID) },
        { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_ID) },
-       { USB_DEVICE(SAMSUNG_VENDOR_ID, SAMSUNG_PRODUCT_ID) },
        { USB_DEVICE(SIEMENS_VENDOR_ID, SIEMENS_PRODUCT_ID_SX1),
                .driver_info = PL2303_QUIRK_UART_STATE_IDX0 },
        { USB_DEVICE(SIEMENS_VENDOR_ID, SIEMENS_PRODUCT_ID_X65),
index 71fd9da1d6e7ac6e36ecdf38e8f8192c60fbbc39..e3b7af8adfb73ccefa92d4ba3c2c927a044dfa43 100644 (file)
 #define ALCATEL_VENDOR_ID      0x11f7
 #define ALCATEL_PRODUCT_ID     0x02df
 
-/* Samsung I330 phone cradle */
-#define SAMSUNG_VENDOR_ID      0x04e8
-#define SAMSUNG_PRODUCT_ID     0x8001
-
 #define SIEMENS_VENDOR_ID      0x11f5
 #define SIEMENS_PRODUCT_ID_SX1 0x0001
 #define SIEMENS_PRODUCT_ID_X65 0x0003
index bf2bd40e5f2ac7cdf1291caf1350f686925039bf..60afb39eb73c0b95d261ec367890a306621fd2de 100644 (file)
@@ -95,7 +95,7 @@ static const struct usb_device_id id_table[] = {
                .driver_info = (kernel_ulong_t)&palm_os_4_probe },
        { USB_DEVICE(ACER_VENDOR_ID, ACER_S10_ID),
                .driver_info = (kernel_ulong_t)&palm_os_4_probe },
-       { USB_DEVICE(SAMSUNG_VENDOR_ID, SAMSUNG_SCH_I330_ID),
+       { USB_DEVICE_INTERFACE_CLASS(SAMSUNG_VENDOR_ID, SAMSUNG_SCH_I330_ID, 0xff),
                .driver_info = (kernel_ulong_t)&palm_os_4_probe },
        { USB_DEVICE(SAMSUNG_VENDOR_ID, SAMSUNG_SPH_I500_ID),
                .driver_info = (kernel_ulong_t)&palm_os_4_probe },
index d684b4b8108ff34a5c4023088d9e927dcb378f6b..caf188800c679e7f24fc329903848a8c1f64d41a 100644 (file)
@@ -766,6 +766,13 @@ UNUSUAL_DEV(  0x059f, 0x0643, 0x0000, 0x0000,
                USB_SC_DEVICE, USB_PR_DEVICE, NULL,
                US_FL_GO_SLOW ),
 
+/* Reported by Christian Schaller <cschalle@redhat.com> */
+UNUSUAL_DEV(  0x059f, 0x0651, 0x0000, 0x0000,
+               "LaCie",
+               "External HDD",
+               USB_SC_DEVICE, USB_PR_DEVICE, NULL,
+               US_FL_NO_WP_DETECT ),
+
 /* Submitted by Joel Bourquard <numlock@freesurf.ch>
  * Some versions of this device need the SubClass and Protocol overrides
  * while others don't.
index 3a145a643e0d5185146001275b47d3d0cc745454..6897f1c1bc732efe36632895fcedc577b7292a33 100644 (file)
@@ -274,6 +274,10 @@ static int pwm_backlight_probe(struct platform_device *pdev)
 
        pb->pwm = devm_pwm_get(&pdev->dev, NULL);
        if (IS_ERR(pb->pwm)) {
+               ret = PTR_ERR(pb->pwm);
+               if (ret == -EPROBE_DEFER)
+                       goto err_alloc;
+
                dev_err(&pdev->dev, "unable to request PWM, trying legacy API\n");
                pb->legacy = true;
                pb->pwm = pwm_request(data->pwm_id, "pwm-backlight");
index 2b8553bd871514db8bfbd4877838c66d30f6598b..38387950490eb8dbd07c85434ac59e5129af2c1f 100644 (file)
@@ -957,7 +957,7 @@ unsigned xen_evtchn_nr_channels(void)
 }
 EXPORT_SYMBOL_GPL(xen_evtchn_nr_channels);
 
-int bind_virq_to_irq(unsigned int virq, unsigned int cpu)
+int bind_virq_to_irq(unsigned int virq, unsigned int cpu, bool percpu)
 {
        struct evtchn_bind_virq bind_virq;
        int evtchn, irq, ret;
@@ -971,8 +971,12 @@ int bind_virq_to_irq(unsigned int virq, unsigned int cpu)
                if (irq < 0)
                        goto out;
 
-               irq_set_chip_and_handler_name(irq, &xen_percpu_chip,
-                                             handle_percpu_irq, "virq");
+               if (percpu)
+                       irq_set_chip_and_handler_name(irq, &xen_percpu_chip,
+                                                     handle_percpu_irq, "virq");
+               else
+                       irq_set_chip_and_handler_name(irq, &xen_dynamic_chip,
+                                                     handle_edge_irq, "virq");
 
                bind_virq.virq = virq;
                bind_virq.vcpu = cpu;
@@ -1062,7 +1066,7 @@ int bind_virq_to_irqhandler(unsigned int virq, unsigned int cpu,
 {
        int irq, retval;
 
-       irq = bind_virq_to_irq(virq, cpu);
+       irq = bind_virq_to_irq(virq, cpu, irqflags & IRQF_PERCPU);
        if (irq < 0)
                return irq;
        retval = request_irq(irq, handler, irqflags, devname, dev_id);
index 9de772ee0031707c59292ac7849520ef8d6e9e47..614aaa1969bdfded3485ae9a72146269dd9101eb 100644 (file)
@@ -880,6 +880,8 @@ static int __add_keyed_refs(struct btrfs_fs_info *fs_info,
  * indirect refs to their parent bytenr.
  * When roots are found, they're added to the roots list
  *
+ * NOTE: This can return values > 0
+ *
  * FIXME some caching might speed things up
  */
 static int find_parent_nodes(struct btrfs_trans_handle *trans,
@@ -1198,6 +1200,19 @@ int btrfs_find_all_roots(struct btrfs_trans_handle *trans,
        return ret;
 }
 
+/**
+ * btrfs_check_shared - tell us whether an extent is shared
+ *
+ * @trans: optional trans handle
+ *
+ * btrfs_check_shared uses the backref walking code but will short
+ * circuit as soon as it finds a root or inode that doesn't match the
+ * one passed in. This provides a significant performance benefit for
+ * callers (such as fiemap) which want to know whether the extent is
+ * shared but do not need a ref count.
+ *
+ * Return: 0 if extent is not shared, 1 if it is shared, < 0 on error.
+ */
 int btrfs_check_shared(struct btrfs_trans_handle *trans,
                       struct btrfs_fs_info *fs_info, u64 root_objectid,
                       u64 inum, u64 bytenr)
@@ -1226,11 +1241,13 @@ int btrfs_check_shared(struct btrfs_trans_handle *trans,
                ret = find_parent_nodes(trans, fs_info, bytenr, elem.seq, tmp,
                                        roots, NULL, root_objectid, inum);
                if (ret == BACKREF_FOUND_SHARED) {
+                       /* this is the only condition under which we return 1 */
                        ret = 1;
                        break;
                }
                if (ret < 0 && ret != -ENOENT)
                        break;
+               ret = 0;
                node = ulist_next(tmp, &uiter);
                if (!node)
                        break;
index 0ec8e228b89f42505cc0c9c8ffef96e1a2f3f9a4..0ec3acd14cbf5e1273f331231f09165710d80d91 100644 (file)
@@ -3180,8 +3180,6 @@ static int write_one_cache_group(struct btrfs_trans_handle *trans,
        btrfs_mark_buffer_dirty(leaf);
 fail:
        btrfs_release_path(path);
-       if (ret)
-               btrfs_abort_transaction(trans, root, ret);
        return ret;
 
 }
@@ -3487,8 +3485,30 @@ int btrfs_start_dirty_block_groups(struct btrfs_trans_handle *trans,
                                ret = 0;
                        }
                }
-               if (!ret)
+               if (!ret) {
                        ret = write_one_cache_group(trans, root, path, cache);
+                       /*
+                        * Our block group might still be attached to the list
+                        * of new block groups in the transaction handle of some
+                        * other task (struct btrfs_trans_handle->new_bgs). This
+                        * means its block group item isn't yet in the extent
+                        * tree. If this happens ignore the error, as we will
+                        * try again later in the critical section of the
+                        * transaction commit.
+                        */
+                       if (ret == -ENOENT) {
+                               ret = 0;
+                               spin_lock(&cur_trans->dirty_bgs_lock);
+                               if (list_empty(&cache->dirty_list)) {
+                                       list_add_tail(&cache->dirty_list,
+                                                     &cur_trans->dirty_bgs);
+                                       btrfs_get_block_group(cache);
+                               }
+                               spin_unlock(&cur_trans->dirty_bgs_lock);
+                       } else if (ret) {
+                               btrfs_abort_transaction(trans, root, ret);
+                       }
+               }
 
                /* if its not on the io list, we need to put the block group */
                if (should_put)
@@ -3597,8 +3617,11 @@ int btrfs_write_dirty_block_groups(struct btrfs_trans_handle *trans,
                                ret = 0;
                        }
                }
-               if (!ret)
+               if (!ret) {
                        ret = write_one_cache_group(trans, root, path, cache);
+                       if (ret)
+                               btrfs_abort_transaction(trans, root, ret);
+               }
 
                /* if its not on the io list, we need to put the block group */
                if (should_put)
@@ -8806,6 +8829,24 @@ int btrfs_set_block_group_ro(struct btrfs_root *root,
                goto again;
        }
 
+       /*
+        * if we are changing raid levels, try to allocate a corresponding
+        * block group with the new raid level.
+        */
+       alloc_flags = update_block_group_flags(root, cache->flags);
+       if (alloc_flags != cache->flags) {
+               ret = do_chunk_alloc(trans, root, alloc_flags,
+                                    CHUNK_ALLOC_FORCE);
+               /*
+                * ENOSPC is allowed here, we may have enough space
+                * already allocated at the new raid level to
+                * carry on
+                */
+               if (ret == -ENOSPC)
+                       ret = 0;
+               if (ret < 0)
+                       goto out;
+       }
 
        ret = set_block_group_ro(cache, 0);
        if (!ret)
@@ -8819,7 +8860,9 @@ int btrfs_set_block_group_ro(struct btrfs_root *root,
 out:
        if (cache->flags & BTRFS_BLOCK_GROUP_SYSTEM) {
                alloc_flags = update_block_group_flags(root, cache->flags);
+               lock_chunks(root->fs_info->chunk_root);
                check_system_chunk(trans, root, alloc_flags);
+               unlock_chunks(root->fs_info->chunk_root);
        }
        mutex_unlock(&root->fs_info->ro_block_group_mutex);
 
index 43af5a61ad25b4dbb3f4c0f2cb89160c120d1ac7..c32d226bfeccbb28f25f2f417fa9e57b14411136 100644 (file)
@@ -4772,6 +4772,25 @@ struct extent_buffer *find_extent_buffer(struct btrfs_fs_info *fs_info,
                               start >> PAGE_CACHE_SHIFT);
        if (eb && atomic_inc_not_zero(&eb->refs)) {
                rcu_read_unlock();
+               /*
+                * Lock our eb's refs_lock to avoid races with
+                * free_extent_buffer. When we get our eb it might be flagged
+                * with EXTENT_BUFFER_STALE and another task running
+                * free_extent_buffer might have seen that flag set,
+                * eb->refs == 2, that the buffer isn't under IO (dirty and
+                * writeback flags not set) and it's still in the tree (flag
+                * EXTENT_BUFFER_TREE_REF set), therefore being in the process
+                * of decrementing the extent buffer's reference count twice.
+                * So here we could race and increment the eb's reference count,
+                * clear its stale flag, mark it as dirty and drop our reference
+                * before the other task finishes executing free_extent_buffer,
+                * which would later result in an attempt to free an extent
+                * buffer that is dirty.
+                */
+               if (test_bit(EXTENT_BUFFER_STALE, &eb->bflags)) {
+                       spin_lock(&eb->refs_lock);
+                       spin_unlock(&eb->refs_lock);
+               }
                mark_extent_buffer_accessed(eb, NULL);
                return eb;
        }
index 5e020d76fd07b00da1bacec4c5662dc0f1078ba7..9dbe5b548fa6a74029960de0ea1d8ebf63f835e8 100644 (file)
@@ -3466,6 +3466,7 @@ int btrfs_write_out_ino_cache(struct btrfs_root *root,
        struct btrfs_free_space_ctl *ctl = root->free_ino_ctl;
        int ret;
        struct btrfs_io_ctl io_ctl;
+       bool release_metadata = true;
 
        if (!btrfs_test_opt(root, INODE_MAP_CACHE))
                return 0;
@@ -3473,11 +3474,20 @@ int btrfs_write_out_ino_cache(struct btrfs_root *root,
        memset(&io_ctl, 0, sizeof(io_ctl));
        ret = __btrfs_write_out_cache(root, inode, ctl, NULL, &io_ctl,
                                      trans, path, 0);
-       if (!ret)
+       if (!ret) {
+               /*
+                * At this point writepages() didn't error out, so our metadata
+                * reservation is released when the writeback finishes, at
+                * inode.c:btrfs_finish_ordered_io(), regardless of it finishing
+                * with or without an error.
+                */
+               release_metadata = false;
                ret = btrfs_wait_cache_io(root, trans, NULL, &io_ctl, path, 0);
+       }
 
        if (ret) {
-               btrfs_delalloc_release_metadata(inode, inode->i_size);
+               if (release_metadata)
+                       btrfs_delalloc_release_metadata(inode, inode->i_size);
 #ifdef DEBUG
                btrfs_err(root->fs_info,
                        "failed to write free ino cache for root %llu",
index 157cc54fc63486e485a95bf6d8d6da692ef171ca..760c4a5e096b4d5a403f7923ad4b65537a085886 100644 (file)
@@ -722,6 +722,7 @@ void btrfs_start_ordered_extent(struct inode *inode,
 int btrfs_wait_ordered_range(struct inode *inode, u64 start, u64 len)
 {
        int ret = 0;
+       int ret_wb = 0;
        u64 end;
        u64 orig_end;
        struct btrfs_ordered_extent *ordered;
@@ -741,9 +742,14 @@ int btrfs_wait_ordered_range(struct inode *inode, u64 start, u64 len)
        if (ret)
                return ret;
 
-       ret = filemap_fdatawait_range(inode->i_mapping, start, orig_end);
-       if (ret)
-               return ret;
+       /*
+        * If we have a writeback error don't return immediately. Wait first
+        * for any ordered extents that haven't completed yet. This is to make
+        * sure no one can dirty the same page ranges and call writepages()
+        * before the ordered extents complete - to avoid failures (-EEXIST)
+        * when adding the new ordered extents to the ordered tree.
+        */
+       ret_wb = filemap_fdatawait_range(inode->i_mapping, start, orig_end);
 
        end = orig_end;
        while (1) {
@@ -767,7 +773,7 @@ int btrfs_wait_ordered_range(struct inode *inode, u64 start, u64 len)
                        break;
                end--;
        }
-       return ret;
+       return ret_wb ? ret_wb : ret;
 }
 
 /*
index 96aebf3bcd5b37d35604c76ec584d29686ad34e2..174f5e1e00abfa533b1cb7483e44aae0f550e63a 100644 (file)
@@ -4625,6 +4625,7 @@ int btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
 {
        u64 chunk_offset;
 
+       ASSERT(mutex_is_locked(&extent_root->fs_info->chunk_mutex));
        chunk_offset = find_next_chunk(extent_root->fs_info);
        return __btrfs_alloc_chunk(trans, extent_root, chunk_offset, type);
 }
index 430e0348c99ebb9b86c65ccd957a1b5e69ed6a2a..7dc886c9a78fc428b368a1c911b8c1ad745f48a5 100644 (file)
@@ -24,6 +24,7 @@
 #include "cifsfs.h"
 #include "dns_resolve.h"
 #include "cifs_debug.h"
+#include "cifs_unicode.h"
 
 static LIST_HEAD(cifs_dfs_automount_list);
 
@@ -312,7 +313,7 @@ static struct vfsmount *cifs_dfs_do_automount(struct dentry *mntpt)
        xid = get_xid();
        rc = get_dfs_path(xid, ses, full_path + 1, cifs_sb->local_nls,
                &num_referrals, &referrals,
-               cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
+               cifs_remap(cifs_sb));
        free_xid(xid);
 
        cifs_put_tlink(tlink);
index 0303c6793d903ab07cb7d1829bc372f0be3fc15f..5a53ac6b1e02515be90a4e446b103aa9f6f26874 100644 (file)
 #include "cifsglob.h"
 #include "cifs_debug.h"
 
-/*
- * 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 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_utf16_bytes(const __le16 *from, int maxbytes,
-               const struct nls_table *codepage)
-{
-       int i;
-       int charlen, outlen = 0;
-       int maxwords = maxbytes / 2;
-       char tmp[NLS_MAX_CHARSET_SIZE];
-       __u16 ftmp;
-
-       for (i = 0; i < maxwords; i++) {
-               ftmp = get_unaligned_le16(&from[i]);
-               if (ftmp == 0)
-                       break;
-
-               charlen = codepage->uni2char(ftmp, tmp, NLS_MAX_CHARSET_SIZE);
-               if (charlen > 0)
-                       outlen += charlen;
-               else
-                       outlen++;
-       }
-
-       return outlen;
-}
-
 int cifs_remap(struct cifs_sb_info *cifs_sb)
 {
        int map_type;
@@ -155,10 +120,13 @@ convert_sfm_char(const __u16 src_char, char *target)
  * enough to hold the result of the conversion (at least NLS_MAX_CHARSET_SIZE).
  */
 static int
-cifs_mapchar(char *target, const __u16 src_char, const struct nls_table *cp,
+cifs_mapchar(char *target, const __u16 *from, const struct nls_table *cp,
             int maptype)
 {
        int len = 1;
+       __u16 src_char;
+
+       src_char = *from;
 
        if ((maptype == SFM_MAP_UNI_RSVD) && convert_sfm_char(src_char, target))
                return len;
@@ -168,10 +136,23 @@ cifs_mapchar(char *target, const __u16 src_char, const struct nls_table *cp,
 
        /* if character not one of seven in special remap set */
        len = cp->uni2char(src_char, target, NLS_MAX_CHARSET_SIZE);
-       if (len <= 0) {
-               *target = '?';
-               len = 1;
-       }
+       if (len <= 0)
+               goto surrogate_pair;
+
+       return len;
+
+surrogate_pair:
+       /* convert SURROGATE_PAIR and IVS */
+       if (strcmp(cp->charset, "utf8"))
+               goto unknown;
+       len = utf16s_to_utf8s(from, 3, UTF16_LITTLE_ENDIAN, target, 6);
+       if (len <= 0)
+               goto unknown;
+       return len;
+
+unknown:
+       *target = '?';
+       len = 1;
        return len;
 }
 
@@ -206,7 +187,7 @@ cifs_from_utf16(char *to, const __le16 *from, int tolen, int fromlen,
        int nullsize = nls_nullsize(codepage);
        int fromwords = fromlen / 2;
        char tmp[NLS_MAX_CHARSET_SIZE];
-       __u16 ftmp;
+       __u16 ftmp[3];          /* ftmp[3] = 3array x 2bytes = 6bytes UTF-16 */
 
        /*
         * because the chars can be of varying widths, we need to take care
@@ -217,9 +198,17 @@ cifs_from_utf16(char *to, const __le16 *from, int tolen, int fromlen,
        safelen = tolen - (NLS_MAX_CHARSET_SIZE + nullsize);
 
        for (i = 0; i < fromwords; i++) {
-               ftmp = get_unaligned_le16(&from[i]);
-               if (ftmp == 0)
+               ftmp[0] = get_unaligned_le16(&from[i]);
+               if (ftmp[0] == 0)
                        break;
+               if (i + 1 < fromwords)
+                       ftmp[1] = get_unaligned_le16(&from[i + 1]);
+               else
+                       ftmp[1] = 0;
+               if (i + 2 < fromwords)
+                       ftmp[2] = get_unaligned_le16(&from[i + 2]);
+               else
+                       ftmp[2] = 0;
 
                /*
                 * check to see if converting this character might make the
@@ -234,6 +223,17 @@ cifs_from_utf16(char *to, const __le16 *from, int tolen, int fromlen,
                /* put converted char into 'to' buffer */
                charlen = cifs_mapchar(&to[outlen], ftmp, codepage, map_type);
                outlen += charlen;
+
+               /* charlen (=bytes of UTF-8 for 1 character)
+                * 4bytes UTF-8(surrogate pair) is charlen=4
+                *   (4bytes UTF-16 code)
+                * 7-8bytes UTF-8(IVS) is charlen=3+4 or 4+4
+                *   (2 UTF-8 pairs divided to 2 UTF-16 pairs) */
+               if (charlen == 4)
+                       i++;
+               else if (charlen >= 5)
+                       /* 5-6bytes UTF-8 */
+                       i += 2;
        }
 
        /* properly null-terminate string */
@@ -295,6 +295,46 @@ cifs_strtoUTF16(__le16 *to, const char *from, int len,
        return i;
 }
 
+/*
+ * 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 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_utf16_bytes(const __le16 *from, int maxbytes,
+               const struct nls_table *codepage)
+{
+       int i;
+       int charlen, outlen = 0;
+       int maxwords = maxbytes / 2;
+       char tmp[NLS_MAX_CHARSET_SIZE];
+       __u16 ftmp[3];
+
+       for (i = 0; i < maxwords; i++) {
+               ftmp[0] = get_unaligned_le16(&from[i]);
+               if (ftmp[0] == 0)
+                       break;
+               if (i + 1 < maxwords)
+                       ftmp[1] = get_unaligned_le16(&from[i + 1]);
+               else
+                       ftmp[1] = 0;
+               if (i + 2 < maxwords)
+                       ftmp[2] = get_unaligned_le16(&from[i + 2]);
+               else
+                       ftmp[2] = 0;
+
+               charlen = cifs_mapchar(tmp, ftmp, codepage, NO_MAP_UNI_RSVD);
+               outlen += charlen;
+       }
+
+       return outlen;
+}
+
 /*
  * cifs_strndup_from_utf16 - copy a string from wire format to the local
  * codepage
@@ -409,10 +449,15 @@ cifsConvertToUTF16(__le16 *target, const char *source, int srclen,
        char src_char;
        __le16 dst_char;
        wchar_t tmp;
+       wchar_t *wchar_to;      /* UTF-16 */
+       int ret;
+       unicode_t u;
 
        if (map_chars == NO_MAP_UNI_RSVD)
                return cifs_strtoUTF16(target, source, PATH_MAX, cp);
 
+       wchar_to = kzalloc(6, GFP_KERNEL);
+
        for (i = 0; i < srclen; j++) {
                src_char = source[i];
                charlen = 1;
@@ -441,11 +486,55 @@ cifsConvertToUTF16(__le16 *target, const char *source, int srclen,
                         * if no match, use question mark, which at least in
                         * some cases serves as wild card
                         */
-                       if (charlen < 1) {
-                               dst_char = cpu_to_le16(0x003f);
-                               charlen = 1;
+                       if (charlen > 0)
+                               goto ctoUTF16;
+
+                       /* convert SURROGATE_PAIR */
+                       if (strcmp(cp->charset, "utf8") || !wchar_to)
+                               goto unknown;
+                       if (*(source + i) & 0x80) {
+                               charlen = utf8_to_utf32(source + i, 6, &u);
+                               if (charlen < 0)
+                                       goto unknown;
+                       } else
+                               goto unknown;
+                       ret  = utf8s_to_utf16s(source + i, charlen,
+                                              UTF16_LITTLE_ENDIAN,
+                                              wchar_to, 6);
+                       if (ret < 0)
+                               goto unknown;
+
+                       i += charlen;
+                       dst_char = cpu_to_le16(*wchar_to);
+                       if (charlen <= 3)
+                               /* 1-3bytes UTF-8 to 2bytes UTF-16 */
+                               put_unaligned(dst_char, &target[j]);
+                       else if (charlen == 4) {
+                               /* 4bytes UTF-8(surrogate pair) to 4bytes UTF-16
+                                * 7-8bytes UTF-8(IVS) divided to 2 UTF-16
+                                *   (charlen=3+4 or 4+4) */
+                               put_unaligned(dst_char, &target[j]);
+                               dst_char = cpu_to_le16(*(wchar_to + 1));
+                               j++;
+                               put_unaligned(dst_char, &target[j]);
+                       } else if (charlen >= 5) {
+                               /* 5-6bytes UTF-8 to 6bytes UTF-16 */
+                               put_unaligned(dst_char, &target[j]);
+                               dst_char = cpu_to_le16(*(wchar_to + 1));
+                               j++;
+                               put_unaligned(dst_char, &target[j]);
+                               dst_char = cpu_to_le16(*(wchar_to + 2));
+                               j++;
+                               put_unaligned(dst_char, &target[j]);
                        }
+                       continue;
+
+unknown:
+                       dst_char = cpu_to_le16(0x003f);
+                       charlen = 1;
                }
+
+ctoUTF16:
                /*
                 * character may take more than one byte in the source string,
                 * but will take exactly two bytes in the target string
@@ -456,6 +545,7 @@ cifsConvertToUTF16(__le16 *target, const char *source, int srclen,
 
 ctoUTF16_out:
        put_unaligned(0, &target[j]); /* Null terminate target unicode string */
+       kfree(wchar_to);
        return j;
 }
 
index f5089bde363576dcab6a35887f3c539a8a7e6247..0a9fb6b53126a7c95715a862bfb3b067f443fc1a 100644 (file)
@@ -469,6 +469,8 @@ cifs_show_options(struct seq_file *s, struct dentry *root)
                seq_puts(s, ",nouser_xattr");
        if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR)
                seq_puts(s, ",mapchars");
+       if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SFM_CHR)
+               seq_puts(s, ",mapposix");
        if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL)
                seq_puts(s, ",sfu");
        if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
index c31ce98c1704a32b998f993d9a26613dc1342e29..c63fd1dde25b861b011f604522572c5619f177f1 100644 (file)
@@ -361,11 +361,11 @@ extern int CIFSUnixCreateHardLink(const unsigned int xid,
 extern int CIFSUnixCreateSymLink(const unsigned int xid,
                        struct cifs_tcon *tcon,
                        const char *fromName, const char *toName,
-                       const struct nls_table *nls_codepage);
+                       const struct nls_table *nls_codepage, int remap);
 extern int CIFSSMBUnixQuerySymLink(const unsigned int xid,
                        struct cifs_tcon *tcon,
                        const unsigned char *searchName, char **syminfo,
-                       const struct nls_table *nls_codepage);
+                       const struct nls_table *nls_codepage, int remap);
 extern int CIFSSMBQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon,
                               __u16 fid, char **symlinkinfo,
                               const struct nls_table *nls_codepage);
index 84650a51c7c4064357eab083868cc613a75f7f18..f26ffbfc64d8b4eca26b8e8101f705043fc7a4a0 100644 (file)
@@ -2784,7 +2784,7 @@ CIFSSMBCopy(const unsigned int xid, struct cifs_tcon *tcon,
 int
 CIFSUnixCreateSymLink(const unsigned int xid, struct cifs_tcon *tcon,
                      const char *fromName, const char *toName,
-                     const struct nls_table *nls_codepage)
+                     const struct nls_table *nls_codepage, int remap)
 {
        TRANSACTION2_SPI_REQ *pSMB = NULL;
        TRANSACTION2_SPI_RSP *pSMBr = NULL;
@@ -2804,9 +2804,9 @@ CIFSUnixCreateSymLink(const unsigned int xid, struct cifs_tcon *tcon,
 
        if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
                name_len =
-                   cifs_strtoUTF16((__le16 *) pSMB->FileName, fromName,
-                                   /* find define for this maxpathcomponent */
-                                   PATH_MAX, nls_codepage);
+                   cifsConvertToUTF16((__le16 *) pSMB->FileName, fromName,
+                               /* find define for this maxpathcomponent */
+                                       PATH_MAX, nls_codepage, remap);
                name_len++;     /* trailing null */
                name_len *= 2;
 
@@ -2828,9 +2828,9 @@ CIFSUnixCreateSymLink(const unsigned int xid, struct cifs_tcon *tcon,
        data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
        if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
                name_len_target =
-                   cifs_strtoUTF16((__le16 *) data_offset, toName, PATH_MAX
-                                   /* find define for this maxpathcomponent */
-                                   , nls_codepage);
+                   cifsConvertToUTF16((__le16 *) data_offset, toName,
+                               /* find define for this maxpathcomponent */
+                                       PATH_MAX, nls_codepage, remap);
                name_len_target++;      /* trailing null */
                name_len_target *= 2;
        } else {        /* BB improve the check for buffer overruns BB */
@@ -3034,7 +3034,7 @@ CIFSCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon,
 int
 CIFSSMBUnixQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon,
                        const unsigned char *searchName, char **symlinkinfo,
-                       const struct nls_table *nls_codepage)
+                       const struct nls_table *nls_codepage, int remap)
 {
 /* SMB_QUERY_FILE_UNIX_LINK */
        TRANSACTION2_QPI_REQ *pSMB = NULL;
@@ -3055,8 +3055,9 @@ CIFSSMBUnixQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon,
 
        if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
                name_len =
-                       cifs_strtoUTF16((__le16 *) pSMB->FileName, searchName,
-                                       PATH_MAX, nls_codepage);
+                       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 */
@@ -4917,7 +4918,7 @@ CIFSGetDFSRefer(const unsigned int xid, struct cifs_ses *ses,
                strncpy(pSMB->RequestFileName, search_name, name_len);
        }
 
-       if (ses->server && ses->server->sign)
+       if (ses->server->sign)
                pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
 
        pSMB->hdr.Uid = ses->Suid;
index f3bfe08e177b6c86a4f1a99a8905f1b417f82af5..8383d5ea42028dac6788e642b6c3ed0f61459d51 100644 (file)
@@ -386,6 +386,7 @@ cifs_reconnect(struct TCP_Server_Info *server)
                rc = generic_ip_connect(server);
                if (rc) {
                        cifs_dbg(FYI, "reconnect error %d\n", rc);
+                       mutex_unlock(&server->srv_mutex);
                        msleep(3000);
                } else {
                        atomic_inc(&tcpSesReconnectCount);
@@ -393,8 +394,8 @@ cifs_reconnect(struct TCP_Server_Info *server)
                        if (server->tcpStatus != CifsExiting)
                                server->tcpStatus = CifsNeedNegotiate;
                        spin_unlock(&GlobalMid_Lock);
+                       mutex_unlock(&server->srv_mutex);
                }
-               mutex_unlock(&server->srv_mutex);
        } while (server->tcpStatus == CifsNeedReconnect);
 
        return rc;
index 338d56936f6af694b7085284a38e7b751ba7eb66..c3eb998a99bd18a2ed9b7b843c99be15fedab9df 100644 (file)
@@ -620,8 +620,7 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, umode_t mode,
                }
                rc = CIFSSMBUnixSetPathInfo(xid, tcon, full_path, &args,
                                            cifs_sb->local_nls,
-                                           cifs_sb->mnt_cifs_flags &
-                                               CIFS_MOUNT_MAP_SPECIAL_CHR);
+                                           cifs_remap(cifs_sb));
                if (rc)
                        goto mknod_out;
 
index cafbf10521d5017074196e02ad37218939d0ab70..3f50cee79df9d3318209e19281acef536b34af37 100644 (file)
@@ -140,8 +140,7 @@ int cifs_posix_open(char *full_path, struct inode **pinode,
        posix_flags = cifs_posix_convert_flags(f_flags);
        rc = CIFSPOSIXCreate(xid, tcon, posix_flags, mode, pnetfid, presp_data,
                             poplock, full_path, cifs_sb->local_nls,
-                            cifs_sb->mnt_cifs_flags &
-                                       CIFS_MOUNT_MAP_SPECIAL_CHR);
+                            cifs_remap(cifs_sb));
        cifs_put_tlink(tlink);
 
        if (rc)
@@ -1553,8 +1552,8 @@ cifs_setlk(struct file *file, struct file_lock *flock, __u32 type,
                rc = server->ops->mand_unlock_range(cfile, flock, xid);
 
 out:
-       if (flock->fl_flags & FL_POSIX)
-               posix_lock_file_wait(file, flock);
+       if (flock->fl_flags & FL_POSIX && !rc)
+               rc = posix_lock_file_wait(file, flock);
        return rc;
 }
 
index 55b58112d122248b92305ea00eb66c6715a40b03..f621b44cb8009fe87bf631e0a96c941fe63d3408 100644 (file)
@@ -373,8 +373,7 @@ int cifs_get_inode_info_unix(struct inode **pinode,
 
        /* could have done a find first instead but this returns more info */
        rc = CIFSSMBUnixQPathInfo(xid, tcon, full_path, &find_data,
-                                 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
-                                       CIFS_MOUNT_MAP_SPECIAL_CHR);
+                                 cifs_sb->local_nls, cifs_remap(cifs_sb));
        cifs_put_tlink(tlink);
 
        if (!rc) {
@@ -402,9 +401,25 @@ int cifs_get_inode_info_unix(struct inode **pinode,
                        rc = -ENOMEM;
        } else {
                /* we already have inode, update it */
+
+               /* if uniqueid is different, return error */
+               if (unlikely(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM &&
+                   CIFS_I(*pinode)->uniqueid != fattr.cf_uniqueid)) {
+                       rc = -ESTALE;
+                       goto cgiiu_exit;
+               }
+
+               /* if filetype is different, return error */
+               if (unlikely(((*pinode)->i_mode & S_IFMT) !=
+                   (fattr.cf_mode & S_IFMT))) {
+                       rc = -ESTALE;
+                       goto cgiiu_exit;
+               }
+
                cifs_fattr_to_inode(*pinode, &fattr);
        }
 
+cgiiu_exit:
        return rc;
 }
 
@@ -839,6 +854,15 @@ cifs_get_inode_info(struct inode **inode, const char *full_path,
                if (!*inode)
                        rc = -ENOMEM;
        } else {
+               /* we already have inode, update it */
+
+               /* if filetype is different, return error */
+               if (unlikely(((*inode)->i_mode & S_IFMT) !=
+                   (fattr.cf_mode & S_IFMT))) {
+                       rc = -ESTALE;
+                       goto cgii_exit;
+               }
+
                cifs_fattr_to_inode(*inode, &fattr);
        }
 
@@ -2215,8 +2239,7 @@ cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs)
                pTcon = tlink_tcon(tlink);
                rc = CIFSSMBUnixSetPathInfo(xid, pTcon, full_path, args,
                                    cifs_sb->local_nls,
-                                   cifs_sb->mnt_cifs_flags &
-                                       CIFS_MOUNT_MAP_SPECIAL_CHR);
+                                   cifs_remap(cifs_sb));
                cifs_put_tlink(tlink);
        }
 
index 252e672d56043468fb8f906ce371acef27d74db0..e6c707cc62b39b445b4b374eeec51a5be4fe07f4 100644 (file)
@@ -717,7 +717,8 @@ cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname)
                rc = create_mf_symlink(xid, pTcon, cifs_sb, full_path, symname);
        else if (pTcon->unix_ext)
                rc = CIFSUnixCreateSymLink(xid, pTcon, full_path, symname,
-                                          cifs_sb->local_nls);
+                                          cifs_sb->local_nls,
+                                          cifs_remap(cifs_sb));
        /* else
           rc = CIFSCreateReparseSymLink(xid, pTcon, fromName, toName,
                                        cifs_sb_target->local_nls); */
index b4a47237486b883851e889e78505bd1179c7842d..b1eede3678a91d8d1ea3e350cb035cabf1da7ba7 100644 (file)
@@ -90,6 +90,8 @@ cifs_prime_dcache(struct dentry *parent, struct qstr *name,
        if (dentry) {
                inode = d_inode(dentry);
                if (inode) {
+                       if (d_mountpoint(dentry))
+                               goto out;
                        /*
                         * If we're generating inode numbers, then we don't
                         * want to clobber the existing one with the one that
index 7bfdd6066276256fc03855cd809f63c167d3991b..fc537c29044edd8a158bb130a65e371370826164 100644 (file)
@@ -960,7 +960,8 @@ cifs_query_symlink(const unsigned int xid, struct cifs_tcon *tcon,
        /* Check for unix extensions */
        if (cap_unix(tcon->ses)) {
                rc = CIFSSMBUnixQuerySymLink(xid, tcon, full_path, target_path,
-                                            cifs_sb->local_nls);
+                                            cifs_sb->local_nls,
+                                            cifs_remap(cifs_sb));
                if (rc == -EREMOTE)
                        rc = cifs_unix_dfs_readlink(xid, tcon, full_path,
                                                    target_path,
index 65cd7a84c8bc3206033a917fe9d98fc939cbe1af..54cbe19d9c0871a1bb47a17edfc1d414cb383b9f 100644 (file)
@@ -110,7 +110,7 @@ smb2_hdr_assemble(struct smb2_hdr *hdr, __le16 smb2_cmd /* command */ ,
 
        /* GLOBAL_CAP_LARGE_MTU will only be set if dialect > SMB2.02 */
        /* See sections 2.2.4 and 3.2.4.1.5 of MS-SMB2 */
-       if ((tcon->ses) &&
+       if ((tcon->ses) && (tcon->ses->server) &&
            (tcon->ses->server->capabilities & SMB2_GLOBAL_CAP_LARGE_MTU))
                hdr->CreditCharge = cpu_to_le16(1);
        /* else CreditCharge MBZ */
index 49a1c61433b73722683cad25eef1fb92045e265a..1977c2a553aca711ba145d1670ea9a84fd45ea84 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -659,6 +659,9 @@ int setup_arg_pages(struct linux_binprm *bprm,
        if (stack_base > STACK_SIZE_MAX)
                stack_base = STACK_SIZE_MAX;
 
+       /* Add space for stack randomization. */
+       stack_base += (STACK_RND_MASK << PAGE_SHIFT);
+
        /* Make sure we didn't let the argument array grow too large. */
        if (vma->vm_end - vma->vm_start > stack_base)
                return -ENOMEM;
index 009a0590b20fb328c5829573ee77440dabb8e83e..9a83f149ac85525b821a4d24ba5387b93b3229d6 100644 (file)
@@ -2889,7 +2889,6 @@ extern int ext4_map_blocks(handle_t *handle, struct inode *inode,
                           struct ext4_map_blocks *map, int flags);
 extern int ext4_ext_calc_metadata_amount(struct inode *inode,
                                         ext4_lblk_t lblocks);
-extern int ext4_extent_tree_init(handle_t *, struct inode *);
 extern int ext4_ext_calc_credits_for_single_extent(struct inode *inode,
                                                   int num,
                                                   struct ext4_ext_path *path);
index 3445035c7e015e9460f2cd3f74b698bf823cabb6..d4184318181878b023931078377ae17c9568a208 100644 (file)
@@ -87,6 +87,12 @@ int __ext4_journal_stop(const char *where, unsigned int line, handle_t *handle)
                ext4_put_nojournal(handle);
                return 0;
        }
+
+       if (!handle->h_transaction) {
+               err = jbd2_journal_stop(handle);
+               return handle->h_err ? handle->h_err : err;
+       }
+
        sb = handle->h_transaction->t_journal->j_private;
        err = handle->h_err;
        rc = jbd2_journal_stop(handle);
index d74e08029643d3e5eeb1f8a14d9a78c290549863..e003a1e81dc351c76465908bec21702ecc6d4b91 100644 (file)
@@ -377,7 +377,7 @@ static int ext4_valid_extent(struct inode *inode, struct ext4_extent *ext)
        ext4_lblk_t lblock = le32_to_cpu(ext->ee_block);
        ext4_lblk_t last = lblock + len - 1;
 
-       if (lblock > last)
+       if (len == 0 || lblock > last)
                return 0;
        return ext4_data_block_valid(EXT4_SB(inode->i_sb), block, len);
 }
@@ -5396,6 +5396,14 @@ int ext4_collapse_range(struct inode *inode, loff_t offset, loff_t len)
        loff_t new_size, ioffset;
        int ret;
 
+       /*
+        * We need to test this early because xfstests assumes that a
+        * collapse range of (0, 1) will return EOPNOTSUPP if the file
+        * system does not support collapse range.
+        */
+       if (!ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))
+               return -EOPNOTSUPP;
+
        /* Collapse range works only on fs block size aligned offsets. */
        if (offset & (EXT4_CLUSTER_SIZE(sb) - 1) ||
            len & (EXT4_CLUSTER_SIZE(sb) - 1))
index 55b187c3bac1f1626cf0267734aa805b6f9a1263..0554b0b5957bb5db223534f2116d5eea18eae2d4 100644 (file)
@@ -4345,7 +4345,7 @@ static void ext4_update_other_inodes_time(struct super_block *sb,
        int inode_size = EXT4_INODE_SIZE(sb);
 
        oi.orig_ino = orig_ino;
-       ino = orig_ino & ~(inodes_per_block - 1);
+       ino = (orig_ino & ~(inodes_per_block - 1)) + 1;
        for (i = 0; i < inodes_per_block; i++, ino++, buf += inode_size) {
                if (ino == orig_ino)
                        continue;
index f06d0589ddba5db7226a38a6e0de3ef2cdee48d9..ca9d4a2fed415649cd9744fdac2a1e8bdfa1631a 100644 (file)
@@ -294,6 +294,8 @@ static void __save_error_info(struct super_block *sb, const char *func,
        struct ext4_super_block *es = EXT4_SB(sb)->s_es;
 
        EXT4_SB(sb)->s_mount_state |= EXT4_ERROR_FS;
+       if (bdev_read_only(sb->s_bdev))
+               return;
        es->s_state |= cpu_to_le16(EXT4_ERROR_FS);
        es->s_last_error_time = cpu_to_le32(get_seconds());
        strncpy(es->s_last_error_func, func, sizeof(es->s_last_error_func));
index ef263174acd23a88f2a110b80a67afc2fab2ddc0..07d8d8f52faf50d027f2f90a1699c7afa274aa34 100644 (file)
@@ -581,7 +581,7 @@ static int hostfs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
        if (name == NULL)
                goto out_put;
 
-       fd = file_create(name, mode & S_IFMT);
+       fd = file_create(name, mode & 0777);
        if (fd < 0)
                error = fd;
        else
index b5128c6e63ad6644d19bf861a062d63f48265a4d..a9079d035ae59d9a6983bcaa79625ce5f0e5c343 100644 (file)
@@ -842,15 +842,23 @@ static int scan_revoke_records(journal_t *journal, struct buffer_head *bh,
 {
        jbd2_journal_revoke_header_t *header;
        int offset, max;
+       int csum_size = 0;
+       __u32 rcount;
        int record_len = 4;
 
        header = (jbd2_journal_revoke_header_t *) bh->b_data;
        offset = sizeof(jbd2_journal_revoke_header_t);
-       max = be32_to_cpu(header->r_count);
+       rcount = be32_to_cpu(header->r_count);
 
        if (!jbd2_revoke_block_csum_verify(journal, header))
                return -EINVAL;
 
+       if (jbd2_journal_has_csum_v2or3(journal))
+               csum_size = sizeof(struct jbd2_journal_revoke_tail);
+       if (rcount > journal->j_blocksize - csum_size)
+               return -EINVAL;
+       max = rcount;
+
        if (JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_64BIT))
                record_len = 8;
 
index c6cbaef2bda1498d8f2e00eeca30a40c8a462361..14214da80eb8ea5d781389ed5ff3b1e373f4e7b4 100644 (file)
@@ -577,7 +577,7 @@ static void write_one_revoke_record(journal_t *journal,
 {
        int csum_size = 0;
        struct buffer_head *descriptor;
-       int offset;
+       int sz, offset;
        journal_header_t *header;
 
        /* If we are already aborting, this all becomes a noop.  We
@@ -594,9 +594,14 @@ static void write_one_revoke_record(journal_t *journal,
        if (jbd2_journal_has_csum_v2or3(journal))
                csum_size = sizeof(struct jbd2_journal_revoke_tail);
 
+       if (JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_64BIT))
+               sz = 8;
+       else
+               sz = 4;
+
        /* Make sure we have a descriptor with space left for the record */
        if (descriptor) {
-               if (offset >= journal->j_blocksize - csum_size) {
+               if (offset + sz > journal->j_blocksize - csum_size) {
                        flush_descriptor(journal, descriptor, offset, write_op);
                        descriptor = NULL;
                }
@@ -619,16 +624,13 @@ static void write_one_revoke_record(journal_t *journal,
                *descriptorp = descriptor;
        }
 
-       if (JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_64BIT)) {
+       if (JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_64BIT))
                * ((__be64 *)(&descriptor->b_data[offset])) =
                        cpu_to_be64(record->blocknr);
-               offset += 8;
-
-       } else {
+       else
                * ((__be32 *)(&descriptor->b_data[offset])) =
                        cpu_to_be32(record->blocknr);
-               offset += 4;
-       }
+       offset += sz;
 
        *offsetp = offset;
 }
index 5f09370c90a8199647a87ef7cb6a5cfdba113d2b..ff2f2e6ad3114664cbcd80c3812b6b875f64807b 100644 (file)
@@ -551,7 +551,6 @@ int jbd2_journal_extend(handle_t *handle, int nblocks)
        int result;
        int wanted;
 
-       WARN_ON(!transaction);
        if (is_handle_aborted(handle))
                return -EROFS;
        journal = transaction->t_journal;
@@ -627,7 +626,6 @@ int jbd2__journal_restart(handle_t *handle, int nblocks, gfp_t gfp_mask)
        tid_t           tid;
        int             need_to_start, ret;
 
-       WARN_ON(!transaction);
        /* If we've had an abort of any type, don't even think about
         * actually doing the restart! */
        if (is_handle_aborted(handle))
@@ -785,7 +783,6 @@ do_get_write_access(handle_t *handle, struct journal_head *jh,
        int need_copy = 0;
        unsigned long start_lock, time_lock;
 
-       WARN_ON(!transaction);
        if (is_handle_aborted(handle))
                return -EROFS;
        journal = transaction->t_journal;
@@ -1051,7 +1048,6 @@ int jbd2_journal_get_create_access(handle_t *handle, struct buffer_head *bh)
        int err;
 
        jbd_debug(5, "journal_head %p\n", jh);
-       WARN_ON(!transaction);
        err = -EROFS;
        if (is_handle_aborted(handle))
                goto out;
@@ -1266,7 +1262,6 @@ int jbd2_journal_dirty_metadata(handle_t *handle, struct buffer_head *bh)
        struct journal_head *jh;
        int ret = 0;
 
-       WARN_ON(!transaction);
        if (is_handle_aborted(handle))
                return -EROFS;
        journal = transaction->t_journal;
@@ -1397,7 +1392,6 @@ int jbd2_journal_forget (handle_t *handle, struct buffer_head *bh)
        int err = 0;
        int was_modified = 0;
 
-       WARN_ON(!transaction);
        if (is_handle_aborted(handle))
                return -EROFS;
        journal = transaction->t_journal;
@@ -1530,8 +1524,22 @@ int jbd2_journal_stop(handle_t *handle)
        tid_t tid;
        pid_t pid;
 
-       if (!transaction)
-               goto free_and_exit;
+       if (!transaction) {
+               /*
+                * Handle is already detached from the transaction so
+                * there is nothing to do other than decrease a refcount,
+                * or free the handle if refcount drops to zero
+                */
+               if (--handle->h_ref > 0) {
+                       jbd_debug(4, "h_ref %d -> %d\n", handle->h_ref + 1,
+                                                        handle->h_ref);
+                       return err;
+               } else {
+                       if (handle->h_rsv_handle)
+                               jbd2_free_handle(handle->h_rsv_handle);
+                       goto free_and_exit;
+               }
+       }
        journal = transaction->t_journal;
 
        J_ASSERT(journal_current_handle() == handle);
@@ -2373,7 +2381,6 @@ int jbd2_journal_file_inode(handle_t *handle, struct jbd2_inode *jinode)
        transaction_t *transaction = handle->h_transaction;
        journal_t *journal;
 
-       WARN_ON(!transaction);
        if (is_handle_aborted(handle))
                return -EROFS;
        journal = transaction->t_journal;
index f131fc23ffc4c18f03a9764973fa998bf0e5f79e..fffca9517321c88ee1e0128b864b257c56e2350d 100644 (file)
@@ -518,7 +518,14 @@ static struct kernfs_node *__kernfs_new_node(struct kernfs_root *root,
        if (!kn)
                goto err_out1;
 
-       ret = ida_simple_get(&root->ino_ida, 1, 0, GFP_KERNEL);
+       /*
+        * If the ino of the sysfs entry created for a kmem cache gets
+        * allocated from an ida layer, which is accounted to the memcg that
+        * owns the cache, the memcg will get pinned forever. So do not account
+        * ino ida allocations.
+        */
+       ret = ida_simple_get(&root->ino_ida, 1, 0,
+                            GFP_KERNEL | __GFP_NOACCOUNT);
        if (ret < 0)
                goto err_out2;
        kn->ino = ret;
index 45b35b9b1e36a1213a2c2736e4ae551dcd0d8848..55e1e3af23a3d3f2313f977b185eb8c3f8ccbc6d 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/mm.h>
 #include <linux/delay.h>
 #include <linux/errno.h>
+#include <linux/file.h>
 #include <linux/string.h>
 #include <linux/ratelimit.h>
 #include <linux/printk.h>
@@ -5604,6 +5605,7 @@ static struct nfs4_lockdata *nfs4_alloc_lockdata(struct file_lock *fl,
        p->server = server;
        atomic_inc(&lsp->ls_count);
        p->ctx = get_nfs_open_context(ctx);
+       get_file(fl->fl_file);
        memcpy(&p->fl, fl, sizeof(p->fl));
        return p;
 out_free_seqid:
@@ -5716,6 +5718,7 @@ static void nfs4_lock_release(void *calldata)
                nfs_free_seqid(data->arg.lock_seqid);
        nfs4_put_lock_state(data->lsp);
        put_nfs_open_context(data->ctx);
+       fput(data->fl.fl_file);
        kfree(data);
        dprintk("%s: done!\n", __func__);
 }
index d12a4be613a5ced58599f8095822f4659b32f9a4..dfc19f1575a19d00bee1b0aeef6575e4416a9ef9 100644 (file)
@@ -1845,12 +1845,15 @@ int nfs_wb_all(struct inode *inode)
        trace_nfs_writeback_inode_enter(inode);
 
        ret = filemap_write_and_wait(inode->i_mapping);
-       if (!ret) {
-               ret = nfs_commit_inode(inode, FLUSH_SYNC);
-               if (!ret)
-                       pnfs_sync_inode(inode, true);
-       }
+       if (ret)
+               goto out;
+       ret = nfs_commit_inode(inode, FLUSH_SYNC);
+       if (ret < 0)
+               goto out;
+       pnfs_sync_inode(inode, true);
+       ret = 0;
 
+out:
        trace_nfs_writeback_inode_exit(inode, ret);
        return ret;
 }
index 03d647bf195d78bb3d6611553c9ad3e6fa4385a2..cdefaa331a0719e88df91ef7c04c32706ae199a1 100644 (file)
@@ -181,6 +181,17 @@ nfsd4_block_proc_layoutcommit(struct inode *inode,
 }
 
 const struct nfsd4_layout_ops bl_layout_ops = {
+       /*
+        * Pretend that we send notification to the client.  This is a blatant
+        * lie to force recent Linux clients to cache our device IDs.
+        * We rarely ever change the device ID, so the harm of leaking deviceids
+        * for a while isn't too bad.  Unfortunately RFC5661 is a complete mess
+        * in this regard, but I filed errata 4119 for this a while ago, and
+        * hopefully the Linux client will eventually start caching deviceids
+        * without this again.
+        */
+       .notify_types           =
+                       NOTIFY_DEVICEID4_DELETE | NOTIFY_DEVICEID4_CHANGE,
        .proc_getdeviceinfo     = nfsd4_block_proc_getdeviceinfo,
        .encode_getdeviceinfo   = nfsd4_block_encode_getdeviceinfo,
        .proc_layoutget         = nfsd4_block_proc_layoutget,
index 58277859a467d878cf5cd5d947d7361f8b3396cf..5694cfb7a47b73a0d7128ed987cf1aaba6ea8859 100644 (file)
@@ -224,7 +224,7 @@ static int nfs_cb_stat_to_errno(int status)
 }
 
 static int decode_cb_op_status(struct xdr_stream *xdr, enum nfs_opnum4 expected,
-                              enum nfsstat4 *status)
+                              int *status)
 {
        __be32 *p;
        u32 op;
@@ -235,7 +235,7 @@ static int decode_cb_op_status(struct xdr_stream *xdr, enum nfs_opnum4 expected,
        op = be32_to_cpup(p++);
        if (unlikely(op != expected))
                goto out_unexpected;
-       *status = be32_to_cpup(p);
+       *status = nfs_cb_stat_to_errno(be32_to_cpup(p));
        return 0;
 out_overflow:
        print_overflow_msg(__func__, xdr);
@@ -446,22 +446,16 @@ static int decode_cb_sequence4resok(struct xdr_stream *xdr,
 static int decode_cb_sequence4res(struct xdr_stream *xdr,
                                  struct nfsd4_callback *cb)
 {
-       enum nfsstat4 nfserr;
        int status;
 
        if (cb->cb_minorversion == 0)
                return 0;
 
-       status = decode_cb_op_status(xdr, OP_CB_SEQUENCE, &nfserr);
-       if (unlikely(status))
-               goto out;
-       if (unlikely(nfserr != NFS4_OK))
-               goto out_default;
-       status = decode_cb_sequence4resok(xdr, cb);
-out:
-       return status;
-out_default:
-       return nfs_cb_stat_to_errno(nfserr);
+       status = decode_cb_op_status(xdr, OP_CB_SEQUENCE, &cb->cb_status);
+       if (unlikely(status || cb->cb_status))
+               return status;
+
+       return decode_cb_sequence4resok(xdr, cb);
 }
 
 /*
@@ -524,26 +518,19 @@ static int nfs4_xdr_dec_cb_recall(struct rpc_rqst *rqstp,
                                  struct nfsd4_callback *cb)
 {
        struct nfs4_cb_compound_hdr hdr;
-       enum nfsstat4 nfserr;
        int status;
 
        status = decode_cb_compound4res(xdr, &hdr);
        if (unlikely(status))
-               goto out;
+               return status;
 
        if (cb != NULL) {
                status = decode_cb_sequence4res(xdr, cb);
-               if (unlikely(status))
-                       goto out;
+               if (unlikely(status || cb->cb_status))
+                       return status;
        }
 
-       status = decode_cb_op_status(xdr, OP_CB_RECALL, &nfserr);
-       if (unlikely(status))
-               goto out;
-       if (unlikely(nfserr != NFS4_OK))
-               status = nfs_cb_stat_to_errno(nfserr);
-out:
-       return status;
+       return decode_cb_op_status(xdr, OP_CB_RECALL, &cb->cb_status);
 }
 
 #ifdef CONFIG_NFSD_PNFS
@@ -621,24 +608,18 @@ static int nfs4_xdr_dec_cb_layout(struct rpc_rqst *rqstp,
                                  struct nfsd4_callback *cb)
 {
        struct nfs4_cb_compound_hdr hdr;
-       enum nfsstat4 nfserr;
        int status;
 
        status = decode_cb_compound4res(xdr, &hdr);
        if (unlikely(status))
-               goto out;
+               return status;
+
        if (cb) {
                status = decode_cb_sequence4res(xdr, cb);
-               if (unlikely(status))
-                       goto out;
+               if (unlikely(status || cb->cb_status))
+                       return status;
        }
-       status = decode_cb_op_status(xdr, OP_CB_LAYOUTRECALL, &nfserr);
-       if (unlikely(status))
-               goto out;
-       if (unlikely(nfserr != NFS4_OK))
-               status = nfs_cb_stat_to_errno(nfserr);
-out:
-       return status;
+       return decode_cb_op_status(xdr, OP_CB_LAYOUTRECALL, &cb->cb_status);
 }
 #endif /* CONFIG_NFSD_PNFS */
 
@@ -898,13 +879,6 @@ static void nfsd4_cb_prepare(struct rpc_task *task, void *calldata)
                if (!nfsd41_cb_get_slot(clp, task))
                        return;
        }
-       spin_lock(&clp->cl_lock);
-       if (list_empty(&cb->cb_per_client)) {
-               /* This is the first call, not a restart */
-               cb->cb_done = false;
-               list_add(&cb->cb_per_client, &clp->cl_callbacks);
-       }
-       spin_unlock(&clp->cl_lock);
        rpc_call_start(task);
 }
 
@@ -918,22 +892,33 @@ static void nfsd4_cb_done(struct rpc_task *task, void *calldata)
 
        if (clp->cl_minorversion) {
                /* No need for lock, access serialized in nfsd4_cb_prepare */
-               ++clp->cl_cb_session->se_cb_seq_nr;
+               if (!task->tk_status)
+                       ++clp->cl_cb_session->se_cb_seq_nr;
                clear_bit(0, &clp->cl_cb_slot_busy);
                rpc_wake_up_next(&clp->cl_cb_waitq);
                dprintk("%s: freed slot, new seqid=%d\n", __func__,
                        clp->cl_cb_session->se_cb_seq_nr);
        }
 
-       if (clp->cl_cb_client != task->tk_client) {
-               /* We're shutting down or changing cl_cb_client; leave
-                * it to nfsd4_process_cb_update to restart the call if
-                * necessary. */
+       /*
+        * If the backchannel connection was shut down while this
+        * task was queued, we need to resubmit it after setting up
+        * a new backchannel connection.
+        *
+        * Note that if we lost our callback connection permanently
+        * the submission code will error out, so we don't need to
+        * handle that case here.
+        */
+       if (task->tk_flags & RPC_TASK_KILLED) {
+               task->tk_status = 0;
+               cb->cb_need_restart = true;
                return;
        }
 
-       if (cb->cb_done)
-               return;
+       if (cb->cb_status) {
+               WARN_ON_ONCE(task->tk_status);
+               task->tk_status = cb->cb_status;
+       }
 
        switch (cb->cb_ops->done(cb, task)) {
        case 0:
@@ -949,21 +934,17 @@ static void nfsd4_cb_done(struct rpc_task *task, void *calldata)
        default:
                BUG();
        }
-       cb->cb_done = true;
 }
 
 static void nfsd4_cb_release(void *calldata)
 {
        struct nfsd4_callback *cb = calldata;
-       struct nfs4_client *clp = cb->cb_clp;
-
-       if (cb->cb_done) {
-               spin_lock(&clp->cl_lock);
-               list_del(&cb->cb_per_client);
-               spin_unlock(&clp->cl_lock);
 
+       if (cb->cb_need_restart)
+               nfsd4_run_cb(cb);
+       else
                cb->cb_ops->release(cb);
-       }
+
 }
 
 static const struct rpc_call_ops nfsd4_cb_ops = {
@@ -1058,9 +1039,6 @@ static void nfsd4_process_cb_update(struct nfsd4_callback *cb)
                nfsd4_mark_cb_down(clp, err);
                return;
        }
-       /* Yay, the callback channel's back! Restart any callbacks: */
-       list_for_each_entry(cb, &clp->cl_callbacks, cb_per_client)
-               queue_work(callback_wq, &cb->cb_work);
 }
 
 static void
@@ -1071,8 +1049,12 @@ nfsd4_run_cb_work(struct work_struct *work)
        struct nfs4_client *clp = cb->cb_clp;
        struct rpc_clnt *clnt;
 
-       if (cb->cb_ops && cb->cb_ops->prepare)
-               cb->cb_ops->prepare(cb);
+       if (cb->cb_need_restart) {
+               cb->cb_need_restart = false;
+       } else {
+               if (cb->cb_ops && cb->cb_ops->prepare)
+                       cb->cb_ops->prepare(cb);
+       }
 
        if (clp->cl_flags & NFSD4_CLIENT_CB_FLAG_MASK)
                nfsd4_process_cb_update(cb);
@@ -1084,6 +1066,15 @@ nfsd4_run_cb_work(struct work_struct *work)
                        cb->cb_ops->release(cb);
                return;
        }
+
+       /*
+        * Don't send probe messages for 4.1 or later.
+        */
+       if (!cb->cb_ops && clp->cl_minorversion) {
+               clp->cl_cb_state = NFSD4_CB_UP;
+               return;
+       }
+
        cb->cb_msg.rpc_cred = clp->cl_cb_cred;
        rpc_call_async(clnt, &cb->cb_msg, RPC_TASK_SOFT | RPC_TASK_SOFTCONN,
                        cb->cb_ops ? &nfsd4_cb_ops : &nfsd4_cb_probe_ops, cb);
@@ -1098,8 +1089,8 @@ void nfsd4_init_cb(struct nfsd4_callback *cb, struct nfs4_client *clp,
        cb->cb_msg.rpc_resp = cb;
        cb->cb_ops = ops;
        INIT_WORK(&cb->cb_work, nfsd4_run_cb_work);
-       INIT_LIST_HEAD(&cb->cb_per_client);
-       cb->cb_done = true;
+       cb->cb_status = 0;
+       cb->cb_need_restart = false;
 }
 
 void nfsd4_run_cb(struct nfsd4_callback *cb)
index 38f2d7abe3a707061c3f860ce8042649bf5109eb..039f9c8a95e84289c7296e9b78973efbea9d6e5a 100644 (file)
@@ -94,6 +94,7 @@ static struct kmem_cache *lockowner_slab;
 static struct kmem_cache *file_slab;
 static struct kmem_cache *stateid_slab;
 static struct kmem_cache *deleg_slab;
+static struct kmem_cache *odstate_slab;
 
 static void free_session(struct nfsd4_session *);
 
@@ -281,6 +282,7 @@ put_nfs4_file(struct nfs4_file *fi)
        if (atomic_dec_and_lock(&fi->fi_ref, &state_lock)) {
                hlist_del_rcu(&fi->fi_hash);
                spin_unlock(&state_lock);
+               WARN_ON_ONCE(!list_empty(&fi->fi_clnt_odstate));
                WARN_ON_ONCE(!list_empty(&fi->fi_delegations));
                call_rcu(&fi->fi_rcu, nfsd4_free_file_rcu);
        }
@@ -471,6 +473,86 @@ static void nfs4_file_put_access(struct nfs4_file *fp, u32 access)
                __nfs4_file_put_access(fp, O_RDONLY);
 }
 
+/*
+ * Allocate a new open/delegation state counter. This is needed for
+ * pNFS for proper return on close semantics.
+ *
+ * Note that we only allocate it for pNFS-enabled exports, otherwise
+ * all pointers to struct nfs4_clnt_odstate are always NULL.
+ */
+static struct nfs4_clnt_odstate *
+alloc_clnt_odstate(struct nfs4_client *clp)
+{
+       struct nfs4_clnt_odstate *co;
+
+       co = kmem_cache_zalloc(odstate_slab, GFP_KERNEL);
+       if (co) {
+               co->co_client = clp;
+               atomic_set(&co->co_odcount, 1);
+       }
+       return co;
+}
+
+static void
+hash_clnt_odstate_locked(struct nfs4_clnt_odstate *co)
+{
+       struct nfs4_file *fp = co->co_file;
+
+       lockdep_assert_held(&fp->fi_lock);
+       list_add(&co->co_perfile, &fp->fi_clnt_odstate);
+}
+
+static inline void
+get_clnt_odstate(struct nfs4_clnt_odstate *co)
+{
+       if (co)
+               atomic_inc(&co->co_odcount);
+}
+
+static void
+put_clnt_odstate(struct nfs4_clnt_odstate *co)
+{
+       struct nfs4_file *fp;
+
+       if (!co)
+               return;
+
+       fp = co->co_file;
+       if (atomic_dec_and_lock(&co->co_odcount, &fp->fi_lock)) {
+               list_del(&co->co_perfile);
+               spin_unlock(&fp->fi_lock);
+
+               nfsd4_return_all_file_layouts(co->co_client, fp);
+               kmem_cache_free(odstate_slab, co);
+       }
+}
+
+static struct nfs4_clnt_odstate *
+find_or_hash_clnt_odstate(struct nfs4_file *fp, struct nfs4_clnt_odstate *new)
+{
+       struct nfs4_clnt_odstate *co;
+       struct nfs4_client *cl;
+
+       if (!new)
+               return NULL;
+
+       cl = new->co_client;
+
+       spin_lock(&fp->fi_lock);
+       list_for_each_entry(co, &fp->fi_clnt_odstate, co_perfile) {
+               if (co->co_client == cl) {
+                       get_clnt_odstate(co);
+                       goto out;
+               }
+       }
+       co = new;
+       co->co_file = fp;
+       hash_clnt_odstate_locked(new);
+out:
+       spin_unlock(&fp->fi_lock);
+       return co;
+}
+
 struct nfs4_stid *nfs4_alloc_stid(struct nfs4_client *cl,
                                         struct kmem_cache *slab)
 {
@@ -606,7 +688,8 @@ static void block_delegations(struct knfsd_fh *fh)
 }
 
 static struct nfs4_delegation *
-alloc_init_deleg(struct nfs4_client *clp, struct svc_fh *current_fh)
+alloc_init_deleg(struct nfs4_client *clp, struct svc_fh *current_fh,
+                struct nfs4_clnt_odstate *odstate)
 {
        struct nfs4_delegation *dp;
        long n;
@@ -631,6 +714,8 @@ alloc_init_deleg(struct nfs4_client *clp, struct svc_fh *current_fh)
        INIT_LIST_HEAD(&dp->dl_perfile);
        INIT_LIST_HEAD(&dp->dl_perclnt);
        INIT_LIST_HEAD(&dp->dl_recall_lru);
+       dp->dl_clnt_odstate = odstate;
+       get_clnt_odstate(odstate);
        dp->dl_type = NFS4_OPEN_DELEGATE_READ;
        dp->dl_retries = 1;
        nfsd4_init_cb(&dp->dl_recall, dp->dl_stid.sc_client,
@@ -714,6 +799,7 @@ static void destroy_delegation(struct nfs4_delegation *dp)
        spin_lock(&state_lock);
        unhash_delegation_locked(dp);
        spin_unlock(&state_lock);
+       put_clnt_odstate(dp->dl_clnt_odstate);
        nfs4_put_deleg_lease(dp->dl_stid.sc_file);
        nfs4_put_stid(&dp->dl_stid);
 }
@@ -724,6 +810,7 @@ static void revoke_delegation(struct nfs4_delegation *dp)
 
        WARN_ON(!list_empty(&dp->dl_recall_lru));
 
+       put_clnt_odstate(dp->dl_clnt_odstate);
        nfs4_put_deleg_lease(dp->dl_stid.sc_file);
 
        if (clp->cl_minorversion == 0)
@@ -933,6 +1020,7 @@ static void nfs4_free_ol_stateid(struct nfs4_stid *stid)
 {
        struct nfs4_ol_stateid *stp = openlockstateid(stid);
 
+       put_clnt_odstate(stp->st_clnt_odstate);
        release_all_access(stp);
        if (stp->st_stateowner)
                nfs4_put_stateowner(stp->st_stateowner);
@@ -1538,7 +1626,6 @@ static struct nfs4_client *alloc_client(struct xdr_netobj name)
        INIT_LIST_HEAD(&clp->cl_openowners);
        INIT_LIST_HEAD(&clp->cl_delegations);
        INIT_LIST_HEAD(&clp->cl_lru);
-       INIT_LIST_HEAD(&clp->cl_callbacks);
        INIT_LIST_HEAD(&clp->cl_revoked);
 #ifdef CONFIG_NFSD_PNFS
        INIT_LIST_HEAD(&clp->cl_lo_states);
@@ -1634,6 +1721,7 @@ __destroy_client(struct nfs4_client *clp)
        while (!list_empty(&reaplist)) {
                dp = list_entry(reaplist.next, struct nfs4_delegation, dl_recall_lru);
                list_del_init(&dp->dl_recall_lru);
+               put_clnt_odstate(dp->dl_clnt_odstate);
                nfs4_put_deleg_lease(dp->dl_stid.sc_file);
                nfs4_put_stid(&dp->dl_stid);
        }
@@ -3057,6 +3145,7 @@ static void nfsd4_init_file(struct knfsd_fh *fh, unsigned int hashval,
        spin_lock_init(&fp->fi_lock);
        INIT_LIST_HEAD(&fp->fi_stateids);
        INIT_LIST_HEAD(&fp->fi_delegations);
+       INIT_LIST_HEAD(&fp->fi_clnt_odstate);
        fh_copy_shallow(&fp->fi_fhandle, fh);
        fp->fi_deleg_file = NULL;
        fp->fi_had_conflict = false;
@@ -3073,6 +3162,7 @@ static void nfsd4_init_file(struct knfsd_fh *fh, unsigned int hashval,
 void
 nfsd4_free_slabs(void)
 {
+       kmem_cache_destroy(odstate_slab);
        kmem_cache_destroy(openowner_slab);
        kmem_cache_destroy(lockowner_slab);
        kmem_cache_destroy(file_slab);
@@ -3103,8 +3193,14 @@ nfsd4_init_slabs(void)
                        sizeof(struct nfs4_delegation), 0, 0, NULL);
        if (deleg_slab == NULL)
                goto out_free_stateid_slab;
+       odstate_slab = kmem_cache_create("nfsd4_odstate",
+                       sizeof(struct nfs4_clnt_odstate), 0, 0, NULL);
+       if (odstate_slab == NULL)
+               goto out_free_deleg_slab;
        return 0;
 
+out_free_deleg_slab:
+       kmem_cache_destroy(deleg_slab);
 out_free_stateid_slab:
        kmem_cache_destroy(stateid_slab);
 out_free_file_slab:
@@ -3581,6 +3677,14 @@ nfsd4_process_open1(struct nfsd4_compound_state *cstate,
        open->op_stp = nfs4_alloc_open_stateid(clp);
        if (!open->op_stp)
                return nfserr_jukebox;
+
+       if (nfsd4_has_session(cstate) &&
+           (cstate->current_fh.fh_export->ex_flags & NFSEXP_PNFS)) {
+               open->op_odstate = alloc_clnt_odstate(clp);
+               if (!open->op_odstate)
+                       return nfserr_jukebox;
+       }
+
        return nfs_ok;
 }
 
@@ -3869,7 +3973,7 @@ static int nfs4_setlease(struct nfs4_delegation *dp)
 
 static struct nfs4_delegation *
 nfs4_set_delegation(struct nfs4_client *clp, struct svc_fh *fh,
-                   struct nfs4_file *fp)
+                   struct nfs4_file *fp, struct nfs4_clnt_odstate *odstate)
 {
        int status;
        struct nfs4_delegation *dp;
@@ -3877,7 +3981,7 @@ nfs4_set_delegation(struct nfs4_client *clp, struct svc_fh *fh,
        if (fp->fi_had_conflict)
                return ERR_PTR(-EAGAIN);
 
-       dp = alloc_init_deleg(clp, fh);
+       dp = alloc_init_deleg(clp, fh, odstate);
        if (!dp)
                return ERR_PTR(-ENOMEM);
 
@@ -3903,6 +4007,7 @@ nfs4_set_delegation(struct nfs4_client *clp, struct svc_fh *fh,
        spin_unlock(&state_lock);
 out:
        if (status) {
+               put_clnt_odstate(dp->dl_clnt_odstate);
                nfs4_put_stid(&dp->dl_stid);
                return ERR_PTR(status);
        }
@@ -3980,7 +4085,7 @@ nfs4_open_delegation(struct svc_fh *fh, struct nfsd4_open *open,
                default:
                        goto out_no_deleg;
        }
-       dp = nfs4_set_delegation(clp, fh, stp->st_stid.sc_file);
+       dp = nfs4_set_delegation(clp, fh, stp->st_stid.sc_file, stp->st_clnt_odstate);
        if (IS_ERR(dp))
                goto out_no_deleg;
 
@@ -4069,6 +4174,11 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf
                        release_open_stateid(stp);
                        goto out;
                }
+
+               stp->st_clnt_odstate = find_or_hash_clnt_odstate(fp,
+                                                       open->op_odstate);
+               if (stp->st_clnt_odstate == open->op_odstate)
+                       open->op_odstate = NULL;
        }
        update_stateid(&stp->st_stid.sc_stateid);
        memcpy(&open->op_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t));
@@ -4129,6 +4239,8 @@ void nfsd4_cleanup_open_state(struct nfsd4_compound_state *cstate,
                kmem_cache_free(file_slab, open->op_file);
        if (open->op_stp)
                nfs4_put_stid(&open->op_stp->st_stid);
+       if (open->op_odstate)
+               kmem_cache_free(odstate_slab, open->op_odstate);
 }
 
 __be32
@@ -4385,10 +4497,17 @@ static __be32 check_stateid_generation(stateid_t *in, stateid_t *ref, bool has_s
        return nfserr_old_stateid;
 }
 
+static __be32 nfsd4_check_openowner_confirmed(struct nfs4_ol_stateid *ols)
+{
+       if (ols->st_stateowner->so_is_open_owner &&
+           !(openowner(ols->st_stateowner)->oo_flags & NFS4_OO_CONFIRMED))
+               return nfserr_bad_stateid;
+       return nfs_ok;
+}
+
 static __be32 nfsd4_validate_stateid(struct nfs4_client *cl, stateid_t *stateid)
 {
        struct nfs4_stid *s;
-       struct nfs4_ol_stateid *ols;
        __be32 status = nfserr_bad_stateid;
 
        if (ZERO_STATEID(stateid) || ONE_STATEID(stateid))
@@ -4418,13 +4537,7 @@ static __be32 nfsd4_validate_stateid(struct nfs4_client *cl, stateid_t *stateid)
                break;
        case NFS4_OPEN_STID:
        case NFS4_LOCK_STID:
-               ols = openlockstateid(s);
-               if (ols->st_stateowner->so_is_open_owner
-                               && !(openowner(ols->st_stateowner)->oo_flags
-                                               & NFS4_OO_CONFIRMED))
-                       status = nfserr_bad_stateid;
-               else
-                       status = nfs_ok;
+               status = nfsd4_check_openowner_confirmed(openlockstateid(s));
                break;
        default:
                printk("unknown stateid type %x\n", s->sc_type);
@@ -4516,8 +4629,8 @@ nfs4_preprocess_stateid_op(struct net *net, struct nfsd4_compound_state *cstate,
                status = nfs4_check_fh(current_fh, stp);
                if (status)
                        goto out;
-               if (stp->st_stateowner->so_is_open_owner
-                   && !(openowner(stp->st_stateowner)->oo_flags & NFS4_OO_CONFIRMED))
+               status = nfsd4_check_openowner_confirmed(stp);
+               if (status)
                        goto out;
                status = nfs4_check_openmode(stp, flags);
                if (status)
@@ -4852,9 +4965,6 @@ nfsd4_close(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
        update_stateid(&stp->st_stid.sc_stateid);
        memcpy(&close->cl_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t));
 
-       nfsd4_return_all_file_layouts(stp->st_stateowner->so_client,
-                                     stp->st_stid.sc_file);
-
        nfsd4_close_open_stateid(stp);
 
        /* put reference from nfs4_preprocess_seqid_op */
@@ -6488,6 +6598,7 @@ nfs4_state_shutdown_net(struct net *net)
        list_for_each_safe(pos, next, &reaplist) {
                dp = list_entry (pos, struct nfs4_delegation, dl_recall_lru);
                list_del_init(&dp->dl_recall_lru);
+               put_clnt_odstate(dp->dl_clnt_odstate);
                nfs4_put_deleg_lease(dp->dl_stid.sc_file);
                nfs4_put_stid(&dp->dl_stid);
        }
index 4f3bfeb1176662ce5c7eb6f59f9440c95c8cf68e..dbc4f85a500825a2c80b21a9a92b52ff1631b8fb 100644 (file)
@@ -63,12 +63,12 @@ typedef struct {
 
 struct nfsd4_callback {
        struct nfs4_client *cb_clp;
-       struct list_head cb_per_client;
        u32 cb_minorversion;
        struct rpc_message cb_msg;
        struct nfsd4_callback_ops *cb_ops;
        struct work_struct cb_work;
-       bool cb_done;
+       int cb_status;
+       bool cb_need_restart;
 };
 
 struct nfsd4_callback_ops {
@@ -126,6 +126,7 @@ struct nfs4_delegation {
        struct list_head        dl_perfile;
        struct list_head        dl_perclnt;
        struct list_head        dl_recall_lru;  /* delegation recalled */
+       struct nfs4_clnt_odstate *dl_clnt_odstate;
        u32                     dl_type;
        time_t                  dl_time;
 /* For recall: */
@@ -332,7 +333,6 @@ struct nfs4_client {
        int                     cl_cb_state;
        struct nfsd4_callback   cl_cb_null;
        struct nfsd4_session    *cl_cb_session;
-       struct list_head        cl_callbacks; /* list of in-progress callbacks */
 
        /* for all client information that callback code might need: */
        spinlock_t              cl_lock;
@@ -464,6 +464,17 @@ static inline struct nfs4_lockowner * lockowner(struct nfs4_stateowner *so)
        return container_of(so, struct nfs4_lockowner, lo_owner);
 }
 
+/*
+ * Per-client state indicating no. of opens and outstanding delegations
+ * on a file from a particular client.'od' stands for 'open & delegation'
+ */
+struct nfs4_clnt_odstate {
+       struct nfs4_client      *co_client;
+       struct nfs4_file        *co_file;
+       struct list_head        co_perfile;
+       atomic_t                co_odcount;
+};
+
 /*
  * nfs4_file: a file opened by some number of (open) nfs4_stateowners.
  *
@@ -485,6 +496,7 @@ struct nfs4_file {
                struct list_head        fi_delegations;
                struct rcu_head         fi_rcu;
        };
+       struct list_head        fi_clnt_odstate;
        /* One each for O_RDONLY, O_WRONLY, O_RDWR: */
        struct file *           fi_fds[3];
        /*
@@ -526,6 +538,7 @@ struct nfs4_ol_stateid {
        struct list_head              st_perstateowner;
        struct list_head              st_locks;
        struct nfs4_stateowner      * st_stateowner;
+       struct nfs4_clnt_odstate    * st_clnt_odstate;
        unsigned char                 st_access_bmap;
        unsigned char                 st_deny_bmap;
        struct nfs4_ol_stateid         * st_openstp;
index f982ae84f0cd2303df5275086a3a05ce519bbd86..2f8c092be2b3344901f07f2f16e0ee239034ccdf 100644 (file)
@@ -247,6 +247,7 @@ struct nfsd4_open {
        struct nfs4_openowner *op_openowner; /* used during processing */
        struct nfs4_file *op_file;          /* used during processing */
        struct nfs4_ol_stateid *op_stp;     /* used during processing */
+       struct nfs4_clnt_odstate *op_odstate; /* used during processing */
        struct nfs4_acl *op_acl;
        struct xdr_netobj op_label;
 };
index 24f640441bd90977a079aac782768025c68f3712..84d693d374284b580208fec3b8eb3c57bdd4195c 100644 (file)
@@ -299,6 +299,9 @@ int ovl_copy_up_one(struct dentry *parent, struct dentry *dentry,
        struct cred *override_cred;
        char *link = NULL;
 
+       if (WARN_ON(!workdir))
+               return -EROFS;
+
        ovl_path_upper(parent, &parentpath);
        upperdir = parentpath.dentry;
 
index d139405d2bfad7cfd94c735913ecebf221def5b5..692ceda3bc21f6976b65f3e2d5aa4b7ef2e9c5e8 100644 (file)
@@ -222,6 +222,9 @@ static struct dentry *ovl_clear_empty(struct dentry *dentry,
        struct kstat stat;
        int err;
 
+       if (WARN_ON(!workdir))
+               return ERR_PTR(-EROFS);
+
        err = ovl_lock_rename_workdir(workdir, upperdir);
        if (err)
                goto out;
@@ -322,6 +325,9 @@ static int ovl_create_over_whiteout(struct dentry *dentry, struct inode *inode,
        struct dentry *newdentry;
        int err;
 
+       if (WARN_ON(!workdir))
+               return -EROFS;
+
        err = ovl_lock_rename_workdir(workdir, upperdir);
        if (err)
                goto out;
@@ -506,11 +512,28 @@ static int ovl_remove_and_whiteout(struct dentry *dentry, bool is_dir)
        struct dentry *opaquedir = NULL;
        int err;
 
-       if (is_dir && OVL_TYPE_MERGE_OR_LOWER(ovl_path_type(dentry))) {
-               opaquedir = ovl_check_empty_and_clear(dentry);
-               err = PTR_ERR(opaquedir);
-               if (IS_ERR(opaquedir))
-                       goto out;
+       if (WARN_ON(!workdir))
+               return -EROFS;
+
+       if (is_dir) {
+               if (OVL_TYPE_MERGE_OR_LOWER(ovl_path_type(dentry))) {
+                       opaquedir = ovl_check_empty_and_clear(dentry);
+                       err = PTR_ERR(opaquedir);
+                       if (IS_ERR(opaquedir))
+                               goto out;
+               } else {
+                       LIST_HEAD(list);
+
+                       /*
+                        * When removing an empty opaque directory, then it
+                        * makes no sense to replace it with an exact replica of
+                        * itself.  But emptiness still needs to be checked.
+                        */
+                       err = ovl_check_empty_dir(dentry, &list);
+                       ovl_cache_free(&list);
+                       if (err)
+                               goto out;
+               }
        }
 
        err = ovl_lock_rename_workdir(workdir, upperdir);
index 5f0d1993e6e3952bda9352d231e8fce7dee838e8..bf8537c7f455207830046a50d67d394f86d37f4a 100644 (file)
@@ -529,7 +529,7 @@ static int ovl_remount(struct super_block *sb, int *flags, char *data)
 {
        struct ovl_fs *ufs = sb->s_fs_info;
 
-       if (!(*flags & MS_RDONLY) && !ufs->upper_mnt)
+       if (!(*flags & MS_RDONLY) && (!ufs->upper_mnt || !ufs->workdir))
                return -EROFS;
 
        return 0;
@@ -925,9 +925,10 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
                ufs->workdir = ovl_workdir_create(ufs->upper_mnt, workpath.dentry);
                err = PTR_ERR(ufs->workdir);
                if (IS_ERR(ufs->workdir)) {
-                       pr_err("overlayfs: failed to create directory %s/%s\n",
-                              ufs->config.workdir, OVL_WORKDIR_NAME);
-                       goto out_put_upper_mnt;
+                       pr_warn("overlayfs: failed to create directory %s/%s (errno: %i); mounting read-only\n",
+                               ufs->config.workdir, OVL_WORKDIR_NAME, -err);
+                       sb->s_flags |= MS_RDONLY;
+                       ufs->workdir = NULL;
                }
        }
 
@@ -997,7 +998,6 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
        kfree(ufs->lower_mnt);
 out_put_workdir:
        dput(ufs->workdir);
-out_put_upper_mnt:
        mntput(ufs->upper_mnt);
 out_put_lowerpath:
        for (i = 0; i < numlower; i++)
index 2dd405c9be78d474fe4c1c11a70651b6741ab396..45c39a37f9249562761dc9615ffecf12ec194846 100644 (file)
        {0x1002, 0x6658, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_BONAIRE|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x665c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_BONAIRE|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x665d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_BONAIRE|RADEON_NEW_MEMMAP}, \
+       {0x1002, 0x665f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_BONAIRE|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x6660, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_HAINAN|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x6663, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_HAINAN|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x6664, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_HAINAN|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
index 7f9a516f24dec57182f51cff3580db3904208a84..5d93a6645e88676a7d90a1ac55b5d5d6792da667 100644 (file)
@@ -821,8 +821,6 @@ extern int scsi_cmd_ioctl(struct request_queue *, struct gendisk *, fmode_t,
 extern int sg_scsi_ioctl(struct request_queue *, struct gendisk *, fmode_t,
                         struct scsi_ioctl_command __user *);
 
-extern void blk_queue_bio(struct request_queue *q, struct bio *bio);
-
 /*
  * A queue has just exitted congestion.  Note this in the global counter of
  * congested queues, and wake up anyone who was waiting for requests to be
index ae2982c0f7a60ed93339e767feaf1fc89aa02134..656da2a12ffee319f67cb744945f028599e0603c 100644 (file)
@@ -17,7 +17,7 @@
 #define PHY_ID_BCM7250                 0xae025280
 #define PHY_ID_BCM7364                 0xae025260
 #define PHY_ID_BCM7366                 0x600d8490
-#define PHY_ID_BCM7425                 0x03625e60
+#define PHY_ID_BCM7425                 0x600d86b0
 #define PHY_ID_BCM7429                 0x600d8730
 #define PHY_ID_BCM7439                 0x600d8480
 #define PHY_ID_BCM7439_2               0xae025080
index 97a9373e61e80d048ee6259eb4962bd831cac822..15928f0647e44187eb00ae7e128f4047519b093b 100644 (file)
@@ -30,6 +30,7 @@ struct vm_area_struct;
 #define ___GFP_HARDWALL                0x20000u
 #define ___GFP_THISNODE                0x40000u
 #define ___GFP_RECLAIMABLE     0x80000u
+#define ___GFP_NOACCOUNT       0x100000u
 #define ___GFP_NOTRACK         0x200000u
 #define ___GFP_NO_KSWAPD       0x400000u
 #define ___GFP_OTHER_NODE      0x800000u
@@ -87,6 +88,7 @@ struct vm_area_struct;
 #define __GFP_HARDWALL   ((__force gfp_t)___GFP_HARDWALL) /* Enforce hardwall cpuset memory allocs */
 #define __GFP_THISNODE ((__force gfp_t)___GFP_THISNODE)/* No fallback, no policies */
 #define __GFP_RECLAIMABLE ((__force gfp_t)___GFP_RECLAIMABLE) /* Page is reclaimable */
+#define __GFP_NOACCOUNT        ((__force gfp_t)___GFP_NOACCOUNT) /* Don't account to kmemcg */
 #define __GFP_NOTRACK  ((__force gfp_t)___GFP_NOTRACK)  /* Don't track with kmemcheck */
 
 #define __GFP_NO_KSWAPD        ((__force gfp_t)___GFP_NO_KSWAPD)
index 0408421d885f9433c61149e2769bdd3c08192522..0042bf330b99ffa6edd77677529753bdd00b79d4 100644 (file)
@@ -74,7 +74,7 @@ struct sensor_hub_pending {
  * @usage:             Usage id for this hub device instance.
  * @start_collection_index: Starting index for a phy type collection
  * @end_collection_index: Last index for a phy type collection
- * @mutex:             synchronizing mutex.
+ * @mutex_ptr:         synchronizing mutex pointer.
  * @pending:           Holds information of pending sync read request.
  */
 struct hid_sensor_hub_device {
@@ -84,7 +84,7 @@ struct hid_sensor_hub_device {
        u32 usage;
        int start_collection_index;
        int end_collection_index;
-       struct mutex mutex;
+       struct mutex *mutex_ptr;
        struct sensor_hub_pending pending;
 };
 
index 5fc3d1083071ca24a96a6da038324fafae997667..2b6a204bd8d40cfb74db80e19bec216795366e33 100644 (file)
@@ -166,19 +166,34 @@ static inline bool ktime_before(const ktime_t cmp1, const ktime_t cmp2)
 }
 
 #if BITS_PER_LONG < 64
-extern u64 __ktime_divns(const ktime_t kt, s64 div);
-static inline u64 ktime_divns(const ktime_t kt, s64 div)
+extern s64 __ktime_divns(const ktime_t kt, s64 div);
+static inline s64 ktime_divns(const ktime_t kt, s64 div)
 {
+       /*
+        * Negative divisors could cause an inf loop,
+        * so bug out here.
+        */
+       BUG_ON(div < 0);
        if (__builtin_constant_p(div) && !(div >> 32)) {
-               u64 ns = kt.tv64;
-               do_div(ns, div);
-               return ns;
+               s64 ns = kt.tv64;
+               u64 tmp = ns < 0 ? -ns : ns;
+
+               do_div(tmp, div);
+               return ns < 0 ? -tmp : tmp;
        } else {
                return __ktime_divns(kt, div);
        }
 }
 #else /* BITS_PER_LONG < 64 */
-# define ktime_divns(kt, div)          (u64)((kt).tv64 / (div))
+static inline s64 ktime_divns(const ktime_t kt, s64 div)
+{
+       /*
+        * 32-bit implementation cannot handle negative divisors,
+        * so catch them on 64bit as well.
+        */
+       WARN_ON(div < 0);
+       return kt.tv64 / div;
+}
 #endif
 
 static inline s64 ktime_to_us(const ktime_t kt)
index 8dad4a307bb8c4b086e8f6f62211d91d8c05a53a..28aeae46f355fdfdc96f28dd5a091dacbc85e9b8 100644 (file)
@@ -205,6 +205,7 @@ enum {
        ATA_LFLAG_SW_ACTIVITY   = (1 << 7), /* keep activity stats */
        ATA_LFLAG_NO_LPM        = (1 << 8), /* disable LPM on this link */
        ATA_LFLAG_RST_ONCE      = (1 << 9), /* limit recovery to one reset */
+       ATA_LFLAG_CHANGED       = (1 << 10), /* LPM state changed on this link */
 
        /* struct ata_port flags */
        ATA_FLAG_SLAVE_POSS     = (1 << 0), /* host supports slave dev */
@@ -309,6 +310,12 @@ enum {
         */
        ATA_TMOUT_PMP_SRST_WAIT = 5000,
 
+       /* When the LPM policy is set to ATA_LPM_MAX_POWER, there might
+        * be a spurious PHY event, so ignore the first PHY event that
+        * occurs within 10s after the policy change.
+        */
+       ATA_TMOUT_SPURIOUS_PHY  = 10000,
+
        /* ATA bus states */
        BUS_UNKNOWN             = 0,
        BUS_DMA                 = 1,
@@ -788,6 +795,8 @@ struct ata_link {
        struct ata_eh_context   eh_context;
 
        struct ata_device       device[ATA_MAX_DEVICES];
+
+       unsigned long           last_lpm_change; /* when last LPM change happened */
 };
 #define ATA_LINK_CLEAR_BEGIN           offsetof(struct ata_link, active_tag)
 #define ATA_LINK_CLEAR_END             offsetof(struct ata_link, device[0])
@@ -1201,6 +1210,7 @@ extern struct ata_device *ata_dev_pair(struct ata_device *adev);
 extern int ata_do_set_mode(struct ata_link *link, struct ata_device **r_failed_dev);
 extern void ata_scsi_port_error_handler(struct Scsi_Host *host, struct ata_port *ap);
 extern void ata_scsi_cmd_error_handler(struct Scsi_Host *host, struct ata_port *ap, struct list_head *eh_q);
+extern bool sata_lpm_ignore_phy_events(struct ata_link *link);
 
 extern int ata_cable_40wire(struct ata_port *ap);
 extern int ata_cable_80wire(struct ata_port *ap);
index 72dff5fb0d0ceaf0386d80f1cba83c7bb2c7632f..6c8918114804fda89d00ed3e6b1482539f2dd4ee 100644 (file)
@@ -463,6 +463,8 @@ memcg_kmem_newpage_charge(gfp_t gfp, struct mem_cgroup **memcg, int order)
        if (!memcg_kmem_enabled())
                return true;
 
+       if (gfp & __GFP_NOACCOUNT)
+               return true;
        /*
         * __GFP_NOFAIL allocations will move on even if charging is not
         * possible. Therefore we don't even try, and have this allocation
@@ -522,6 +524,8 @@ memcg_kmem_get_cache(struct kmem_cache *cachep, gfp_t gfp)
 {
        if (!memcg_kmem_enabled())
                return cachep;
+       if (gfp & __GFP_NOACCOUNT)
+               return cachep;
        if (gfp & __GFP_NOFAIL)
                return cachep;
        if (in_interrupt() || (!current->mm) || (current->flags & PF_KTHREAD))
index 1899c74a712791ba33f7e17f2d139da21da70c42..05b9a694e21312ad26beec7dfa0f32f719cc8c87 100644 (file)
@@ -25,7 +25,6 @@
 #ifndef _LINUX_NETDEVICE_H
 #define _LINUX_NETDEVICE_H
 
-#include <linux/pm_qos.h>
 #include <linux/timer.h>
 #include <linux/bug.h>
 #include <linux/delay.h>
@@ -1499,8 +1498,6 @@ enum netdev_priv_flags {
  *
  *     @qdisc_tx_busylock:     XXX: need comments on this one
  *
- *     @pm_qos_req:    Power Management QoS object
- *
  *     FIXME: cleanup struct net_device such that network protocol info
  *     moves out.
  */
index a947ab8b441ad968f0953e6ce15d03270325e55b..533d9807e543701099cb77dbbb780513b7d48381 100644 (file)
@@ -5,8 +5,6 @@
 #ifndef __LINUX_PLATFORM_DATA_SI5351_H__
 #define __LINUX_PLATFORM_DATA_SI5351_H__
 
-struct clk;
-
 /**
  * enum si5351_pll_src - Si5351 pll clock source
  * @SI5351_PLL_SRC_DEFAULT: default, do not change eeprom config
@@ -107,8 +105,6 @@ struct si5351_clkout_config {
  * @clkout: array of clkout configuration
  */
 struct si5351_platform_data {
-       struct clk *clk_xtal;
-       struct clk *clk_clkin;
        enum si5351_pll_src pll_src[2];
        struct si5351_clkout_config clkout[8];
 };
index dbcbcc59aa92e77de6c1c6065b403c0fa7d0dd15..843ceca9a21e5f1327fa5c82fa5f3089c5ebab23 100644 (file)
@@ -17,6 +17,7 @@
 #ifndef _LINUX_RHASHTABLE_H
 #define _LINUX_RHASHTABLE_H
 
+#include <linux/atomic.h>
 #include <linux/compiler.h>
 #include <linux/errno.h>
 #include <linux/jhash.h>
@@ -100,6 +101,7 @@ struct rhashtable;
  * @key_len: Length of key
  * @key_offset: Offset of key in struct to be hashed
  * @head_offset: Offset of rhash_head in struct to be hashed
+ * @insecure_max_entries: Maximum number of entries (may be exceeded)
  * @max_size: Maximum size while expanding
  * @min_size: Minimum size while shrinking
  * @nulls_base: Base value to generate nulls marker
@@ -115,6 +117,7 @@ struct rhashtable_params {
        size_t                  key_len;
        size_t                  key_offset;
        size_t                  head_offset;
+       unsigned int            insecure_max_entries;
        unsigned int            max_size;
        unsigned int            min_size;
        u32                     nulls_base;
@@ -286,6 +289,18 @@ static inline bool rht_grow_above_100(const struct rhashtable *ht,
                (!ht->p.max_size || tbl->size < ht->p.max_size);
 }
 
+/**
+ * rht_grow_above_max - returns true if table is above maximum
+ * @ht:                hash table
+ * @tbl:       current table
+ */
+static inline bool rht_grow_above_max(const struct rhashtable *ht,
+                                     const struct bucket_table *tbl)
+{
+       return ht->p.insecure_max_entries &&
+              atomic_read(&ht->nelems) >= ht->p.insecure_max_entries;
+}
+
 /* The bucket lock is selected based on the hash and protects mutations
  * on a group of hash buckets.
  *
@@ -589,6 +604,10 @@ static inline int __rhashtable_insert_fast(
                goto out;
        }
 
+       err = -E2BIG;
+       if (unlikely(rht_grow_above_max(ht, tbl)))
+               goto out;
+
        if (unlikely(rht_grow_above_100(ht, tbl))) {
 slow_path:
                spin_unlock_bh(lock);
index 6341f5be6e2474c0a7e30fdd75e3eae5b4286bf3..a30b172df6e1a760905f83c2136ac35f4611320f 100644 (file)
@@ -18,7 +18,7 @@ static inline int rt_task(struct task_struct *p)
 #ifdef CONFIG_RT_MUTEXES
 extern int rt_mutex_getprio(struct task_struct *p);
 extern void rt_mutex_setprio(struct task_struct *p, int prio);
-extern int rt_mutex_check_prio(struct task_struct *task, int newprio);
+extern int rt_mutex_get_effective_prio(struct task_struct *task, int newprio);
 extern struct task_struct *rt_mutex_get_top_task(struct task_struct *task);
 extern void rt_mutex_adjust_pi(struct task_struct *p);
 static inline bool tsk_is_pi_blocked(struct task_struct *tsk)
@@ -31,9 +31,10 @@ static inline int rt_mutex_getprio(struct task_struct *p)
        return p->normal_prio;
 }
 
-static inline int rt_mutex_check_prio(struct task_struct *task, int newprio)
+static inline int rt_mutex_get_effective_prio(struct task_struct *task,
+                                             int newprio)
 {
-       return 0;
+       return newprio;
 }
 
 static inline struct task_struct *rt_mutex_get_top_task(struct task_struct *task)
index 66e374d62f64347025ed0a0bc7dade0744e16818..f15154a879c711870ba649f867fc6eeb47212f14 100644 (file)
@@ -176,6 +176,7 @@ struct nf_bridge_info {
        struct net_device       *physindev;
        struct net_device       *physoutdev;
        char                    neigh_header[8];
+       __be32                  ipv4_daddr;
 };
 #endif
 
index 0caa3a2d4106eab0137d20ac75518af7964281ba..e8bbf403618f47931e1b32d4ade97b06465fc982 100644 (file)
@@ -145,11 +145,21 @@ struct tcp_sock {
  *     read the code and the spec side by side (and laugh ...)
  *     See RFC793 and RFC1122. The RFC writes these in capitals.
  */
+       u64     bytes_received; /* RFC4898 tcpEStatsAppHCThruOctetsReceived
+                                * sum(delta(rcv_nxt)), or how many bytes
+                                * were acked.
+                                */
        u32     rcv_nxt;        /* What we want to receive next         */
        u32     copied_seq;     /* Head of yet unread data              */
        u32     rcv_wup;        /* rcv_nxt on last window update sent   */
        u32     snd_nxt;        /* Next sequence we send                */
 
+       u64     bytes_acked;    /* RFC4898 tcpEStatsAppHCThruOctetsAcked
+                                * sum(delta(snd_una)), or how many bytes
+                                * were acked.
+                                */
+       struct u64_stats_sync syncp; /* protects 64bit vars (cf tcp_get_info()) */
+
        u32     snd_una;        /* First byte we want an ack for        */
        u32     snd_sml;        /* Last byte of the most recently transmitted small packet */
        u32     rcv_tstamp;     /* timestamp of last received ACK (for keepalives) */
index fe5623c9af715fda985da02bcecb1c9451b3789c..d76631f615c224ac29e64198050279aa01e97880 100644 (file)
@@ -339,6 +339,7 @@ struct tty_file_private {
 #define TTY_EXCLUSIVE          3       /* Exclusive open mode */
 #define TTY_DEBUG              4       /* Debugging */
 #define TTY_DO_WRITE_WAKEUP    5       /* Call write_wakeup after queuing new */
+#define TTY_OTHER_DONE         6       /* Closed pty has completed input processing */
 #define TTY_LDISC_OPEN         11      /* Line discipline is open */
 #define TTY_PTY_LOCK           16      /* pty private */
 #define TTY_NO_WRITE_SPLIT     17      /* Preserve write boundaries to driver */
@@ -462,7 +463,6 @@ extern int tty_hung_up_p(struct file *filp);
 extern void do_SAK(struct tty_struct *tty);
 extern void __do_SAK(struct tty_struct *tty);
 extern void no_tty(void);
-extern void tty_flush_to_ldisc(struct tty_struct *tty);
 extern void tty_buffer_free_all(struct tty_port *port);
 extern void tty_buffer_flush(struct tty_struct *tty, struct tty_ldisc *ld);
 extern void tty_buffer_init(struct tty_port *port);
index 0ee05da3889946c10dd8fabaeb50e59cc20739c3..03835522dfcb68ab830a9d38768c374a99ec131d 100644 (file)
@@ -109,12 +109,12 @@ static inline bool gid_lte(kgid_t left, kgid_t right)
 
 static inline bool uid_valid(kuid_t uid)
 {
-       return !uid_eq(uid, INVALID_UID);
+       return __kuid_val(uid) != (uid_t) -1;
 }
 
 static inline bool gid_valid(kgid_t gid)
 {
-       return !gid_eq(gid, INVALID_GID);
+       return __kgid_val(gid) != (gid_t) -1;
 }
 
 #ifdef CONFIG_USER_NS
index eeda67652766a9979478de97105322b5ee6a7977..6ea16c84293b0cdcb981df77481a4fa5e509fdde 100644 (file)
@@ -30,11 +30,13 @@ struct wpan_phy_cca;
 struct cfg802154_ops {
        struct net_device * (*add_virtual_intf_deprecated)(struct wpan_phy *wpan_phy,
                                                           const char *name,
+                                                          unsigned char name_assign_type,
                                                           int type);
        void    (*del_virtual_intf_deprecated)(struct wpan_phy *wpan_phy,
                                               struct net_device *dev);
        int     (*add_virtual_intf)(struct wpan_phy *wpan_phy,
                                    const char *name,
+                                   unsigned char name_assign_type,
                                    enum nl802154_iftype type,
                                    __le64 extended_addr);
        int     (*del_virtual_intf)(struct wpan_phy *wpan_phy,
index aeee28081245c9215f10badd611f58ba0124fcd0..1e18005f7f65f061f6084ea1823a8d37368a57e4 100644 (file)
@@ -120,11 +120,13 @@ static inline u32 codel_time_to_us(codel_time_t val)
  * struct codel_params - contains codel parameters
  * @target:    target queue size (in time units)
  * @interval:  width of moving time window
+ * @mtu:       device mtu, or minimal queue backlog in bytes.
  * @ecn:       is Explicit Congestion Notification enabled
  */
 struct codel_params {
        codel_time_t    target;
        codel_time_t    interval;
+       u32             mtu;
        bool            ecn;
 };
 
@@ -166,10 +168,12 @@ struct codel_stats {
        u32             ecn_mark;
 };
 
-static void codel_params_init(struct codel_params *params)
+static void codel_params_init(struct codel_params *params,
+                             const struct Qdisc *sch)
 {
        params->interval = MS2TIME(100);
        params->target = MS2TIME(5);
+       params->mtu = psched_mtu(qdisc_dev(sch));
        params->ecn = false;
 }
 
@@ -180,7 +184,7 @@ static void codel_vars_init(struct codel_vars *vars)
 
 static void codel_stats_init(struct codel_stats *stats)
 {
-       stats->maxpacket = 256;
+       stats->maxpacket = 0;
 }
 
 /*
@@ -234,7 +238,7 @@ static bool codel_should_drop(const struct sk_buff *skb,
                stats->maxpacket = qdisc_pkt_len(skb);
 
        if (codel_time_before(vars->ldelay, params->target) ||
-           sch->qstats.backlog <= stats->maxpacket) {
+           sch->qstats.backlog <= params->mtu) {
                /* went below - stay below for at least interval */
                vars->first_above_time = 0;
                return false;
index 48a8158235874b1625c65651b0bd92eedd999fe5..497bc14cdb85f4f8b33da8fbe7aba9d491df50e2 100644 (file)
@@ -129,9 +129,10 @@ struct inet_connection_sock {
 
                u32               probe_timestamp;
        } icsk_mtup;
-       u32                       icsk_ca_priv[16];
        u32                       icsk_user_timeout;
-#define ICSK_CA_PRIV_SIZE      (16 * sizeof(u32))
+
+       u64                       icsk_ca_priv[64 / sizeof(u64)];
+#define ICSK_CA_PRIV_SIZE      (8 * sizeof(u64))
 };
 
 #define ICSK_TIME_RETRANS      1       /* Retransmit timer */
index b4bef1152c05c52b87dc877e9d4e8b09050842f7..8e3668b44c2984aeb3531d14927dd2bf6b9f88a3 100644 (file)
@@ -1666,6 +1666,8 @@ struct ieee80211_tx_control {
  * @sta: station table entry, %NULL for per-vif queue
  * @tid: the TID for this queue (unused for per-vif queue)
  * @ac: the AC for this queue
+ * @drv_priv: data area for driver use, will always be aligned to
+ *     sizeof(void *).
  *
  * The driver can obtain packets from this queue by calling
  * ieee80211_tx_dequeue().
index e18e7fd43f47d996613b0c1e7dfe6bc0e636c476..7df28a4c23f98793626371d1e2334ad91f7ebf87 100644 (file)
@@ -247,19 +247,109 @@ static inline void ieee802154_le64_to_be64(void *be64_dst, const void *le64_src)
        __put_unaligned_memmove64(swab64p(le64_src), be64_dst);
 }
 
-/* Basic interface to register ieee802154 device */
+/**
+ * ieee802154_alloc_hw - Allocate a new hardware device
+ *
+ * This must be called once for each hardware device. The returned pointer
+ * must be used to refer to this device when calling other functions.
+ * mac802154 allocates a private data area for the driver pointed to by
+ * @priv in &struct ieee802154_hw, the size of this area is given as
+ * @priv_data_len.
+ *
+ * @priv_data_len: length of private data
+ * @ops: callbacks for this device
+ *
+ * Return: A pointer to the new hardware device, or %NULL on error.
+ */
 struct ieee802154_hw *
 ieee802154_alloc_hw(size_t priv_data_len, const struct ieee802154_ops *ops);
+
+/**
+ * ieee802154_free_hw - free hardware descriptor
+ *
+ * This function frees everything that was allocated, including the
+ * private data for the driver. You must call ieee802154_unregister_hw()
+ * before calling this function.
+ *
+ * @hw: the hardware to free
+ */
 void ieee802154_free_hw(struct ieee802154_hw *hw);
+
+/**
+ * ieee802154_register_hw - Register hardware device
+ *
+ * You must call this function before any other functions in
+ * mac802154. Note that before a hardware can be registered, you
+ * need to fill the contained wpan_phy's information.
+ *
+ * @hw: the device to register as returned by ieee802154_alloc_hw()
+ *
+ * Return: 0 on success. An error code otherwise.
+ */
 int ieee802154_register_hw(struct ieee802154_hw *hw);
+
+/**
+ * ieee802154_unregister_hw - Unregister a hardware device
+ *
+ * This function instructs mac802154 to free allocated resources
+ * and unregister netdevices from the networking subsystem.
+ *
+ * @hw: the hardware to unregister
+ */
 void ieee802154_unregister_hw(struct ieee802154_hw *hw);
 
+/**
+ * ieee802154_rx - receive frame
+ *
+ * Use this function to hand received frames to mac802154. The receive
+ * buffer in @skb must start with an IEEE 802.15.4 header. In case of a
+ * paged @skb is used, the driver is recommended to put the ieee802154
+ * header of the frame on the linear part of the @skb to avoid memory
+ * allocation and/or memcpy by the stack.
+ *
+ * This function may not be called in IRQ context. Calls to this function
+ * for a single hardware must be synchronized against each other.
+ *
+ * @hw: the hardware this frame came in on
+ * @skb: the buffer to receive, owned by mac802154 after this call
+ */
 void ieee802154_rx(struct ieee802154_hw *hw, struct sk_buff *skb);
+
+/**
+ * ieee802154_rx_irqsafe - receive frame
+ *
+ * Like ieee802154_rx() but can be called in IRQ context
+ * (internally defers to a tasklet.)
+ *
+ * @hw: the hardware this frame came in on
+ * @skb: the buffer to receive, owned by mac802154 after this call
+ * @lqi: link quality indicator
+ */
 void ieee802154_rx_irqsafe(struct ieee802154_hw *hw, struct sk_buff *skb,
                           u8 lqi);
-
+/**
+ * ieee802154_wake_queue - wake ieee802154 queue
+ * @hw: pointer as obtained from ieee802154_alloc_hw().
+ *
+ * Drivers should use this function instead of netif_wake_queue.
+ */
 void ieee802154_wake_queue(struct ieee802154_hw *hw);
+
+/**
+ * ieee802154_stop_queue - stop ieee802154 queue
+ * @hw: pointer as obtained from ieee802154_alloc_hw().
+ *
+ * Drivers should use this function instead of netif_stop_queue.
+ */
 void ieee802154_stop_queue(struct ieee802154_hw *hw);
+
+/**
+ * ieee802154_xmit_complete - frame transmission complete
+ *
+ * @hw: pointer as obtained from ieee802154_alloc_hw().
+ * @skb: buffer for transmission
+ * @ifs_handling: indicate interframe space handling
+ */
 void ieee802154_xmit_complete(struct ieee802154_hw *hw, struct sk_buff *skb,
                              bool ifs_handling);
 
index c56a438c3a1eaf89d630edb17dd20802f0e01590..ce13cf20f6253e866f52534b7e7dc10e5bac1a0e 100644 (file)
@@ -574,11 +574,14 @@ static inline void sctp_v6_map_v4(union sctp_addr *addr)
 /* Map v4 address to v4-mapped v6 address */
 static inline void sctp_v4_map_v6(union sctp_addr *addr)
 {
+       __be16 port;
+
+       port = addr->v4.sin_port;
+       addr->v6.sin6_addr.s6_addr32[3] = addr->v4.sin_addr.s_addr;
+       addr->v6.sin6_port = port;
        addr->v6.sin6_family = AF_INET6;
        addr->v6.sin6_flowinfo = 0;
        addr->v6.sin6_scope_id = 0;
-       addr->v6.sin6_port = addr->v4.sin_port;
-       addr->v6.sin6_addr.s6_addr32[3] = addr->v4.sin_addr.s_addr;
        addr->v6.sin6_addr.s6_addr32[0] = 0;
        addr->v6.sin6_addr.s6_addr32[1] = 0;
        addr->v6.sin6_addr.s6_addr32[2] = htonl(0x0000ffff);
index 051dc5c2802d3296f8b49d4b40911c0c22345262..6d204f3f9df8cafb82d856db08769a7d24dfd79e 100644 (file)
@@ -576,7 +576,7 @@ static inline int tcp_bound_to_half_wnd(struct tcp_sock *tp, int pktsize)
 }
 
 /* tcp.c */
-void tcp_get_info(const struct sock *, struct tcp_info *);
+void tcp_get_info(struct sock *, struct tcp_info *);
 
 /* Read 'sendfile()'-style from a TCP socket */
 typedef int (*sk_read_actor_t)(read_descriptor_t *, struct sk_buff *,
@@ -804,6 +804,8 @@ enum tcp_ca_ack_event_flags {
 /* Requires ECN/ECT set on all packets */
 #define TCP_CONG_NEEDS_ECN     0x2
 
+union tcp_cc_info;
+
 struct tcp_congestion_ops {
        struct list_head        list;
        u32 key;
@@ -829,7 +831,8 @@ struct tcp_congestion_ops {
        /* hook for packet ack accounting (optional) */
        void (*pkts_acked)(struct sock *sk, u32 num_acked, s32 rtt_us);
        /* get info for inet_diag (optional) */
-       int (*get_info)(struct sock *sk, u32 ext, struct sk_buff *skb);
+       size_t (*get_info)(struct sock *sk, u32 ext, int *attr,
+                          union tcp_cc_info *info);
 
        char            name[TCP_CA_NAME_MAX];
        struct module   *owner;
index d65c0a09efd32041e3dd07ff80d0a421f0de6ae8..c7093c75bdd6b70a53c1c35a0950a92ad49722da 100644 (file)
@@ -143,4 +143,8 @@ struct tcp_dctcp_info {
        __u32   dctcp_ab_tot;
 };
 
+union tcp_cc_info {
+       struct tcpvegas_info    vegas;
+       struct tcp_dctcp_info   dctcp;
+};
 #endif /* _UAPI_INET_DIAG_H_ */
index bc9abfe88c9a0e1ba4a80f7f16af038c5cd1f2ac..139d4dd1cab83f1cee0399e9924138a24d350ba7 100644 (file)
@@ -31,4 +31,14 @@ struct mpls_label {
 #define MPLS_LS_TTL_MASK        0x000000FF
 #define MPLS_LS_TTL_SHIFT       0
 
+/* Reserved labels */
+#define MPLS_LABEL_IPV4NULL            0 /* RFC3032 */
+#define MPLS_LABEL_RTALERT             1 /* RFC3032 */
+#define MPLS_LABEL_IPV6NULL            2 /* RFC3032 */
+#define MPLS_LABEL_IMPLNULL            3 /* RFC3032 */
+#define MPLS_LABEL_ENTROPY             7 /* RFC6790 */
+#define MPLS_LABEL_GAL                 13 /* RFC5586 */
+#define MPLS_LABEL_OAMALERT            14 /* RFC3429 */
+#define MPLS_LABEL_EXTENSION           15 /* RFC7274 */
+
 #endif /* _UAPI_MPLS_H */
index 9993a421201c231af01d85ef7c1d355745526565..ef9f80f0f529d156a906b461cc7595c4c83358a6 100644 (file)
@@ -42,6 +42,9 @@ enum tcp_conntrack {
 /* The field td_maxack has been set */
 #define IP_CT_TCP_FLAG_MAXACK_SET              0x20
 
+/* Marks possibility for expected RFC5961 challenge ACK */
+#define IP_CT_EXP_CHALLENGE_ACK                0x40
+
 struct nf_ct_tcp_flags {
        __u8 flags;
        __u8 mask;
index 974db03f7b1a2d9ddf96d0b34a409f8356e94d1a..17fb02f488da88efdcd071258a487ab563251f37 100644 (file)
@@ -337,7 +337,7 @@ struct rtnexthop {
 #define RTNH_F_DEAD            1       /* Nexthop is dead (used by multipath)  */
 #define RTNH_F_PERVASIVE       2       /* Do recursive gateway lookup  */
 #define RTNH_F_ONLINK          4       /* Gateway is forced on link    */
-#define RTNH_F_EXTERNAL                8       /* Route installed externally   */
+#define RTNH_F_OFFLOAD         8       /* offloaded route */
 
 /* Macros to handle hexthops */
 
index 3b9718328d8bf7732a73a13a4811b98ff667f000..faa72f4fa547bcfe643b9cfd32b83b62caf6b973 100644 (file)
@@ -112,6 +112,7 @@ enum {
 #define TCP_FASTOPEN           23      /* Enable FastOpen on listeners */
 #define TCP_TIMESTAMP          24
 #define TCP_NOTSENT_LOWAT      25      /* limit number of unsent bytes in write queue */
+#define TCP_CC_INFO            26      /* Get Congestion Control (optional) info */
 
 struct tcp_repair_opt {
        __u32   opt_code;
@@ -189,6 +190,8 @@ struct tcp_info {
 
        __u64   tcpi_pacing_rate;
        __u64   tcpi_max_pacing_rate;
+       __u64   tcpi_bytes_acked; /* RFC4898 tcpEStatsAppHCThruOctetsAcked */
+       __u64   tcpi_bytes_received; /* RFC4898 tcpEStatsAppHCThruOctetsReceived */
 };
 
 /* for TCP_MD5SIG socket option */
index 5321cd9636e6a48e0e4ad0e68fe159e2d015e7c8..7d95fdf9cf3e773f3d800194ca43a2f0a7acdd7a 100644 (file)
@@ -17,7 +17,7 @@ int bind_evtchn_to_irqhandler(unsigned int evtchn,
                              irq_handler_t handler,
                              unsigned long irqflags, const char *devname,
                              void *dev_id);
-int bind_virq_to_irq(unsigned int virq, unsigned int cpu);
+int bind_virq_to_irq(unsigned int virq, unsigned int cpu, bool percpu);
 int bind_virq_to_irqhandler(unsigned int virq, unsigned int cpu,
                            irq_handler_t handler,
                            unsigned long irqflags, const char *devname,
index 81aa3a4ece9f787038027bb4e5a1e456312c1182..1a3bf48743ce1c62c26077d642084cbdc8b40d6b 100644 (file)
@@ -913,10 +913,30 @@ static void put_ctx(struct perf_event_context *ctx)
  * Those places that change perf_event::ctx will hold both
  * perf_event_ctx::mutex of the 'old' and 'new' ctx value.
  *
- * Lock ordering is by mutex address. There is one other site where
- * perf_event_context::mutex nests and that is put_event(). But remember that
- * that is a parent<->child context relation, and migration does not affect
- * children, therefore these two orderings should not interact.
+ * Lock ordering is by mutex address. There are two other sites where
+ * perf_event_context::mutex nests and those are:
+ *
+ *  - perf_event_exit_task_context()   [ child , 0 ]
+ *      __perf_event_exit_task()
+ *        sync_child_event()
+ *          put_event()                        [ parent, 1 ]
+ *
+ *  - perf_event_init_context()                [ parent, 0 ]
+ *      inherit_task_group()
+ *        inherit_group()
+ *          inherit_event()
+ *            perf_event_alloc()
+ *              perf_init_event()
+ *                perf_try_init_event()        [ child , 1 ]
+ *
+ * While it appears there is an obvious deadlock here -- the parent and child
+ * nesting levels are inverted between the two. This is in fact safe because
+ * life-time rules separate them. That is an exiting task cannot fork, and a
+ * spawning task cannot (yet) exit.
+ *
+ * But remember that that these are parent<->child context relations, and
+ * migration does not affect children, therefore these two orderings should not
+ * interact.
  *
  * The change in perf_event::ctx does not affect children (as claimed above)
  * because the sys_perf_event_open() case will install a new event and break
@@ -3657,9 +3677,6 @@ static void perf_remove_from_owner(struct perf_event *event)
        }
 }
 
-/*
- * Called when the last reference to the file is gone.
- */
 static void put_event(struct perf_event *event)
 {
        struct perf_event_context *ctx;
@@ -3697,6 +3714,9 @@ int perf_event_release_kernel(struct perf_event *event)
 }
 EXPORT_SYMBOL_GPL(perf_event_release_kernel);
 
+/*
+ * Called when the last reference to the file is gone.
+ */
 static int perf_release(struct inode *inode, struct file *file)
 {
        put_event(file->private_data);
@@ -7364,7 +7384,12 @@ static int perf_try_init_event(struct pmu *pmu, struct perf_event *event)
                return -ENODEV;
 
        if (event->group_leader != event) {
-               ctx = perf_event_ctx_lock(event->group_leader);
+               /*
+                * This ctx->mutex can nest when we're called through
+                * inheritance. See the perf_event_ctx_lock_nested() comment.
+                */
+               ctx = perf_event_ctx_lock_nested(event->group_leader,
+                                                SINGLE_DEPTH_NESTING);
                BUG_ON(!ctx);
        }
 
index b73279367087ca779072b79a784f69224929c149..b025295f49662469d1f3b4257f3835d2f40f01e1 100644 (file)
@@ -265,15 +265,17 @@ struct task_struct *rt_mutex_get_top_task(struct task_struct *task)
 }
 
 /*
- * Called by sched_setscheduler() to check whether the priority change
- * is overruled by a possible priority boosting.
+ * Called by sched_setscheduler() to get the priority which will be
+ * effective after the change.
  */
-int rt_mutex_check_prio(struct task_struct *task, int newprio)
+int rt_mutex_get_effective_prio(struct task_struct *task, int newprio)
 {
        if (!task_has_pi_waiters(task))
-               return 0;
+               return newprio;
 
-       return task_top_pi_waiter(task)->task->prio <= newprio;
+       if (task_top_pi_waiter(task)->task->prio <= newprio)
+               return task_top_pi_waiter(task)->task->prio;
+       return newprio;
 }
 
 /*
index fe22f7510bceab3fad0f008379a91f34db074d37..123673291ffbb160734ed889b934d557611a1cf1 100644 (file)
@@ -3300,15 +3300,18 @@ static void __setscheduler_params(struct task_struct *p,
 
 /* Actually do priority change: must hold pi & rq lock. */
 static void __setscheduler(struct rq *rq, struct task_struct *p,
-                          const struct sched_attr *attr)
+                          const struct sched_attr *attr, bool keep_boost)
 {
        __setscheduler_params(p, attr);
 
        /*
-        * If we get here, there was no pi waiters boosting the
-        * task. It is safe to use the normal prio.
+        * Keep a potential priority boosting if called from
+        * sched_setscheduler().
         */
-       p->prio = normal_prio(p);
+       if (keep_boost)
+               p->prio = rt_mutex_get_effective_prio(p, normal_prio(p));
+       else
+               p->prio = normal_prio(p);
 
        if (dl_prio(p->prio))
                p->sched_class = &dl_sched_class;
@@ -3408,7 +3411,7 @@ static int __sched_setscheduler(struct task_struct *p,
        int newprio = dl_policy(attr->sched_policy) ? MAX_DL_PRIO - 1 :
                      MAX_RT_PRIO - 1 - attr->sched_priority;
        int retval, oldprio, oldpolicy = -1, queued, running;
-       int policy = attr->sched_policy;
+       int new_effective_prio, policy = attr->sched_policy;
        unsigned long flags;
        const struct sched_class *prev_class;
        struct rq *rq;
@@ -3590,15 +3593,14 @@ static int __sched_setscheduler(struct task_struct *p,
        oldprio = p->prio;
 
        /*
-        * Special case for priority boosted tasks.
-        *
-        * If the new priority is lower or equal (user space view)
-        * than the current (boosted) priority, we just store the new
+        * Take priority boosted tasks into account. If the new
+        * effective priority is unchanged, we just store the new
         * normal parameters and do not touch the scheduler class and
         * the runqueue. This will be done when the task deboost
         * itself.
         */
-       if (rt_mutex_check_prio(p, newprio)) {
+       new_effective_prio = rt_mutex_get_effective_prio(p, newprio);
+       if (new_effective_prio == oldprio) {
                __setscheduler_params(p, attr);
                task_rq_unlock(rq, p, &flags);
                return 0;
@@ -3612,7 +3614,7 @@ static int __sched_setscheduler(struct task_struct *p,
                put_prev_task(rq, p);
 
        prev_class = p->sched_class;
-       __setscheduler(rq, p, attr);
+       __setscheduler(rq, p, attr, true);
 
        if (running)
                p->sched_class->set_curr_task(rq);
@@ -4387,10 +4389,7 @@ long __sched io_schedule_timeout(long timeout)
        long ret;
 
        current->in_iowait = 1;
-       if (old_iowait)
-               blk_schedule_flush_plug(current);
-       else
-               blk_flush_plug(current);
+       blk_schedule_flush_plug(current);
 
        delayacct_blkio_start();
        rq = raw_rq();
@@ -6997,27 +6996,23 @@ static int cpuset_cpu_inactive(struct notifier_block *nfb, unsigned long action,
        unsigned long flags;
        long cpu = (long)hcpu;
        struct dl_bw *dl_b;
+       bool overflow;
+       int cpus;
 
-       switch (action & ~CPU_TASKS_FROZEN) {
+       switch (action) {
        case CPU_DOWN_PREPARE:
-               /* explicitly allow suspend */
-               if (!(action & CPU_TASKS_FROZEN)) {
-                       bool overflow;
-                       int cpus;
-
-                       rcu_read_lock_sched();
-                       dl_b = dl_bw_of(cpu);
+               rcu_read_lock_sched();
+               dl_b = dl_bw_of(cpu);
 
-                       raw_spin_lock_irqsave(&dl_b->lock, flags);
-                       cpus = dl_bw_cpus(cpu);
-                       overflow = __dl_overflow(dl_b, cpus, 0, 0);
-                       raw_spin_unlock_irqrestore(&dl_b->lock, flags);
+               raw_spin_lock_irqsave(&dl_b->lock, flags);
+               cpus = dl_bw_cpus(cpu);
+               overflow = __dl_overflow(dl_b, cpus, 0, 0);
+               raw_spin_unlock_irqrestore(&dl_b->lock, flags);
 
-                       rcu_read_unlock_sched();
+               rcu_read_unlock_sched();
 
-                       if (overflow)
-                               return notifier_from_errno(-EBUSY);
-               }
+               if (overflow)
+                       return notifier_from_errno(-EBUSY);
                cpuset_update_active_cpus(false);
                break;
        case CPU_DOWN_PREPARE_FROZEN:
@@ -7346,7 +7341,7 @@ static void normalize_task(struct rq *rq, struct task_struct *p)
        queued = task_on_rq_queued(p);
        if (queued)
                dequeue_task(rq, p, 0);
-       __setscheduler(rq, p, &attr);
+       __setscheduler(rq, p, &attr, false);
        if (queued) {
                enqueue_task(rq, p, 0);
                resched_curr(rq);
index 76d4bd962b19b3bab345460676954ef6f7c14568..93ef7190bdeaadbf99efe07954cca3bee6399d07 100644 (file)
@@ -266,21 +266,23 @@ lock_hrtimer_base(const struct hrtimer *timer, unsigned long *flags)
 /*
  * Divide a ktime value by a nanosecond value
  */
-u64 __ktime_divns(const ktime_t kt, s64 div)
+s64 __ktime_divns(const ktime_t kt, s64 div)
 {
-       u64 dclc;
        int sft = 0;
+       s64 dclc;
+       u64 tmp;
 
        dclc = ktime_to_ns(kt);
+       tmp = dclc < 0 ? -dclc : dclc;
+
        /* Make sure the divisor is less than 2^32: */
        while (div >> 32) {
                sft++;
                div >>= 1;
        }
-       dclc >>= sft;
-       do_div(dclc, (unsigned long) div);
-
-       return dclc;
+       tmp >>= sft;
+       do_div(tmp, (unsigned long) div);
+       return dclc < 0 ? -tmp : tmp;
 }
 EXPORT_SYMBOL_GPL(__ktime_divns);
 #endif /* BITS_PER_LONG >= 64 */
index 2316f50b07a456e979603fcee13a66fca03b1baa..581a68a04c64089b847d3b76d1abc138a83bb209 100644 (file)
@@ -41,6 +41,8 @@
 #define NMI_WATCHDOG_ENABLED      (1 << NMI_WATCHDOG_ENABLED_BIT)
 #define SOFT_WATCHDOG_ENABLED     (1 << SOFT_WATCHDOG_ENABLED_BIT)
 
+static DEFINE_MUTEX(watchdog_proc_mutex);
+
 #ifdef CONFIG_HARDLOCKUP_DETECTOR
 static unsigned long __read_mostly watchdog_enabled = SOFT_WATCHDOG_ENABLED|NMI_WATCHDOG_ENABLED;
 #else
@@ -608,26 +610,36 @@ void watchdog_nmi_enable_all(void)
 {
        int cpu;
 
-       if (!watchdog_user_enabled)
-               return;
+       mutex_lock(&watchdog_proc_mutex);
+
+       if (!(watchdog_enabled & NMI_WATCHDOG_ENABLED))
+               goto unlock;
 
        get_online_cpus();
        for_each_online_cpu(cpu)
                watchdog_nmi_enable(cpu);
        put_online_cpus();
+
+unlock:
+       mutex_unlock(&watchdog_proc_mutex);
 }
 
 void watchdog_nmi_disable_all(void)
 {
        int cpu;
 
+       mutex_lock(&watchdog_proc_mutex);
+
        if (!watchdog_running)
-               return;
+               goto unlock;
 
        get_online_cpus();
        for_each_online_cpu(cpu)
                watchdog_nmi_disable(cpu);
        put_online_cpus();
+
+unlock:
+       mutex_unlock(&watchdog_proc_mutex);
 }
 #else
 static int watchdog_nmi_enable(unsigned int cpu) { return 0; }
@@ -744,8 +756,6 @@ static int proc_watchdog_update(void)
 
 }
 
-static DEFINE_MUTEX(watchdog_proc_mutex);
-
 /*
  * common function for watchdog, nmi_watchdog and soft_watchdog parameter
  *
index b28df4019adedfe182d5c719da62b6bf05c031fe..4396434e471536b4772ef06efcb983f87c580889 100644 (file)
@@ -14,6 +14,7 @@
  * published by the Free Software Foundation.
  */
 
+#include <linux/atomic.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/log2.h>
@@ -446,6 +447,10 @@ int rhashtable_insert_slow(struct rhashtable *ht, const void *key,
        if (key && rhashtable_lookup_fast(ht, key, ht->p))
                goto exit;
 
+       err = -E2BIG;
+       if (unlikely(rht_grow_above_max(ht, tbl)))
+               goto exit;
+
        err = -EAGAIN;
        if (rhashtable_check_elasticity(ht, tbl, hash) ||
            rht_grow_above_100(ht, tbl))
@@ -738,6 +743,12 @@ int rhashtable_init(struct rhashtable *ht,
        if (params->max_size)
                ht->p.max_size = rounddown_pow_of_two(params->max_size);
 
+       if (params->insecure_max_entries)
+               ht->p.insecure_max_entries =
+                       rounddown_pow_of_two(params->insecure_max_entries);
+       else
+               ht->p.insecure_max_entries = ht->p.max_size * 2;
+
        ht->p.min_size = max(ht->p.min_size, HASH_MIN_SIZE);
 
        /* The maximum (not average) chain length grows with the
index 5405aff5a590c370d3c8ca37c0f9a0c19cb46775..f0fe4f2c1fa7aa865055731834cdd78e0684cca5 100644 (file)
 #define BYTES_PER_POINTER      sizeof(void *)
 
 /* GFP bitmask for kmemleak internal allocations */
-#define gfp_kmemleak_mask(gfp) (((gfp) & (GFP_KERNEL | GFP_ATOMIC)) | \
+#define gfp_kmemleak_mask(gfp) (((gfp) & (GFP_KERNEL | GFP_ATOMIC | \
+                                          __GFP_NOACCOUNT)) | \
                                 __GFP_NORETRY | __GFP_NOMEMALLOC | \
                                 __GFP_NOWARN)
 
index ede26291d4aa92ad120bfd006786414fd6d45c56..747743237d9f4d3ead6117d4ee152c00659cd362 100644 (file)
@@ -2518,7 +2518,7 @@ static void __init check_numabalancing_enable(void)
        if (numabalancing_override)
                set_numabalancing_state(numabalancing_override == 1);
 
-       if (nr_node_ids > 1 && !numabalancing_override) {
+       if (num_online_nodes() > 1 && !numabalancing_override) {
                pr_info("%s automatic NUMA balancing. "
                        "Configure with numa_balancing= or the "
                        "kernel.numa_balancing sysctl",
index 755a42c76eb4747623da51acdeb780b322b5ac06..303c908790efca6f7d0b30cc6d8a9db918085e10 100644 (file)
@@ -101,7 +101,8 @@ void unset_migratetype_isolate(struct page *page, unsigned migratetype)
                        buddy_idx = __find_buddy_index(page_idx, order);
                        buddy = page + (buddy_idx - page_idx);
 
-                       if (!is_migrate_isolate_page(buddy)) {
+                       if (pfn_valid_within(page_to_pfn(buddy)) &&
+                           !is_migrate_isolate_page(buddy)) {
                                __isolate_free_page(page, order);
                                kernel_map_pages(page, (1 << order), 1);
                                set_page_refcounted(page);
index 98a30a5b866472b7421f5394636934bc23ec7f94..59555f0f8fc85b039cab18350906ae3c86a477af 100644 (file)
@@ -443,7 +443,7 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
        case NETDEV_UP:
                /* Put all VLANs for this dev in the up state too.  */
                vlan_group_for_each_dev(grp, i, vlandev) {
-                       flgs = vlandev->flags;
+                       flgs = dev_get_flags(vlandev);
                        if (flgs & IFF_UP)
                                continue;
 
index 476709bd068a474f7edcac83a4869849ccfb4b17..c4802f3bd4c51086de62c048858fb7f6057f3bbb 100644 (file)
@@ -1557,7 +1557,8 @@ static int hci_dev_do_close(struct hci_dev *hdev)
 {
        BT_DBG("%s %p", hdev->name, hdev);
 
-       if (!hci_dev_test_flag(hdev, HCI_UNREGISTER)) {
+       if (!hci_dev_test_flag(hdev, HCI_UNREGISTER) &&
+           test_bit(HCI_UP, &hdev->flags)) {
                /* Execute vendor specific shutdown routine */
                if (hdev->shutdown)
                        hdev->shutdown(hdev);
@@ -2853,9 +2854,11 @@ static void le_scan_disable_work_complete(struct hci_dev *hdev, u8 status,
                         * state. If we were running both LE and BR/EDR inquiry
                         * simultaneously, and BR/EDR inquiry is already
                         * finished, stop discovery, otherwise BR/EDR inquiry
-                        * will stop discovery when finished.
+                        * will stop discovery when finished. If we will resolve
+                        * remote device name, do not change discovery state.
                         */
-                       if (!test_bit(HCI_INQUIRY, &hdev->flags))
+                       if (!test_bit(HCI_INQUIRY, &hdev->flags) &&
+                           hdev->discovery.state != DISCOVERY_RESOLVING)
                                hci_discovery_set_state(hdev,
                                                        DISCOVERY_STOPPED);
                } else {
index 4b6722f8f1790811d2ef4b9b1ae8839628b745c8..a3abe6ed111ec236dabc7b19f24c0373efb8f613 100644 (file)
@@ -1072,7 +1072,7 @@ static int br_ip6_multicast_mld2_report(struct net_bridge *br,
 
                err = br_ip6_multicast_add_group(br, port, &grec->grec_mca,
                                                 vid);
-               if (!err)
+               if (err)
                        break;
        }
 
index ab55e2472beb0e44dece07e327f2e0eb8d3f502c..60ddfbeb47f598fed5908dfc492abef48c0acd75 100644 (file)
 #include <net/route.h>
 #include <net/netfilter/br_netfilter.h>
 
-#if IS_ENABLED(CONFIG_NF_CONNTRACK)
-#include <net/netfilter/nf_conntrack.h>
-#endif
-
 #include <asm/uaccess.h>
 #include "br_private.h"
 #ifdef CONFIG_SYSCTL
@@ -350,24 +346,15 @@ static int br_nf_pre_routing_finish_bridge(struct sock *sk, struct sk_buff *skb)
        return 0;
 }
 
-static bool dnat_took_place(const struct sk_buff *skb)
+static bool daddr_was_changed(const struct sk_buff *skb,
+                             const struct nf_bridge_info *nf_bridge)
 {
-#if IS_ENABLED(CONFIG_NF_CONNTRACK)
-       enum ip_conntrack_info ctinfo;
-       struct nf_conn *ct;
-
-       ct = nf_ct_get(skb, &ctinfo);
-       if (!ct || nf_ct_is_untracked(ct))
-               return false;
-
-       return test_bit(IPS_DST_NAT_BIT, &ct->status);
-#else
-       return false;
-#endif
+       return ip_hdr(skb)->daddr != nf_bridge->ipv4_daddr;
 }
 
 /* This requires some explaining. If DNAT has taken place,
  * we will need to fix up the destination Ethernet address.
+ * This is also true when SNAT takes place (for the reply direction).
  *
  * There are two cases to consider:
  * 1. The packet was DNAT'ed to a device in the same bridge
@@ -421,7 +408,7 @@ static int br_nf_pre_routing_finish(struct sock *sk, struct sk_buff *skb)
                nf_bridge->pkt_otherhost = false;
        }
        nf_bridge->mask ^= BRNF_NF_BRIDGE_PREROUTING;
-       if (dnat_took_place(skb)) {
+       if (daddr_was_changed(skb, nf_bridge)) {
                if ((err = ip_route_input(skb, iph->daddr, iph->saddr, iph->tos, dev))) {
                        struct in_device *in_dev = __in_dev_get_rcu(dev);
 
@@ -632,6 +619,7 @@ static unsigned int br_nf_pre_routing(const struct nf_hook_ops *ops,
                                      struct sk_buff *skb,
                                      const struct nf_hook_state *state)
 {
+       struct nf_bridge_info *nf_bridge;
        struct net_bridge_port *p;
        struct net_bridge *br;
        __u32 len = nf_bridge_encap_header_len(skb);
@@ -669,6 +657,9 @@ static unsigned int br_nf_pre_routing(const struct nf_hook_ops *ops,
        if (!setup_pre_routing(skb))
                return NF_DROP;
 
+       nf_bridge = nf_bridge_info_get(skb);
+       nf_bridge->ipv4_daddr = ip_hdr(skb)->daddr;
+
        skb->protocol = htons(ETH_P_IP);
 
        NF_HOOK(NFPROTO_IPV4, NF_INET_PRE_ROUTING, state->sk, skb,
index 4fcaa67750fda845ad0a180332c4cd96a9524086..7caf7fae2d5b8aa369b924e1c87a47c343fb8954 100644 (file)
@@ -97,7 +97,9 @@ static void br_forward_delay_timer_expired(unsigned long arg)
                netif_carrier_on(br->dev);
        }
        br_log_state(p);
+       rcu_read_lock();
        br_ifinfo_notify(RTM_NEWLINK, p);
+       rcu_read_unlock();
        spin_unlock(&br->lock);
 }
 
index 91180a7fc94376ea3ca7eecf274c03c3bc919590..24c7c96bf5f8fc9a2929e6e8a1f18017f880bdd7 100644 (file)
@@ -1117,6 +1117,8 @@ static int do_replace(struct net *net, const void __user *user,
                return -ENOMEM;
        if (tmp.num_counters >= INT_MAX / sizeof(struct ebt_counter))
                return -ENOMEM;
+       if (tmp.num_counters == 0)
+               return -EINVAL;
 
        tmp.name[sizeof(tmp.name) - 1] = 0;
 
@@ -2159,6 +2161,8 @@ static int compat_copy_ebt_replace_from_user(struct ebt_replace *repl,
                return -ENOMEM;
        if (tmp.num_counters >= INT_MAX / sizeof(struct ebt_counter))
                return -ENOMEM;
+       if (tmp.num_counters == 0)
+               return -EINVAL;
 
        memcpy(repl, &tmp, offsetof(struct ebt_replace, hook_entry));
 
index 4ec0c803aef112196657503cd615fe7a83e800bb..112ad784838a5bf6b46eed6c2b90f2d8b0e50d7a 100644 (file)
@@ -330,6 +330,10 @@ static long caif_stream_data_wait(struct sock *sk, long timeo)
                release_sock(sk);
                timeo = schedule_timeout(timeo);
                lock_sock(sk);
+
+               if (sock_flag(sk, SOCK_DEAD))
+                       break;
+
                clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
        }
 
@@ -373,6 +377,10 @@ static int caif_stream_recvmsg(struct socket *sock, struct msghdr *msg,
                struct sk_buff *skb;
 
                lock_sock(sk);
+               if (sock_flag(sk, SOCK_DEAD)) {
+                       err = -ECONNRESET;
+                       goto unlock;
+               }
                skb = skb_dequeue(&sk->sk_receive_queue);
                caif_check_flow_release(sk);
 
index 41a4abc7e98eebfd36487d6d381f680732d4cd68..c4ec9239249ae6541a8ee378f95230a42c2f3a3d 100644 (file)
@@ -1306,8 +1306,6 @@ static void __unregister_linger_request(struct ceph_osd_client *osdc,
                if (list_empty(&req->r_osd_item))
                        req->r_osd = NULL;
        }
-
-       list_del_init(&req->r_req_lru_item); /* can be on notarget */
        ceph_osdc_put_request(req);
 }
 
@@ -2017,20 +2015,29 @@ static void kick_requests(struct ceph_osd_client *osdc, bool force_resend,
                err = __map_request(osdc, req,
                                    force_resend || force_resend_writes);
                dout("__map_request returned %d\n", err);
-               if (err == 0)
-                       continue;  /* no change and no osd was specified */
                if (err < 0)
                        continue;  /* hrm! */
-               if (req->r_osd == NULL) {
-                       dout("tid %llu maps to no valid osd\n", req->r_tid);
-                       needmap++;  /* request a newer map */
-                       continue;
-               }
+               if (req->r_osd == NULL || err > 0) {
+                       if (req->r_osd == NULL) {
+                               dout("lingering %p tid %llu maps to no osd\n",
+                                    req, req->r_tid);
+                               /*
+                                * A homeless lingering request makes
+                                * no sense, as it's job is to keep
+                                * a particular OSD connection open.
+                                * Request a newer map and kick the
+                                * request, knowing that it won't be
+                                * resent until we actually get a map
+                                * that can tell us where to send it.
+                                */
+                               needmap++;
+                       }
 
-               dout("kicking lingering %p tid %llu osd%d\n", req, req->r_tid,
-                    req->r_osd ? req->r_osd->o_osd : -1);
-               __register_request(osdc, req);
-               __unregister_linger_request(osdc, req);
+                       dout("kicking lingering %p tid %llu osd%d\n", req,
+                            req->r_tid, req->r_osd ? req->r_osd->o_osd : -1);
+                       __register_request(osdc, req);
+                       __unregister_linger_request(osdc, req);
+               }
        }
        reset_changed_osds(osdc);
        mutex_unlock(&osdc->request_mutex);
index c7ba0388f1be8e37e780f27e0b3bd95f45dd0ade..2c1c67fad64d57f3d744c89843816b2d64f5b834 100644 (file)
@@ -5209,7 +5209,7 @@ static int __netdev_upper_dev_link(struct net_device *dev,
        if (__netdev_find_adj(upper_dev, dev, &upper_dev->all_adj_list.upper))
                return -EBUSY;
 
-       if (__netdev_find_adj(dev, upper_dev, &dev->all_adj_list.upper))
+       if (__netdev_find_adj(dev, upper_dev, &dev->adj_list.upper))
                return -EEXIST;
 
        if (master && netdev_master_upper_dev_get(dev))
index 1d00b89229024b45fef3955cd27221fafe2bfb74..1347e11f5cc9b0aa6ef8485cf44feaa1965a04e9 100644 (file)
@@ -359,7 +359,15 @@ static int ethtool_get_settings(struct net_device *dev, void __user *useraddr)
        int err;
        struct ethtool_cmd cmd;
 
-       err = __ethtool_get_settings(dev, &cmd);
+       if (!dev->ethtool_ops->get_settings)
+               return -EOPNOTSUPP;
+
+       if (copy_from_user(&cmd, useraddr, sizeof(cmd)))
+               return -EFAULT;
+
+       cmd.cmd = ETHTOOL_GSET;
+
+       err = dev->ethtool_ops->get_settings(dev, &cmd);
        if (err < 0)
                return err;
 
index 78fc04ad36fc03a0f1737ee484a08e1824b324dc..572af0011997a2057f30ba0b5022760e11493d98 100644 (file)
@@ -601,7 +601,7 @@ static int rtnl_net_getid(struct sk_buff *skb, struct nlmsghdr *nlh)
        }
 
        err = rtnl_net_fill(msg, NETLINK_CB(skb).portid, nlh->nlmsg_seq, 0,
-                           RTM_GETNSID, net, peer, -1);
+                           RTM_NEWNSID, net, peer, -1);
        if (err < 0)
                goto err_out;
 
index 666e0928ba404b85cf210749e505a2c205e5ee3f..8de36824018de4da2369fb02234692c4e0260b27 100644 (file)
@@ -2416,6 +2416,9 @@ void rtmsg_ifinfo(int type, struct net_device *dev, unsigned int change,
 {
        struct sk_buff *skb;
 
+       if (dev->reg_state != NETREG_REGISTERED)
+               return;
+
        skb = rtmsg_ifinfo_build_skb(type, dev, change, flags);
        if (skb)
                rtmsg_ifinfo_send(skb, dev, flags);
index e891bcf325ca759c9b7498f29ec76aa946198d5e..292f42228bfb361b5748998bbcc538b1e16a2f22 100644 (file)
@@ -1474,8 +1474,8 @@ void sk_release_kernel(struct sock *sk)
                return;
 
        sock_hold(sk);
-       sock_net_set(sk, get_net(&init_net));
        sock_release(sk->sk_socket);
+       sock_net_set(sk, get_net(&init_net));
        sock_put(sk);
 }
 EXPORT_SYMBOL(sk_release_kernel);
index 05dab2957cd49e9be95c6bbe1cef1eb9f35ab8a2..4adfd4d5471b83c254313a887687cb497ce7ad3a 100644 (file)
@@ -3,7 +3,9 @@ obj-$(CONFIG_IEEE802154_SOCKET) += ieee802154_socket.o
 obj-y += 6lowpan/
 
 ieee802154-y := netlink.o nl-mac.o nl-phy.o nl_policy.o core.o \
-                header_ops.o sysfs.o nl802154.o
+                header_ops.o sysfs.o nl802154.o trace.o
 ieee802154_socket-y := socket.o
 
+CFLAGS_trace.o := -I$(src)
+
 ccflags-y += -D__CHECK_ENDIAN__
index 1b9d25f6e898616d7972950692bcd1eab71ddb26..346c6665d25e59bf372bacedc5a2ae6df30d227c 100644 (file)
@@ -175,6 +175,7 @@ int ieee802154_add_iface(struct sk_buff *skb, struct genl_info *info)
        int rc = -ENOBUFS;
        struct net_device *dev;
        int type = __IEEE802154_DEV_INVALID;
+       unsigned char name_assign_type;
 
        pr_debug("%s\n", __func__);
 
@@ -190,8 +191,10 @@ int ieee802154_add_iface(struct sk_buff *skb, struct genl_info *info)
                if (devname[nla_len(info->attrs[IEEE802154_ATTR_DEV_NAME]) - 1]
                                != '\0')
                        return -EINVAL; /* phy name should be null-terminated */
+               name_assign_type = NET_NAME_USER;
        } else  {
                devname = "wpan%d";
+               name_assign_type = NET_NAME_ENUM;
        }
 
        if (strlen(devname) >= IFNAMSIZ)
@@ -221,7 +224,7 @@ int ieee802154_add_iface(struct sk_buff *skb, struct genl_info *info)
        }
 
        dev = rdev_add_virtual_intf_deprecated(wpan_phy_to_rdev(phy), devname,
-                                              type);
+                                              name_assign_type, type);
        if (IS_ERR(dev)) {
                rc = PTR_ERR(dev);
                goto nla_put_failure;
index a4daf91b8d0a395d6964dad93cf292e566dee22c..f3c12f6a4a392ad301e5a79fcabb2bb9f8521431 100644 (file)
@@ -589,7 +589,7 @@ static int nl802154_new_interface(struct sk_buff *skb, struct genl_info *info)
 
        return rdev_add_virtual_intf(rdev,
                                     nla_data(info->attrs[NL802154_ATTR_IFNAME]),
-                                    type, extended_addr);
+                                    NET_NAME_USER, type, extended_addr);
 }
 
 static int nl802154_del_interface(struct sk_buff *skb, struct genl_info *info)
index 7c46732fad2bdd3f6778fce066cb89330b5aeaa3..7b5a9dd94fe5a2b55d01103aa529261141ece521 100644 (file)
@@ -4,13 +4,16 @@
 #include <net/cfg802154.h>
 
 #include "core.h"
+#include "trace.h"
 
 static inline struct net_device *
 rdev_add_virtual_intf_deprecated(struct cfg802154_registered_device *rdev,
-                                const char *name, int type)
+                                const char *name,
+                                unsigned char name_assign_type,
+                                int type)
 {
        return rdev->ops->add_virtual_intf_deprecated(&rdev->wpan_phy, name,
-                                                     type);
+                                                     name_assign_type, type);
 }
 
 static inline void
@@ -22,75 +25,131 @@ rdev_del_virtual_intf_deprecated(struct cfg802154_registered_device *rdev,
 
 static inline int
 rdev_add_virtual_intf(struct cfg802154_registered_device *rdev, char *name,
+                     unsigned char name_assign_type,
                      enum nl802154_iftype type, __le64 extended_addr)
 {
-       return rdev->ops->add_virtual_intf(&rdev->wpan_phy, name, type,
+       int ret;
+
+       trace_802154_rdev_add_virtual_intf(&rdev->wpan_phy, name, type,
                                           extended_addr);
+       ret = rdev->ops->add_virtual_intf(&rdev->wpan_phy, name,
+                                         name_assign_type, type,
+                                         extended_addr);
+       trace_802154_rdev_return_int(&rdev->wpan_phy, ret);
+       return ret;
 }
 
 static inline int
 rdev_del_virtual_intf(struct cfg802154_registered_device *rdev,
                      struct wpan_dev *wpan_dev)
 {
-       return rdev->ops->del_virtual_intf(&rdev->wpan_phy, wpan_dev);
+       int ret;
+
+       trace_802154_rdev_del_virtual_intf(&rdev->wpan_phy, wpan_dev);
+       ret = rdev->ops->del_virtual_intf(&rdev->wpan_phy, wpan_dev);
+       trace_802154_rdev_return_int(&rdev->wpan_phy, ret);
+       return ret;
 }
 
 static inline int
 rdev_set_channel(struct cfg802154_registered_device *rdev, u8 page, u8 channel)
 {
-       return rdev->ops->set_channel(&rdev->wpan_phy, page, channel);
+       int ret;
+
+       trace_802154_rdev_set_channel(&rdev->wpan_phy, page, channel);
+       ret = rdev->ops->set_channel(&rdev->wpan_phy, page, channel);
+       trace_802154_rdev_return_int(&rdev->wpan_phy, ret);
+       return ret;
 }
 
 static inline int
 rdev_set_cca_mode(struct cfg802154_registered_device *rdev,
                  const struct wpan_phy_cca *cca)
 {
-       return rdev->ops->set_cca_mode(&rdev->wpan_phy, cca);
+       int ret;
+
+       trace_802154_rdev_set_cca_mode(&rdev->wpan_phy, cca);
+       ret = rdev->ops->set_cca_mode(&rdev->wpan_phy, cca);
+       trace_802154_rdev_return_int(&rdev->wpan_phy, ret);
+       return ret;
 }
 
 static inline int
 rdev_set_pan_id(struct cfg802154_registered_device *rdev,
                struct wpan_dev *wpan_dev, __le16 pan_id)
 {
-       return rdev->ops->set_pan_id(&rdev->wpan_phy, wpan_dev, pan_id);
+       int ret;
+
+       trace_802154_rdev_set_pan_id(&rdev->wpan_phy, wpan_dev, pan_id);
+       ret = rdev->ops->set_pan_id(&rdev->wpan_phy, wpan_dev, pan_id);
+       trace_802154_rdev_return_int(&rdev->wpan_phy, ret);
+       return ret;
 }
 
 static inline int
 rdev_set_short_addr(struct cfg802154_registered_device *rdev,
                    struct wpan_dev *wpan_dev, __le16 short_addr)
 {
-       return rdev->ops->set_short_addr(&rdev->wpan_phy, wpan_dev, short_addr);
+       int ret;
+
+       trace_802154_rdev_set_short_addr(&rdev->wpan_phy, wpan_dev, short_addr);
+       ret = rdev->ops->set_short_addr(&rdev->wpan_phy, wpan_dev, short_addr);
+       trace_802154_rdev_return_int(&rdev->wpan_phy, ret);
+       return ret;
 }
 
 static inline int
 rdev_set_backoff_exponent(struct cfg802154_registered_device *rdev,
                          struct wpan_dev *wpan_dev, u8 min_be, u8 max_be)
 {
-       return rdev->ops->set_backoff_exponent(&rdev->wpan_phy, wpan_dev,
+       int ret;
+
+       trace_802154_rdev_set_backoff_exponent(&rdev->wpan_phy, wpan_dev,
                                               min_be, max_be);
+       ret = rdev->ops->set_backoff_exponent(&rdev->wpan_phy, wpan_dev,
+                                             min_be, max_be);
+       trace_802154_rdev_return_int(&rdev->wpan_phy, ret);
+       return ret;
 }
 
 static inline int
 rdev_set_max_csma_backoffs(struct cfg802154_registered_device *rdev,
                           struct wpan_dev *wpan_dev, u8 max_csma_backoffs)
 {
-       return rdev->ops->set_max_csma_backoffs(&rdev->wpan_phy, wpan_dev,
-                                               max_csma_backoffs);
+       int ret;
+
+       trace_802154_rdev_set_csma_backoffs(&rdev->wpan_phy, wpan_dev,
+                                           max_csma_backoffs);
+       ret = rdev->ops->set_max_csma_backoffs(&rdev->wpan_phy, wpan_dev,
+                                              max_csma_backoffs);
+       trace_802154_rdev_return_int(&rdev->wpan_phy, ret);
+       return ret;
 }
 
 static inline int
 rdev_set_max_frame_retries(struct cfg802154_registered_device *rdev,
                           struct wpan_dev *wpan_dev, s8 max_frame_retries)
 {
-       return rdev->ops->set_max_frame_retries(&rdev->wpan_phy, wpan_dev,
+       int ret;
+
+       trace_802154_rdev_set_max_frame_retries(&rdev->wpan_phy, wpan_dev,
                                                max_frame_retries);
+       ret = rdev->ops->set_max_frame_retries(&rdev->wpan_phy, wpan_dev,
+                                              max_frame_retries);
+       trace_802154_rdev_return_int(&rdev->wpan_phy, ret);
+       return ret;
 }
 
 static inline int
 rdev_set_lbt_mode(struct cfg802154_registered_device *rdev,
                  struct wpan_dev *wpan_dev, bool mode)
 {
-       return rdev->ops->set_lbt_mode(&rdev->wpan_phy, wpan_dev, mode);
+       int ret;
+
+       trace_802154_rdev_set_lbt_mode(&rdev->wpan_phy, wpan_dev, mode);
+       ret = rdev->ops->set_lbt_mode(&rdev->wpan_phy, wpan_dev, mode);
+       trace_802154_rdev_return_int(&rdev->wpan_phy, ret);
+       return ret;
 }
 
 #endif /* __CFG802154_RDEV_OPS */
diff --git a/net/ieee802154/trace.c b/net/ieee802154/trace.c
new file mode 100644 (file)
index 0000000..95f997f
--- /dev/null
@@ -0,0 +1,7 @@
+#include <linux/module.h>
+
+#ifndef __CHECKER__
+#define CREATE_TRACE_POINTS
+#include "trace.h"
+
+#endif
diff --git a/net/ieee802154/trace.h b/net/ieee802154/trace.h
new file mode 100644 (file)
index 0000000..5ac25eb
--- /dev/null
@@ -0,0 +1,247 @@
+/* Based on net/wireless/tracing.h */
+
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM cfg802154
+
+#if !defined(__RDEV_CFG802154_OPS_TRACE) || defined(TRACE_HEADER_MULTI_READ)
+#define __RDEV_CFG802154_OPS_TRACE
+
+#include <linux/tracepoint.h>
+
+#include <net/cfg802154.h>
+
+#define MAXNAME                32
+#define WPAN_PHY_ENTRY __array(char, wpan_phy_name, MAXNAME)
+#define WPAN_PHY_ASSIGN        strlcpy(__entry->wpan_phy_name,  \
+                               wpan_phy_name(wpan_phy), \
+                               MAXNAME)
+#define WPAN_PHY_PR_FMT        "%s"
+#define WPAN_PHY_PR_ARG        __entry->wpan_phy_name
+
+#define WPAN_DEV_ENTRY __field(u32, identifier)
+#define WPAN_DEV_ASSIGN        (__entry->identifier) = (!IS_ERR_OR_NULL(wpan_dev) \
+                                        ? wpan_dev->identifier : 0)
+#define WPAN_DEV_PR_FMT        "wpan_dev(%u)"
+#define WPAN_DEV_PR_ARG        (__entry->identifier)
+
+#define WPAN_CCA_ENTRY __field(enum nl802154_cca_modes, cca_mode) \
+                       __field(enum nl802154_cca_opts, cca_opt)
+#define WPAN_CCA_ASSIGN \
+       do {                                     \
+               (__entry->cca_mode) = cca->mode; \
+               (__entry->cca_opt) = cca->opt;   \
+       } while (0)
+#define WPAN_CCA_PR_FMT        "cca_mode: %d, cca_opt: %d"
+#define WPAN_CCA_PR_ARG __entry->cca_mode, __entry->cca_opt
+
+#define BOOL_TO_STR(bo) (bo) ? "true" : "false"
+
+/*************************************************************
+ *                     rdev->ops traces                     *
+ *************************************************************/
+
+TRACE_EVENT(802154_rdev_add_virtual_intf,
+       TP_PROTO(struct wpan_phy *wpan_phy, char *name,
+                enum nl802154_iftype type, __le64 extended_addr),
+       TP_ARGS(wpan_phy, name, type, extended_addr),
+       TP_STRUCT__entry(
+               WPAN_PHY_ENTRY
+               __string(vir_intf_name, name ? name : "<noname>")
+               __field(enum nl802154_iftype, type)
+               __field(__le64, extended_addr)
+       ),
+       TP_fast_assign(
+               WPAN_PHY_ASSIGN;
+               __assign_str(vir_intf_name, name ? name : "<noname>");
+               __entry->type = type;
+               __entry->extended_addr = extended_addr;
+       ),
+       TP_printk(WPAN_PHY_PR_FMT ", virtual intf name: %s, type: %d, ea %llx",
+                 WPAN_PHY_PR_ARG, __get_str(vir_intf_name), __entry->type,
+                 __le64_to_cpu(__entry->extended_addr))
+);
+
+TRACE_EVENT(802154_rdev_del_virtual_intf,
+       TP_PROTO(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev),
+       TP_ARGS(wpan_phy, wpan_dev),
+       TP_STRUCT__entry(
+               WPAN_PHY_ENTRY
+               WPAN_DEV_ENTRY
+       ),
+       TP_fast_assign(
+               WPAN_PHY_ASSIGN;
+               WPAN_DEV_ASSIGN;
+       ),
+       TP_printk(WPAN_PHY_PR_FMT ", " WPAN_DEV_PR_FMT, WPAN_PHY_PR_ARG,
+                 WPAN_DEV_PR_ARG)
+);
+
+TRACE_EVENT(802154_rdev_set_channel,
+       TP_PROTO(struct wpan_phy *wpan_phy, u8 page, u8 channel),
+       TP_ARGS(wpan_phy, page, channel),
+       TP_STRUCT__entry(
+               WPAN_PHY_ENTRY
+               __field(u8, page)
+               __field(u8, channel)
+       ),
+       TP_fast_assign(
+               WPAN_PHY_ASSIGN;
+               __entry->page = page;
+               __entry->channel = channel;
+       ),
+       TP_printk(WPAN_PHY_PR_FMT ", page: %d, channel: %d", WPAN_PHY_PR_ARG,
+                 __entry->page, __entry->channel)
+);
+
+TRACE_EVENT(802154_rdev_set_cca_mode,
+       TP_PROTO(struct wpan_phy *wpan_phy, const struct wpan_phy_cca *cca),
+       TP_ARGS(wpan_phy, cca),
+       TP_STRUCT__entry(
+               WPAN_PHY_ENTRY
+               WPAN_CCA_ENTRY
+       ),
+       TP_fast_assign(
+               WPAN_PHY_ASSIGN;
+               WPAN_CCA_ASSIGN;
+       ),
+       TP_printk(WPAN_PHY_PR_FMT ", " WPAN_CCA_PR_FMT, WPAN_PHY_PR_ARG,
+                 WPAN_CCA_PR_ARG)
+);
+
+DECLARE_EVENT_CLASS(802154_le16_template,
+       TP_PROTO(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev,
+                __le16 le16arg),
+       TP_ARGS(wpan_phy, wpan_dev, le16arg),
+       TP_STRUCT__entry(
+               WPAN_PHY_ENTRY
+               WPAN_DEV_ENTRY
+               __field(__le16, le16arg)
+       ),
+       TP_fast_assign(
+               WPAN_PHY_ASSIGN;
+               WPAN_DEV_ASSIGN;
+               __entry->le16arg = le16arg;
+       ),
+       TP_printk(WPAN_PHY_PR_FMT ", " WPAN_DEV_PR_FMT ", pan id: 0x%04x",
+                 WPAN_PHY_PR_ARG, WPAN_DEV_PR_ARG,
+                 __le16_to_cpu(__entry->le16arg))
+);
+
+DEFINE_EVENT(802154_le16_template, 802154_rdev_set_pan_id,
+       TP_PROTO(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev,
+                __le16 le16arg),
+       TP_ARGS(wpan_phy, wpan_dev, le16arg)
+);
+
+DEFINE_EVENT_PRINT(802154_le16_template, 802154_rdev_set_short_addr,
+       TP_PROTO(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev,
+                __le16 le16arg),
+       TP_ARGS(wpan_phy, wpan_dev, le16arg),
+       TP_printk(WPAN_PHY_PR_FMT ", " WPAN_DEV_PR_FMT ", sa: 0x%04x",
+                 WPAN_PHY_PR_ARG, WPAN_DEV_PR_ARG,
+                 __le16_to_cpu(__entry->le16arg))
+);
+
+TRACE_EVENT(802154_rdev_set_backoff_exponent,
+       TP_PROTO(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev,
+                u8 min_be, u8 max_be),
+       TP_ARGS(wpan_phy, wpan_dev, min_be, max_be),
+       TP_STRUCT__entry(
+               WPAN_PHY_ENTRY
+               WPAN_DEV_ENTRY
+               __field(u8, min_be)
+               __field(u8, max_be)
+       ),
+       TP_fast_assign(
+               WPAN_PHY_ASSIGN;
+               WPAN_DEV_ASSIGN;
+               __entry->min_be = min_be;
+               __entry->max_be = max_be;
+       ),
+
+       TP_printk(WPAN_PHY_PR_FMT ", " WPAN_DEV_PR_FMT
+                 ", min be: %d, max_be: %d", WPAN_PHY_PR_ARG,
+                 WPAN_DEV_PR_ARG, __entry->min_be, __entry->max_be)
+);
+
+TRACE_EVENT(802154_rdev_set_csma_backoffs,
+       TP_PROTO(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev,
+                u8 max_csma_backoffs),
+       TP_ARGS(wpan_phy, wpan_dev, max_csma_backoffs),
+       TP_STRUCT__entry(
+               WPAN_PHY_ENTRY
+               WPAN_DEV_ENTRY
+               __field(u8, max_csma_backoffs)
+       ),
+       TP_fast_assign(
+               WPAN_PHY_ASSIGN;
+               WPAN_DEV_ASSIGN;
+               __entry->max_csma_backoffs = max_csma_backoffs;
+       ),
+
+       TP_printk(WPAN_PHY_PR_FMT ", " WPAN_DEV_PR_FMT
+                 ", max csma backoffs: %d", WPAN_PHY_PR_ARG,
+                 WPAN_DEV_PR_ARG, __entry->max_csma_backoffs)
+);
+
+TRACE_EVENT(802154_rdev_set_max_frame_retries,
+       TP_PROTO(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev,
+                s8 max_frame_retries),
+       TP_ARGS(wpan_phy, wpan_dev, max_frame_retries),
+       TP_STRUCT__entry(
+               WPAN_PHY_ENTRY
+               WPAN_DEV_ENTRY
+               __field(s8, max_frame_retries)
+       ),
+       TP_fast_assign(
+               WPAN_PHY_ASSIGN;
+               WPAN_DEV_ASSIGN;
+               __entry->max_frame_retries = max_frame_retries;
+       ),
+
+       TP_printk(WPAN_PHY_PR_FMT ", " WPAN_DEV_PR_FMT
+                 ", max frame retries: %d", WPAN_PHY_PR_ARG,
+                 WPAN_DEV_PR_ARG, __entry->max_frame_retries)
+);
+
+TRACE_EVENT(802154_rdev_set_lbt_mode,
+       TP_PROTO(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev,
+                bool mode),
+       TP_ARGS(wpan_phy, wpan_dev, mode),
+       TP_STRUCT__entry(
+               WPAN_PHY_ENTRY
+               WPAN_DEV_ENTRY
+               __field(bool, mode)
+       ),
+       TP_fast_assign(
+               WPAN_PHY_ASSIGN;
+               WPAN_DEV_ASSIGN;
+               __entry->mode = mode;
+       ),
+       TP_printk(WPAN_PHY_PR_FMT ", " WPAN_DEV_PR_FMT
+               ", lbt mode: %s", WPAN_PHY_PR_ARG,
+               WPAN_DEV_PR_ARG, BOOL_TO_STR(__entry->mode))
+);
+
+TRACE_EVENT(802154_rdev_return_int,
+       TP_PROTO(struct wpan_phy *wpan_phy, int ret),
+       TP_ARGS(wpan_phy, ret),
+       TP_STRUCT__entry(
+               WPAN_PHY_ENTRY
+               __field(int, ret)
+       ),
+       TP_fast_assign(
+               WPAN_PHY_ASSIGN;
+               __entry->ret = ret;
+       ),
+       TP_printk(WPAN_PHY_PR_FMT ", returned: %d", WPAN_PHY_PR_ARG,
+                 __entry->ret)
+);
+
+#endif /* !__RDEV_CFG802154_OPS_TRACE || TRACE_HEADER_MULTI_READ */
+
+#undef TRACE_INCLUDE_PATH
+#define TRACE_INCLUDE_PATH .
+#undef TRACE_INCLUDE_FILE
+#define TRACE_INCLUDE_FILE trace
+#include <trace/define_trace.h>
index e13fcc602da20ee44dfd505ab1115bbcc0e13375..09b62e17dd8cba4b1041de5f208180d278010604 100644 (file)
@@ -1164,6 +1164,7 @@ int fib_table_insert(struct fib_table *tb, struct fib_config *cfg)
                        state = fa->fa_state;
                        new_fa->fa_state = state & ~FA_S_ACCESSED;
                        new_fa->fa_slen = fa->fa_slen;
+                       new_fa->tb_id = tb->tb_id;
 
                        err = netdev_switch_fib_ipv4_add(key, plen, fi,
                                                         new_fa->fa_tos,
@@ -1764,7 +1765,7 @@ void fib_table_flush_external(struct fib_table *tb)
                        /* record local slen */
                        slen = fa->fa_slen;
 
-                       if (!fi || !(fi->fib_flags & RTNH_F_EXTERNAL))
+                       if (!fi || !(fi->fib_flags & RTNH_F_OFFLOAD))
                                continue;
 
                        netdev_switch_fib_ipv4_del(n->key,
index bb77ebdae3b31bcacbfc4fdb350d4282e400e2e8..4d32262c7502cc22d13a9f3bd47ca72e8ee355e8 100644 (file)
@@ -224,14 +224,16 @@ int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk,
        handler->idiag_get_info(sk, r, info);
 
        if (sk->sk_state < TCP_TIME_WAIT) {
-               int err = 0;
+               union tcp_cc_info info;
+               size_t sz = 0;
+               int attr;
 
                rcu_read_lock();
                ca_ops = READ_ONCE(icsk->icsk_ca_ops);
                if (ca_ops && ca_ops->get_info)
-                       err = ca_ops->get_info(sk, ext, skb);
+                       sz = ca_ops->get_info(sk, ext, &attr, &info);
                rcu_read_unlock();
-               if (err < 0)
+               if (sz && nla_put(skb, attr, sz, &info) < 0)
                        goto errout;
        }
 
index 13bfe84bf3ca5a6aafe6982b8782958b0cce529f..a61200754f4ba29301855ae67055dd11d004780b 100644 (file)
@@ -1075,6 +1075,9 @@ static int do_replace(struct net *net, const void __user *user,
        /* overflow check */
        if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters))
                return -ENOMEM;
+       if (tmp.num_counters == 0)
+               return -EINVAL;
+
        tmp.name[sizeof(tmp.name)-1] = 0;
 
        newinfo = xt_alloc_table_info(tmp.size);
@@ -1499,6 +1502,9 @@ static int compat_do_replace(struct net *net, void __user *user,
                return -ENOMEM;
        if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters))
                return -ENOMEM;
+       if (tmp.num_counters == 0)
+               return -EINVAL;
+
        tmp.name[sizeof(tmp.name)-1] = 0;
 
        newinfo = xt_alloc_table_info(tmp.size);
index c69db7fa25ee6376ee3f2bee87d4ce7f09105fb3..2d0e265fef6e7f2c657c54d4db0fd10e010fa68b 100644 (file)
@@ -1262,6 +1262,9 @@ do_replace(struct net *net, const void __user *user, unsigned int len)
        /* overflow check */
        if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters))
                return -ENOMEM;
+       if (tmp.num_counters == 0)
+               return -EINVAL;
+
        tmp.name[sizeof(tmp.name)-1] = 0;
 
        newinfo = xt_alloc_table_info(tmp.size);
@@ -1809,6 +1812,9 @@ compat_do_replace(struct net *net, void __user *user, unsigned int len)
                return -ENOMEM;
        if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters))
                return -ENOMEM;
+       if (tmp.num_counters == 0)
+               return -EINVAL;
+
        tmp.name[sizeof(tmp.name)-1] = 0;
 
        newinfo = xt_alloc_table_info(tmp.size);
index bff62fc87b8e266dbee59d43359fea8a77e29d60..f45f2a12f37b25b7270560498423df9488405b1d 100644 (file)
@@ -902,6 +902,10 @@ static int ip_error(struct sk_buff *skb)
        bool send;
        int code;
 
+       /* IP on this device is disabled. */
+       if (!in_dev)
+               goto out;
+
        net = dev_net(rt->dst.dev);
        if (!IN_DEV_FORWARD(in_dev)) {
                switch (rt->dst.error) {
index 8c5cd9efebbcfa877fedb49dda67e3d098ccbbc1..f1377f2a0472ec26e88b92be2346cbc3c8a69b41 100644 (file)
 #include <linux/types.h>
 #include <linux/fcntl.h>
 #include <linux/poll.h>
+#include <linux/inet_diag.h>
 #include <linux/init.h>
 #include <linux/fs.h>
 #include <linux/skbuff.h>
@@ -401,6 +402,7 @@ void tcp_init_sock(struct sock *sk)
        tp->snd_ssthresh = TCP_INFINITE_SSTHRESH;
        tp->snd_cwnd_clamp = ~0;
        tp->mss_cache = TCP_MSS_DEFAULT;
+       u64_stats_init(&tp->syncp);
 
        tp->reordering = sysctl_tcp_reordering;
        tcp_enable_early_retrans(tp);
@@ -2592,11 +2594,12 @@ EXPORT_SYMBOL(compat_tcp_setsockopt);
 #endif
 
 /* Return information about state of tcp endpoint in API format. */
-void tcp_get_info(const struct sock *sk, struct tcp_info *info)
+void tcp_get_info(struct sock *sk, struct tcp_info *info)
 {
        const struct tcp_sock *tp = tcp_sk(sk);
        const struct inet_connection_sock *icsk = inet_csk(sk);
        u32 now = tcp_time_stamp;
+       unsigned int start;
        u32 rate;
 
        memset(info, 0, sizeof(*info));
@@ -2663,6 +2666,12 @@ void tcp_get_info(const struct sock *sk, struct tcp_info *info)
 
        rate = READ_ONCE(sk->sk_max_pacing_rate);
        info->tcpi_max_pacing_rate = rate != ~0U ? rate : ~0ULL;
+
+       do {
+               start = u64_stats_fetch_begin_irq(&tp->syncp);
+               info->tcpi_bytes_acked = tp->bytes_acked;
+               info->tcpi_bytes_received = tp->bytes_received;
+       } while (u64_stats_fetch_retry_irq(&tp->syncp, start));
 }
 EXPORT_SYMBOL_GPL(tcp_get_info);
 
@@ -2734,6 +2743,26 @@ static int do_tcp_getsockopt(struct sock *sk, int level,
                        return -EFAULT;
                return 0;
        }
+       case TCP_CC_INFO: {
+               const struct tcp_congestion_ops *ca_ops;
+               union tcp_cc_info info;
+               size_t sz = 0;
+               int attr;
+
+               if (get_user(len, optlen))
+                       return -EFAULT;
+
+               ca_ops = icsk->icsk_ca_ops;
+               if (ca_ops && ca_ops->get_info)
+                       sz = ca_ops->get_info(sk, ~0U, &attr, &info);
+
+               len = min_t(unsigned int, len, sz);
+               if (put_user(len, optlen))
+                       return -EFAULT;
+               if (copy_to_user(optval, &info, len))
+                       return -EFAULT;
+               return 0;
+       }
        case TCP_QUICKACK:
                val = !icsk->icsk_ack.pingpong;
                break;
index 4376016f7fa5cf84a3114d1551da623442c9c713..4c41c1287197eb4748198ae9532d1f6233aa7f6a 100644 (file)
@@ -277,7 +277,8 @@ static void dctcp_cwnd_event(struct sock *sk, enum tcp_ca_event ev)
        }
 }
 
-static int dctcp_get_info(struct sock *sk, u32 ext, struct sk_buff *skb)
+static size_t dctcp_get_info(struct sock *sk, u32 ext, int *attr,
+                            union tcp_cc_info *info)
 {
        const struct dctcp *ca = inet_csk_ca(sk);
 
@@ -286,18 +287,17 @@ static int dctcp_get_info(struct sock *sk, u32 ext, struct sk_buff *skb)
         */
        if (ext & (1 << (INET_DIAG_DCTCPINFO - 1)) ||
            ext & (1 << (INET_DIAG_VEGASINFO - 1))) {
-               struct tcp_dctcp_info info;
-
-               memset(&info, 0, sizeof(info));
+               memset(info, 0, sizeof(struct tcp_dctcp_info));
                if (inet_csk(sk)->icsk_ca_ops != &dctcp_reno) {
-                       info.dctcp_enabled = 1;
-                       info.dctcp_ce_state = (u16) ca->ce_state;
-                       info.dctcp_alpha = ca->dctcp_alpha;
-                       info.dctcp_ab_ecn = ca->acked_bytes_ecn;
-                       info.dctcp_ab_tot = ca->acked_bytes_total;
+                       info->dctcp.dctcp_enabled = 1;
+                       info->dctcp.dctcp_ce_state = (u16) ca->ce_state;
+                       info->dctcp.dctcp_alpha = ca->dctcp_alpha;
+                       info->dctcp.dctcp_ab_ecn = ca->acked_bytes_ecn;
+                       info->dctcp.dctcp_ab_tot = ca->acked_bytes_total;
                }
 
-               return nla_put(skb, INET_DIAG_DCTCPINFO, sizeof(info), &info);
+               *attr = INET_DIAG_DCTCPINFO;
+               return sizeof(*info);
        }
        return 0;
 }
index e3d87aca6be8fafe02bec5a8f862a88a6fe79d50..46b087a27503acdf1ff55449c8e41269b1497e67 100644 (file)
@@ -206,6 +206,11 @@ static bool tcp_fastopen_create_child(struct sock *sk,
                        skb_set_owner_r(skb2, child);
                        __skb_queue_tail(&child->sk_receive_queue, skb2);
                        tp->syn_data_acked = 1;
+
+                       /* u64_stats_update_begin(&tp->syncp) not needed here,
+                        * as we certainly are not changing upper 32bit value (0)
+                        */
+                       tp->bytes_received = end_seq - TCP_SKB_CB(skb)->seq - 1;
                } else {
                        end_seq = TCP_SKB_CB(skb)->seq + 1;
                }
index 67476f085e4843dacaeb1b4d6b71ecc160c99b97..f71002e4db0ba7fe8dfe35bb2196bbaae751ed59 100644 (file)
@@ -300,24 +300,25 @@ static u32 tcp_illinois_ssthresh(struct sock *sk)
 }
 
 /* Extract info for Tcp socket info provided via netlink. */
-static int tcp_illinois_info(struct sock *sk, u32 ext, struct sk_buff *skb)
+static size_t tcp_illinois_info(struct sock *sk, u32 ext, int *attr,
+                               union tcp_cc_info *info)
 {
        const struct illinois *ca = inet_csk_ca(sk);
 
        if (ext & (1 << (INET_DIAG_VEGASINFO - 1))) {
-               struct tcpvegas_info info = {
-                       .tcpv_enabled = 1,
-                       .tcpv_rttcnt = ca->cnt_rtt,
-                       .tcpv_minrtt = ca->base_rtt,
-               };
+               info->vegas.tcpv_enabled = 1;
+               info->vegas.tcpv_rttcnt = ca->cnt_rtt;
+               info->vegas.tcpv_minrtt = ca->base_rtt;
+               info->vegas.tcpv_rtt = 0;
 
-               if (info.tcpv_rttcnt > 0) {
+               if (info->vegas.tcpv_rttcnt > 0) {
                        u64 t = ca->sum_rtt;
 
-                       do_div(t, info.tcpv_rttcnt);
-                       info.tcpv_rtt = t;
+                       do_div(t, info->vegas.tcpv_rttcnt);
+                       info->vegas.tcpv_rtt = t;
                }
-               return nla_put(skb, INET_DIAG_VEGASINFO, sizeof(info), &info);
+               *attr = INET_DIAG_VEGASINFO;
+               return sizeof(struct tcpvegas_info);
        }
        return 0;
 }
index 3a4d9b34bed44a2f6b77b2be0e753867bad32292..c9ab964189a0162c7de19d4319f6c3e56194117b 100644 (file)
@@ -1820,14 +1820,12 @@ tcp_sacktag_write_queue(struct sock *sk, const struct sk_buff *ack_skb,
        for (j = 0; j < used_sacks; j++)
                tp->recv_sack_cache[i++] = sp[j];
 
-       tcp_mark_lost_retrans(sk);
-
-       tcp_verify_left_out(tp);
-
        if ((state.reord < tp->fackets_out) &&
            ((inet_csk(sk)->icsk_ca_state != TCP_CA_Loss) || tp->undo_marker))
                tcp_update_reordering(sk, tp->fackets_out - state.reord, 0);
 
+       tcp_mark_lost_retrans(sk);
+       tcp_verify_left_out(tp);
 out:
 
 #if FASTRETRANS_DEBUG > 0
@@ -2700,16 +2698,21 @@ static void tcp_process_loss(struct sock *sk, int flag, bool is_dupack)
        struct tcp_sock *tp = tcp_sk(sk);
        bool recovered = !before(tp->snd_una, tp->high_seq);
 
+       if ((flag & FLAG_SND_UNA_ADVANCED) &&
+           tcp_try_undo_loss(sk, false))
+               return;
+
        if (tp->frto) { /* F-RTO RFC5682 sec 3.1 (sack enhanced version). */
                /* Step 3.b. A timeout is spurious if not all data are
                 * lost, i.e., never-retransmitted data are (s)acked.
                 */
-               if (tcp_try_undo_loss(sk, flag & FLAG_ORIG_SACK_ACKED))
+               if ((flag & FLAG_ORIG_SACK_ACKED) &&
+                   tcp_try_undo_loss(sk, true))
                        return;
 
-               if (after(tp->snd_nxt, tp->high_seq) &&
-                   (flag & FLAG_DATA_SACKED || is_dupack)) {
-                       tp->frto = 0; /* Loss was real: 2nd part of step 3.a */
+               if (after(tp->snd_nxt, tp->high_seq)) {
+                       if (flag & FLAG_DATA_SACKED || is_dupack)
+                               tp->frto = 0; /* Step 3.a. loss was real */
                } else if (flag & FLAG_SND_UNA_ADVANCED && !recovered) {
                        tp->high_seq = tp->snd_nxt;
                        __tcp_push_pending_frames(sk, tcp_current_mss(sk),
@@ -2734,8 +2737,6 @@ static void tcp_process_loss(struct sock *sk, int flag, bool is_dupack)
                else if (flag & FLAG_SND_UNA_ADVANCED)
                        tcp_reset_reno_sack(tp);
        }
-       if (tcp_try_undo_loss(sk, false))
-               return;
        tcp_xmit_retransmit_queue(sk);
 }
 
@@ -3280,6 +3281,28 @@ static inline bool tcp_may_update_window(const struct tcp_sock *tp,
                (ack_seq == tp->snd_wl1 && nwin > tp->snd_wnd);
 }
 
+/* If we update tp->snd_una, also update tp->bytes_acked */
+static void tcp_snd_una_update(struct tcp_sock *tp, u32 ack)
+{
+       u32 delta = ack - tp->snd_una;
+
+       u64_stats_update_begin(&tp->syncp);
+       tp->bytes_acked += delta;
+       u64_stats_update_end(&tp->syncp);
+       tp->snd_una = ack;
+}
+
+/* If we update tp->rcv_nxt, also update tp->bytes_received */
+static void tcp_rcv_nxt_update(struct tcp_sock *tp, u32 seq)
+{
+       u32 delta = seq - tp->rcv_nxt;
+
+       u64_stats_update_begin(&tp->syncp);
+       tp->bytes_received += delta;
+       u64_stats_update_end(&tp->syncp);
+       tp->rcv_nxt = seq;
+}
+
 /* Update our send window.
  *
  * Window update algorithm, described in RFC793/RFC1122 (used in linux-2.2
@@ -3315,7 +3338,7 @@ static int tcp_ack_update_window(struct sock *sk, const struct sk_buff *skb, u32
                }
        }
 
-       tp->snd_una = ack;
+       tcp_snd_una_update(tp, ack);
 
        return flag;
 }
@@ -3497,7 +3520,7 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag)
                 * Note, we use the fact that SND.UNA>=SND.WL2.
                 */
                tcp_update_wl(tp, ack_seq);
-               tp->snd_una = ack;
+               tcp_snd_una_update(tp, ack);
                flag |= FLAG_WIN_UPDATE;
 
                tcp_in_ack_event(sk, CA_ACK_WIN_UPDATE);
@@ -4236,7 +4259,7 @@ static void tcp_ofo_queue(struct sock *sk)
 
                tail = skb_peek_tail(&sk->sk_receive_queue);
                eaten = tail && tcp_try_coalesce(sk, tail, skb, &fragstolen);
-               tp->rcv_nxt = TCP_SKB_CB(skb)->end_seq;
+               tcp_rcv_nxt_update(tp, TCP_SKB_CB(skb)->end_seq);
                if (!eaten)
                        __skb_queue_tail(&sk->sk_receive_queue, skb);
                if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN)
@@ -4404,7 +4427,7 @@ static int __must_check tcp_queue_rcv(struct sock *sk, struct sk_buff *skb, int
        __skb_pull(skb, hdrlen);
        eaten = (tail &&
                 tcp_try_coalesce(sk, tail, skb, fragstolen)) ? 1 : 0;
-       tcp_sk(sk)->rcv_nxt = TCP_SKB_CB(skb)->end_seq;
+       tcp_rcv_nxt_update(tcp_sk(sk), TCP_SKB_CB(skb)->end_seq);
        if (!eaten) {
                __skb_queue_tail(&sk->sk_receive_queue, skb);
                skb_set_owner_r(skb, sk);
@@ -4497,7 +4520,7 @@ static void tcp_data_queue(struct sock *sk, struct sk_buff *skb)
 
                        eaten = tcp_queue_rcv(sk, skb, 0, &fragstolen);
                }
-               tp->rcv_nxt = TCP_SKB_CB(skb)->end_seq;
+               tcp_rcv_nxt_update(tp, TCP_SKB_CB(skb)->end_seq);
                if (skb->len)
                        tcp_event_data_recv(sk, skb);
                if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN)
@@ -5245,7 +5268,7 @@ void tcp_rcv_established(struct sock *sk, struct sk_buff *skb,
                                        tcp_rcv_rtt_measure_ts(sk, skb);
 
                                        __skb_pull(skb, tcp_header_len);
-                                       tp->rcv_nxt = TCP_SKB_CB(skb)->end_seq;
+                                       tcp_rcv_nxt_update(tp, TCP_SKB_CB(skb)->end_seq);
                                        NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPHPHITSTOUSER);
                                        eaten = 1;
                                }
index e5d7649136fcb31ca70b097dcbd9873df07e7417..b5732a54f2ad60f5a528535f7754d644527d4d81 100644 (file)
@@ -300,7 +300,7 @@ void tcp_time_wait(struct sock *sk, int state, int timeo)
                        tw->tw_v6_daddr = sk->sk_v6_daddr;
                        tw->tw_v6_rcv_saddr = sk->sk_v6_rcv_saddr;
                        tw->tw_tclass = np->tclass;
-                       tw->tw_flowlabel = np->flow_label >> 12;
+                       tw->tw_flowlabel = be32_to_cpu(np->flow_label & IPV6_FLOWLABEL_MASK);
                        tw->tw_ipv6only = sk->sk_ipv6only;
                }
 #endif
index c71a1b8f7bde3082a6520128bb6f47d3081de8ac..a6cea1d5e20d47f06eab95f3344a3e3b7c44da89 100644 (file)
@@ -286,18 +286,19 @@ static void tcp_vegas_cong_avoid(struct sock *sk, u32 ack, u32 acked)
 }
 
 /* Extract info for Tcp socket info provided via netlink. */
-int tcp_vegas_get_info(struct sock *sk, u32 ext, struct sk_buff *skb)
+size_t tcp_vegas_get_info(struct sock *sk, u32 ext, int *attr,
+                         union tcp_cc_info *info)
 {
        const struct vegas *ca = inet_csk_ca(sk);
+
        if (ext & (1 << (INET_DIAG_VEGASINFO - 1))) {
-               struct tcpvegas_info info = {
-                       .tcpv_enabled = ca->doing_vegas_now,
-                       .tcpv_rttcnt = ca->cntRTT,
-                       .tcpv_rtt = ca->baseRTT,
-                       .tcpv_minrtt = ca->minRTT,
-               };
-
-               return nla_put(skb, INET_DIAG_VEGASINFO, sizeof(info), &info);
+               info->vegas.tcpv_enabled = ca->doing_vegas_now,
+               info->vegas.tcpv_rttcnt = ca->cntRTT,
+               info->vegas.tcpv_rtt = ca->baseRTT,
+               info->vegas.tcpv_minrtt = ca->minRTT,
+
+               *attr = INET_DIAG_VEGASINFO;
+               return sizeof(struct tcpvegas_info);
        }
        return 0;
 }
index e8a6b33cc61dd7c4d58ea7d3ebd1dd1f35041de9..ef9da5306c685b269cc1efe64ee40196faf11e66 100644 (file)
@@ -19,6 +19,7 @@ void tcp_vegas_init(struct sock *sk);
 void tcp_vegas_state(struct sock *sk, u8 ca_state);
 void tcp_vegas_pkts_acked(struct sock *sk, u32 cnt, s32 rtt_us);
 void tcp_vegas_cwnd_event(struct sock *sk, enum tcp_ca_event event);
-int tcp_vegas_get_info(struct sock *sk, u32 ext, struct sk_buff *skb);
+size_t tcp_vegas_get_info(struct sock *sk, u32 ext, int *attr,
+                         union tcp_cc_info *info);
 
 #endif /* __TCP_VEGAS_H */
index b3c57cceb9907fe9d79f33f33369a96b647b5f26..c10732e39837872c724b801700f627a7fb1c9390 100644 (file)
@@ -256,18 +256,19 @@ static void tcp_westwood_event(struct sock *sk, enum tcp_ca_event event)
 }
 
 /* Extract info for Tcp socket info provided via netlink. */
-static int tcp_westwood_info(struct sock *sk, u32 ext, struct sk_buff *skb)
+static size_t tcp_westwood_info(struct sock *sk, u32 ext, int *attr,
+                               union tcp_cc_info *info)
 {
        const struct westwood *ca = inet_csk_ca(sk);
 
        if (ext & (1 << (INET_DIAG_VEGASINFO - 1))) {
-               struct tcpvegas_info info = {
-                       .tcpv_enabled = 1,
-                       .tcpv_rtt = jiffies_to_usecs(ca->rtt),
-                       .tcpv_minrtt = jiffies_to_usecs(ca->rtt_min),
-               };
+               info->vegas.tcpv_enabled = 1;
+               info->vegas.tcpv_rttcnt = 0;
+               info->vegas.tcpv_rtt    = jiffies_to_usecs(ca->rtt),
+               info->vegas.tcpv_minrtt = jiffies_to_usecs(ca->rtt_min),
 
-               return nla_put(skb, INET_DIAG_VEGASINFO, sizeof(info), &info);
+               *attr = INET_DIAG_VEGASINFO;
+               return sizeof(struct tcpvegas_info);
        }
        return 0;
 }
index 96dbffff5a2400bfca0a7b0bee9072d76ec92e88..bde57b113009794637a07b405173bef1fd3c6fb3 100644 (file)
@@ -693,6 +693,7 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt,
 {
        struct rt6_info *iter = NULL;
        struct rt6_info **ins;
+       struct rt6_info **fallback_ins = NULL;
        int replace = (info->nlh &&
                       (info->nlh->nlmsg_flags & NLM_F_REPLACE));
        int add = (!info->nlh ||
@@ -716,8 +717,13 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt,
                            (info->nlh->nlmsg_flags & NLM_F_EXCL))
                                return -EEXIST;
                        if (replace) {
-                               found++;
-                               break;
+                               if (rt_can_ecmp == rt6_qualify_for_ecmp(iter)) {
+                                       found++;
+                                       break;
+                               }
+                               if (rt_can_ecmp)
+                                       fallback_ins = fallback_ins ?: ins;
+                               goto next_iter;
                        }
 
                        if (iter->dst.dev == rt->dst.dev &&
@@ -753,9 +759,17 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt,
                if (iter->rt6i_metric > rt->rt6i_metric)
                        break;
 
+next_iter:
                ins = &iter->dst.rt6_next;
        }
 
+       if (fallback_ins && !found) {
+               /* No ECMP-able route found, replace first non-ECMP one */
+               ins = fallback_ins;
+               iter = *ins;
+               found++;
+       }
+
        /* Reset round-robin state, if necessary */
        if (ins == &fn->leaf)
                fn->rr_ptr = NULL;
@@ -815,6 +829,8 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt,
                }
 
        } else {
+               int nsiblings;
+
                if (!found) {
                        if (add)
                                goto add;
@@ -835,8 +851,27 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt,
                        info->nl_net->ipv6.rt6_stats->fib_route_nodes++;
                        fn->fn_flags |= RTN_RTINFO;
                }
+               nsiblings = iter->rt6i_nsiblings;
                fib6_purge_rt(iter, fn, info->nl_net);
                rt6_release(iter);
+
+               if (nsiblings) {
+                       /* Replacing an ECMP route, remove all siblings */
+                       ins = &rt->dst.rt6_next;
+                       iter = *ins;
+                       while (iter) {
+                               if (rt6_qualify_for_ecmp(iter)) {
+                                       *ins = iter->dst.rt6_next;
+                                       fib6_purge_rt(iter, fn, info->nl_net);
+                                       rt6_release(iter);
+                                       nsiblings--;
+                               } else {
+                                       ins = &iter->dst.rt6_next;
+                               }
+                               iter = *ins;
+                       }
+                       WARN_ON(nsiblings != 0);
+               }
        }
 
        return 0;
index 7fde1f265c90e90f16291e6c861b6e242111c25b..bc09cb97b8401011c112afe469fd231382387622 100644 (file)
@@ -886,22 +886,45 @@ static int ip6_dst_lookup_tail(struct sock *sk,
 #endif
        int err;
 
-       if (!*dst)
-               *dst = ip6_route_output(net, sk, fl6);
-
-       err = (*dst)->error;
-       if (err)
-               goto out_err_release;
+       /* The correct way to handle this would be to do
+        * ip6_route_get_saddr, and then ip6_route_output; however,
+        * the route-specific preferred source forces the
+        * ip6_route_output call _before_ ip6_route_get_saddr.
+        *
+        * In source specific routing (no src=any default route),
+        * ip6_route_output will fail given src=any saddr, though, so
+        * that's why we try it again later.
+        */
+       if (ipv6_addr_any(&fl6->saddr) && (!*dst || !(*dst)->error)) {
+               struct rt6_info *rt;
+               bool had_dst = *dst != NULL;
 
-       if (ipv6_addr_any(&fl6->saddr)) {
-               struct rt6_info *rt = (struct rt6_info *) *dst;
+               if (!had_dst)
+                       *dst = ip6_route_output(net, sk, fl6);
+               rt = (*dst)->error ? NULL : (struct rt6_info *)*dst;
                err = ip6_route_get_saddr(net, rt, &fl6->daddr,
                                          sk ? inet6_sk(sk)->srcprefs : 0,
                                          &fl6->saddr);
                if (err)
                        goto out_err_release;
+
+               /* If we had an erroneous initial result, pretend it
+                * never existed and let the SA-enabled version take
+                * over.
+                */
+               if (!had_dst && (*dst)->error) {
+                       dst_release(*dst);
+                       *dst = NULL;
+               }
        }
 
+       if (!*dst)
+               *dst = ip6_route_output(net, sk, fl6);
+
+       err = (*dst)->error;
+       if (err)
+               goto out_err_release;
+
 #ifdef CONFIG_IPV6_OPTIMISTIC_DAD
        /*
         * Here if the dst entry we've looked up
@@ -1277,8 +1300,10 @@ static int __ip6_append_data(struct sock *sk,
 
        /* If this is the first and only packet and device
         * supports checksum offloading, let's use it.
+        * Use transhdrlen, same as IPv4, because partial
+        * sums only work when transhdrlen is set.
         */
-       if (!skb && sk->sk_protocol == IPPROTO_UDP &&
+       if (transhdrlen && sk->sk_protocol == IPPROTO_UDP &&
            length + fragheaderlen < mtu &&
            rt->dst.dev->features & NETIF_F_V6_CSUM &&
            !exthdrlen)
index 1a732a1d3c8e13c58508cef9381d2d32e5a34448..62f5b0d0bc9bfbf19940ba0c70ef9da464bf467f 100644 (file)
@@ -1275,6 +1275,9 @@ do_replace(struct net *net, const void __user *user, unsigned int len)
        /* overflow check */
        if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters))
                return -ENOMEM;
+       if (tmp.num_counters == 0)
+               return -EINVAL;
+
        tmp.name[sizeof(tmp.name)-1] = 0;
 
        newinfo = xt_alloc_table_info(tmp.size);
@@ -1822,6 +1825,9 @@ compat_do_replace(struct net *net, void __user *user, unsigned int len)
                return -ENOMEM;
        if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters))
                return -ENOMEM;
+       if (tmp.num_counters == 0)
+               return -EINVAL;
+
        tmp.name[sizeof(tmp.name)-1] = 0;
 
        newinfo = xt_alloc_table_info(tmp.size);
index 5c48293ff06235e72f586007ff1e7bb568733b92..c73ae5039e46d3811d60bf5df9e9482d966a4966 100644 (file)
@@ -2245,9 +2245,10 @@ int ip6_route_get_saddr(struct net *net,
                        unsigned int prefs,
                        struct in6_addr *saddr)
 {
-       struct inet6_dev *idev = ip6_dst_idev((struct dst_entry *)rt);
+       struct inet6_dev *idev =
+               rt ? ip6_dst_idev((struct dst_entry *)rt) : NULL;
        int err = 0;
-       if (rt->rt6i_prefsrc.plen)
+       if (rt && rt->rt6i_prefsrc.plen)
                *saddr = rt->rt6i_prefsrc.addr;
        else
                err = ipv6_dev_get_saddr(net, idev ? idev->dev : NULL,
@@ -2503,9 +2504,9 @@ static int ip6_route_multipath(struct fib6_config *cfg, int add)
        int attrlen;
        int err = 0, last_err = 0;
 
+       remaining = cfg->fc_mp_len;
 beginning:
        rtnh = (struct rtnexthop *)cfg->fc_mp;
-       remaining = cfg->fc_mp_len;
 
        /* Parse a Multipath Entry */
        while (rtnh_ok(rtnh, remaining)) {
@@ -2535,15 +2536,19 @@ static int ip6_route_multipath(struct fib6_config *cfg, int add)
                                 * next hops that have been already added.
                                 */
                                add = 0;
+                               remaining = cfg->fc_mp_len - remaining;
                                goto beginning;
                        }
                }
                /* Because each route is added like a single route we remove
-                * this flag after the first nexthop (if there is a collision,
-                * we have already fail to add the first nexthop:
-                * fib6_add_rt2node() has reject it).
+                * these flags after the first nexthop: if there is a collision,
+                * we have already failed to add the first nexthop:
+                * fib6_add_rt2node() has rejected it; when replacing, old
+                * nexthops have been replaced by first new, the rest should
+                * be added to it.
                 */
-               cfg->fc_nlinfo.nlh->nlmsg_flags &= ~NLM_F_EXCL;
+               cfg->fc_nlinfo.nlh->nlmsg_flags &= ~(NLM_F_EXCL |
+                                                    NLM_F_REPLACE);
                rtnh = rtnh_next(rtnh, &remaining);
        }
 
index b6575d6655681e8e84993a5db929c7309d47d4d3..3adffb300238ebdaf729871bafbb348e82fbde56 100644 (file)
@@ -914,7 +914,7 @@ static void tcp_v6_timewait_ack(struct sock *sk, struct sk_buff *skb)
                        tcptw->tw_rcv_wnd >> tw->tw_rcv_wscale,
                        tcp_time_stamp + tcptw->tw_ts_offset,
                        tcptw->tw_ts_recent, tw->tw_bound_dev_if, tcp_twsk_md5_key(tcptw),
-                       tw->tw_tclass, (tw->tw_flowlabel << 12));
+                       tw->tw_tclass, cpu_to_be32(tw->tw_flowlabel));
 
        inet_twsk_put(tw);
 }
index 3477c919fcc8eb534c3a438ab6d607a6215897f8..c2ec41617a35481d8b5b11dbae59884a0c16cbb3 100644 (file)
@@ -731,7 +731,9 @@ static bool __udp_v6_is_mcast_sock(struct net *net, struct sock *sk,
            (inet->inet_dport && inet->inet_dport != rmt_port) ||
            (!ipv6_addr_any(&sk->sk_v6_daddr) &&
                    !ipv6_addr_equal(&sk->sk_v6_daddr, rmt_addr)) ||
-           (sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif))
+           (sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif) ||
+           (!ipv6_addr_any(&sk->sk_v6_rcv_saddr) &&
+                   !ipv6_addr_equal(&sk->sk_v6_rcv_saddr, loc_addr)))
                return false;
        if (!inet6_mc_check(sk, loc_addr, rmt_addr))
                return false;
index 265e42721a661cf54a46246065168d6a17885147..ff347a0eebd4fdbcbd1580c8af0450c23f673f85 100644 (file)
@@ -2495,51 +2495,22 @@ static bool ieee80211_coalesce_started_roc(struct ieee80211_local *local,
                                           struct ieee80211_roc_work *new_roc,
                                           struct ieee80211_roc_work *cur_roc)
 {
-       unsigned long j = jiffies;
-       unsigned long cur_roc_end = cur_roc->hw_start_time +
-                                   msecs_to_jiffies(cur_roc->duration);
-       struct ieee80211_roc_work *next_roc;
-       int new_dur;
+       unsigned long now = jiffies;
+       unsigned long remaining = cur_roc->hw_start_time +
+                                 msecs_to_jiffies(cur_roc->duration) -
+                                 now;
 
        if (WARN_ON(!cur_roc->started || !cur_roc->hw_begun))
                return false;
 
-       if (time_after(j + IEEE80211_ROC_MIN_LEFT, cur_roc_end))
+       /* if it doesn't fit entirely, schedule a new one */
+       if (new_roc->duration > jiffies_to_msecs(remaining))
                return false;
 
        ieee80211_handle_roc_started(new_roc);
 
-       new_dur = new_roc->duration - jiffies_to_msecs(cur_roc_end - j);
-
-       /* cur_roc is long enough - add new_roc to the dependents list. */
-       if (new_dur <= 0) {
-               list_add_tail(&new_roc->list, &cur_roc->dependents);
-               return true;
-       }
-
-       new_roc->duration = new_dur;
-
-       /*
-        * if cur_roc was already coalesced before, we might
-        * want to extend the next roc instead of adding
-        * a new one.
-        */
-       next_roc = list_entry(cur_roc->list.next,
-                             struct ieee80211_roc_work, list);
-       if (&next_roc->list != &local->roc_list &&
-           next_roc->chan == new_roc->chan &&
-           next_roc->sdata == new_roc->sdata &&
-           !WARN_ON(next_roc->started)) {
-               list_add_tail(&new_roc->list, &next_roc->dependents);
-               next_roc->duration = max(next_roc->duration,
-                                        new_roc->duration);
-               next_roc->type = max(next_roc->type, new_roc->type);
-               return true;
-       }
-
-       /* add right after cur_roc */
-       list_add(&new_roc->list, &cur_roc->list);
-
+       /* add to dependents so we send the expired event properly */
+       list_add_tail(&new_roc->list, &cur_roc->dependents);
        return true;
 }
 
@@ -2652,17 +2623,9 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local,
                         * In the offloaded ROC case, if it hasn't begun, add
                         * this new one to the dependent list to be handled
                         * when the master one begins. If it has begun,
-                        * check that there's still a minimum time left and
-                        * if so, start this one, transmitting the frame, but
-                        * add it to the list directly after this one with
-                        * a reduced time so we'll ask the driver to execute
-                        * it right after finishing the previous one, in the
-                        * hope that it'll also be executed right afterwards,
-                        * effectively extending the old one.
-                        * If there's no minimum time left, just add it to the
-                        * normal list.
-                        * TODO: the ROC type is ignored here, assuming that it
-                        * is better to immediately use the current ROC.
+                        * check if it fits entirely within the existing one,
+                        * in which case it will just be dependent as well.
+                        * Otherwise, schedule it by itself.
                         */
                        if (!tmp->hw_begun) {
                                list_add_tail(&roc->list, &tmp->dependents);
index ab46ab4a72498fd04f1c12ac6bb44f867d86869b..c0a9187bc3a9d579b36824fa64ecbbcbd6575110 100644 (file)
@@ -205,6 +205,8 @@ enum ieee80211_packet_rx_flags {
  * @IEEE80211_RX_CMNTR: received on cooked monitor already
  * @IEEE80211_RX_BEACON_REPORTED: This frame was already reported
  *     to cfg80211_report_obss_beacon().
+ * @IEEE80211_RX_REORDER_TIMER: this frame is released by the
+ *     reorder buffer timeout timer, not the normal RX path
  *
  * These flags are used across handling multiple interfaces
  * for a single frame.
@@ -212,6 +214,7 @@ enum ieee80211_packet_rx_flags {
 enum ieee80211_rx_flags {
        IEEE80211_RX_CMNTR              = BIT(0),
        IEEE80211_RX_BEACON_REPORTED    = BIT(1),
+       IEEE80211_RX_REORDER_TIMER      = BIT(2),
 };
 
 struct ieee80211_rx_data {
@@ -325,12 +328,6 @@ struct mesh_preq_queue {
        u8 flags;
 };
 
-#if HZ/100 == 0
-#define IEEE80211_ROC_MIN_LEFT 1
-#else
-#define IEEE80211_ROC_MIN_LEFT (HZ/100)
-#endif
-
 struct ieee80211_roc_work {
        struct list_head list;
        struct list_head dependents;
index b4ac596a7cb76205cf39d935708d3383490c2b73..84cef600c5730e74c6456e801ffa93ef55e4e47f 100644 (file)
@@ -522,6 +522,12 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up)
                memcpy(sdata->vif.hw_queue, master->vif.hw_queue,
                       sizeof(sdata->vif.hw_queue));
                sdata->vif.bss_conf.chandef = master->vif.bss_conf.chandef;
+
+               mutex_lock(&local->key_mtx);
+               sdata->crypto_tx_tailroom_needed_cnt +=
+                       master->crypto_tx_tailroom_needed_cnt;
+               mutex_unlock(&local->key_mtx);
+
                break;
                }
        case NL80211_IFTYPE_AP:
@@ -819,13 +825,15 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
         * (because if we remove a STA after ops->remove_interface()
         * the driver will have removed the vif info already!)
         *
-        * This is relevant only in WDS mode, in all other modes we've
-        * already removed all stations when disconnecting or similar,
-        * so warn otherwise.
+        * In WDS mode a station must exist here and be flushed, for
+        * AP_VLANs stations may exist since there's nothing else that
+        * would have removed them, but in other modes there shouldn't
+        * be any stations.
         */
        flushed = sta_info_flush(sdata);
-       WARN_ON_ONCE((sdata->vif.type != NL80211_IFTYPE_WDS && flushed > 0) ||
-                    (sdata->vif.type == NL80211_IFTYPE_WDS && flushed != 1));
+       WARN_ON_ONCE(sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
+                    ((sdata->vif.type != NL80211_IFTYPE_WDS && flushed > 0) ||
+                     (sdata->vif.type == NL80211_IFTYPE_WDS && flushed != 1)));
 
        /* don't count this interface for promisc/allmulti while it is down */
        if (sdata->flags & IEEE80211_SDATA_ALLMULTI)
index 2291cd7300911514db84c0135369b807e93a9d06..a907f2d5c12d857bf1811af24e57f5af09eb8665 100644 (file)
@@ -58,6 +58,22 @@ static void assert_key_lock(struct ieee80211_local *local)
        lockdep_assert_held(&local->key_mtx);
 }
 
+static void
+update_vlan_tailroom_need_count(struct ieee80211_sub_if_data *sdata, int delta)
+{
+       struct ieee80211_sub_if_data *vlan;
+
+       if (sdata->vif.type != NL80211_IFTYPE_AP)
+               return;
+
+       mutex_lock(&sdata->local->mtx);
+
+       list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list)
+               vlan->crypto_tx_tailroom_needed_cnt += delta;
+
+       mutex_unlock(&sdata->local->mtx);
+}
+
 static void increment_tailroom_need_count(struct ieee80211_sub_if_data *sdata)
 {
        /*
@@ -79,6 +95,8 @@ static void increment_tailroom_need_count(struct ieee80211_sub_if_data *sdata)
         * http://mid.gmane.org/1308590980.4322.19.camel@jlt3.sipsolutions.net
         */
 
+       update_vlan_tailroom_need_count(sdata, 1);
+
        if (!sdata->crypto_tx_tailroom_needed_cnt++) {
                /*
                 * Flush all XMIT packets currently using HW encryption or no
@@ -88,6 +106,15 @@ static void increment_tailroom_need_count(struct ieee80211_sub_if_data *sdata)
        }
 }
 
+static void decrease_tailroom_need_count(struct ieee80211_sub_if_data *sdata,
+                                        int delta)
+{
+       WARN_ON_ONCE(sdata->crypto_tx_tailroom_needed_cnt < delta);
+
+       update_vlan_tailroom_need_count(sdata, -delta);
+       sdata->crypto_tx_tailroom_needed_cnt -= delta;
+}
+
 static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
 {
        struct ieee80211_sub_if_data *sdata;
@@ -144,7 +171,7 @@ static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
 
                if (!((key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) ||
                      (key->conf.flags & IEEE80211_KEY_FLAG_RESERVE_TAILROOM)))
-                       sdata->crypto_tx_tailroom_needed_cnt--;
+                       decrease_tailroom_need_count(sdata, 1);
 
                WARN_ON((key->conf.flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE) &&
                        (key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV));
@@ -541,7 +568,7 @@ static void __ieee80211_key_destroy(struct ieee80211_key *key,
                        schedule_delayed_work(&sdata->dec_tailroom_needed_wk,
                                              HZ/2);
                } else {
-                       sdata->crypto_tx_tailroom_needed_cnt--;
+                       decrease_tailroom_need_count(sdata, 1);
                }
        }
 
@@ -631,6 +658,7 @@ void ieee80211_key_free(struct ieee80211_key *key, bool delay_tailroom)
 void ieee80211_enable_keys(struct ieee80211_sub_if_data *sdata)
 {
        struct ieee80211_key *key;
+       struct ieee80211_sub_if_data *vlan;
 
        ASSERT_RTNL();
 
@@ -639,7 +667,14 @@ void ieee80211_enable_keys(struct ieee80211_sub_if_data *sdata)
 
        mutex_lock(&sdata->local->key_mtx);
 
-       sdata->crypto_tx_tailroom_needed_cnt = 0;
+       WARN_ON_ONCE(sdata->crypto_tx_tailroom_needed_cnt ||
+                    sdata->crypto_tx_tailroom_pending_dec);
+
+       if (sdata->vif.type == NL80211_IFTYPE_AP) {
+               list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list)
+                       WARN_ON_ONCE(vlan->crypto_tx_tailroom_needed_cnt ||
+                                    vlan->crypto_tx_tailroom_pending_dec);
+       }
 
        list_for_each_entry(key, &sdata->key_list, list) {
                increment_tailroom_need_count(sdata);
@@ -649,6 +684,22 @@ void ieee80211_enable_keys(struct ieee80211_sub_if_data *sdata)
        mutex_unlock(&sdata->local->key_mtx);
 }
 
+void ieee80211_reset_crypto_tx_tailroom(struct ieee80211_sub_if_data *sdata)
+{
+       struct ieee80211_sub_if_data *vlan;
+
+       mutex_lock(&sdata->local->key_mtx);
+
+       sdata->crypto_tx_tailroom_needed_cnt = 0;
+
+       if (sdata->vif.type == NL80211_IFTYPE_AP) {
+               list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list)
+                       vlan->crypto_tx_tailroom_needed_cnt = 0;
+       }
+
+       mutex_unlock(&sdata->local->key_mtx);
+}
+
 void ieee80211_iter_keys(struct ieee80211_hw *hw,
                         struct ieee80211_vif *vif,
                         void (*iter)(struct ieee80211_hw *hw,
@@ -688,8 +739,8 @@ static void ieee80211_free_keys_iface(struct ieee80211_sub_if_data *sdata,
 {
        struct ieee80211_key *key, *tmp;
 
-       sdata->crypto_tx_tailroom_needed_cnt -=
-               sdata->crypto_tx_tailroom_pending_dec;
+       decrease_tailroom_need_count(sdata,
+                                    sdata->crypto_tx_tailroom_pending_dec);
        sdata->crypto_tx_tailroom_pending_dec = 0;
 
        ieee80211_debugfs_key_remove_mgmt_default(sdata);
@@ -709,6 +760,7 @@ void ieee80211_free_keys(struct ieee80211_sub_if_data *sdata,
 {
        struct ieee80211_local *local = sdata->local;
        struct ieee80211_sub_if_data *vlan;
+       struct ieee80211_sub_if_data *master;
        struct ieee80211_key *key, *tmp;
        LIST_HEAD(keys);
 
@@ -728,8 +780,20 @@ void ieee80211_free_keys(struct ieee80211_sub_if_data *sdata,
        list_for_each_entry_safe(key, tmp, &keys, list)
                __ieee80211_key_destroy(key, false);
 
-       WARN_ON_ONCE(sdata->crypto_tx_tailroom_needed_cnt ||
-                    sdata->crypto_tx_tailroom_pending_dec);
+       if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) {
+               if (sdata->bss) {
+                       master = container_of(sdata->bss,
+                                             struct ieee80211_sub_if_data,
+                                             u.ap);
+
+                       WARN_ON_ONCE(sdata->crypto_tx_tailroom_needed_cnt !=
+                                    master->crypto_tx_tailroom_needed_cnt);
+               }
+       } else {
+               WARN_ON_ONCE(sdata->crypto_tx_tailroom_needed_cnt ||
+                            sdata->crypto_tx_tailroom_pending_dec);
+       }
+
        if (sdata->vif.type == NL80211_IFTYPE_AP) {
                list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list)
                        WARN_ON_ONCE(vlan->crypto_tx_tailroom_needed_cnt ||
@@ -793,8 +857,8 @@ void ieee80211_delayed_tailroom_dec(struct work_struct *wk)
         */
 
        mutex_lock(&sdata->local->key_mtx);
-       sdata->crypto_tx_tailroom_needed_cnt -=
-               sdata->crypto_tx_tailroom_pending_dec;
+       decrease_tailroom_need_count(sdata,
+                                    sdata->crypto_tx_tailroom_pending_dec);
        sdata->crypto_tx_tailroom_pending_dec = 0;
        mutex_unlock(&sdata->local->key_mtx);
 }
index c5a31835be0e0ca22c154b1345d91be761308833..96557dd1e77dff325072cff12b7b671aad942015 100644 (file)
@@ -161,6 +161,7 @@ void ieee80211_free_keys(struct ieee80211_sub_if_data *sdata,
 void ieee80211_free_sta_keys(struct ieee80211_local *local,
                             struct sta_info *sta);
 void ieee80211_enable_keys(struct ieee80211_sub_if_data *sdata);
+void ieee80211_reset_crypto_tx_tailroom(struct ieee80211_sub_if_data *sdata);
 
 #define key_mtx_dereference(local, ref) \
        rcu_dereference_protected(ref, lockdep_is_held(&((local)->key_mtx)))
index 260eed45b6d2ff105052643169465c04d333c182..5793f75c5ffde91de02e9698bd27500ff4640826 100644 (file)
@@ -2121,7 +2121,8 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx)
                /* deliver to local stack */
                skb->protocol = eth_type_trans(skb, dev);
                memset(skb->cb, 0, sizeof(skb->cb));
-               if (rx->local->napi)
+               if (!(rx->flags & IEEE80211_RX_REORDER_TIMER) &&
+                   rx->local->napi)
                        napi_gro_receive(rx->local->napi, skb);
                else
                        netif_receive_skb(skb);
@@ -3231,7 +3232,7 @@ void ieee80211_release_reorder_timeout(struct sta_info *sta, int tid)
                /* This is OK -- must be QoS data frame */
                .security_idx = tid,
                .seqno_idx = tid,
-               .flags = 0,
+               .flags = IEEE80211_RX_REORDER_TIMER,
        };
        struct tid_ampdu_rx *tid_agg_rx;
 
index 12971b71d0fa1ea8ce69dbdc09314c1c1641d7c8..2880f2ae99abe3a05b6421f53340a42e11a9ca30 100644 (file)
@@ -66,6 +66,7 @@
 
 static const struct rhashtable_params sta_rht_params = {
        .nelem_hint = 3, /* start small */
+       .automatic_shrinking = true,
        .head_offset = offsetof(struct sta_info, hash_node),
        .key_offset = offsetof(struct sta_info, sta.addr),
        .key_len = ETH_ALEN,
@@ -157,8 +158,24 @@ struct sta_info *sta_info_get(struct ieee80211_sub_if_data *sdata,
                              const u8 *addr)
 {
        struct ieee80211_local *local = sdata->local;
+       struct sta_info *sta;
+       struct rhash_head *tmp;
+       const struct bucket_table *tbl;
+
+       rcu_read_lock();
+       tbl = rht_dereference_rcu(local->sta_hash.tbl, &local->sta_hash);
 
-       return rhashtable_lookup_fast(&local->sta_hash, addr, sta_rht_params);
+       for_each_sta_info(local, tbl, addr, sta, tmp) {
+               if (sta->sdata == sdata) {
+                       rcu_read_unlock();
+                       /* this is safe as the caller must already hold
+                        * another rcu read section or the mutex
+                        */
+                       return sta;
+               }
+       }
+       rcu_read_unlock();
+       return NULL;
 }
 
 /*
index 79412f16b61db9953a4a537db3bd5693d7c61cdb..b864ebc6ab8fbf2a09baca02e650e7fe0314cc75 100644 (file)
@@ -2022,6 +2022,9 @@ int ieee80211_reconfig(struct ieee80211_local *local)
        mutex_unlock(&local->sta_mtx);
 
        /* add back keys */
+       list_for_each_entry(sdata, &local->interfaces, list)
+               ieee80211_reset_crypto_tx_tailroom(sdata);
+
        list_for_each_entry(sdata, &local->interfaces, list)
                if (ieee80211_sdata_running(sdata))
                        ieee80211_enable_keys(sdata);
index a4220e92f0cc20c0feb04c307f6ed72097f4fe3a..efa3f48f1ec5d51ea7191c8ae90dda77c0d330e1 100644 (file)
@@ -98,8 +98,7 @@ static u8 *ieee80211_wep_add_iv(struct ieee80211_local *local,
 
        hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED);
 
-       if (WARN_ON(skb_tailroom(skb) < IEEE80211_WEP_ICV_LEN ||
-                   skb_headroom(skb) < IEEE80211_WEP_IV_LEN))
+       if (WARN_ON(skb_headroom(skb) < IEEE80211_WEP_IV_LEN))
                return NULL;
 
        hdrlen = ieee80211_hdrlen(hdr->frame_control);
@@ -167,6 +166,9 @@ int ieee80211_wep_encrypt(struct ieee80211_local *local,
        size_t len;
        u8 rc4key[3 + WLAN_KEY_LEN_WEP104];
 
+       if (WARN_ON(skb_tailroom(skb) < IEEE80211_WEP_ICV_LEN))
+               return -1;
+
        iv = ieee80211_wep_add_iv(local, skb, keylen, keyidx);
        if (!iv)
                return -1;
index 5d9f68c75e5f8f68c5884d467e5a9d16db0edaac..70be9c799f8a81596a4e753b239849549d792dd0 100644 (file)
 
 static struct net_device *
 ieee802154_add_iface_deprecated(struct wpan_phy *wpan_phy,
-                               const char *name, int type)
+                               const char *name,
+                               unsigned char name_assign_type, int type)
 {
        struct ieee802154_local *local = wpan_phy_priv(wpan_phy);
        struct net_device *dev;
 
        rtnl_lock();
-       dev = ieee802154_if_add(local, name, type,
+       dev = ieee802154_if_add(local, name, name_assign_type, type,
                                cpu_to_le64(0x0000000000000000ULL));
        rtnl_unlock();
 
@@ -45,12 +46,14 @@ static void ieee802154_del_iface_deprecated(struct wpan_phy *wpan_phy,
 
 static int
 ieee802154_add_iface(struct wpan_phy *phy, const char *name,
+                    unsigned char name_assign_type,
                     enum nl802154_iftype type, __le64 extended_addr)
 {
        struct ieee802154_local *local = wpan_phy_priv(phy);
        struct net_device *err;
 
-       err = ieee802154_if_add(local, name, type, extended_addr);
+       err = ieee802154_if_add(local, name, name_assign_type, type,
+                               extended_addr);
        return PTR_ERR_OR_ZERO(err);
 }
 
index bebd70ffc7a3d101551f023e515db24033883f0b..127ba18386fc639aac4ccda482ebe4be11b8e6ee 100644 (file)
@@ -182,7 +182,8 @@ void ieee802154_iface_exit(void);
 void ieee802154_if_remove(struct ieee802154_sub_if_data *sdata);
 struct net_device *
 ieee802154_if_add(struct ieee802154_local *local, const char *name,
-                 enum nl802154_iftype type, __le64 extended_addr);
+                 unsigned char name_assign_type, enum nl802154_iftype type,
+                 __le64 extended_addr);
 void ieee802154_remove_interfaces(struct ieee802154_local *local);
 
 #endif /* __IEEE802154_I_H */
index 38b56f9d9386a4821e50cfdd6059fa115c5e4358..91b75abbd1a1d05b3219b9089232d9f67eb73ccd 100644 (file)
@@ -522,7 +522,8 @@ ieee802154_setup_sdata(struct ieee802154_sub_if_data *sdata,
 
 struct net_device *
 ieee802154_if_add(struct ieee802154_local *local, const char *name,
-                 enum nl802154_iftype type, __le64 extended_addr)
+                 unsigned char name_assign_type, enum nl802154_iftype type,
+                 __le64 extended_addr)
 {
        struct net_device *ndev = NULL;
        struct ieee802154_sub_if_data *sdata = NULL;
@@ -531,7 +532,7 @@ ieee802154_if_add(struct ieee802154_local *local, const char *name,
        ASSERT_RTNL();
 
        ndev = alloc_netdev(sizeof(*sdata) + local->hw.vif_data_size, name,
-                           NET_NAME_UNKNOWN, ieee802154_if_setup);
+                           name_assign_type, ieee802154_if_setup);
        if (!ndev)
                return ERR_PTR(-ENOMEM);
 
index dcf73958133a0d6d0c28f825f648b13cc9ef478b..5b2be12832e65fca351dec5a61619c1042de9004 100644 (file)
@@ -134,7 +134,7 @@ llsec_key_alloc(const struct ieee802154_llsec_key *template)
        for (i = 0; i < ARRAY_SIZE(key->tfm); i++) {
                key->tfm[i] = crypto_alloc_aead("ccm(aes)", 0,
                                                CRYPTO_ALG_ASYNC);
-               if (!key->tfm[i])
+               if (IS_ERR(key->tfm[i]))
                        goto err_tfm;
                if (crypto_aead_setkey(key->tfm[i], template->key,
                                       IEEE802154_LLSEC_KEY_SIZE))
@@ -144,7 +144,7 @@ llsec_key_alloc(const struct ieee802154_llsec_key *template)
        }
 
        key->tfm0 = crypto_alloc_blkcipher("ctr(aes)", 0, CRYPTO_ALG_ASYNC);
-       if (!key->tfm0)
+       if (IS_ERR(key->tfm0))
                goto err_tfm;
 
        if (crypto_blkcipher_setkey(key->tfm0, template->key,
index 8500378c8318cd3b5b7e3a368f44080b40c5900f..08cb32dc8fd33e892e53f7f87f601b10ede8c38d 100644 (file)
@@ -161,18 +161,21 @@ int ieee802154_register_hw(struct ieee802154_hw *hw)
 
        rtnl_lock();
 
-       dev = ieee802154_if_add(local, "wpan%d", NL802154_IFTYPE_NODE,
+       dev = ieee802154_if_add(local, "wpan%d", NET_NAME_ENUM,
+                               NL802154_IFTYPE_NODE,
                                cpu_to_le64(0x0000000000000000ULL));
        if (IS_ERR(dev)) {
                rtnl_unlock();
                rc = PTR_ERR(dev);
-               goto out_wq;
+               goto out_phy;
        }
 
        rtnl_unlock();
 
        return 0;
 
+out_phy:
+       wpan_phy_unregister(local->phy);
 out_wq:
        destroy_workqueue(local->workqueue);
 out:
index 954810c76a8650d87ec4bddc62fa5618e48c1341..7b3f732269e43bb33dc1a6584eaa91b74eab9b64 100644 (file)
@@ -647,7 +647,7 @@ int nla_get_labels(const struct nlattr *nla,
                        return -EINVAL;
 
                switch (dec.label) {
-               case LABEL_IMPLICIT_NULL:
+               case MPLS_LABEL_IMPLNULL:
                        /* RFC3032: This is a label that an LSR may
                         * assign and distribute, but which never
                         * actually appears in the encapsulation.
@@ -935,7 +935,7 @@ static int resize_platform_label_table(struct net *net, size_t limit)
        }
 
        /* In case the predefined labels need to be populated */
-       if (limit > LABEL_IPV4_EXPLICIT_NULL) {
+       if (limit > MPLS_LABEL_IPV4NULL) {
                struct net_device *lo = net->loopback_dev;
                rt0 = mpls_rt_alloc(lo->addr_len);
                if (!rt0)
@@ -945,7 +945,7 @@ static int resize_platform_label_table(struct net *net, size_t limit)
                rt0->rt_via_table = NEIGH_LINK_TABLE;
                memcpy(rt0->rt_via, lo->dev_addr, lo->addr_len);
        }
-       if (limit > LABEL_IPV6_EXPLICIT_NULL) {
+       if (limit > MPLS_LABEL_IPV6NULL) {
                struct net_device *lo = net->loopback_dev;
                rt2 = mpls_rt_alloc(lo->addr_len);
                if (!rt2)
@@ -973,15 +973,15 @@ static int resize_platform_label_table(struct net *net, size_t limit)
        memcpy(labels, old, cp_size);
 
        /* If needed set the predefined labels */
-       if ((old_limit <= LABEL_IPV6_EXPLICIT_NULL) &&
-           (limit > LABEL_IPV6_EXPLICIT_NULL)) {
-               RCU_INIT_POINTER(labels[LABEL_IPV6_EXPLICIT_NULL], rt2);
+       if ((old_limit <= MPLS_LABEL_IPV6NULL) &&
+           (limit > MPLS_LABEL_IPV6NULL)) {
+               RCU_INIT_POINTER(labels[MPLS_LABEL_IPV6NULL], rt2);
                rt2 = NULL;
        }
 
-       if ((old_limit <= LABEL_IPV4_EXPLICIT_NULL) &&
-           (limit > LABEL_IPV4_EXPLICIT_NULL)) {
-               RCU_INIT_POINTER(labels[LABEL_IPV4_EXPLICIT_NULL], rt0);
+       if ((old_limit <= MPLS_LABEL_IPV4NULL) &&
+           (limit > MPLS_LABEL_IPV4NULL)) {
+               RCU_INIT_POINTER(labels[MPLS_LABEL_IPV4NULL], rt0);
                rt0 = NULL;
        }
 
index 693877d69606a1ecdab02dd78dc74eefdaf26f3f..b064c345042c17ccd9ec841535857fb29041a8a3 100644 (file)
@@ -1,16 +1,6 @@
 #ifndef MPLS_INTERNAL_H
 #define MPLS_INTERNAL_H
 
-#define LABEL_IPV4_EXPLICIT_NULL       0 /* RFC3032 */
-#define LABEL_ROUTER_ALERT_LABEL       1 /* RFC3032 */
-#define LABEL_IPV6_EXPLICIT_NULL       2 /* RFC3032 */
-#define LABEL_IMPLICIT_NULL            3 /* RFC3032 */
-#define LABEL_ENTROPY_INDICATOR                7 /* RFC6790 */
-#define LABEL_GAL                      13 /* RFC5586 */
-#define LABEL_OAM_ALERT                        14 /* RFC3429 */
-#define LABEL_EXTENSION                        15 /* RFC7274 */
-
-
 struct mpls_shim_hdr {
        __be32 label_stack_entry;
 };
index f70e34a68f702ab39c43e27d4b8e8127b49525f6..a0f3e6a3c7d18f344d3321a83b5c11d1988d5d3d 100644 (file)
@@ -863,6 +863,7 @@ config NETFILTER_XT_TARGET_TPROXY
        depends on NETFILTER_XTABLES
        depends on NETFILTER_ADVANCED
        depends on (IPV6 || IPV6=n)
+       depends on (IP6_NF_IPTABLES || IP6_NF_IPTABLES=n)
        depends on IP_NF_MANGLE
        select NF_DEFRAG_IPV4
        select NF_DEFRAG_IPV6 if IP6_NF_IPTABLES
@@ -1356,6 +1357,7 @@ config NETFILTER_XT_MATCH_SOCKET
        depends on NETFILTER_ADVANCED
        depends on !NF_CONNTRACK || NF_CONNTRACK
        depends on (IPV6 || IPV6=n)
+       depends on (IP6_NF_IPTABLES || IP6_NF_IPTABLES=n)
        select NF_DEFRAG_IPV4
        select NF_DEFRAG_IPV6 if IP6_NF_IPTABLES
        help
index 49532672f66dad0c3bae1b923993b0d1f518b25b..285eae3a145483c48c00493651a46a5d81656845 100644 (file)
@@ -3823,6 +3823,9 @@ static void __net_exit ip_vs_control_net_cleanup_sysctl(struct net *net)
        cancel_work_sync(&ipvs->defense_work.work);
        unregister_net_sysctl_table(ipvs->sysctl_hdr);
        ip_vs_stop_estimator(net, &ipvs->tot_stats);
+
+       if (!net_eq(net, &init_net))
+               kfree(ipvs->sysctl_tbl);
 }
 
 #else
index 5caa0c41bf26c3e6a2542f0dd50ac6f029ed8a84..70383de7205460a8ebdadd7fd1ba615fc7681296 100644 (file)
@@ -202,7 +202,7 @@ static const u8 tcp_conntracks[2][6][TCP_CONNTRACK_MAX] = {
  *     sES -> sES      :-)
  *     sFW -> sCW      Normal close request answered by ACK.
  *     sCW -> sCW
- *     sLA -> sTW      Last ACK detected.
+ *     sLA -> sTW      Last ACK detected (RFC5961 challenged)
  *     sTW -> sTW      Retransmitted last ACK. Remain in the same state.
  *     sCL -> sCL
  */
@@ -261,7 +261,7 @@ static const u8 tcp_conntracks[2][6][TCP_CONNTRACK_MAX] = {
  *     sES -> sES      :-)
  *     sFW -> sCW      Normal close request answered by ACK.
  *     sCW -> sCW
- *     sLA -> sTW      Last ACK detected.
+ *     sLA -> sTW      Last ACK detected (RFC5961 challenged)
  *     sTW -> sTW      Retransmitted last ACK.
  *     sCL -> sCL
  */
@@ -906,6 +906,7 @@ static int tcp_packet(struct nf_conn *ct,
                                        1 : ct->proto.tcp.last_win;
                        ct->proto.tcp.seen[ct->proto.tcp.last_dir].td_scale =
                                ct->proto.tcp.last_wscale;
+                       ct->proto.tcp.last_flags &= ~IP_CT_EXP_CHALLENGE_ACK;
                        ct->proto.tcp.seen[ct->proto.tcp.last_dir].flags =
                                ct->proto.tcp.last_flags;
                        memset(&ct->proto.tcp.seen[dir], 0,
@@ -923,7 +924,9 @@ static int tcp_packet(struct nf_conn *ct,
                 * may be in sync but we are not. In that case, we annotate
                 * the TCP options and let the packet go through. If it is a
                 * valid SYN packet, the server will reply with a SYN/ACK, and
-                * then we'll get in sync. Otherwise, the server ignores it. */
+                * then we'll get in sync. Otherwise, the server potentially
+                * responds with a challenge ACK if implementing RFC5961.
+                */
                if (index == TCP_SYN_SET && dir == IP_CT_DIR_ORIGINAL) {
                        struct ip_ct_tcp_state seen = {};
 
@@ -939,6 +942,13 @@ static int tcp_packet(struct nf_conn *ct,
                                ct->proto.tcp.last_flags |=
                                        IP_CT_TCP_FLAG_SACK_PERM;
                        }
+                       /* Mark the potential for RFC5961 challenge ACK,
+                        * this pose a special problem for LAST_ACK state
+                        * as ACK is intrepretated as ACKing last FIN.
+                        */
+                       if (old_state == TCP_CONNTRACK_LAST_ACK)
+                               ct->proto.tcp.last_flags |=
+                                       IP_CT_EXP_CHALLENGE_ACK;
                }
                spin_unlock_bh(&ct->lock);
                if (LOG_INVALID(net, IPPROTO_TCP))
@@ -970,6 +980,25 @@ static int tcp_packet(struct nf_conn *ct,
                        nf_log_packet(net, pf, 0, skb, NULL, NULL, NULL,
                                  "nf_ct_tcp: invalid state ");
                return -NF_ACCEPT;
+       case TCP_CONNTRACK_TIME_WAIT:
+               /* RFC5961 compliance cause stack to send "challenge-ACK"
+                * e.g. in response to spurious SYNs.  Conntrack MUST
+                * not believe this ACK is acking last FIN.
+                */
+               if (old_state == TCP_CONNTRACK_LAST_ACK &&
+                   index == TCP_ACK_SET &&
+                   ct->proto.tcp.last_dir != dir &&
+                   ct->proto.tcp.last_index == TCP_SYN_SET &&
+                   (ct->proto.tcp.last_flags & IP_CT_EXP_CHALLENGE_ACK)) {
+                       /* Detected RFC5961 challenge ACK */
+                       ct->proto.tcp.last_flags &= ~IP_CT_EXP_CHALLENGE_ACK;
+                       spin_unlock_bh(&ct->lock);
+                       if (LOG_INVALID(net, IPPROTO_TCP))
+                               nf_log_packet(net, pf, 0, skb, NULL, NULL, NULL,
+                                     "nf_ct_tcp: challenge-ACK ignored ");
+                       return NF_ACCEPT; /* Don't change state */
+               }
+               break;
        case TCP_CONNTRACK_CLOSE:
                if (index == TCP_RST_SET
                    && (ct->proto.tcp.seen[!dir].flags & IP_CT_TCP_FLAG_MAXACK_SET)
index ad9d11fb29fd208cd44d67e786b7977afc9e51e7..34ded09317e715cc94b80ce8d918006bbe1f714b 100644 (file)
@@ -4472,9 +4472,9 @@ EXPORT_SYMBOL_GPL(nft_data_init);
  */
 void nft_data_uninit(const struct nft_data *data, enum nft_data_types type)
 {
-       switch (type) {
-       case NFT_DATA_VALUE:
+       if (type < NFT_DATA_VERDICT)
                return;
+       switch (type) {
        case NFT_DATA_VERDICT:
                return nft_verdict_uninit(data);
        default:
index 3ad91266c821489500fbc8cbbcfc7bfd774b6f48..4ef1fae8445ed5d00183e3b15c7ca18133957983 100644 (file)
@@ -1073,7 +1073,13 @@ static struct pernet_operations nfnl_log_net_ops = {
 
 static int __init nfnetlink_log_init(void)
 {
-       int status = -ENOMEM;
+       int status;
+
+       status = register_pernet_subsys(&nfnl_log_net_ops);
+       if (status < 0) {
+               pr_err("failed to register pernet ops\n");
+               goto out;
+       }
 
        netlink_register_notifier(&nfulnl_rtnl_notifier);
        status = nfnetlink_subsys_register(&nfulnl_subsys);
@@ -1088,28 +1094,23 @@ static int __init nfnetlink_log_init(void)
                goto cleanup_subsys;
        }
 
-       status = register_pernet_subsys(&nfnl_log_net_ops);
-       if (status < 0) {
-               pr_err("failed to register pernet ops\n");
-               goto cleanup_logger;
-       }
        return status;
 
-cleanup_logger:
-       nf_log_unregister(&nfulnl_logger);
 cleanup_subsys:
        nfnetlink_subsys_unregister(&nfulnl_subsys);
 cleanup_netlink_notifier:
        netlink_unregister_notifier(&nfulnl_rtnl_notifier);
+       unregister_pernet_subsys(&nfnl_log_net_ops);
+out:
        return status;
 }
 
 static void __exit nfnetlink_log_fini(void)
 {
-       unregister_pernet_subsys(&nfnl_log_net_ops);
        nf_log_unregister(&nfulnl_logger);
        nfnetlink_subsys_unregister(&nfulnl_subsys);
        netlink_unregister_notifier(&nfulnl_rtnl_notifier);
+       unregister_pernet_subsys(&nfnl_log_net_ops);
 }
 
 MODULE_DESCRIPTION("netfilter userspace logging");
index 0b98c74202390ae79598ceb955360f937bb9556d..11c7682fa0ea1fbd13c90a38126f6a77efcac537 100644 (file)
@@ -1317,7 +1317,13 @@ static struct pernet_operations nfnl_queue_net_ops = {
 
 static int __init nfnetlink_queue_init(void)
 {
-       int status = -ENOMEM;
+       int status;
+
+       status = register_pernet_subsys(&nfnl_queue_net_ops);
+       if (status < 0) {
+               pr_err("nf_queue: failed to register pernet ops\n");
+               goto out;
+       }
 
        netlink_register_notifier(&nfqnl_rtnl_notifier);
        status = nfnetlink_subsys_register(&nfqnl_subsys);
@@ -1326,19 +1332,13 @@ static int __init nfnetlink_queue_init(void)
                goto cleanup_netlink_notifier;
        }
 
-       status = register_pernet_subsys(&nfnl_queue_net_ops);
-       if (status < 0) {
-               pr_err("nf_queue: failed to register pernet ops\n");
-               goto cleanup_subsys;
-       }
        register_netdevice_notifier(&nfqnl_dev_notifier);
        nf_register_queue_handler(&nfqh);
        return status;
 
-cleanup_subsys:
-       nfnetlink_subsys_unregister(&nfqnl_subsys);
 cleanup_netlink_notifier:
        netlink_unregister_notifier(&nfqnl_rtnl_notifier);
+out:
        return status;
 }
 
@@ -1346,9 +1346,9 @@ static void __exit nfnetlink_queue_fini(void)
 {
        nf_unregister_queue_handler();
        unregister_netdevice_notifier(&nfqnl_dev_notifier);
-       unregister_pernet_subsys(&nfnl_queue_net_ops);
        nfnetlink_subsys_unregister(&nfqnl_subsys);
        netlink_unregister_notifier(&nfqnl_rtnl_notifier);
+       unregister_pernet_subsys(&nfnl_queue_net_ops);
 
        rcu_barrier(); /* Wait for completion of call_rcu()'s */
 }
index ec4adbdcb9b4a9926b4d992906f51787c57dc6a2..bf6e76643f7876d8dee4df261baf077aad837be3 100644 (file)
@@ -89,7 +89,7 @@ static inline int netlink_is_kernel(struct sock *sk)
        return nlk_sk(sk)->flags & NETLINK_KERNEL_SOCKET;
 }
 
-struct netlink_table *nl_table;
+struct netlink_table *nl_table __read_mostly;
 EXPORT_SYMBOL_GPL(nl_table);
 
 static DECLARE_WAIT_QUEUE_HEAD(nl_table_wait);
@@ -1081,6 +1081,7 @@ static int netlink_insert(struct sock *sk, u32 portid)
        if (err) {
                if (err == -EEXIST)
                        err = -EADDRINUSE;
+               nlk_sk(sk)->portid = 0;
                sock_put(sk);
        }
 
@@ -3139,7 +3140,6 @@ static const struct rhashtable_params netlink_rhashtable_params = {
        .key_len = netlink_compare_arg_len,
        .obj_hashfn = netlink_hash,
        .obj_cmpfn = netlink_compare,
-       .max_size = 65536,
        .automatic_shrinking = true,
 };
 
index 5102c3cc4eec4ecec6698859935d7769d37a174c..b5989c6ee5513904127a8ffec31d09589094c8f6 100644 (file)
@@ -2311,11 +2311,14 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
                tlen = dev->needed_tailroom;
                skb = sock_alloc_send_skb(&po->sk,
                                hlen + tlen + sizeof(struct sockaddr_ll),
-                               0, &err);
+                               !need_wait, &err);
 
-               if (unlikely(skb == NULL))
+               if (unlikely(skb == NULL)) {
+                       /* we assume the socket was initially writeable ... */
+                       if (likely(len_sum > 0))
+                               err = len_sum;
                        goto out_status;
-
+               }
                tp_len = tpacket_fill_skb(po, skb, ph, dev, size_max, proto,
                                          addr, hlen);
                if (tp_len > dev->mtu + dev->hard_header_len) {
index 14f041398ca1744ea7596decaad7145184c7df0c..da6da57e5f36b5cc13a5bc92abfedb6a5ccea45d 100644 (file)
@@ -126,7 +126,10 @@ static struct rds_connection *__rds_conn_create(__be32 laddr, __be32 faddr,
        struct rds_transport *loop_trans;
        unsigned long flags;
        int ret;
+       struct rds_transport *otrans = trans;
 
+       if (!is_outgoing && otrans->t_type == RDS_TRANS_TCP)
+               goto new_conn;
        rcu_read_lock();
        conn = rds_conn_lookup(head, laddr, faddr, trans);
        if (conn && conn->c_loopback && conn->c_trans != &rds_loop_transport &&
@@ -142,6 +145,7 @@ static struct rds_connection *__rds_conn_create(__be32 laddr, __be32 faddr,
        if (conn)
                goto out;
 
+new_conn:
        conn = kmem_cache_zalloc(rds_conn_slab, gfp);
        if (!conn) {
                conn = ERR_PTR(-ENOMEM);
@@ -230,13 +234,22 @@ static struct rds_connection *__rds_conn_create(__be32 laddr, __be32 faddr,
                /* Creating normal conn */
                struct rds_connection *found;
 
-               found = rds_conn_lookup(head, laddr, faddr, trans);
+               if (!is_outgoing && otrans->t_type == RDS_TRANS_TCP)
+                       found = NULL;
+               else
+                       found = rds_conn_lookup(head, laddr, faddr, trans);
                if (found) {
                        trans->conn_free(conn->c_transport_data);
                        kmem_cache_free(rds_conn_slab, conn);
                        conn = found;
                } else {
-                       hlist_add_head_rcu(&conn->c_hash_node, head);
+                       if ((is_outgoing && otrans->t_type == RDS_TRANS_TCP) ||
+                           (otrans->t_type != RDS_TRANS_TCP)) {
+                               /* Only the active side should be added to
+                                * reconnect list for TCP.
+                                */
+                               hlist_add_head_rcu(&conn->c_hash_node, head);
+                       }
                        rds_cong_add_conn(conn);
                        rds_conn_count++;
                }
index 31b74f5e61adbd37535b636b1499c384bdd992f5..8a09ee7db3c13bdd833784c4ee311e048a7c2789 100644 (file)
@@ -183,8 +183,17 @@ void rds_ib_cm_connect_complete(struct rds_connection *conn, struct rdma_cm_even
 
        /* If the peer gave us the last packet it saw, process this as if
         * we had received a regular ACK. */
-       if (dp && dp->dp_ack_seq)
-               rds_send_drop_acked(conn, be64_to_cpu(dp->dp_ack_seq), NULL);
+       if (dp) {
+               /* dp structure start is not guaranteed to be 8 bytes aligned.
+                * Since dp_ack_seq is 64-bit extended load operations can be
+                * used so go through get_unaligned to avoid unaligned errors.
+                */
+               __be64 dp_ack_seq = get_unaligned(&dp->dp_ack_seq);
+
+               if (dp_ack_seq)
+                       rds_send_drop_acked(conn, be64_to_cpu(dp_ack_seq),
+                                           NULL);
+       }
 
        rds_connect_complete(conn);
 }
index f9f564a6c960e47b3c243d11a3e11317c5a56353..973109c7b8e86f21bec783eb9e4e118e6e8ebb8b 100644 (file)
@@ -62,6 +62,7 @@ void rds_tcp_state_change(struct sock *sk)
                case TCP_ESTABLISHED:
                        rds_connect_complete(conn);
                        break;
+               case TCP_CLOSE_WAIT:
                case TCP_CLOSE:
                        rds_conn_drop(conn);
                default:
index 23ab4dcd1d9f03942aa4d70bc7f6d9aa401f7707..0da49e34495f1e974bf466b83ba1144ec8965f61 100644 (file)
@@ -45,12 +45,45 @@ static void rds_tcp_accept_worker(struct work_struct *work);
 static DECLARE_WORK(rds_tcp_listen_work, rds_tcp_accept_worker);
 static struct socket *rds_tcp_listen_sock;
 
+static int rds_tcp_keepalive(struct socket *sock)
+{
+       /* values below based on xs_udp_default_timeout */
+       int keepidle = 5; /* send a probe 'keepidle' secs after last data */
+       int keepcnt = 5; /* number of unack'ed probes before declaring dead */
+       int keepalive = 1;
+       int ret = 0;
+
+       ret = kernel_setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE,
+                               (char *)&keepalive, sizeof(keepalive));
+       if (ret < 0)
+               goto bail;
+
+       ret = kernel_setsockopt(sock, IPPROTO_TCP, TCP_KEEPCNT,
+                               (char *)&keepcnt, sizeof(keepcnt));
+       if (ret < 0)
+               goto bail;
+
+       ret = kernel_setsockopt(sock, IPPROTO_TCP, TCP_KEEPIDLE,
+                               (char *)&keepidle, sizeof(keepidle));
+       if (ret < 0)
+               goto bail;
+
+       /* KEEPINTVL is the interval between successive probes. We follow
+        * the model in xs_tcp_finish_connecting() and re-use keepidle.
+        */
+       ret = kernel_setsockopt(sock, IPPROTO_TCP, TCP_KEEPINTVL,
+                               (char *)&keepidle, sizeof(keepidle));
+bail:
+       return ret;
+}
+
 static int rds_tcp_accept_one(struct socket *sock)
 {
        struct socket *new_sock = NULL;
        struct rds_connection *conn;
        int ret;
        struct inet_sock *inet;
+       struct rds_tcp_connection *rs_tcp;
 
        ret = sock_create_lite(sock->sk->sk_family, sock->sk->sk_type,
                               sock->sk->sk_protocol, &new_sock);
@@ -63,6 +96,10 @@ static int rds_tcp_accept_one(struct socket *sock)
        if (ret < 0)
                goto out;
 
+       ret = rds_tcp_keepalive(new_sock);
+       if (ret < 0)
+               goto out;
+
        rds_tcp_tune(new_sock);
 
        inet = inet_sk(new_sock->sk);
@@ -77,6 +114,15 @@ static int rds_tcp_accept_one(struct socket *sock)
                ret = PTR_ERR(conn);
                goto out;
        }
+       /* An incoming SYN request came in, and TCP just accepted it.
+        * We always create a new conn for listen side of TCP, and do not
+        * add it to the c_hash_list.
+        *
+        * If the client reboots, this conn will need to be cleaned up.
+        * rds_tcp_state_change() will do that cleanup
+        */
+       rs_tcp = (struct rds_tcp_connection *)conn->c_transport_data;
+       WARN_ON(!rs_tcp || rs_tcp->t_sock);
 
        /*
         * see the comment above rds_queue_delayed_reconnect()
index 8b0470e418dc6e9475464768d629969087e66b37..a75864d93142153bfff4ab765620e10bcfab3e96 100644 (file)
@@ -81,6 +81,11 @@ int unregister_tcf_proto_ops(struct tcf_proto_ops *ops)
        struct tcf_proto_ops *t;
        int rc = -ENOENT;
 
+       /* Wait for outstanding call_rcu()s, if any, from a
+        * tcf_proto_ops's destroy() handler.
+        */
+       rcu_barrier();
+
        write_lock(&cls_mod_lock);
        list_for_each_entry(t, &tcf_proto_base, head) {
                if (t == ops) {
@@ -308,12 +313,11 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n)
                case RTM_DELTFILTER:
                        err = tp->ops->delete(tp, fh);
                        if (err == 0) {
-                               tfilter_notify(net, skb, n, tp, fh, RTM_DELTFILTER);
-                               if (tcf_destroy(tp, false)) {
-                                       struct tcf_proto *next = rtnl_dereference(tp->next);
+                               struct tcf_proto *next = rtnl_dereference(tp->next);
 
+                               tfilter_notify(net, skb, n, tp, fh, RTM_DELTFILTER);
+                               if (tcf_destroy(tp, false))
                                        RCU_INIT_POINTER(*back, next);
-                               }
                        }
                        goto errout;
                case RTM_GETTFILTER:
index ad9eed70bc8f8e16c3118c6527374a952823e2c0..1e1c89e51a118e79610c49412e335191fc3ba834 100644 (file)
@@ -815,10 +815,8 @@ static int qdisc_graft(struct net_device *dev, struct Qdisc *parent,
                if (dev->flags & IFF_UP)
                        dev_deactivate(dev);
 
-               if (new && new->ops->attach) {
-                       new->ops->attach(new);
-                       num_q = 0;
-               }
+               if (new && new->ops->attach)
+                       goto skip;
 
                for (i = 0; i < num_q; i++) {
                        struct netdev_queue *dev_queue = dev_ingress_queue(dev);
@@ -834,12 +832,16 @@ static int qdisc_graft(struct net_device *dev, struct Qdisc *parent,
                                qdisc_destroy(old);
                }
 
+skip:
                if (!ingress) {
                        notify_and_destroy(net, skb, n, classid,
                                           dev->qdisc, new);
                        if (new && !new->ops->attach)
                                atomic_inc(&new->refcnt);
                        dev->qdisc = new ? : &noop_qdisc;
+
+                       if (new && new->ops->attach)
+                               new->ops->attach(new);
                } else {
                        notify_and_destroy(net, skb, n, classid, old, new);
                }
index de28f8e968e8176ac7630a1e6fcccb45ad295f5d..7a0bdb16ac92fd0a20f565295392bed8674c8d90 100644 (file)
@@ -164,7 +164,7 @@ static int codel_init(struct Qdisc *sch, struct nlattr *opt)
 
        sch->limit = DEFAULT_CODEL_LIMIT;
 
-       codel_params_init(&q->params);
+       codel_params_init(&q->params, sch);
        codel_vars_init(&q->vars);
        codel_stats_init(&q->stats);
 
index 1e52decb7b59cf0b4173d0f17efdab8fefee5f26..c244c45b78d7feca32fda3b925f7605aebf0a5b6 100644 (file)
@@ -391,7 +391,7 @@ static int fq_codel_init(struct Qdisc *sch, struct nlattr *opt)
        q->perturbation = prandom_u32();
        INIT_LIST_HEAD(&q->new_flows);
        INIT_LIST_HEAD(&q->old_flows);
-       codel_params_init(&q->cparams);
+       codel_params_init(&q->cparams, sch);
        codel_stats_init(&q->cstats);
        q->cparams.ecn = true;
 
index a4ca4517cdc82843e21e5245989a59e89aa53702..634529e0ce6bddc44b48161b6f76bd79af0a2a8e 100644 (file)
@@ -229,7 +229,7 @@ static int gred_enqueue(struct sk_buff *skb, struct Qdisc *sch)
                break;
        }
 
-       if (q->backlog + qdisc_pkt_len(skb) <= q->limit) {
+       if (gred_backlog(t, q, sch) + qdisc_pkt_len(skb) <= q->limit) {
                q->backlog += qdisc_pkt_len(skb);
                return qdisc_enqueue_tail(skb, sch);
        }
@@ -553,7 +553,7 @@ static int gred_dump(struct Qdisc *sch, struct sk_buff *skb)
 
                opt.limit       = q->limit;
                opt.DP          = q->DP;
-               opt.backlog     = q->backlog;
+               opt.backlog     = gred_backlog(table, q, sch);
                opt.prio        = q->prio;
                opt.qth_min     = q->parms.qth_min >> q->parms.Wlog;
                opt.qth_max     = q->parms.qth_max >> q->parms.Wlog;
index 1ec19f6f0c2b9fe71ee9a7110873873274b9ab62..eeeba5adee6d939ab3429100d231a46e82b1ff94 100644 (file)
@@ -793,20 +793,26 @@ int gssx_dec_accept_sec_context(struct rpc_rqst *rqstp,
 {
        u32 value_follows;
        int err;
+       struct page *scratch;
+
+       scratch = alloc_page(GFP_KERNEL);
+       if (!scratch)
+               return -ENOMEM;
+       xdr_set_scratch_buffer(xdr, page_address(scratch), PAGE_SIZE);
 
        /* res->status */
        err = gssx_dec_status(xdr, &res->status);
        if (err)
-               return err;
+               goto out_free;
 
        /* res->context_handle */
        err = gssx_dec_bool(xdr, &value_follows);
        if (err)
-               return err;
+               goto out_free;
        if (value_follows) {
                err = gssx_dec_ctx(xdr, res->context_handle);
                if (err)
-                       return err;
+                       goto out_free;
        } else {
                res->context_handle = NULL;
        }
@@ -814,11 +820,11 @@ int gssx_dec_accept_sec_context(struct rpc_rqst *rqstp,
        /* res->output_token */
        err = gssx_dec_bool(xdr, &value_follows);
        if (err)
-               return err;
+               goto out_free;
        if (value_follows) {
                err = gssx_dec_buffer(xdr, res->output_token);
                if (err)
-                       return err;
+                       goto out_free;
        } else {
                res->output_token = NULL;
        }
@@ -826,14 +832,17 @@ int gssx_dec_accept_sec_context(struct rpc_rqst *rqstp,
        /* res->delegated_cred_handle */
        err = gssx_dec_bool(xdr, &value_follows);
        if (err)
-               return err;
+               goto out_free;
        if (value_follows) {
                /* we do not support upcall servers sending this data. */
-               return -EINVAL;
+               err = -EINVAL;
+               goto out_free;
        }
 
        /* res->options */
        err = gssx_dec_option_array(xdr, &res->options);
 
+out_free:
+       __free_page(scratch);
        return err;
 }
index 46568b85c3339f57a0d6835e82eff4b67c3ba326..055453d486683ec19433961db220292e4f60571d 100644 (file)
@@ -338,7 +338,7 @@ int netdev_switch_fib_ipv4_add(u32 dst, int dst_len, struct fib_info *fi,
                                              fi, tos, type, nlflags,
                                              tb_id);
                if (!err)
-                       fi->fib_flags |= RTNH_F_EXTERNAL;
+                       fi->fib_flags |= RTNH_F_OFFLOAD;
        }
 
        return err;
@@ -364,7 +364,7 @@ int netdev_switch_fib_ipv4_del(u32 dst, int dst_len, struct fib_info *fi,
        const struct swdev_ops *ops;
        int err = 0;
 
-       if (!(fi->fib_flags & RTNH_F_EXTERNAL))
+       if (!(fi->fib_flags & RTNH_F_OFFLOAD))
                return 0;
 
        dev = netdev_switch_get_dev_by_nhs(fi);
@@ -376,7 +376,7 @@ int netdev_switch_fib_ipv4_del(u32 dst, int dst_len, struct fib_info *fi,
                err = ops->swdev_fib_ipv4_del(dev, htonl(dst), dst_len,
                                              fi, tos, type, tb_id);
                if (!err)
-                       fi->fib_flags &= ~RTNH_F_EXTERNAL;
+                       fi->fib_flags &= ~RTNH_F_OFFLOAD;
        }
 
        return err;
index 5266ea7b922b76d1977dea57cc7c227594c49285..06430598cf512fdaff480671620e8fa69c259bb5 100644 (file)
@@ -1880,6 +1880,10 @@ static long unix_stream_data_wait(struct sock *sk, long timeo,
                unix_state_unlock(sk);
                timeo = freezable_schedule_timeout(timeo);
                unix_state_lock(sk);
+
+               if (sock_flag(sk, SOCK_DEAD))
+                       break;
+
                clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
        }
 
@@ -1939,6 +1943,10 @@ static int unix_stream_recvmsg(struct socket *sock, struct msghdr *msg,
                struct sk_buff *skb, *last;
 
                unix_state_lock(sk);
+               if (sock_flag(sk, SOCK_DEAD)) {
+                       err = -ECONNRESET;
+                       goto unlock;
+               }
                last = skb = skb_peek(&sk->sk_receive_queue);
 again:
                if (skb == NULL) {
index 0c356fb650220c6cd5d452d68a22eeb286d40d13..18ffccf004264d202632990d40227c27c41d27ad 100644 (file)
@@ -14,9 +14,10 @@ define allow-override
     $(eval $(1) = $(2)))
 endef
 
-# Allow setting CC and AR, or setting CROSS_COMPILE as a prefix.
+# Allow setting CC and AR and LD, or setting CROSS_COMPILE as a prefix.
 $(call allow-override,CC,$(CROSS_COMPILE)gcc)
 $(call allow-override,AR,$(CROSS_COMPILE)ar)
+$(call allow-override,LD,$(CROSS_COMPILE)ld)
 
 INSTALL = install
 
index a11e3c357be7f8fb00720694324f26adae0402c5..cd2cc59a5da7900e53084fe19e650438e13af0a2 100644 (file)
@@ -28,6 +28,9 @@
 #define __init
 #define noinline
 #define list_add_tail_rcu list_add_tail
+#define list_for_each_entry_rcu list_for_each_entry
+#define barrier() 
+#define synchronize_sched()
 
 #ifndef CALLER_ADDR0
 #define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0))
index c5baf9c591b7bb5a2c280e173f4e0a2b561285fa..618c2bcd4eabc6143b0e7f0431f57b8620101fe5 100644 (file)
@@ -123,6 +123,8 @@ static int get_last_jit_image(char *haystack, size_t hlen,
        assert(ret == 0);
 
        ptr = haystack;
+       memset(pmatch, 0, sizeof(pmatch));
+
        while (1) {
                ret = regexec(&regex, ptr, 1, pmatch, 0);
                if (ret == 0) {
index c699dc35eef9cbd1bc96427f453acc23a2e9c103..d31a7bbd7cee8610db236c7842cfb5ec63dc56b0 100644 (file)
@@ -24,7 +24,7 @@ unexport MAKEFLAGS
 # (To override it, run 'make JOBS=1' and similar.)
 #
 ifeq ($(JOBS),)
-  JOBS := $(shell egrep -c '^processor|^CPU' /proc/cpuinfo 2>/dev/null)
+  JOBS := $(shell (getconf _NPROCESSORS_ONLN || egrep -c '^processor|^CPU[0-9]' /proc/cpuinfo) 2>/dev/null)
   ifeq ($(JOBS),0)
     JOBS := 1
   endif
index ddf63569df5ae166e466901aa1a60e1b194fe508..5bdb781163d1f2d0eb6a69fea8a976fa2873f3b1 100644 (file)
@@ -1,4 +1,8 @@
-.PHONY: all all_32 all_64 check_build32 clean run_tests
+all:
+
+include ../lib.mk
+
+.PHONY: all all_32 all_64 warn_32bit_failure clean
 
 TARGETS_C_BOTHBITS := sigreturn single_step_syscall
 
@@ -7,42 +11,47 @@ BINARIES_64 := $(TARGETS_C_BOTHBITS:%=%_64)
 
 CFLAGS := -O2 -g -std=gnu99 -pthread -Wall
 
-UNAME_P := $(shell uname -p)
+UNAME_M := $(shell uname -m)
+CAN_BUILD_I386 := $(shell ./check_cc.sh $(CC) trivial_32bit_program.c -m32)
+CAN_BUILD_X86_64 := $(shell ./check_cc.sh $(CC) trivial_64bit_program.c)
 
-# Always build 32-bit tests
+ifeq ($(CAN_BUILD_I386),1)
 all: all_32
+TEST_PROGS += $(BINARIES_32)
+endif
 
-# If we're on a 64-bit host, build 64-bit tests as well
-ifeq ($(shell uname -p),x86_64)
+ifeq ($(CAN_BUILD_X86_64),1)
 all: all_64
+TEST_PROGS += $(BINARIES_64)
 endif
 
-all_32: check_build32 $(BINARIES_32)
+all_32: $(BINARIES_32)
 
 all_64: $(BINARIES_64)
 
 clean:
        $(RM) $(BINARIES_32) $(BINARIES_64)
 
-run_tests:
-       ./run_x86_tests.sh
-
 $(TARGETS_C_BOTHBITS:%=%_32): %_32: %.c
        $(CC) -m32 -o $@ $(CFLAGS) $(EXTRA_CFLAGS) $^ -lrt -ldl
 
 $(TARGETS_C_BOTHBITS:%=%_64): %_64: %.c
        $(CC) -m64 -o $@ $(CFLAGS) $(EXTRA_CFLAGS) $^ -lrt -ldl
 
-check_build32:
-       @if ! $(CC) -m32 -o /dev/null trivial_32bit_program.c; then     \
-         echo "Warning: you seem to have a broken 32-bit build" 2>&1;  \
-         echo "environment.  If you are using a Debian-like";          \
-         echo " distribution, try:";                                   \
-         echo "";                                                      \
-         echo "  apt-get install gcc-multilib libc6-i386 libc6-dev-i386"; \
-         echo "";                                                      \
-         echo "If you are using a Fedora-like distribution, try:";     \
-         echo "";                                                      \
-         echo "  yum install glibc-devel.*i686";                       \
-         exit 1;                                                       \
-       fi
+# x86_64 users should be encouraged to install 32-bit libraries
+ifeq ($(CAN_BUILD_I386)$(CAN_BUILD_X86_64),01)
+all: warn_32bit_failure
+
+warn_32bit_failure:
+       @echo "Warning: you seem to have a broken 32-bit build" 2>&1;   \
+       echo "environment.  This will reduce test coverage of 64-bit" 2>&1; \
+       echo "kernels.  If you are using a Debian-like distribution," 2>&1; \
+       echo "try:"; 2>&1; \
+       echo "";                                                        \
+       echo "  apt-get install gcc-multilib libc6-i386 libc6-dev-i386"; \
+       echo "";                                                        \
+       echo "If you are using a Fedora-like distribution, try:";       \
+       echo "";                                                        \
+       echo "  yum install glibc-devel.*i686";                         \
+       exit 0;
+endif
diff --git a/tools/testing/selftests/x86/check_cc.sh b/tools/testing/selftests/x86/check_cc.sh
new file mode 100755 (executable)
index 0000000..172d329
--- /dev/null
@@ -0,0 +1,16 @@
+#!/bin/sh
+# check_cc.sh - Helper to test userspace compilation support
+# Copyright (c) 2015 Andrew Lutomirski
+# GPL v2
+
+CC="$1"
+TESTPROG="$2"
+shift 2
+
+if "$CC" -o /dev/null "$TESTPROG" -O0 "$@" 2>/dev/null; then
+    echo 1
+else
+    echo 0
+fi
+
+exit 0
diff --git a/tools/testing/selftests/x86/run_x86_tests.sh b/tools/testing/selftests/x86/run_x86_tests.sh
deleted file mode 100644 (file)
index 3fc19b3..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-#!/bin/bash
-
-# This is deliberately minimal.  IMO kselftests should provide a standard
-# script here.
-./sigreturn_32 || exit 1
-./single_step_syscall_32 || exit 1
-
-if [[ "$uname -p" -eq "x86_64" ]]; then
-    ./sigreturn_64 || exit 1
-    ./single_step_syscall_64 || exit 1
-fi
-
-exit 0
index 2e231beb0a39e7c4b1571dc6ee746941ff069705..fabdf0f51621e30a850c510ffcce8841115c10f2 100644 (file)
@@ -4,6 +4,10 @@
  * GPL v2
  */
 
+#ifndef __i386__
+# error wrong architecture
+#endif
+
 #include <stdio.h>
 
 int main()
diff --git a/tools/testing/selftests/x86/trivial_64bit_program.c b/tools/testing/selftests/x86/trivial_64bit_program.c
new file mode 100644 (file)
index 0000000..b994946
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * Trivial program to check that we have a valid 32-bit build environment.
+ * Copyright (c) 2015 Andy Lutomirski
+ * GPL v2
+ */
+
+#ifndef __x86_64__
+# error wrong architecture
+#endif
+
+#include <stdio.h>
+
+int main()
+{
+       printf("\n");
+
+       return 0;
+}
index 0788621c8d760f01f714d377a18c6a390a990fde..2e83dd3655a28ae606a0a2c8c4b80a58331ef24e 100644 (file)
@@ -12,10 +12,6 @@ TARGET=tmon
 INSTALL_PROGRAM=install -m 755 -p
 DEL_FILE=rm -f
 
-INSTALL_CONFIGFILE=install -m 644 -p
-CONFIG_FILE=
-CONFIG_PATH=
-
 # Static builds might require -ltinfo, for instance
 ifneq ($(findstring -static, $(LDFLAGS)),)
 STATIC := --static
@@ -38,13 +34,9 @@ valgrind: tmon
 install:
        - mkdir -p $(INSTALL_ROOT)/$(BINDIR)
        - $(INSTALL_PROGRAM) "$(TARGET)" "$(INSTALL_ROOT)/$(BINDIR)/$(TARGET)"
-       - mkdir -p $(INSTALL_ROOT)/$(CONFIG_PATH)
-       - $(INSTALL_CONFIGFILE) "$(CONFIG_FILE)" "$(INSTALL_ROOT)/$(CONFIG_PATH)"
 
 uninstall:
        $(DEL_FILE) "$(INSTALL_ROOT)/$(BINDIR)/$(TARGET)"
-       $(CONFIG_FILE) "$(CONFIG_PATH)"
-
 
 clean:
        find . -name "*.o" | xargs $(DEL_FILE)
index ac884b65a0725fc9b4e2ed46a490996524fd96a3..93aadaf7ff63d66afab325a67bd09fba982de947 100644 (file)
@@ -3,7 +3,7 @@
 TARGETS=page-types slabinfo page_owner_sort
 
 LIB_DIR = ../lib/api
-LIBS = $(LIB_DIR)/libapikfs.a
+LIBS = $(LIB_DIR)/libapi.a
 
 CC = $(CROSS_COMPILE)gcc
 CFLAGS = -Wall -Wextra -I../lib/