]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
Merge branch 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 8 Jan 2016 23:21:48 +0000 (15:21 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 8 Jan 2016 23:21:48 +0000 (15:21 -0800)
Pull x86 fixes from Ingo Molnar:
 "A handful of x86 fixes:

   - a syscall ABI fix, fixing an Android breakage
   - a Xen PV guest fix relating to the RTC device, causing a
     non-working console
   - a Xen guest syscall stack frame fix
   - an MCE hotplug CPU crash fix"

* 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86/numachip: Fix NumaConnect2 MMCFG PCI access
  x86/entry: Restore traditional SYSENTER calling convention
  x86/entry: Fix some comments
  x86/paravirt: Prevent rtc_cmos platform device init on PV guests
  x86/xen: Avoid fast syscall path for Xen PV guests
  x86/mce: Ensure offline CPUs don't participate in rendezvous process

594 files changed:
Documentation/devicetree/bindings/dma/ti-edma.txt
Documentation/devicetree/bindings/gpio/gpio-mpc8xxx.txt
Documentation/devicetree/bindings/input/sun4i-lradc-keys.txt
Documentation/devicetree/bindings/mtd/partition.txt
Documentation/devicetree/bindings/net/cpsw.txt
Documentation/networking/e100.txt
MAINTAINERS
Makefile
arch/arc/Kconfig
arch/arc/Makefile
arch/arc/boot/dts/axs10x_mb.dtsi
arch/arc/boot/dts/nsim_hs.dts
arch/arc/include/asm/cache.h
arch/arc/include/asm/mach_desc.h
arch/arc/include/asm/smp.h
arch/arc/include/asm/unwind.h
arch/arc/kernel/intc-arcv2.c
arch/arc/kernel/irq.c
arch/arc/kernel/mcip.c
arch/arc/kernel/perf_event.c
arch/arc/kernel/setup.c
arch/arc/kernel/smp.c
arch/arc/kernel/unwind.c
arch/arc/mm/highmem.c
arch/arc/mm/init.c
arch/arm/boot/dts/am4372.dtsi
arch/arm/boot/dts/am43xx-clocks.dtsi
arch/arm/boot/dts/at91-sama5d2_xplained.dts
arch/arm/boot/dts/berlin2q.dtsi
arch/arm/boot/dts/dm816x.dtsi
arch/arm/boot/dts/imx6q-gw5400-a.dts
arch/arm/boot/dts/imx6qdl-gw51xx.dtsi
arch/arm/boot/dts/imx6qdl-gw52xx.dtsi
arch/arm/boot/dts/imx6qdl-gw53xx.dtsi
arch/arm/boot/dts/imx6qdl-gw54xx.dtsi
arch/arm/boot/dts/imx6qdl-sabreauto.dtsi
arch/arm/boot/dts/omap4-duovero-parlor.dts
arch/arm/boot/dts/sun6i-a31s-primo81.dts
arch/arm/boot/dts/tegra124-nyan.dtsi
arch/arm/boot/dts/vf610-colibri.dtsi
arch/arm/boot/dts/vf610.dtsi
arch/arm/boot/dts/vfxxx.dtsi
arch/arm/include/asm/arch_gicv3.h
arch/arm/include/asm/uaccess.h
arch/arm/kernel/process.c
arch/arm/kernel/swp_emulate.c
arch/arm/kernel/sys_oabi-compat.c
arch/arm/lib/uaccess_with_memcpy.c
arch/arm/mach-at91/Kconfig
arch/arm/mach-at91/pm.c
arch/arm/mach-exynos/pmu.c
arch/arm/mach-ixp4xx/include/mach/io.h
arch/arm/mach-omap2/Kconfig
arch/arm/mach-omap2/timer.c
arch/arm/mach-pxa/ezx.c
arch/arm/mach-s3c24xx/pll-s3c2440-12000000.c
arch/arm/mach-s3c24xx/pll-s3c2440-16934400.c
arch/arm/mm/context.c
arch/arm/mm/dma-mapping.c
arch/arm/mm/init.c
arch/arm/mm/proc-v7.S
arch/arm/net/bpf_jit_32.c
arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi
arch/arm64/include/asm/arch_gicv3.h
arch/arm64/include/asm/pgtable.h
arch/arm64/kernel/vmlinux.lds.S
arch/ia64/include/asm/unistd.h
arch/ia64/include/uapi/asm/unistd.h
arch/ia64/kernel/entry.S
arch/m32r/include/asm/Kbuild
arch/m32r/include/asm/io.h
arch/microblaze/kernel/dma.c
arch/mips/include/asm/uaccess.h
arch/mips/kernel/cps-vec.S
arch/mips/kernel/mips_ksyms.c
arch/mips/lib/memset.S
arch/mips/mm/dma-default.c
arch/mips/net/bpf_jit.c
arch/mips/pci/pci-rt2880.c
arch/mips/pmcs-msp71xx/msp_setup.c
arch/mips/sni/reset.c
arch/mips/vdso/Makefile
arch/parisc/include/asm/pgtable.h
arch/parisc/include/uapi/asm/unistd.h
arch/parisc/kernel/pci.c
arch/parisc/kernel/signal.c
arch/parisc/kernel/syscall_table.S
arch/powerpc/boot/dts/sbc8641d.dts
arch/powerpc/include/asm/systbl.h
arch/powerpc/include/uapi/asm/unistd.h
arch/powerpc/kernel/eeh_driver.c
arch/powerpc/kvm/book3s_hv.c
arch/powerpc/net/bpf_jit_comp.c
arch/powerpc/platforms/powernv/opal-irqchip.c
arch/powerpc/platforms/powernv/opal.c
arch/s390/kernel/dis.c
arch/sh/include/uapi/asm/unistd_64.h
arch/sparc/include/asm/elf_64.h
arch/sparc/include/uapi/asm/unistd.h
arch/sparc/kernel/head_64.S
arch/sparc/kernel/perf_event.c
arch/sparc/kernel/rtrap_64.S
arch/sparc/kernel/setup_64.c
arch/sparc/kernel/systbls_32.S
arch/sparc/kernel/systbls_64.S
arch/sparc/lib/NG2copy_from_user.S
arch/sparc/lib/NG2copy_to_user.S
arch/sparc/lib/NG2memcpy.S
arch/sparc/lib/NG4copy_from_user.S
arch/sparc/lib/NG4copy_to_user.S
arch/sparc/lib/NG4memcpy.S
arch/sparc/lib/U1copy_from_user.S
arch/sparc/lib/U1copy_to_user.S
arch/sparc/lib/U1memcpy.S
arch/sparc/lib/U3copy_from_user.S
arch/sparc/lib/U3copy_to_user.S
arch/sparc/lib/U3memcpy.S
arch/sparc/net/bpf_jit_comp.c
arch/tile/Kconfig
arch/tile/include/asm/page.h
arch/x86/kvm/cpuid.h
arch/x86/kvm/mtrr.c
arch/x86/kvm/svm.c
arch/x86/kvm/vmx.c
arch/x86/kvm/x86.c
arch/x86/mm/dump_pagetables.c
arch/x86/um/signal.c
arch/x86/xen/mmu.c
arch/x86/xen/suspend.c
block/blk-core.c
crypto/ablkcipher.c
crypto/algif_skcipher.c
crypto/async_tx/async_memcpy.c
crypto/async_tx/async_pq.c
crypto/async_tx/async_raid6_recov.c
crypto/async_tx/async_xor.c
crypto/blkcipher.c
drivers/acpi/nfit.c
drivers/acpi/processor_driver.c
drivers/base/memory.c
drivers/base/power/domain.c
drivers/block/null_blk.c
drivers/block/xen-blkback/blkback.c
drivers/block/xen-blkback/common.h
drivers/bus/sunxi-rsb.c
drivers/clk/imx/clk-vf610.c
drivers/clocksource/mmio.c
drivers/connector/connector.c
drivers/cpufreq/Kconfig.arm
drivers/cpufreq/intel_pstate.c
drivers/cpufreq/s3c24xx-cpufreq.c
drivers/cpufreq/scpi-cpufreq.c
drivers/dma/at_xdmac.c
drivers/dma/bcm2835-dma.c
drivers/dma/edma.c
drivers/dma/xgene-dma.c
drivers/firmware/dmi_scan.c
drivers/fpga/fpga-mgr.c
drivers/gpio/gpio-ath79.c
drivers/gpio/gpio-generic.c
drivers/gpio/gpiolib.c
drivers/gpu/drm/amd/amdgpu/amdgpu.h
drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
drivers/gpu/drm/drm_probe_helper.c
drivers/gpu/drm/exynos/exynos_drm_crtc.c
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/i915_gem.c
drivers/gpu/drm/i915/i915_gem_context.c
drivers/gpu/drm/i915/i915_gem_gtt.c
drivers/gpu/drm/i915/i915_gem_stolen.c
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_drv.h
drivers/gpu/drm/i915/intel_hdmi.c
drivers/gpu/drm/i915/intel_pm.c
drivers/gpu/drm/nouveau/include/nvkm/core/device.h
drivers/gpu/drm/nouveau/nvkm/engine/device/pci.c
drivers/gpu/drm/nouveau/nvkm/engine/gr/nv40.c
drivers/gpu/drm/nouveau/nvkm/subdev/bios/fan.c
drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk104.c
drivers/gpu/drm/omapdrm/omap_fbdev.c
drivers/gpu/drm/radeon/cik.c
drivers/gpu/drm/radeon/radeon_vce.c
drivers/gpu/drm/ttm/ttm_lock.c
drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c
drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
drivers/gpu/drm/vmwgfx/vmwgfx_kms.h
drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c
drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c
drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c
drivers/gpu/vga/vgaarb.c
drivers/hid/hid-ids.h
drivers/hid/usbhid/hid-quirks.c
drivers/hwmon/Kconfig
drivers/hwmon/tmp102.c
drivers/i2c/busses/i2c-davinci.c
drivers/i2c/busses/i2c-designware-core.c
drivers/i2c/busses/i2c-designware-core.h
drivers/i2c/busses/i2c-designware-platdrv.c
drivers/i2c/busses/i2c-imx.c
drivers/i2c/busses/i2c-mv64xxx.c
drivers/i2c/busses/i2c-rcar.c
drivers/i2c/busses/i2c-rk3x.c
drivers/i2c/busses/i2c-st.c
drivers/iio/adc/qcom-spmi-vadc.c
drivers/iio/industrialio-buffer.c
drivers/iio/industrialio-core.c
drivers/iio/light/apds9960.c
drivers/iio/proximity/pulsedlight-lidar-lite-v2.c
drivers/infiniband/core/cma.c
drivers/infiniband/core/mad.c
drivers/infiniband/core/sa_query.c
drivers/infiniband/core/uverbs_cmd.c
drivers/infiniband/core/verbs.c
drivers/infiniband/hw/mlx4/main.c
drivers/infiniband/hw/mlx4/qp.c
drivers/infiniband/hw/mlx4/srq.c
drivers/infiniband/hw/mlx5/mr.c
drivers/infiniband/hw/ocrdma/ocrdma.h
drivers/infiniband/hw/ocrdma/ocrdma_hw.c
drivers/infiniband/hw/ocrdma/ocrdma_hw.h
drivers/infiniband/hw/ocrdma/ocrdma_main.c
drivers/infiniband/hw/ocrdma/ocrdma_sli.h
drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
drivers/infiniband/hw/qib/qib_qsfp.c
drivers/infiniband/hw/qib/qib_verbs.h
drivers/infiniband/ulp/iser/iser_verbs.c
drivers/infiniband/ulp/isert/ib_isert.c
drivers/infiniband/ulp/srp/ib_srp.c
drivers/infiniband/ulp/srp/ib_srp.h
drivers/input/joystick/db9.c
drivers/input/joystick/gamecon.c
drivers/input/joystick/turbografx.c
drivers/input/joystick/walkera0701.c
drivers/input/misc/arizona-haptics.c
drivers/input/mouse/elan_i2c_core.c
drivers/input/serio/parkbd.c
drivers/input/tablet/aiptek.c
drivers/input/touchscreen/atmel_mxt_ts.c
drivers/input/touchscreen/elants_i2c.c
drivers/iommu/amd_iommu_v2.c
drivers/iommu/dma-iommu.c
drivers/iommu/intel-iommu.c
drivers/iommu/intel-svm.c
drivers/iommu/iommu.c
drivers/iommu/ipmmu-vmsa.c
drivers/irqchip/irq-versatile-fpga.c
drivers/isdn/gigaset/ser-gigaset.c
drivers/isdn/hardware/mISDN/mISDNipac.c
drivers/lightnvm/Kconfig
drivers/lightnvm/core.c
drivers/lightnvm/gennvm.c
drivers/lightnvm/rrpc.c
drivers/md/dm-thin-metadata.c
drivers/md/md.c
drivers/md/md.h
drivers/md/persistent-data/dm-btree.c
drivers/md/persistent-data/dm-btree.h
drivers/md/persistent-data/dm-space-map-metadata.c
drivers/md/raid10.c
drivers/media/pci/ivtv/ivtv-driver.c
drivers/media/usb/airspy/airspy.c
drivers/media/usb/hackrf/hackrf.c
drivers/memory/fsl_ifc.c
drivers/misc/cxl/native.c
drivers/mtd/mtdcore.c
drivers/mtd/ofpart.c
drivers/mtd/spi-nor/spi-nor.c
drivers/mtd/ubi/debug.c
drivers/mtd/ubi/io.c
drivers/mtd/ubi/wl.c
drivers/net/ethernet/amd/xgbe/xgbe-dev.c
drivers/net/ethernet/apm/xgene/xgene_enet_main.c
drivers/net/ethernet/apm/xgene/xgene_enet_main.h
drivers/net/ethernet/atheros/atl1c/atl1c_main.c
drivers/net/ethernet/aurora/Kconfig
drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
drivers/net/ethernet/broadcom/bnxt/bnxt.c
drivers/net/ethernet/broadcom/bnxt/bnxt.h
drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c
drivers/net/ethernet/cavium/thunder/nic_main.c
drivers/net/ethernet/chelsio/cxgb4/clip_tbl.c
drivers/net/ethernet/emulex/benet/be.h
drivers/net/ethernet/emulex/benet/be_main.c
drivers/net/ethernet/emulex/benet/be_roce.c
drivers/net/ethernet/emulex/benet/be_roce.h
drivers/net/ethernet/ezchip/nps_enet.c
drivers/net/ethernet/freescale/fs_enet/mac-fcc.c
drivers/net/ethernet/freescale/fsl_pq_mdio.c
drivers/net/ethernet/freescale/gianfar.c
drivers/net/ethernet/freescale/gianfar.h
drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c
drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h
drivers/net/ethernet/intel/i40e/i40e_adminq.c
drivers/net/ethernet/intel/i40e/i40e_main.c
drivers/net/ethernet/intel/i40evf/i40e_adminq.c
drivers/net/ethernet/intel/i40evf/i40evf_main.c
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
drivers/net/ethernet/marvell/mvpp2.c
drivers/net/ethernet/mellanox/mlx4/cmd.c
drivers/net/ethernet/mellanox/mlx4/en_clock.c
drivers/net/ethernet/mellanox/mlx4/en_main.c
drivers/net/ethernet/mellanox/mlx4/en_netdev.c
drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
drivers/net/ethernet/natsemi/natsemi.c
drivers/net/ethernet/qlogic/qed/qed.h
drivers/net/ethernet/qlogic/qed/qed_dev.c
drivers/net/ethernet/qlogic/qed/qed_int.c
drivers/net/ethernet/qlogic/qed/qed_int.h
drivers/net/ethernet/qlogic/qed/qed_main.c
drivers/net/ethernet/qlogic/qed/qed_reg_addr.h
drivers/net/ethernet/qlogic/qed/qed_sp.h
drivers/net/ethernet/qlogic/qed/qed_spq.c
drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_vnic.c
drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c
drivers/net/ethernet/qlogic/qlge/qlge_main.c
drivers/net/ethernet/qualcomm/qca_spi.c
drivers/net/ethernet/renesas/ravb_main.c
drivers/net/ethernet/renesas/sh_eth.c
drivers/net/ethernet/renesas/sh_eth.h
drivers/net/ethernet/sfc/ef10.c
drivers/net/ethernet/sfc/efx.h
drivers/net/ethernet/sfc/farch.c
drivers/net/ethernet/sfc/txc43128_phy.c
drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
drivers/net/ethernet/ti/cpsw.c
drivers/net/geneve.c
drivers/net/hamradio/6pack.c
drivers/net/hamradio/mkiss.c
drivers/net/phy/mdio-mux.c
drivers/net/phy/micrel.c
drivers/net/ppp/pppoe.c
drivers/net/ppp/pptp.c
drivers/net/usb/cdc_mbim.c
drivers/net/usb/cdc_ncm.c
drivers/net/usb/qmi_wwan.c
drivers/net/usb/r8152.c
drivers/net/veth.c
drivers/net/vmxnet3/vmxnet3_drv.c
drivers/net/vmxnet3/vmxnet3_int.h
drivers/net/vrf.c
drivers/net/vxlan.c
drivers/net/wireless/iwlwifi/iwl-7000.c
drivers/net/wireless/iwlwifi/mvm/sta.c
drivers/net/xen-netback/netback.c
drivers/nvme/host/lightnvm.c
drivers/nvme/host/pci.c
drivers/parisc/iommu-helpers.h
drivers/pci/host/pcie-hisi.c
drivers/phy/Kconfig
drivers/phy/phy-bcm-cygnus-pcie.c
drivers/phy/phy-berlin-sata.c
drivers/phy/phy-brcmstb-sata.c
drivers/phy/phy-core.c
drivers/phy/phy-miphy28lp.c
drivers/phy/phy-miphy365x.c
drivers/phy/phy-mt65xx-usb3.c
drivers/phy/phy-rockchip-usb.c
drivers/pinctrl/bcm/pinctrl-bcm2835.c
drivers/pinctrl/freescale/pinctrl-vf610.c
drivers/pinctrl/intel/pinctrl-broxton.c
drivers/pinctrl/intel/pinctrl-intel.c
drivers/pinctrl/intel/pinctrl-intel.h
drivers/pinctrl/intel/pinctrl-sunrisepoint.c
drivers/powercap/intel_rapl.c
drivers/rtc/rtc-da9063.c
drivers/rtc/rtc-rk808.c
drivers/s390/crypto/ap_bus.c
drivers/s390/virtio/virtio_ccw.c
drivers/scsi/scsi_pm.c
drivers/scsi/ses.c
drivers/spi/spi-fsl-dspi.c
drivers/spi/spi.c
drivers/spi/spidev.c
drivers/staging/android/ion/ion_chunk_heap.c
drivers/staging/iio/iio_simple_dummy_events.c
drivers/staging/lustre/lustre/obdecho/echo_client.c
drivers/tty/n_tty.c
drivers/tty/serial/8250/8250_uniphier.c
drivers/tty/serial/earlycon.c
drivers/tty/serial/sh-sci.c
drivers/tty/serial/sunhv.c
drivers/tty/tty_buffer.c
drivers/usb/class/cdc-acm.c
drivers/usb/core/config.c
drivers/usb/core/hub.c
drivers/usb/core/port.c
drivers/usb/core/quirks.c
drivers/usb/dwc2/platform.c
drivers/usb/dwc3/gadget.c
drivers/usb/gadget/function/f_fs.c
drivers/usb/gadget/function/f_midi.c
drivers/usb/gadget/function/uvc_configfs.c
drivers/usb/gadget/udc/pxa27x_udc.c
drivers/usb/host/ohci-at91.c
drivers/usb/host/whci/qset.c
drivers/usb/host/xhci-hub.c
drivers/usb/host/xhci-pci.c
drivers/usb/host/xhci-ring.c
drivers/usb/host/xhci.c
drivers/usb/musb/Kconfig
drivers/usb/musb/musb_core.c
drivers/usb/phy/phy-msm-usb.c
drivers/usb/phy/phy-mxs-usb.c
drivers/usb/renesas_usbhs/mod_gadget.c
drivers/usb/serial/cp210x.c
drivers/usb/serial/ipaq.c
drivers/usb/serial/usb-serial-simple.c
drivers/usb/storage/uas.c
drivers/usb/storage/unusual_devs.h
drivers/usb/storage/unusual_uas.h
drivers/video/fbdev/fsl-diu-fb.c
drivers/video/fbdev/omap2/dss/venc.c
drivers/xen/events/events_fifo.c
drivers/xen/xen-pciback/pciback.h
drivers/xen/xen-pciback/pciback_ops.c
drivers/xen/xen-pciback/xenbus.c
drivers/xen/xen-scsiback.c
fs/block_dev.c
fs/btrfs/extent-tree.c
fs/btrfs/file.c
fs/btrfs/free-space-cache.c
fs/btrfs/transaction.c
fs/btrfs/transaction.h
fs/btrfs/volumes.c
fs/cifs/inode.c
fs/exofs/inode.c
fs/fuse/cuse.c
fs/fuse/file.c
fs/nfs/callback_xdr.c
fs/nfs/inode.c
fs/nfs/internal.h
fs/nfs/objlayout/objio_osd.c
fs/nfs/pagelist.c
fs/nfs/pnfs.c
fs/nfsd/nfs4layouts.c
fs/ocfs2/dlm/dlmmaster.c
fs/ocfs2/locks.c
fs/ocfs2/namei.c
fs/ocfs2/resize.c
fs/proc/base.c
include/linux/blkdev.h
include/linux/enclosure.h
include/linux/filter.h
include/linux/ftrace.h
include/linux/irqchip/arm-gic-v3.h
include/linux/kmemleak.h
include/linux/lightnvm.h
include/linux/mlx4/device.h
include/linux/mmdebug.h
include/linux/mtd/spi-nor.h
include/linux/netdevice.h
include/linux/netfilter/nfnetlink.h
include/linux/platform_data/edma.h
include/linux/qed/common_hsi.h
include/linux/qed/qed_chain.h
include/linux/rhashtable.h
include/linux/sched.h
include/linux/stop_machine.h
include/linux/usb/cdc_ncm.h
include/linux/usb/quirks.h
include/linux/vmstat.h
include/linux/wait.h
include/net/dst.h
include/net/inet_sock.h
include/net/inetpeer.h
include/net/l3mdev.h
include/net/route.h
include/net/sctp/structs.h
include/net/sock.h
include/net/vxlan.h
include/net/xfrm.h
include/rdma/ib_mad.h
include/rdma/ib_verbs.h
include/sound/hda_register.h
include/sound/soc.h
include/uapi/linux/Kbuild
include/uapi/linux/openvswitch.h
include/xen/interface/io/ring.h
init/Kconfig
kernel/events/core.c
kernel/fork.c
kernel/irq/manage.c
kernel/locking/osq_lock.c
kernel/module.c
kernel/sched/fair.c
kernel/sched/wait.c
kernel/stop_machine.c
kernel/trace/trace_printk.c
lib/dma-debug.c
lib/rhashtable.c
mm/backing-dev.c
mm/hugetlb.c
mm/memcontrol.c
mm/memory_hotplug.c
mm/oom_kill.c
mm/page_alloc.c
mm/shmem.c
mm/vmstat.c
mm/zswap.c
net/ax25/af_ax25.c
net/batman-adv/distributed-arp-table.c
net/batman-adv/routing.c
net/batman-adv/translation-table.c
net/bluetooth/sco.c
net/bridge/br_stp_if.c
net/core/dst.c
net/core/skbuff.c
net/core/sock.c
net/decnet/af_decnet.c
net/ipv4/af_inet.c
net/ipv4/fib_frontend.c
net/ipv4/fou.c
net/ipv4/ipip.c
net/ipv4/netfilter/Kconfig
net/ipv4/raw.c
net/ipv4/tcp_input.c
net/ipv4/tcp_ipv4.c
net/ipv4/tcp_output.c
net/ipv4/udp.c
net/ipv4/xfrm4_policy.c
net/ipv6/addrconf.c
net/ipv6/addrlabel.c
net/ipv6/af_inet6.c
net/ipv6/ip6_gre.c
net/ipv6/ndisc.c
net/ipv6/netfilter/Kconfig
net/ipv6/tcp_ipv6.c
net/ipv6/xfrm6_policy.c
net/irda/af_irda.c
net/mac80211/cfg.c
net/mac80211/ieee80211_i.h
net/mac80211/mlme.c
net/mac80211/rx.c
net/mac80211/util.c
net/mac80211/vht.c
net/mpls/af_mpls.c
net/mpls/mpls_iptunnel.c
net/netfilter/nf_tables_api.c
net/netfilter/nf_tables_netdev.c
net/netfilter/nfnetlink.c
net/netfilter/nfnetlink_queue.c
net/netfilter/nft_ct.c
net/openvswitch/conntrack.c
net/openvswitch/flow_netlink.c
net/rfkill/core.c
net/sched/sch_api.c
net/sched/sch_generic.c
net/sctp/ipv6.c
net/sctp/outqueue.c
net/sctp/sm_make_chunk.c
net/sctp/sm_statefuns.c
net/sctp/socket.c
net/socket.c
net/sunrpc/backchannel_rqst.c
net/sunrpc/sched.c
net/sunrpc/svc.c
net/unix/af_unix.c
net/wireless/nl80211.c
net/wireless/reg.c
net/xfrm/xfrm_policy.c
scripts/recordmcount.c
security/keys/keyctl.c
sound/pci/hda/hda_intel.c
sound/pci/hda/patch_ca0132.c
sound/pci/hda/patch_realtek.c
sound/pci/rme96.c
sound/soc/codecs/arizona.c
sound/soc/codecs/es8328.c
sound/soc/codecs/es8328.h
sound/soc/codecs/rt5645.c
sound/soc/codecs/rt5645.h
sound/soc/codecs/sgtl5000.c
sound/soc/codecs/wm8974.c
sound/soc/davinci/davinci-mcasp.c
sound/soc/fsl/fsl_sai.c
sound/soc/intel/skylake/skl-topology.c
sound/soc/intel/skylake/skl.c
sound/soc/intel/skylake/skl.h
sound/soc/rockchip/rockchip_spdif.c
sound/soc/rockchip/rockchip_spdif.h
sound/usb/mixer.c
sound/usb/mixer_maps.c
sound/usb/mixer_quirks.c
sound/usb/mixer_quirks.h
sound/usb/quirks.c
tools/perf/builtin-buildid-list.c
tools/perf/ui/browsers/hists.c
tools/perf/util/build-id.c
tools/perf/util/parse-events.c
virt/kvm/arm/vgic.c

index d3d0a4fb1c733b8288884869088fda088328546d..079b42a81d7cf3c5af086872fc86127023ab2c15 100644 (file)
@@ -22,8 +22,7 @@ Required properties:
 Optional properties:
 - ti,hwmods:   Name of the hwmods associated to the eDMA CC
 - ti,edma-memcpy-channels: List of channels allocated to be used for memcpy, iow
-               these channels will be SW triggered channels. The list must
-               contain 16 bits numbers, see example.
+               these channels will be SW triggered channels. See example.
 - ti,edma-reserved-slot-ranges: PaRAM slot ranges which should not be used by
                the driver, they are allocated to be used by for example the
                DSP. See example.
@@ -56,10 +55,9 @@ edma: edma@49000000 {
        ti,tptcs = <&edma_tptc0 7>, <&edma_tptc1 7>, <&edma_tptc2 0>;
 
        /* Channel 20 and 21 is allocated for memcpy */
-       ti,edma-memcpy-channels = /bits/ 16 <20 21>;
-       /* The following PaRAM slots are reserved: 35-45 and 100-110 */
-       ti,edma-reserved-slot-ranges = /bits/ 16 <35 10>,
-                                      /bits/ 16 <100 10>;
+       ti,edma-memcpy-channels = <20 21>;
+       /* The following PaRAM slots are reserved: 35-44 and 100-109 */
+       ti,edma-reserved-slot-ranges = <35 10>, <100 10>;
 };
 
 edma_tptc0: tptc@49800000 {
index f2455c50533d6c7388ebfacbe572d164e5d11314..120bc4971cf3ed92cf9590af16643645e5c89234 100644 (file)
@@ -11,6 +11,10 @@ Required properties:
       0 = active high
       1 = active low
 
+Optional properties:
+- little-endian : GPIO registers are used as little endian. If not
+                  present registers are used as big endian by default.
+
 Example:
 
 gpio0: gpio@1100 {
index b9c32f6fd687b04a3737c871bcf5c694665d3b84..4357e498ef0422d5fdc2715e3daf065ac80e41f4 100644 (file)
@@ -12,7 +12,7 @@ Each key is represented as a sub-node of "allwinner,sun4i-a10-lradc-keys":
 Required subnode-properties:
        - label: Descriptive name of the key.
        - linux,code: Keycode to emit.
-       - channel: Channel this key is attached to, mut be 0 or 1.
+       - channel: Channel this key is attached to, must be 0 or 1.
        - voltage: Voltage in ÂµV at lradc input when this key is pressed.
 
 Example:
index f1e2a02381a498a8f94e379870a8dcb1d2dec4ca..1c63e40659fcaada93e54ec81e8a12f62dca1f83 100644 (file)
@@ -6,7 +6,9 @@ used for what purposes, but which don't use an on-flash partition table such
 as RedBoot.
 
 The partition table should be a subnode of the mtd node and should be named
-'partitions'. Partitions are defined in subnodes of the partitions node.
+'partitions'. This node should have the following property:
+- compatible : (required) must be "fixed-partitions"
+Partitions are then defined in subnodes of the partitions node.
 
 For backwards compatibility partitions as direct subnodes of the mtd device are
 supported. This use is discouraged.
@@ -36,6 +38,7 @@ Examples:
 
 flash@0 {
        partitions {
+               compatible = "fixed-partitions";
                #address-cells = <1>;
                #size-cells = <1>;
 
@@ -53,6 +56,7 @@ flash@0 {
 
 flash@1 {
        partitions {
+               compatible = "fixed-partitions";
                #address-cells = <1>;
                #size-cells = <2>;
 
@@ -66,6 +70,7 @@ flash@1 {
 
 flash@2 {
        partitions {
+               compatible = "fixed-partitions";
                #address-cells = <2>;
                #size-cells = <2>;
 
index 9853f8e7096613e990c28cc545b39ab7f26afddc..28a4781ab6d7b9d6a1ab553ed96857f0f509e250 100644 (file)
@@ -40,18 +40,18 @@ Optional properties:
 
 Slave Properties:
 Required properties:
-- phy_id               : Specifies slave phy id
 - phy-mode             : See ethernet.txt file in the same directory
 
 Optional properties:
 - dual_emac_res_vlan   : Specifies VID to be used to segregate the ports
 - mac-address          : See ethernet.txt file in the same directory
+- phy_id               : Specifies slave phy id
 - phy-handle           : See ethernet.txt file in the same directory
 
 Slave sub-nodes:
 - fixed-link           : See fixed-link.txt file in the same directory
-                         Either the properties phy_id and phy-mode,
-                         or the sub-node fixed-link can be specified
+                         Either the property phy_id, or the sub-node
+                         fixed-link can be specified
 
 Note: "ti,hwmods" field is used to fetch the base address and irq
 resources from TI, omap hwmod data base during device registration.
index f862cf3aff3495d96f699cd666af6dbf3d18a453..42ddbd4b52a9d646a539ad154d7400c0a61c02c7 100644 (file)
@@ -181,17 +181,3 @@ For general information, go to the Intel support website at:
 If an issue is identified with the released source code on the supported
 kernel with a supported adapter, email the specific information related to the
 issue to e1000-devel@lists.sourceforge.net.
-
-
-License
-=======
-
-This software program is released under the terms of a license agreement
-between you ('Licensee') and Intel. Do not use or load this software or any
-associated materials (collectively, the 'Software') until you have carefully
-read the full terms and conditions of the file COPYING located in this software
-package. By loading or using the Software, you agree to the terms of this
-Agreement. If you do not agree with the terms of this Agreement, do not install
-or use the Software.
-
-* Other names and brands may be claimed as the property of others.
index 38df53f828e1ea9036957d93d3cf744164e2f3c1..233f83464814f138c4c68f0815d2dbeace552ef6 100644 (file)
@@ -2975,6 +2975,7 @@ F:        kernel/cpuset.c
 CONTROL GROUP - MEMORY RESOURCE CONTROLLER (MEMCG)
 M:     Johannes Weiner <hannes@cmpxchg.org>
 M:     Michal Hocko <mhocko@kernel.org>
+M:     Vladimir Davydov <vdavydov@virtuozzo.com>
 L:     cgroups@vger.kernel.org
 L:     linux-mm@kvack.org
 S:     Maintained
@@ -5577,7 +5578,7 @@ R:        Jesse Brandeburg <jesse.brandeburg@intel.com>
 R:     Shannon Nelson <shannon.nelson@intel.com>
 R:     Carolyn Wyborny <carolyn.wyborny@intel.com>
 R:     Don Skidmore <donald.c.skidmore@intel.com>
-R:     Matthew Vick <matthew.vick@intel.com>
+R:     Bruce Allan <bruce.w.allan@intel.com>
 R:     John Ronciak <john.ronciak@intel.com>
 R:     Mitch Williams <mitch.a.williams@intel.com>
 L:     intel-wired-lan@lists.osuosl.org
@@ -8379,6 +8380,14 @@ L:       linux-samsung-soc@vger.kernel.org (moderated for non-subscribers)
 S:     Maintained
 F:     drivers/pinctrl/samsung/
 
+PIN CONTROLLER - SINGLE
+M:     Tony Lindgren <tony@atomide.com>
+M:     Haojian Zhuang <haojian.zhuang@linaro.org>
+L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+L:     linux-omap@vger.kernel.org
+S:     Maintained
+F:     drivers/pinctrl/pinctrl-single.c
+
 PIN CONTROLLER - ST SPEAR
 M:     Viresh Kumar <vireshk@kernel.org>
 L:     spear-devel@list.st.com
@@ -8945,6 +8954,13 @@ F:       drivers/rpmsg/
 F:     Documentation/rpmsg.txt
 F:     include/linux/rpmsg.h
 
+RENESAS ETHERNET DRIVERS
+R:     Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+L:     netdev@vger.kernel.org
+L:     linux-sh@vger.kernel.org
+F:     drivers/net/ethernet/renesas/
+F:     include/linux/sh_eth.h
+
 RESET CONTROLLER FRAMEWORK
 M:     Philipp Zabel <p.zabel@pengutronix.de>
 S:     Maintained
index d644f6e92cf653be39a981d7ca6b021084c7eaa5..9d94adeceab6d4343d87ad5fc08307641534301e 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 4
 PATCHLEVEL = 4
 SUBLEVEL = 0
-EXTRAVERSION = -rc4
+EXTRAVERSION = -rc8
 NAME = Blurry Fish Butt
 
 # *DOCUMENTATION*
index 2c2ac3f3ff80370bd6bad9fffc9dfb8c8f6931e8..6312f607932fd2241782827cce2ec7968ea3c8b6 100644 (file)
@@ -445,6 +445,7 @@ config LINUX_LINK_BASE
          However some customers have peripherals mapped at this addr, so
          Linux needs to be scooted a bit.
          If you don't know what the above means, leave this setting alone.
+         This needs to match memory start address specified in Device Tree
 
 config HIGHMEM
        bool "High Memory Support"
index cf0cf34eeb24b14ef070735e83d25b0f7f6aecec..aeb19021099e315967ba95524e9528c48da0d159 100644 (file)
@@ -81,7 +81,7 @@ endif
 LIBGCC := $(shell $(CC) $(cflags-y) --print-libgcc-file-name)
 
 # Modules with short calls might break for calls into builtin-kernel
-KBUILD_CFLAGS_MODULE   += -mlong-calls
+KBUILD_CFLAGS_MODULE   += -mlong-calls -mno-millicode
 
 # Finally dump eveything into kernel build system
 KBUILD_CFLAGS  += $(cflags-y)
index f3db32154973718268c1998e9f16bb03d1af7e7f..44a578c10732cd1ab79558415e3c66f6825c98bd 100644 (file)
@@ -46,6 +46,7 @@
                        snps,pbl = < 32 >;
                        clocks = <&apbclk>;
                        clock-names = "stmmaceth";
+                       max-speed = <100>;
                };
 
                ehci@0x40000 {
index b0eb0e7fe21d8a66b1d0ef5267f24dd6a1f8f254..fc81879bc1f5800e5efe8eb43395eb2c5509f481 100644 (file)
@@ -17,7 +17,8 @@
 
        memory {
                device_type = "memory";
-               reg = <0x0 0x80000000 0x0 0x40000000    /* 1 GB low mem */
+               /* CONFIG_LINUX_LINK_BASE needs to match low mem start */
+               reg = <0x0 0x80000000 0x0 0x20000000    /* 512 MB low mem */
                       0x1 0x00000000 0x0 0x40000000>;  /* 1 GB highmem */
        };
 
index abf06e81c9290f6eafc441b563061e3389032922..210ef3e7233224b099bd40e85106d2d864e70987 100644 (file)
@@ -62,9 +62,7 @@ extern int ioc_exists;
 #define ARC_REG_IC_IVIC                0x10
 #define ARC_REG_IC_CTRL                0x11
 #define ARC_REG_IC_IVIL                0x19
-#if defined(CONFIG_ARC_MMU_V3) || defined(CONFIG_ARC_MMU_V4)
 #define ARC_REG_IC_PTAG                0x1E
-#endif
 #define ARC_REG_IC_PTAG_HI     0x1F
 
 /* Bit val in IC_CTRL */
index 6ff657a904b61e700421b60423991273df93e1e1..c28e6c347b4900217ad48053c69679bb3da8b607 100644 (file)
@@ -23,7 +23,7 @@
  * @dt_compat:         Array of device tree 'compatible' strings
  *                     (XXX: although only 1st entry is looked at)
  * @init_early:                Very early callback [called from setup_arch()]
- * @init_cpu_smp:      for each CPU as it is coming up (SMP as well as UP)
+ * @init_per_cpu:      for each CPU as it is coming up (SMP as well as UP)
  *                     [(M):init_IRQ(), (o):start_kernel_secondary()]
  * @init_machine:      arch initcall level callback (e.g. populate static
  *                     platform devices or parse Devicetree)
@@ -35,7 +35,7 @@ struct machine_desc {
        const char              **dt_compat;
        void                    (*init_early)(void);
 #ifdef CONFIG_SMP
-       void                    (*init_cpu_smp)(unsigned int);
+       void                    (*init_per_cpu)(unsigned int);
 #endif
        void                    (*init_machine)(void);
        void                    (*init_late)(void);
index 133c867d15af0a627576d9faf89c0569220a6f47..991380438d6bfd6af03e6fff4748b8c5342b6a70 100644 (file)
@@ -48,7 +48,7 @@ extern int smp_ipi_irq_setup(int cpu, int irq);
  * @init_early_smp:    A SMP specific h/w block can init itself
  *                     Could be common across platforms so not covered by
  *                     mach_desc->init_early()
- * @init_irq_cpu:      Called for each core so SMP h/w block driver can do
+ * @init_per_cpu:      Called for each core so SMP h/w block driver can do
  *                     any needed setup per cpu (e.g. IPI request)
  * @cpu_kick:          For Master to kickstart a cpu (optionally at a PC)
  * @ipi_send:          To send IPI to a @cpu
@@ -57,7 +57,7 @@ extern int smp_ipi_irq_setup(int cpu, int irq);
 struct plat_smp_ops {
        const char      *info;
        void            (*init_early_smp)(void);
-       void            (*init_irq_cpu)(int cpu);
+       void            (*init_per_cpu)(int cpu);
        void            (*cpu_kick)(int cpu, unsigned long pc);
        void            (*ipi_send)(int cpu);
        void            (*ipi_clear)(int irq);
index 7ca628b6ee2aa6d1e02f6ad01363990439ec10b7..c11a25bb8158dee7f60a5f00ca8ec0addaf54b56 100644 (file)
@@ -112,7 +112,6 @@ struct unwind_frame_info {
 
 extern int arc_unwind(struct unwind_frame_info *frame);
 extern void arc_unwind_init(void);
-extern void arc_unwind_setup(void);
 extern void *unwind_add_table(struct module *module, const void *table_start,
                              unsigned long table_size);
 extern void unwind_remove_table(void *handle, int init_only);
@@ -152,9 +151,6 @@ static inline void arc_unwind_init(void)
 {
 }
 
-static inline void arc_unwind_setup(void)
-{
-}
 #define unwind_add_table(a, b, c)
 #define unwind_remove_table(a, b)
 
index 26c15682747960d3b5b1c412f76dff3c2ebc7780..0394f9f61b466dea018af3ec371c65a8dbc17acb 100644 (file)
@@ -106,10 +106,21 @@ static struct irq_chip arcv2_irq_chip = {
 static int arcv2_irq_map(struct irq_domain *d, unsigned int irq,
                         irq_hw_number_t hw)
 {
-       if (irq == TIMER0_IRQ || irq == IPI_IRQ)
+       /*
+        * core intc IRQs [16, 23]:
+        * Statically assigned always private-per-core (Timers, WDT, IPI, PCT)
+        */
+       if (hw < 24) {
+               /*
+                * A subsequent request_percpu_irq() fails if percpu_devid is
+                * not set. That in turns sets NOAUTOEN, meaning each core needs
+                * to call enable_percpu_irq()
+                */
+               irq_set_percpu_devid(irq);
                irq_set_chip_and_handler(irq, &arcv2_irq_chip, handle_percpu_irq);
-       else
+       } else {
                irq_set_chip_and_handler(irq, &arcv2_irq_chip, handle_level_irq);
+       }
 
        return 0;
 }
index 2ee226546c6a821f739a079326ed92ad52fe16b8..ba17f85285cfe85c53ba6c93db08d620c7109fb9 100644 (file)
@@ -29,11 +29,11 @@ void __init init_IRQ(void)
 
 #ifdef CONFIG_SMP
        /* a SMP H/w block could do IPI IRQ request here */
-       if (plat_smp_ops.init_irq_cpu)
-               plat_smp_ops.init_irq_cpu(smp_processor_id());
+       if (plat_smp_ops.init_per_cpu)
+               plat_smp_ops.init_per_cpu(smp_processor_id());
 
-       if (machine_desc->init_cpu_smp)
-               machine_desc->init_cpu_smp(smp_processor_id());
+       if (machine_desc->init_per_cpu)
+               machine_desc->init_per_cpu(smp_processor_id());
 #endif
 }
 
@@ -51,6 +51,18 @@ void arch_do_IRQ(unsigned int irq, struct pt_regs *regs)
        set_irq_regs(old_regs);
 }
 
+/*
+ * API called for requesting percpu interrupts - called by each CPU
+ *  - For boot CPU, actually request the IRQ with genirq core + enables
+ *  - For subsequent callers only enable called locally
+ *
+ * Relies on being called by boot cpu first (i.e. request called ahead) of
+ * any enable as expected by genirq. Hence Suitable only for TIMER, IPI
+ * which are guaranteed to be setup on boot core first.
+ * Late probed peripherals such as perf can't use this as there no guarantee
+ * of being called on boot CPU first.
+ */
+
 void arc_request_percpu_irq(int irq, int cpu,
                             irqreturn_t (*isr)(int irq, void *dev),
                             const char *irq_nm,
@@ -60,14 +72,17 @@ void arc_request_percpu_irq(int irq, int cpu,
        if (!cpu) {
                int rc;
 
+#ifdef CONFIG_ISA_ARCOMPACT
                /*
-                * These 2 calls are essential to making percpu IRQ APIs work
-                * Ideally these details could be hidden in irq chip map function
-                * but the issue is IPIs IRQs being static (non-DT) and platform
-                * specific, so we can't identify them there.
+                * A subsequent request_percpu_irq() fails if percpu_devid is
+                * not set. That in turns sets NOAUTOEN, meaning each core needs
+                * to call enable_percpu_irq()
+                *
+                * For ARCv2, this is done in irq map function since we know
+                * which irqs are strictly per cpu
                 */
                irq_set_percpu_devid(irq);
-               irq_modify_status(irq, IRQ_NOAUTOEN, 0);  /* @irq, @clr, @set */
+#endif
 
                rc = request_percpu_irq(irq, isr, irq_nm, percpu_dev);
                if (rc)
index 74a9b074ac3e4e64d97ef8e069f73a9104531682..bd237acdf4f2f9601efbf4c25c45067ddd2b69d9 100644 (file)
@@ -132,7 +132,7 @@ static void mcip_probe_n_setup(void)
 struct plat_smp_ops plat_smp_ops = {
        .info           = smp_cpuinfo_buf,
        .init_early_smp = mcip_probe_n_setup,
-       .init_irq_cpu   = mcip_setup_per_cpu,
+       .init_per_cpu   = mcip_setup_per_cpu,
        .ipi_send       = mcip_ipi_send,
        .ipi_clear      = mcip_ipi_clear,
 };
index 0c08bb1ce15aab114c344609879eaa86bfa59a9d..8b134cfe5e1f11023b559639497f7e1a35d2ee79 100644 (file)
@@ -428,12 +428,11 @@ static irqreturn_t arc_pmu_intr(int irq, void *dev)
 
 #endif /* CONFIG_ISA_ARCV2 */
 
-void arc_cpu_pmu_irq_init(void)
+static void arc_cpu_pmu_irq_init(void *data)
 {
-       struct arc_pmu_cpu *pmu_cpu = this_cpu_ptr(&arc_pmu_cpu);
+       int irq = *(int *)data;
 
-       arc_request_percpu_irq(arc_pmu->irq, smp_processor_id(), arc_pmu_intr,
-                              "ARC perf counters", pmu_cpu);
+       enable_percpu_irq(irq, IRQ_TYPE_NONE);
 
        /* Clear all pending interrupt flags */
        write_aux_reg(ARC_REG_PCT_INT_ACT, 0xffffffff);
@@ -515,7 +514,6 @@ static int arc_pmu_device_probe(struct platform_device *pdev)
 
        if (has_interrupts) {
                int irq = platform_get_irq(pdev, 0);
-               unsigned long flags;
 
                if (irq < 0) {
                        pr_err("Cannot get IRQ number for the platform\n");
@@ -524,24 +522,12 @@ static int arc_pmu_device_probe(struct platform_device *pdev)
 
                arc_pmu->irq = irq;
 
-               /*
-                * arc_cpu_pmu_irq_init() needs to be called on all cores for
-                * their respective local PMU.
-                * However we use opencoded on_each_cpu() to ensure it is called
-                * on core0 first, so that arc_request_percpu_irq() sets up
-                * AUTOEN etc. Otherwise enable_percpu_irq() fails to enable
-                * perf IRQ on non master cores.
-                * see arc_request_percpu_irq()
-                */
-               preempt_disable();
-               local_irq_save(flags);
-               arc_cpu_pmu_irq_init();
-               local_irq_restore(flags);
-               smp_call_function((smp_call_func_t)arc_cpu_pmu_irq_init, 0, 1);
-               preempt_enable();
-
-               /* Clean all pending interrupt flags */
-               write_aux_reg(ARC_REG_PCT_INT_ACT, 0xffffffff);
+               /* intc map function ensures irq_set_percpu_devid() called */
+               request_percpu_irq(irq, arc_pmu_intr, "ARC perf counters",
+                                  this_cpu_ptr(&arc_pmu_cpu));
+
+               on_each_cpu(arc_cpu_pmu_irq_init, &irq, 1);
+
        } else
                arc_pmu->pmu.capabilities |= PERF_PMU_CAP_NO_INTERRUPT;
 
index c33e77c0ad3e9eb60367b6c2510c4e35c60d3b52..e1b87444ea9a0740b9651ad6b68fd39f701121a0 100644 (file)
@@ -429,7 +429,6 @@ void __init setup_arch(char **cmdline_p)
 #endif
 
        arc_unwind_init();
-       arc_unwind_setup();
 }
 
 static int __init customize_machine(void)
index 580587805fa302d0d28f7adc89434b920b3be651..ef6e9e15b82abf72d946ab45c3e20096854605c5 100644 (file)
@@ -132,11 +132,11 @@ void start_kernel_secondary(void)
        pr_info("## CPU%u LIVE ##: Executing Code...\n", cpu);
 
        /* Some SMP H/w setup - for each cpu */
-       if (plat_smp_ops.init_irq_cpu)
-               plat_smp_ops.init_irq_cpu(cpu);
+       if (plat_smp_ops.init_per_cpu)
+               plat_smp_ops.init_per_cpu(cpu);
 
-       if (machine_desc->init_cpu_smp)
-               machine_desc->init_cpu_smp(cpu);
+       if (machine_desc->init_per_cpu)
+               machine_desc->init_per_cpu(cpu);
 
        arc_local_timer_setup();
 
index 7352475451f6c3798885c97b04c11ddd53146990..5eb707640e9c48c9939c3fcfd0022f8cfc897684 100644 (file)
@@ -170,6 +170,23 @@ static struct unwind_table *find_table(unsigned long pc)
 
 static unsigned long read_pointer(const u8 **pLoc,
                                  const void *end, signed ptrType);
+static void init_unwind_hdr(struct unwind_table *table,
+                           void *(*alloc) (unsigned long));
+
+/*
+ * wrappers for header alloc (vs. calling one vs. other at call site)
+ * to elide section mismatches warnings
+ */
+static void *__init unw_hdr_alloc_early(unsigned long sz)
+{
+       return __alloc_bootmem_nopanic(sz, sizeof(unsigned int),
+                                      MAX_DMA_ADDRESS);
+}
+
+static void *unw_hdr_alloc(unsigned long sz)
+{
+       return kmalloc(sz, GFP_KERNEL);
+}
 
 static void init_unwind_table(struct unwind_table *table, const char *name,
                              const void *core_start, unsigned long core_size,
@@ -209,6 +226,8 @@ void __init arc_unwind_init(void)
                          __start_unwind, __end_unwind - __start_unwind,
                          NULL, 0);
          /*__start_unwind_hdr, __end_unwind_hdr - __start_unwind_hdr);*/
+
+       init_unwind_hdr(&root_table, unw_hdr_alloc_early);
 }
 
 static const u32 bad_cie, not_fde;
@@ -241,8 +260,8 @@ static void swap_eh_frame_hdr_table_entries(void *p1, void *p2, int size)
        e2->fde = v;
 }
 
-static void __init setup_unwind_table(struct unwind_table *table,
-                                     void *(*alloc) (unsigned long))
+static void init_unwind_hdr(struct unwind_table *table,
+                           void *(*alloc) (unsigned long))
 {
        const u8 *ptr;
        unsigned long tableSize = table->size, hdrSize;
@@ -277,10 +296,10 @@ static void __init setup_unwind_table(struct unwind_table *table,
                if (cie == &not_fde)
                        continue;
                if (cie == NULL || cie == &bad_cie)
-                       return;
+                       goto ret_err;
                ptrType = fde_pointer_type(cie);
                if (ptrType < 0)
-                       return;
+                       goto ret_err;
 
                ptr = (const u8 *)(fde + 2);
                if (!read_pointer(&ptr, (const u8 *)(fde + 1) + *fde,
@@ -296,13 +315,15 @@ static void __init setup_unwind_table(struct unwind_table *table,
        }
 
        if (tableSize || !n)
-               return;
+               goto ret_err;
 
        hdrSize = 4 + sizeof(unsigned long) + sizeof(unsigned int)
            + 2 * n * sizeof(unsigned long);
+
        header = alloc(hdrSize);
        if (!header)
-               return;
+               goto ret_err;
+
        header->version = 1;
        header->eh_frame_ptr_enc = DW_EH_PE_abs | DW_EH_PE_native;
        header->fde_count_enc = DW_EH_PE_abs | DW_EH_PE_data4;
@@ -340,18 +361,10 @@ static void __init setup_unwind_table(struct unwind_table *table,
        table->hdrsz = hdrSize;
        smp_wmb();
        table->header = (const void *)header;
-}
-
-static void *__init balloc(unsigned long sz)
-{
-       return __alloc_bootmem_nopanic(sz,
-                                      sizeof(unsigned int),
-                                      __pa(MAX_DMA_ADDRESS));
-}
+       return;
 
-void __init arc_unwind_setup(void)
-{
-       setup_unwind_table(&root_table, balloc);
+ret_err:
+       panic("Attention !!! Dwarf FDE parsing errors\n");;
 }
 
 #ifdef CONFIG_MODULES
@@ -377,6 +390,8 @@ void *unwind_add_table(struct module *module, const void *table_start,
                          table_start, table_size,
                          NULL, 0);
 
+       init_unwind_hdr(table, unw_hdr_alloc);
+
 #ifdef UNWIND_DEBUG
        unw_debug("Table added for [%s] %lx %lx\n",
                module->name, table->core.pc, table->core.range);
@@ -439,6 +454,7 @@ void unwind_remove_table(void *handle, int init_only)
        info.init_only = init_only;
 
        unlink_table(&info); /* XXX: SMP */
+       kfree(table->header);
        kfree(table);
 }
 
@@ -588,9 +604,6 @@ static signed fde_pointer_type(const u32 *cie)
        const u8 *ptr = (const u8 *)(cie + 2);
        unsigned version = *ptr;
 
-       if (version != 1)
-               return -1;      /* unsupported */
-
        if (*++ptr) {
                const char *aug;
                const u8 *end = (const u8 *)(cie + 1) + *cie;
@@ -1002,9 +1015,7 @@ int arc_unwind(struct unwind_frame_info *frame)
                ptr = (const u8 *)(cie + 2);
                end = (const u8 *)(cie + 1) + *cie;
                frame->call_frame = 1;
-               if ((state.version = *ptr) != 1)
-                       cie = NULL;     /* unsupported version */
-               else if (*++ptr) {
+               if (*++ptr) {
                        /* check if augmentation size is first (thus present) */
                        if (*ptr == 'z') {
                                while (++ptr < end && *ptr) {
index 065ee6bfa82a2463ee60c790f08c5b60382715f3..92dd92cad7f92db32f9ecc1b73992e1ea0a5f74d 100644 (file)
@@ -111,7 +111,7 @@ void __kunmap_atomic(void *kv)
 }
 EXPORT_SYMBOL(__kunmap_atomic);
 
-noinline pte_t *alloc_kmap_pgtable(unsigned long kvaddr)
+static noinline pte_t * __init alloc_kmap_pgtable(unsigned long kvaddr)
 {
        pgd_t *pgd_k;
        pud_t *pud_k;
@@ -127,7 +127,7 @@ noinline pte_t *alloc_kmap_pgtable(unsigned long kvaddr)
        return pte_k;
 }
 
-void kmap_init(void)
+void __init kmap_init(void)
 {
        /* Due to recursive include hell, we can't do this in processor.h */
        BUILD_BUG_ON(PAGE_OFFSET < (VMALLOC_END + FIXMAP_SIZE + PKMAP_SIZE));
index a9305b5a2cd4ba091f7ae18914f6ef5e64d5236c..7d2c4fbf4f22eb1402bc666c077c652c40f38361 100644 (file)
@@ -51,7 +51,9 @@ void __init early_init_dt_add_memory_arch(u64 base, u64 size)
        int in_use = 0;
 
        if (!low_mem_sz) {
-               BUG_ON(base != low_mem_start);
+               if (base != low_mem_start)
+                       panic("CONFIG_LINUX_LINK_BASE != DT memory { }");
+
                low_mem_sz = size;
                in_use = 1;
        } else {
index d83ff9c9701e36d5d837c87ce292d89c421c4a70..de8791a4d1311883577f51e243769a3c6906a61a 100644 (file)
@@ -74,7 +74,7 @@
                reg = <0x48240200 0x100>;
                interrupts = <GIC_PPI 11 IRQ_TYPE_LEVEL_HIGH>;
                interrupt-parent = <&gic>;
-               clocks = <&dpll_mpu_m2_ck>;
+               clocks = <&mpu_periphclk>;
        };
 
        local_timer: timer@48240600 {
@@ -82,7 +82,7 @@
                reg = <0x48240600 0x100>;
                interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_HIGH>;
                interrupt-parent = <&gic>;
-               clocks = <&dpll_mpu_m2_ck>;
+               clocks = <&mpu_periphclk>;
        };
 
        l2-cache-controller@48242000 {
index cc88728d751de587bcb86abbe179921c493779e9..a38af2bfbfcfbd51f223409e48231d04e73cd7e5 100644 (file)
                ti,invert-autoidle-bit;
        };
 
+       mpu_periphclk: mpu_periphclk {
+               #clock-cells = <0>;
+               compatible = "fixed-factor-clock";
+               clocks = <&dpll_mpu_m2_ck>;
+               clock-mult = <1>;
+               clock-div = <2>;
+       };
+
        dpll_ddr_ck: dpll_ddr_ck {
                #clock-cells = <0>;
                compatible = "ti,am3-dpll-clock";
index ad6de73ed5a5fd2f6b1cd7c19e325d60c21537c9..e74df327cdd3b8d5776cb5d6deb269042f463bdb 100644 (file)
                                                        regulator-name = "VDD_SDHC_1V8";
                                                        regulator-min-microvolt = <1800000>;
                                                        regulator-max-microvolt = <1800000>;
+                                                       regulator-always-on;
                                                };
                                        };
                                };
index 8ea177f375ddd652c98339ac2cc8ef8935396442..fb1da99996ea43f9c3492591e9faf800030d5989 100644 (file)
                sdhci0: sdhci@ab0000 {
                        compatible = "mrvl,pxav3-mmc";
                        reg = <0xab0000 0x200>;
-                       clocks = <&chip_clk CLKID_SDIO1XIN>;
+                       clocks = <&chip_clk CLKID_SDIO1XIN>, <&chip_clk CLKID_SDIO>;
+                       clock-names = "io", "core";
                        interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
                        status = "disabled";
                };
                sdhci1: sdhci@ab0800 {
                        compatible = "mrvl,pxav3-mmc";
                        reg = <0xab0800 0x200>;
-                       clocks = <&chip_clk CLKID_SDIO1XIN>;
+                       clocks = <&chip_clk CLKID_SDIO1XIN>, <&chip_clk CLKID_SDIO>;
+                       clock-names = "io", "core";
                        interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
                        status = "disabled";
                };
                        compatible = "mrvl,pxav3-mmc";
                        reg = <0xab1000 0x200>;
                        interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&chip_clk CLKID_NFC_ECC>, <&chip_clk CLKID_NFC>;
+                       clocks = <&chip_clk CLKID_NFC_ECC>, <&chip_clk CLKID_SDIO>;
                        clock-names = "io", "core";
                        status = "disabled";
                };
index 3c99cfa1a8761604a409b9d0525f143c494571b0..eee636de4cd844237f5490b71c5f00d56dd9f06c 100644 (file)
                        reg = <0x480c8000 0x2000>;
                        interrupts = <77>;
                        ti,hwmods = "mailbox";
+                       #mbox-cells = <1>;
                        ti,mbox-num-users = <4>;
                        ti,mbox-num-fifos = <12>;
                        mbox_dsp: mbox_dsp {
                        ti,spi-num-cs = <4>;
                        ti,hwmods = "mcspi1";
                        dmas = <&edma 16 &edma 17
-                               &edma 18 &edma 19>;
-                       dma-names = "tx0", "rx0", "tx1", "rx1";
+                               &edma 18 &edma 19
+                               &edma 20 &edma 21
+                               &edma 22 &edma 23>;
+                       dma-names = "tx0", "rx0", "tx1", "rx1",
+                                   "tx2", "rx2", "tx3", "rx3";
                };
 
                mmc1: mmc@48060000 {
index 58adf176425a69fc48d16731973f93827b080bab..a51834e1dd2789ed0bfeed69b2dbddc08aa946fc 100644 (file)
 &fec {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_enet>;
-       phy-mode = "rgmii";
+       phy-mode = "rgmii-id";
        phy-reset-gpios = <&gpio1 30 GPIO_ACTIVE_HIGH>;
        status = "okay";
 };
index 7b31fdb79ced5cbac2eecff792fa8d56b1a9a010..dc0cebfe22d7b9a8f0500e1313c67ede2718234d 100644 (file)
@@ -94,7 +94,7 @@
 &fec {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_enet>;
-       phy-mode = "rgmii";
+       phy-mode = "rgmii-id";
        phy-reset-gpios = <&gpio1 30 GPIO_ACTIVE_LOW>;
        status = "okay";
 };
index 1b66328a84987a1040b0406e1b4dfe29a87707ed..18cd4114a23e85a82f724c3b8773c04399826129 100644 (file)
 &fec {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_enet>;
-       phy-mode = "rgmii";
+       phy-mode = "rgmii-id";
        phy-reset-gpios = <&gpio1 30 GPIO_ACTIVE_LOW>;
        status = "okay";
 };
index 7c51839ff93467d209e0f3809b3ed9e8bc541c54..eea90f37bbb8c236ebc97e2e1c90b439e4aed2ed 100644 (file)
 &fec {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_enet>;
-       phy-mode = "rgmii";
+       phy-mode = "rgmii-id";
        phy-reset-gpios = <&gpio1 30 GPIO_ACTIVE_LOW>;
        status = "okay";
 };
index 929e0b37bd9e542e252be1159e6e588dd34b94e1..6c11a2ae35ef98b0f2adcb218d20543cead8f399 100644 (file)
 &fec {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_enet>;
-       phy-mode = "rgmii";
+       phy-mode = "rgmii-id";
        phy-reset-gpios = <&gpio1 30 GPIO_ACTIVE_LOW>;
        status = "okay";
 };
index 8263fc18a7d95ff88b470ae57fd5e2e89036f99f..d354d406954da437071db41de61e349a48644802 100644 (file)
 &clks {
        assigned-clocks = <&clks IMX6QDL_PLL4_BYPASS_SRC>,
                          <&clks IMX6QDL_PLL4_BYPASS>,
-                         <&clks IMX6QDL_CLK_PLL4_POST_DIV>,
                          <&clks IMX6QDL_CLK_LDB_DI0_SEL>,
-                         <&clks IMX6QDL_CLK_LDB_DI1_SEL>;
+                         <&clks IMX6QDL_CLK_LDB_DI1_SEL>,
+                         <&clks IMX6QDL_CLK_PLL4_POST_DIV>;
        assigned-clock-parents = <&clks IMX6QDL_CLK_LVDS2_IN>,
                                 <&clks IMX6QDL_PLL4_BYPASS_SRC>,
                                 <&clks IMX6QDL_CLK_PLL3_USB_OTG>,
                                 <&clks IMX6QDL_CLK_PLL3_USB_OTG>;
-       assigned-clock-rates = <0>, <0>, <24576000>;
+       assigned-clock-rates = <0>, <0>, <0>, <0>, <24576000>;
 };
 
 &ecspi1 {
index 1a78f013f37ab8e2ee4de5361dc16bdeec2b2516..b75f7b2b7c4ac9e0aca7c4c44e3f1b8e2bd09c28 100644 (file)
        };
 };
 
+&uart3 {
+       interrupts-extended = <&wakeupgen GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH
+                              &omap4_pmx_core OMAP4_UART3_RX>;
+};
index 2d4250b1faf80040e3e6c3477fe64b7431141627..68b479b8772c6f3eadc16f2ad6c3d33e35d39c5f 100644 (file)
@@ -83,6 +83,7 @@
                reg = <0x5d>;
                interrupt-parent = <&pio>;
                interrupts = <0 3 IRQ_TYPE_LEVEL_HIGH>; /* PA3 */
+               touchscreen-swapped-x-y;
        };
 };
 
index 40c23a0b7cfc2adf8517e28ac51b0078423a0c61..ec1aa64ded681a1a4f834343b3fc45d0c4946819 100644 (file)
 
        /* CPU DFLL clock */
        clock@0,70110000 {
-               status = "okay";
+               status = "disabled";
                vdd-cpu-supply = <&vdd_cpu>;
                nvidia,i2c-fs-rate = <400000>;
        };
index 19fe045b83342a6ee0f55a02b1490c291b9537dd..2d7eab7552100225efcf2cb5d52a5443459f6a58 100644 (file)
@@ -18,8 +18,3 @@
                reg = <0x80000000 0x10000000>;
        };
 };
-
-&L2 {
-       arm,data-latency = <2 1 2>;
-       arm,tag-latency = <3 2 3>;
-};
index 5f8eb1bd782bf01a6454aa7cb63682835c179650..58bc6e448be5601ed8d04106fbcc193793f040f1 100644 (file)
@@ -19,7 +19,7 @@
                reg = <0x40006000 0x1000>;
                cache-unified;
                cache-level = <2>;
-               arm,data-latency = <1 1 1>;
+               arm,data-latency = <3 3 3>;
                arm,tag-latency = <2 2 2>;
        };
 };
index 0d5acc2cdc8ef93008fc308ac8f3c9c8c1813771..3cd1b27f269780b99d1dbc4af64644bcaa45cce5 100644 (file)
                                compatible = "fsl,vf610-sai";
                                reg = <0x40031000 0x1000>;
                                interrupts = <86 IRQ_TYPE_LEVEL_HIGH>;
-                               clocks = <&clks VF610_CLK_SAI2>;
-                               clock-names = "sai";
+                               clocks = <&clks VF610_CLK_SAI2>,
+                                       <&clks VF610_CLK_SAI2_DIV>,
+                                       <&clks 0>, <&clks 0>;
+                               clock-names = "bus", "mclk1", "mclk2", "mclk3";
                                dma-names = "tx", "rx";
                                dmas = <&edma0 0 21>,
                                        <&edma0 0 20>;
index 6607d976e07d0998639457745ca364cf1305da85..7da5503c0591411f43df6bc767fb8c4eef314789 100644 (file)
@@ -21,6 +21,7 @@
 #ifndef __ASSEMBLY__
 
 #include <linux/io.h>
+#include <asm/barrier.h>
 
 #define __ACCESS_CP15(CRn, Op1, CRm, Op2)      p15, Op1, %0, CRn, CRm, Op2
 #define __ACCESS_CP15_64(Op1, CRm)             p15, Op1, %Q0, %R0, CRm
index 8cc85a4ebec20a1223f966bb868e5def5f70928e..35c9db857ebe9c7d53715ec42518a6e9fbe1dc6e 100644 (file)
@@ -510,10 +510,14 @@ __copy_to_user_std(void __user *to, const void *from, unsigned long n);
 static inline unsigned long __must_check
 __copy_to_user(void __user *to, const void *from, unsigned long n)
 {
+#ifndef CONFIG_UACCESS_WITH_MEMCPY
        unsigned int __ua_flags = uaccess_save_and_enable();
        n = arm_copy_to_user(to, from, n);
        uaccess_restore(__ua_flags);
        return n;
+#else
+       return arm_copy_to_user(to, from, n);
+#endif
 }
 
 extern unsigned long __must_check
index 7a7c4cea55231b1c793982ab63d6c5598004b14b..4adfb46e3ee93276ea506b723eb11e33c57459f4 100644 (file)
@@ -95,6 +95,22 @@ void __show_regs(struct pt_regs *regs)
 {
        unsigned long flags;
        char buf[64];
+#ifndef CONFIG_CPU_V7M
+       unsigned int domain;
+#ifdef CONFIG_CPU_SW_DOMAIN_PAN
+       /*
+        * Get the domain register for the parent context. In user
+        * mode, we don't save the DACR, so lets use what it should
+        * be. For other modes, we place it after the pt_regs struct.
+        */
+       if (user_mode(regs))
+               domain = DACR_UACCESS_ENABLE;
+       else
+               domain = *(unsigned int *)(regs + 1);
+#else
+       domain = get_domain();
+#endif
+#endif
 
        show_regs_print_info(KERN_DEFAULT);
 
@@ -123,21 +139,8 @@ void __show_regs(struct pt_regs *regs)
 
 #ifndef CONFIG_CPU_V7M
        {
-               unsigned int domain = get_domain();
                const char *segment;
 
-#ifdef CONFIG_CPU_SW_DOMAIN_PAN
-               /*
-                * Get the domain register for the parent context. In user
-                * mode, we don't save the DACR, so lets use what it should
-                * be. For other modes, we place it after the pt_regs struct.
-                */
-               if (user_mode(regs))
-                       domain = DACR_UACCESS_ENABLE;
-               else
-                       domain = *(unsigned int *)(regs + 1);
-#endif
-
                if ((domain & domain_mask(DOMAIN_USER)) ==
                    domain_val(DOMAIN_USER, DOMAIN_NOACCESS))
                        segment = "none";
@@ -163,11 +166,11 @@ void __show_regs(struct pt_regs *regs)
                buf[0] = '\0';
 #ifdef CONFIG_CPU_CP15_MMU
                {
-                       unsigned int transbase, dac = get_domain();
+                       unsigned int transbase;
                        asm("mrc p15, 0, %0, c2, c0\n\t"
                            : "=r" (transbase));
                        snprintf(buf, sizeof(buf), "  Table: %08x  DAC: %08x",
-                               transbase, dac);
+                               transbase, domain);
                }
 #endif
                asm("mrc p15, 0, %0, c1, c0\n" : "=r" (ctrl));
index 5b26e7efa9ea415967b63ede27ab1edf2bc8e888..c3fe769d75584c7248015b855bca904589f3e29f 100644 (file)
  */
 #define __user_swpX_asm(data, addr, res, temp, B)              \
        __asm__ __volatile__(                                   \
-       "       mov             %2, %1\n"                       \
-       "0:     ldrex"B"        %1, [%3]\n"                     \
-       "1:     strex"B"        %0, %2, [%3]\n"                 \
+       "0:     ldrex"B"        %2, [%3]\n"                     \
+       "1:     strex"B"        %0, %1, [%3]\n"                 \
        "       cmp             %0, #0\n"                       \
+       "       moveq           %1, %2\n"                       \
        "       movne           %0, %4\n"                       \
        "2:\n"                                                  \
        "       .section         .text.fixup,\"ax\"\n"          \
index b83f3b7737fb9dce2a18c66a086aac2430e98cf6..087acb569b63a4bd90982e0c9b15fc2313636c53 100644 (file)
@@ -193,15 +193,44 @@ struct oabi_flock64 {
        pid_t   l_pid;
 } __attribute__ ((packed,aligned(4)));
 
-asmlinkage long sys_oabi_fcntl64(unsigned int fd, unsigned int cmd,
+static long do_locks(unsigned int fd, unsigned int cmd,
                                 unsigned long arg)
 {
-       struct oabi_flock64 user;
        struct flock64 kernel;
-       mm_segment_t fs = USER_DS; /* initialized to kill a warning */
-       unsigned long local_arg = arg;
-       int ret;
+       struct oabi_flock64 user;
+       mm_segment_t fs;
+       long ret;
+
+       if (copy_from_user(&user, (struct oabi_flock64 __user *)arg,
+                          sizeof(user)))
+               return -EFAULT;
+       kernel.l_type   = user.l_type;
+       kernel.l_whence = user.l_whence;
+       kernel.l_start  = user.l_start;
+       kernel.l_len    = user.l_len;
+       kernel.l_pid    = user.l_pid;
+
+       fs = get_fs();
+       set_fs(KERNEL_DS);
+       ret = sys_fcntl64(fd, cmd, (unsigned long)&kernel);
+       set_fs(fs);
+
+       if (!ret && (cmd == F_GETLK64 || cmd == F_OFD_GETLK)) {
+               user.l_type     = kernel.l_type;
+               user.l_whence   = kernel.l_whence;
+               user.l_start    = kernel.l_start;
+               user.l_len      = kernel.l_len;
+               user.l_pid      = kernel.l_pid;
+               if (copy_to_user((struct oabi_flock64 __user *)arg,
+                                &user, sizeof(user)))
+                       ret = -EFAULT;
+       }
+       return ret;
+}
 
+asmlinkage long sys_oabi_fcntl64(unsigned int fd, unsigned int cmd,
+                                unsigned long arg)
+{
        switch (cmd) {
        case F_OFD_GETLK:
        case F_OFD_SETLK:
@@ -209,39 +238,11 @@ asmlinkage long sys_oabi_fcntl64(unsigned int fd, unsigned int cmd,
        case F_GETLK64:
        case F_SETLK64:
        case F_SETLKW64:
-               if (copy_from_user(&user, (struct oabi_flock64 __user *)arg,
-                                  sizeof(user)))
-                       return -EFAULT;
-               kernel.l_type   = user.l_type;
-               kernel.l_whence = user.l_whence;
-               kernel.l_start  = user.l_start;
-               kernel.l_len    = user.l_len;
-               kernel.l_pid    = user.l_pid;
-               local_arg = (unsigned long)&kernel;
-               fs = get_fs();
-               set_fs(KERNEL_DS);
-       }
-
-       ret = sys_fcntl64(fd, cmd, local_arg);
+               return do_locks(fd, cmd, arg);
 
-       switch (cmd) {
-       case F_GETLK64:
-               if (!ret) {
-                       user.l_type     = kernel.l_type;
-                       user.l_whence   = kernel.l_whence;
-                       user.l_start    = kernel.l_start;
-                       user.l_len      = kernel.l_len;
-                       user.l_pid      = kernel.l_pid;
-                       if (copy_to_user((struct oabi_flock64 __user *)arg,
-                                        &user, sizeof(user)))
-                               ret = -EFAULT;
-               }
-       case F_SETLK64:
-       case F_SETLKW64:
-               set_fs(fs);
+       default:
+               return sys_fcntl64(fd, cmd, arg);
        }
-
-       return ret;
 }
 
 struct oabi_epoll_event {
index d72b90905132487257220939a255ac7ed1d3754d..588bbc288396ae52fe0d801bc537906b3e5dbfce 100644 (file)
@@ -88,6 +88,7 @@ pin_page_for_write(const void __user *_addr, pte_t **ptep, spinlock_t **ptlp)
 static unsigned long noinline
 __copy_to_user_memcpy(void __user *to, const void *from, unsigned long n)
 {
+       unsigned long ua_flags;
        int atomic;
 
        if (unlikely(segment_eq(get_fs(), KERNEL_DS))) {
@@ -118,7 +119,9 @@ __copy_to_user_memcpy(void __user *to, const void *from, unsigned long n)
                if (tocopy > n)
                        tocopy = n;
 
+               ua_flags = uaccess_save_and_enable();
                memcpy((void *)to, from, tocopy);
+               uaccess_restore(ua_flags);
                to += tocopy;
                from += tocopy;
                n -= tocopy;
@@ -145,14 +148,21 @@ arm_copy_to_user(void __user *to, const void *from, unsigned long n)
         * With frame pointer disabled, tail call optimization kicks in
         * as well making this test almost invisible.
         */
-       if (n < 64)
-               return __copy_to_user_std(to, from, n);
-       return __copy_to_user_memcpy(to, from, n);
+       if (n < 64) {
+               unsigned long ua_flags = uaccess_save_and_enable();
+               n = __copy_to_user_std(to, from, n);
+               uaccess_restore(ua_flags);
+       } else {
+               n = __copy_to_user_memcpy(to, from, n);
+       }
+       return n;
 }
        
 static unsigned long noinline
 __clear_user_memset(void __user *addr, unsigned long n)
 {
+       unsigned long ua_flags;
+
        if (unlikely(segment_eq(get_fs(), KERNEL_DS))) {
                memset((void *)addr, 0, n);
                return 0;
@@ -175,7 +185,9 @@ __clear_user_memset(void __user *addr, unsigned long n)
                if (tocopy > n)
                        tocopy = n;
 
+               ua_flags = uaccess_save_and_enable();
                memset((void *)addr, 0, tocopy);
+               uaccess_restore(ua_flags);
                addr += tocopy;
                n -= tocopy;
 
@@ -193,9 +205,14 @@ out:
 unsigned long arm_clear_user(void __user *addr, unsigned long n)
 {
        /* See rational for this in __copy_to_user() above. */
-       if (n < 64)
-               return __clear_user_std(addr, n);
-       return __clear_user_memset(addr, n);
+       if (n < 64) {
+               unsigned long ua_flags = uaccess_save_and_enable();
+               n = __clear_user_std(addr, n);
+               uaccess_restore(ua_flags);
+       } else {
+               n = __clear_user_memset(addr, n);
+       }
+       return n;
 }
 
 #if 0
index 92673006e55c410ad27f60675c8e74bbf1433861..28656c2b54a0baadcc0aeaa6564cd1d91b592259 100644 (file)
@@ -4,7 +4,6 @@ menuconfig ARCH_AT91
        select ARCH_REQUIRE_GPIOLIB
        select COMMON_CLK_AT91
        select PINCTRL
-       select PINCTRL_AT91
        select SOC_BUS
 
 if ARCH_AT91
@@ -17,6 +16,7 @@ config SOC_SAMA5D2
        select HAVE_AT91_USB_CLK
        select HAVE_AT91_H32MX
        select HAVE_AT91_GENERATED_CLK
+       select PINCTRL_AT91PIO4
        help
          Select this if ou are using one of Atmel's SAMA5D2 family SoC.
 
@@ -27,6 +27,7 @@ config SOC_SAMA5D3
        select HAVE_AT91_UTMI
        select HAVE_AT91_SMD
        select HAVE_AT91_USB_CLK
+       select PINCTRL_AT91
        help
          Select this if you are using one of Atmel's SAMA5D3 family SoC.
          This support covers SAMA5D31, SAMA5D33, SAMA5D34, SAMA5D35, SAMA5D36.
@@ -40,6 +41,7 @@ config SOC_SAMA5D4
        select HAVE_AT91_SMD
        select HAVE_AT91_USB_CLK
        select HAVE_AT91_H32MX
+       select PINCTRL_AT91
        help
          Select this if you are using one of Atmel's SAMA5D4 family SoC.
 
@@ -50,6 +52,7 @@ config SOC_AT91RM9200
        select CPU_ARM920T
        select HAVE_AT91_USB_CLK
        select MIGHT_HAVE_PCI
+       select PINCTRL_AT91
        select SOC_SAM_V4_V5
        select SRAM if PM
        help
@@ -65,6 +68,7 @@ config SOC_AT91SAM9
        select HAVE_AT91_UTMI
        select HAVE_FB_ATMEL
        select MEMORY
+       select PINCTRL_AT91
        select SOC_SAM_V4_V5
        select SRAM if PM
        help
index 80e277cfcc8b6965d954473d877b66f91cdec52c..23726fb31741ea1479733ef91e88ac5585f7fe52 100644 (file)
  * implementation should be moved down into the pinctrl driver and get
  * called as part of the generic suspend/resume path.
  */
+#ifdef CONFIG_PINCTRL_AT91
 extern void at91_pinctrl_gpio_suspend(void);
 extern void at91_pinctrl_gpio_resume(void);
+#endif
 
 static struct {
        unsigned long uhp_udp_mask;
@@ -151,8 +153,9 @@ static void at91_pm_suspend(suspend_state_t state)
 
 static int at91_pm_enter(suspend_state_t state)
 {
+#ifdef CONFIG_PINCTRL_AT91
        at91_pinctrl_gpio_suspend();
-
+#endif
        switch (state) {
        /*
         * Suspend-to-RAM is like STANDBY plus slow clock mode, so
@@ -192,7 +195,9 @@ static int at91_pm_enter(suspend_state_t state)
 error:
        target_state = PM_SUSPEND_ON;
 
+#ifdef CONFIG_PINCTRL_AT91
        at91_pinctrl_gpio_resume();
+#endif
        return 0;
 }
 
index de68938ee6aa89a070c910c6de1cf1f5035cf0a4..c21e41dad19c14a66b83bcee65af4b504d8172c7 100644 (file)
@@ -748,8 +748,12 @@ static void exynos5_powerdown_conf(enum sys_powerdown mode)
 void exynos_sys_powerdown_conf(enum sys_powerdown mode)
 {
        unsigned int i;
+       const struct exynos_pmu_data *pmu_data;
+
+       if (!pmu_context)
+               return;
 
-       const struct exynos_pmu_data *pmu_data = pmu_context->pmu_data;
+       pmu_data = pmu_context->pmu_data;
 
        if (pmu_data->powerdown_conf)
                pmu_data->powerdown_conf(mode);
index b024390199639ca31201730ccdbcfceae577be2b..7a0c13bf42694b724e0fcb35439070eefde0a646 100644 (file)
@@ -143,7 +143,7 @@ static inline void __indirect_writesl(volatile void __iomem *bus_addr,
                writel(*vaddr++, bus_addr);
 }
 
-static inline unsigned char __indirect_readb(const volatile void __iomem *p)
+static inline u8 __indirect_readb(const volatile void __iomem *p)
 {
        u32 addr = (u32)p;
        u32 n, byte_enables, data;
@@ -166,7 +166,7 @@ static inline void __indirect_readsb(const volatile void __iomem *bus_addr,
                *vaddr++ = readb(bus_addr);
 }
 
-static inline unsigned short __indirect_readw(const volatile void __iomem *p)
+static inline u16 __indirect_readw(const volatile void __iomem *p)
 {
        u32 addr = (u32)p;
        u32 n, byte_enables, data;
@@ -189,7 +189,7 @@ static inline void __indirect_readsw(const volatile void __iomem *bus_addr,
                *vaddr++ = readw(bus_addr);
 }
 
-static inline unsigned long __indirect_readl(const volatile void __iomem *p)
+static inline u32 __indirect_readl(const volatile void __iomem *p)
 {
        u32 addr = (__force u32)p;
        u32 data;
@@ -350,7 +350,7 @@ static inline void insl(u32 io_addr, void *p, u32 count)
                                        ((unsigned long)p <= (PIO_MASK + PIO_OFFSET)))
 
 #define        ioread8(p)                      ioread8(p)
-static inline unsigned int ioread8(const void __iomem *addr)
+static inline u8 ioread8(const void __iomem *addr)
 {
        unsigned long port = (unsigned long __force)addr;
        if (__is_io_address(port))
@@ -378,7 +378,7 @@ static inline void ioread8_rep(const void __iomem *addr, void *vaddr, u32 count)
 }
 
 #define        ioread16(p)                     ioread16(p)
-static inline unsigned int ioread16(const void __iomem *addr)
+static inline u16 ioread16(const void __iomem *addr)
 {
        unsigned long port = (unsigned long __force)addr;
        if (__is_io_address(port))
@@ -407,7 +407,7 @@ static inline void ioread16_rep(const void __iomem *addr, void *vaddr,
 }
 
 #define        ioread32(p)                     ioread32(p)
-static inline unsigned int ioread32(const void __iomem *addr)
+static inline u32 ioread32(const void __iomem *addr)
 {
        unsigned long port = (unsigned long __force)addr;
        if (__is_io_address(port))
index 5076d3f334d28753e697b9e801b050c5807cadad..0517f0c1581a71091539c5c1abe47473f4b789ef 100644 (file)
@@ -65,6 +65,8 @@ config SOC_AM43XX
        select MACH_OMAP_GENERIC
        select MIGHT_HAVE_CACHE_L2X0
        select HAVE_ARM_SCU
+       select GENERIC_CLOCKEVENTS_BROADCAST
+       select HAVE_ARM_TWD
 
 config SOC_DRA7XX
        bool "TI DRA7XX"
@@ -121,6 +123,7 @@ config ARCH_OMAP2PLUS_TYPICAL
        select NEON if CPU_V7
        select PM
        select REGULATOR
+       select REGULATOR_FIXED_VOLTAGE
        select TWL4030_CORE if ARCH_OMAP3 || ARCH_OMAP4
        select TWL4030_POWER if ARCH_OMAP3 || ARCH_OMAP4
        select VFP
@@ -201,7 +204,6 @@ config MACH_OMAP3_PANDORA
        depends on ARCH_OMAP3
        default y
        select OMAP_PACKAGE_CBB
-       select REGULATOR_FIXED_VOLTAGE if REGULATOR
 
 config MACH_NOKIA_N810
        bool
index b18ebbefae09577e20b19e53167aca5ef11b8d86..f86692dbcfd56efce7250b3a659891ad57a45725 100644 (file)
@@ -320,6 +320,12 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer,
        return r;
 }
 
+#if !defined(CONFIG_SMP) && defined(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST)
+void tick_broadcast(const struct cpumask *mask)
+{
+}
+#endif
+
 static void __init omap2_gp_clockevent_init(int gptimer_id,
                                                const char *fck_source,
                                                const char *property)
index 9a9c15bfcd3451f02c115238813b2193db266844..7c0d5618be5e8b6f394cec5f4d797ad931675735 100644 (file)
@@ -889,6 +889,7 @@ static void __init e680_init(void)
 
        pxa_set_keypad_info(&e680_keypad_platform_data);
 
+       pwm_add_table(ezx_pwm_lookup, ARRAY_SIZE(ezx_pwm_lookup));
        platform_add_devices(ARRAY_AND_SIZE(ezx_devices));
        platform_add_devices(ARRAY_AND_SIZE(e680_devices));
 }
@@ -956,6 +957,7 @@ static void __init a1200_init(void)
 
        pxa_set_keypad_info(&a1200_keypad_platform_data);
 
+       pwm_add_table(ezx_pwm_lookup, ARRAY_SIZE(ezx_pwm_lookup));
        platform_add_devices(ARRAY_AND_SIZE(ezx_devices));
        platform_add_devices(ARRAY_AND_SIZE(a1200_devices));
 }
@@ -1148,6 +1150,7 @@ static void __init a910_init(void)
                platform_device_register(&a910_camera);
        }
 
+       pwm_add_table(ezx_pwm_lookup, ARRAY_SIZE(ezx_pwm_lookup));
        platform_add_devices(ARRAY_AND_SIZE(ezx_devices));
        platform_add_devices(ARRAY_AND_SIZE(a910_devices));
 }
@@ -1215,6 +1218,7 @@ static void __init e6_init(void)
 
        pxa_set_keypad_info(&e6_keypad_platform_data);
 
+       pwm_add_table(ezx_pwm_lookup, ARRAY_SIZE(ezx_pwm_lookup));
        platform_add_devices(ARRAY_AND_SIZE(ezx_devices));
        platform_add_devices(ARRAY_AND_SIZE(e6_devices));
 }
@@ -1256,6 +1260,7 @@ static void __init e2_init(void)
 
        pxa_set_keypad_info(&e2_keypad_platform_data);
 
+       pwm_add_table(ezx_pwm_lookup, ARRAY_SIZE(ezx_pwm_lookup));
        platform_add_devices(ARRAY_AND_SIZE(ezx_devices));
        platform_add_devices(ARRAY_AND_SIZE(e2_devices));
 }
index a19460e6e7b0ec9317e8db98ed9aea2cf6290421..b355fca6cc2efb1a3fccd3763c91430acb66fd69 100644 (file)
@@ -20,7 +20,7 @@
 #include <plat/cpu.h>
 #include <plat/cpu-freq-core.h>
 
-static struct cpufreq_frequency_table s3c2440_plls_12[] __initdata = {
+static struct cpufreq_frequency_table s3c2440_plls_12[] = {
        { .frequency = 75000000,        .driver_data = PLLVAL(0x75, 3, 3),  },  /* FVco 600.000000 */
        { .frequency = 80000000,        .driver_data = PLLVAL(0x98, 4, 3),  },  /* FVco 640.000000 */
        { .frequency = 90000000,        .driver_data = PLLVAL(0x70, 2, 3),  },  /* FVco 720.000000 */
index 1191b29056252e49eee5cc041e0757247dab1bdf..be9a248b5ce901b5eaed665ec4f5d75632775ebc 100644 (file)
@@ -20,7 +20,7 @@
 #include <plat/cpu.h>
 #include <plat/cpu-freq-core.h>
 
-static struct cpufreq_frequency_table s3c2440_plls_169344[] __initdata = {
+static struct cpufreq_frequency_table s3c2440_plls_169344[] = {
        { .frequency = 78019200,        .driver_data = PLLVAL(121, 5, 3),       },      /* FVco 624.153600 */
        { .frequency = 84067200,        .driver_data = PLLVAL(131, 5, 3),       },      /* FVco 672.537600 */
        { .frequency = 90115200,        .driver_data = PLLVAL(141, 5, 3),       },      /* FVco 720.921600 */
index 845769e413323120b6d7b4afed7640746413bc98..c8c8b9ed02e09b57a79bee1ab5db9c337be0d338 100644 (file)
@@ -165,13 +165,28 @@ static void flush_context(unsigned int cpu)
                __flush_icache_all();
 }
 
-static int is_reserved_asid(u64 asid)
+static bool check_update_reserved_asid(u64 asid, u64 newasid)
 {
        int cpu;
-       for_each_possible_cpu(cpu)
-               if (per_cpu(reserved_asids, cpu) == asid)
-                       return 1;
-       return 0;
+       bool hit = false;
+
+       /*
+        * Iterate over the set of reserved ASIDs looking for a match.
+        * If we find one, then we can update our mm to use newasid
+        * (i.e. the same ASID in the current generation) but we can't
+        * exit the loop early, since we need to ensure that all copies
+        * of the old ASID are updated to reflect the mm. Failure to do
+        * so could result in us missing the reserved ASID in a future
+        * generation.
+        */
+       for_each_possible_cpu(cpu) {
+               if (per_cpu(reserved_asids, cpu) == asid) {
+                       hit = true;
+                       per_cpu(reserved_asids, cpu) = newasid;
+               }
+       }
+
+       return hit;
 }
 
 static u64 new_context(struct mm_struct *mm, unsigned int cpu)
@@ -181,12 +196,14 @@ static u64 new_context(struct mm_struct *mm, unsigned int cpu)
        u64 generation = atomic64_read(&asid_generation);
 
        if (asid != 0) {
+               u64 newasid = generation | (asid & ~ASID_MASK);
+
                /*
                 * If our current ASID was active during a rollover, we
                 * can continue to use it and this was just a false alarm.
                 */
-               if (is_reserved_asid(asid))
-                       return generation | (asid & ~ASID_MASK);
+               if (check_update_reserved_asid(asid, newasid))
+                       return newasid;
 
                /*
                 * We had a valid ASID in a previous life, so try to re-use
@@ -194,7 +211,7 @@ static u64 new_context(struct mm_struct *mm, unsigned int cpu)
                 */
                asid &= ~ASID_MASK;
                if (!__test_and_set_bit(asid, asid_map))
-                       goto bump_gen;
+                       return newasid;
        }
 
        /*
@@ -216,11 +233,8 @@ static u64 new_context(struct mm_struct *mm, unsigned int cpu)
 
        __set_bit(asid, asid_map);
        cur_idx = asid;
-
-bump_gen:
-       asid |= generation;
        cpumask_clear(mm_cpumask(mm));
-       return asid;
+       return asid | generation;
 }
 
 void check_and_switch_context(struct mm_struct *mm, struct task_struct *tsk)
index e62400e5fb99fdbf864af966e718a98decf85e29..534a60ae282e702d3b06e8dad289d8f109cd80ef 100644 (file)
@@ -1521,7 +1521,7 @@ static int __map_sg_chunk(struct device *dev, struct scatterlist *sg,
                return -ENOMEM;
 
        for (count = 0, s = sg; count < (size >> PAGE_SHIFT); s = sg_next(s)) {
-               phys_addr_t phys = sg_phys(s) & PAGE_MASK;
+               phys_addr_t phys = page_to_phys(sg_page(s));
                unsigned int len = PAGE_ALIGN(s->offset + s->length);
 
                if (!is_coherent &&
index 8a63b4cdc0f27d0fa7cf69f0bb1ffa51b6289e39..7f8cd1b3557f071a64dafc05eba4c481ef82c79d 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/memblock.h>
 #include <linux/dma-contiguous.h>
 #include <linux/sizes.h>
+#include <linux/stop_machine.h>
 
 #include <asm/cp15.h>
 #include <asm/mach-types.h>
@@ -627,12 +628,10 @@ static struct section_perm ro_perms[] = {
  * safe to be called with preemption disabled, as under stop_machine().
  */
 static inline void section_update(unsigned long addr, pmdval_t mask,
-                                 pmdval_t prot)
+                                 pmdval_t prot, struct mm_struct *mm)
 {
-       struct mm_struct *mm;
        pmd_t *pmd;
 
-       mm = current->active_mm;
        pmd = pmd_offset(pud_offset(pgd_offset(mm, addr), addr), addr);
 
 #ifdef CONFIG_ARM_LPAE
@@ -656,49 +655,82 @@ static inline bool arch_has_strict_perms(void)
        return !!(get_cr() & CR_XP);
 }
 
-#define set_section_perms(perms, field)        {                               \
-       size_t i;                                                       \
-       unsigned long addr;                                             \
-                                                                       \
-       if (!arch_has_strict_perms())                                   \
-               return;                                                 \
-                                                                       \
-       for (i = 0; i < ARRAY_SIZE(perms); i++) {                       \
-               if (!IS_ALIGNED(perms[i].start, SECTION_SIZE) ||        \
-                   !IS_ALIGNED(perms[i].end, SECTION_SIZE)) {          \
-                       pr_err("BUG: section %lx-%lx not aligned to %lx\n", \
-                               perms[i].start, perms[i].end,           \
-                               SECTION_SIZE);                          \
-                       continue;                                       \
-               }                                                       \
-                                                                       \
-               for (addr = perms[i].start;                             \
-                    addr < perms[i].end;                               \
-                    addr += SECTION_SIZE)                              \
-                       section_update(addr, perms[i].mask,             \
-                                      perms[i].field);                 \
-       }                                                               \
+void set_section_perms(struct section_perm *perms, int n, bool set,
+                       struct mm_struct *mm)
+{
+       size_t i;
+       unsigned long addr;
+
+       if (!arch_has_strict_perms())
+               return;
+
+       for (i = 0; i < n; i++) {
+               if (!IS_ALIGNED(perms[i].start, SECTION_SIZE) ||
+                   !IS_ALIGNED(perms[i].end, SECTION_SIZE)) {
+                       pr_err("BUG: section %lx-%lx not aligned to %lx\n",
+                               perms[i].start, perms[i].end,
+                               SECTION_SIZE);
+                       continue;
+               }
+
+               for (addr = perms[i].start;
+                    addr < perms[i].end;
+                    addr += SECTION_SIZE)
+                       section_update(addr, perms[i].mask,
+                               set ? perms[i].prot : perms[i].clear, mm);
+       }
+
 }
 
-static inline void fix_kernmem_perms(void)
+static void update_sections_early(struct section_perm perms[], int n)
 {
-       set_section_perms(nx_perms, prot);
+       struct task_struct *t, *s;
+
+       read_lock(&tasklist_lock);
+       for_each_process(t) {
+               if (t->flags & PF_KTHREAD)
+                       continue;
+               for_each_thread(t, s)
+                       set_section_perms(perms, n, true, s->mm);
+       }
+       read_unlock(&tasklist_lock);
+       set_section_perms(perms, n, true, current->active_mm);
+       set_section_perms(perms, n, true, &init_mm);
+}
+
+int __fix_kernmem_perms(void *unused)
+{
+       update_sections_early(nx_perms, ARRAY_SIZE(nx_perms));
+       return 0;
+}
+
+void fix_kernmem_perms(void)
+{
+       stop_machine(__fix_kernmem_perms, NULL, NULL);
 }
 
 #ifdef CONFIG_DEBUG_RODATA
+int __mark_rodata_ro(void *unused)
+{
+       update_sections_early(ro_perms, ARRAY_SIZE(ro_perms));
+       return 0;
+}
+
 void mark_rodata_ro(void)
 {
-       set_section_perms(ro_perms, prot);
+       stop_machine(__mark_rodata_ro, NULL, NULL);
 }
 
 void set_kernel_text_rw(void)
 {
-       set_section_perms(ro_perms, clear);
+       set_section_perms(ro_perms, ARRAY_SIZE(ro_perms), false,
+                               current->active_mm);
 }
 
 void set_kernel_text_ro(void)
 {
-       set_section_perms(ro_perms, prot);
+       set_section_perms(ro_perms, ARRAY_SIZE(ro_perms), true,
+                               current->active_mm);
 }
 #endif /* CONFIG_DEBUG_RODATA */
 
index de2b246fed3808fce444b560a725ed4007464174..8e1ea433c3f1e321d7ed4e91fe582a5be4eb85be 100644 (file)
@@ -95,7 +95,7 @@ ENDPROC(cpu_v7_dcache_clean_area)
 .equ   cpu_v7_suspend_size, 4 * 9
 #ifdef CONFIG_ARM_CPU_SUSPEND
 ENTRY(cpu_v7_do_suspend)
-       stmfd   sp!, {r4 - r10, lr}
+       stmfd   sp!, {r4 - r11, lr}
        mrc     p15, 0, r4, c13, c0, 0  @ FCSE/PID
        mrc     p15, 0, r5, c13, c0, 3  @ User r/o thread ID
        stmia   r0!, {r4 - r5}
@@ -112,7 +112,7 @@ ENTRY(cpu_v7_do_suspend)
        mrc     p15, 0, r9, c1, c0, 1   @ Auxiliary control register
        mrc     p15, 0, r10, c1, c0, 2  @ Co-processor access control
        stmia   r0, {r5 - r11}
-       ldmfd   sp!, {r4 - r10, pc}
+       ldmfd   sp!, {r4 - r11, pc}
 ENDPROC(cpu_v7_do_suspend)
 
 ENTRY(cpu_v7_do_resume)
index 591f9db3bf4048a4d727f195e4e2fb95e4ca06c4..93d0b6d0b63eede5f36de91428bb181bab2e0971 100644 (file)
@@ -187,19 +187,6 @@ static inline int mem_words_used(struct jit_ctx *ctx)
        return fls(ctx->seen & SEEN_MEM);
 }
 
-static inline bool is_load_to_a(u16 inst)
-{
-       switch (inst) {
-       case BPF_LD | BPF_W | BPF_LEN:
-       case BPF_LD | BPF_W | BPF_ABS:
-       case BPF_LD | BPF_H | BPF_ABS:
-       case BPF_LD | BPF_B | BPF_ABS:
-               return true;
-       default:
-               return false;
-       }
-}
-
 static void jit_fill_hole(void *area, unsigned int size)
 {
        u32 *ptr;
@@ -211,7 +198,6 @@ static void jit_fill_hole(void *area, unsigned int size)
 static void build_prologue(struct jit_ctx *ctx)
 {
        u16 reg_set = saved_regs(ctx);
-       u16 first_inst = ctx->skf->insns[0].code;
        u16 off;
 
 #ifdef CONFIG_FRAME_POINTER
@@ -241,7 +227,7 @@ static void build_prologue(struct jit_ctx *ctx)
                emit(ARM_MOV_I(r_X, 0), ctx);
 
        /* do not leak kernel data to userspace */
-       if ((first_inst != (BPF_RET | BPF_K)) && !(is_load_to_a(first_inst)))
+       if (bpf_needs_clear_a(&ctx->skf->insns[0]))
                emit(ARM_MOV_I(r_A, 0), ctx);
 
        /* stack space for the BPF_MEM words */
@@ -770,7 +756,8 @@ load_ind:
                case BPF_ALU | BPF_RSH | BPF_K:
                        if (unlikely(k > 31))
                                return -1;
-                       emit(ARM_LSR_I(r_A, r_A, k), ctx);
+                       if (k)
+                               emit(ARM_LSR_I(r_A, r_A, k), ctx);
                        break;
                case BPF_ALU | BPF_RSH | BPF_X:
                        update_on_xread(ctx);
index e81cd48d6245eace97978c58057a022d105d990d..925552e7b4f3eaf6ce23fc1e8dd2d77f50073121 100644 (file)
                        clock-frequency = <0>;  /* Updated by bootloader */
                        voltage-ranges = <1800 1800 3300 3300>;
                        sdhci,auto-cmd12;
+                       little-endian;
                        bus-width = <4>;
                };
 
                        reg = <0x0 0x2300000 0x0 0x10000>;
                        interrupts = <0 36 0x4>; /* Level high type */
                        gpio-controller;
+                       little-endian;
                        #gpio-cells = <2>;
                        interrupt-controller;
                        #interrupt-cells = <2>;
                        reg = <0x0 0x2310000 0x0 0x10000>;
                        interrupts = <0 36 0x4>; /* Level high type */
                        gpio-controller;
+                       little-endian;
                        #gpio-cells = <2>;
                        interrupt-controller;
                        #interrupt-cells = <2>;
                        reg = <0x0 0x2320000 0x0 0x10000>;
                        interrupts = <0 37 0x4>; /* Level high type */
                        gpio-controller;
+                       little-endian;
                        #gpio-cells = <2>;
                        interrupt-controller;
                        #interrupt-cells = <2>;
                        reg = <0x0 0x2330000 0x0 0x10000>;
                        interrupts = <0 37 0x4>; /* Level high type */
                        gpio-controller;
+                       little-endian;
                        #gpio-cells = <2>;
                        interrupt-controller;
                        #interrupt-cells = <2>;
index 030cdcb46c6bdabd8bb49901ed231fcdbb5c25fd..2731d3b25ed2e338e76966b5efd86658b7e22263 100644 (file)
@@ -77,6 +77,7 @@
 #ifndef __ASSEMBLY__
 
 #include <linux/stringify.h>
+#include <asm/barrier.h>
 
 /*
  * Low-level accessors
index 7e074f93f383fea1891ce79d4048c22f647841a7..63f52b55defe1041a7913217db490528c441c6f3 100644 (file)
@@ -276,10 +276,14 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
         * hardware updates of the pte (ptep_set_access_flags safely changes
         * valid ptes without going through an invalid entry).
         */
-       if (IS_ENABLED(CONFIG_DEBUG_VM) && IS_ENABLED(CONFIG_ARM64_HW_AFDBM) &&
-           pte_valid(*ptep)) {
-               BUG_ON(!pte_young(pte));
-               BUG_ON(pte_write(*ptep) && !pte_dirty(pte));
+       if (IS_ENABLED(CONFIG_ARM64_HW_AFDBM) &&
+           pte_valid(*ptep) && pte_valid(pte)) {
+               VM_WARN_ONCE(!pte_young(pte),
+                            "%s: racy access flag clearing: 0x%016llx -> 0x%016llx",
+                            __func__, pte_val(*ptep), pte_val(pte));
+               VM_WARN_ONCE(pte_write(*ptep) && !pte_dirty(pte),
+                            "%s: racy dirty state clearing: 0x%016llx -> 0x%016llx",
+                            __func__, pte_val(*ptep), pte_val(pte));
        }
 
        set_pte(ptep, pte);
index 1ee2c3937d4e8badf3ccec9a816ad23f9814506f..71426a78db123d13e98acf8659d65155ff342a06 100644 (file)
@@ -5,6 +5,7 @@
  */
 
 #include <asm-generic/vmlinux.lds.h>
+#include <asm/cache.h>
 #include <asm/kernel-pgtable.h>
 #include <asm/thread_info.h>
 #include <asm/memory.h>
@@ -140,7 +141,7 @@ SECTIONS
                ARM_EXIT_KEEP(EXIT_DATA)
        }
 
-       PERCPU_SECTION(64)
+       PERCPU_SECTION(L1_CACHE_BYTES)
 
        . = ALIGN(PAGE_SIZE);
        __init_end = .;
@@ -158,7 +159,7 @@ SECTIONS
        . = ALIGN(PAGE_SIZE);
        _data = .;
        _sdata = .;
-       RW_DATA_SECTION(64, PAGE_SIZE, THREAD_SIZE)
+       RW_DATA_SECTION(L1_CACHE_BYTES, PAGE_SIZE, THREAD_SIZE)
        PECOFF_EDATA_PADDING
        _edata = .;
 
index db73390568c8dd873fc045cd35773714bd35f8e1..74c132d901bd290bcc803b7c0a0266428a2ec1cb 100644 (file)
@@ -11,7 +11,7 @@
 
 
 
-#define NR_syscalls                    322 /* length of syscall table */
+#define NR_syscalls                    323 /* length of syscall table */
 
 /*
  * The following defines stop scripts/checksyscalls.sh from complaining about
index 9038726e7d26777bf8f704f101ff86090e4d5059..762edce7572eb33f03a3402e4357de69626764c9 100644 (file)
 #define __NR_userfaultfd               1343
 #define __NR_membarrier                        1344
 #define __NR_kcmp                      1345
+#define __NR_mlock2                    1346
 
 #endif /* _UAPI_ASM_IA64_UNISTD_H */
index dcd97f84d065435a8eca5c041f33bb67c3912797..534a74acb849d736726b5f066675f0a3a4c87ed4 100644 (file)
@@ -1771,5 +1771,6 @@ sys_call_table:
        data8 sys_userfaultfd
        data8 sys_membarrier
        data8 sys_kcmp                          // 1345
+       data8 sys_mlock2
 
        .org sys_call_table + 8*NR_syscalls     // guard against failures to increase NR_syscalls
index fd104bd221ced1dff2c9485bdcb1be520171df7f..860e440611c98f7e0c2a9882c18dc73cf166f35e 100644 (file)
@@ -3,6 +3,7 @@ generic-y += clkdev.h
 generic-y += cputime.h
 generic-y += exec.h
 generic-y += irq_work.h
+generic-y += kvm_para.h
 generic-y += mcs_spinlock.h
 generic-y += mm-arch-hooks.h
 generic-y += module.h
index 61b8931bc19250df3af7b42b4e667749332b6be1..4b0f5e001d4d5ab2a545e62dcc276b9815df5821 100644 (file)
@@ -168,13 +168,21 @@ static inline void _writel(unsigned long l, unsigned long addr)
 #define writew_relaxed writew
 #define writel_relaxed writel
 
-#define ioread8 read
+#define ioread8 readb
 #define ioread16 readw
 #define ioread32 readl
 #define iowrite8 writeb
 #define iowrite16 writew
 #define iowrite32 writel
 
+#define ioread8_rep(p, dst, count) insb((unsigned long)(p), (dst), (count))
+#define ioread16_rep(p, dst, count) insw((unsigned long)(p), (dst), (count))
+#define ioread32_rep(p, dst, count) insl((unsigned long)(p), (dst), (count))
+
+#define iowrite8_rep(p, src, count) outsb((unsigned long)(p), (src), (count))
+#define iowrite16_rep(p, src, count) outsw((unsigned long)(p), (src), (count))
+#define iowrite32_rep(p, src, count) outsl((unsigned long)(p), (src), (count))
+
 #define ioread16be(addr)       be16_to_cpu(readw(addr))
 #define ioread32be(addr)       be32_to_cpu(readl(addr))
 #define iowrite16be(v, addr)   writew(cpu_to_be16(v), (addr))
index c89da63129545a9c300e61062e9d958d4c786790..bf4dec229437a836ee1829504be7bf603ce73b37 100644 (file)
@@ -61,7 +61,8 @@ static int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl,
        /* FIXME this part of code is untested */
        for_each_sg(sgl, sg, nents, i) {
                sg->dma_address = sg_phys(sg);
-               __dma_sync(sg_phys(sg), sg->length, direction);
+               __dma_sync(page_to_phys(sg_page(sg)) + sg->offset,
+                                                       sg->length, direction);
        }
 
        return nents;
index 5305d694ffe52010f19a110fd072341a44e4ae85..095ecafe6bd3525444c27812937e2d085bf69b2a 100644 (file)
@@ -599,7 +599,7 @@ extern void __put_user_unknown(void);
  * On error, the variable @x is set to zero.
  */
 #define __get_user_unaligned(x,ptr) \
-       __get_user__unalignednocheck((x),(ptr),sizeof(*(ptr)))
+       __get_user_unaligned_nocheck((x),(ptr),sizeof(*(ptr)))
 
 /*
  * Yuck.  We need two variants, one for 64bit operation and one
@@ -620,8 +620,8 @@ extern void __get_user_unaligned_unknown(void);
 do {                                                                   \
        switch (size) {                                                 \
        case 1: __get_data_asm(val, "lb", ptr); break;                  \
-       case 2: __get_user_unaligned_asm(val, "ulh", ptr); break;       \
-       case 4: __get_user_unaligned_asm(val, "ulw", ptr); break;       \
+       case 2: __get_data_unaligned_asm(val, "ulh", ptr); break;       \
+       case 4: __get_data_unaligned_asm(val, "ulw", ptr); break;       \
        case 8: __GET_USER_UNALIGNED_DW(val, ptr); break;               \
        default: __get_user_unaligned_unknown(); break;                 \
        }                                                               \
@@ -1122,9 +1122,15 @@ extern size_t __copy_in_user_eva(void *__to, const void *__from, size_t __n);
        __cu_to = (to);                                                 \
        __cu_from = (from);                                             \
        __cu_len = (n);                                                 \
-       might_fault();                                                  \
-       __cu_len = __invoke_copy_from_user(__cu_to, __cu_from,          \
-                                          __cu_len);                   \
+       if (eva_kernel_access()) {                                      \
+               __cu_len = __invoke_copy_from_kernel(__cu_to,           \
+                                                    __cu_from,         \
+                                                    __cu_len);         \
+       } else {                                                        \
+               might_fault();                                          \
+               __cu_len = __invoke_copy_from_user(__cu_to, __cu_from,  \
+                                                  __cu_len);           \
+       }                                                               \
        __cu_len;                                                       \
 })
 
@@ -1229,16 +1235,28 @@ __clear_user(void __user *addr, __kernel_size_t size)
 {
        __kernel_size_t res;
 
-       might_fault();
-       __asm__ __volatile__(
-               "move\t$4, %1\n\t"
-               "move\t$5, $0\n\t"
-               "move\t$6, %2\n\t"
-               __MODULE_JAL(__bzero)
-               "move\t%0, $6"
-               : "=r" (res)
-               : "r" (addr), "r" (size)
-               : "$4", "$5", "$6", __UA_t0, __UA_t1, "$31");
+       if (eva_kernel_access()) {
+               __asm__ __volatile__(
+                       "move\t$4, %1\n\t"
+                       "move\t$5, $0\n\t"
+                       "move\t$6, %2\n\t"
+                       __MODULE_JAL(__bzero_kernel)
+                       "move\t%0, $6"
+                       : "=r" (res)
+                       : "r" (addr), "r" (size)
+                       : "$4", "$5", "$6", __UA_t0, __UA_t1, "$31");
+       } else {
+               might_fault();
+               __asm__ __volatile__(
+                       "move\t$4, %1\n\t"
+                       "move\t$5, $0\n\t"
+                       "move\t$6, %2\n\t"
+                       __MODULE_JAL(__bzero)
+                       "move\t%0, $6"
+                       : "=r" (res)
+                       : "r" (addr), "r" (size)
+                       : "$4", "$5", "$6", __UA_t0, __UA_t1, "$31");
+       }
 
        return res;
 }
@@ -1384,7 +1402,7 @@ static inline long strlen_user(const char __user *s)
                might_fault();
                __asm__ __volatile__(
                        "move\t$4, %1\n\t"
-                       __MODULE_JAL(__strlen_kernel_asm)
+                       __MODULE_JAL(__strlen_user_asm)
                        "move\t%0, $2"
                        : "=r" (res)
                        : "r" (s)
index 8fd5a276cad23493f6500d0f4b01515ee20062f5..ac81edd44563119dbf6cf6fa0c9154afb9c47b98 100644 (file)
@@ -257,7 +257,6 @@ LEAF(mips_cps_core_init)
        has_mt  t0, 3f
 
        .set    push
-       .set    mips64r2
        .set    mt
 
        /* Only allow 1 TC per VPE to execute... */
@@ -376,7 +375,6 @@ LEAF(mips_cps_boot_vpes)
         nop
 
        .set    push
-       .set    mips64r2
        .set    mt
 
 1:     /* Enter VPE configuration state */
index 291af0b5c4828adaa22ff0fc065f37c6a094fd85..e2b6ab74643dba93b403dbba2dcfb4eced3e6d9e 100644 (file)
@@ -17,6 +17,7 @@
 #include <asm/fpu.h>
 #include <asm/msa.h>
 
+extern void *__bzero_kernel(void *__s, size_t __count);
 extern void *__bzero(void *__s, size_t __count);
 extern long __strncpy_from_kernel_nocheck_asm(char *__to,
                                              const char *__from, long __len);
@@ -64,6 +65,7 @@ EXPORT_SYMBOL(__copy_from_user_eva);
 EXPORT_SYMBOL(__copy_in_user_eva);
 EXPORT_SYMBOL(__copy_to_user_eva);
 EXPORT_SYMBOL(__copy_user_inatomic_eva);
+EXPORT_SYMBOL(__bzero_kernel);
 #endif
 EXPORT_SYMBOL(__bzero);
 EXPORT_SYMBOL(__strncpy_from_kernel_nocheck_asm);
index b8e63fd0037547cb9939907696da7ae55d699a95..8f0019a2e5c84bcd4f439559dad479b44903269a 100644 (file)
@@ -283,6 +283,8 @@ LEAF(memset)
 1:
 #ifndef CONFIG_EVA
 FEXPORT(__bzero)
+#else
+FEXPORT(__bzero_kernel)
 #endif
        __BUILD_BZERO LEGACY_MODE
 
index d8117be729a20ee26d2df8bb42a6f58b9670f513..730d394ce5f017991146084f9df53794242c970d 100644 (file)
@@ -145,7 +145,7 @@ static void *mips_dma_alloc_coherent(struct device *dev, size_t size,
 
        gfp = massage_gfp_flags(dev, gfp);
 
-       if (IS_ENABLED(CONFIG_DMA_CMA) && !(gfp & GFP_ATOMIC))
+       if (IS_ENABLED(CONFIG_DMA_CMA) && gfpflags_allow_blocking(gfp))
                page = dma_alloc_from_contiguous(dev,
                                        count, get_order(size));
        if (!page)
index 77cb27309db27f781ec9862037074d39e928401a..1a8c96035716a2dfb76f724b6190b33954bee8c8 100644 (file)
@@ -521,19 +521,6 @@ static inline u16 align_sp(unsigned int num)
        return num;
 }
 
-static bool is_load_to_a(u16 inst)
-{
-       switch (inst) {
-       case BPF_LD | BPF_W | BPF_LEN:
-       case BPF_LD | BPF_W | BPF_ABS:
-       case BPF_LD | BPF_H | BPF_ABS:
-       case BPF_LD | BPF_B | BPF_ABS:
-               return true;
-       default:
-               return false;
-       }
-}
-
 static void save_bpf_jit_regs(struct jit_ctx *ctx, unsigned offset)
 {
        int i = 0, real_off = 0;
@@ -614,7 +601,6 @@ static unsigned int get_stack_depth(struct jit_ctx *ctx)
 
 static void build_prologue(struct jit_ctx *ctx)
 {
-       u16 first_inst = ctx->skf->insns[0].code;
        int sp_off;
 
        /* Calculate the total offset for the stack pointer */
@@ -641,7 +627,7 @@ static void build_prologue(struct jit_ctx *ctx)
                emit_jit_reg_move(r_X, r_zero, ctx);
 
        /* Do not leak kernel data to userspace */
-       if ((first_inst != (BPF_RET | BPF_K)) && !(is_load_to_a(first_inst)))
+       if (bpf_needs_clear_a(&ctx->skf->insns[0]))
                emit_jit_reg_move(r_A, r_zero, ctx);
 }
 
index dbbeccc3d714add203aae3ebb5b3a0cd1522f0ae..a245cad4372a4a84094b88eed05ba3080a146190 100644 (file)
@@ -221,7 +221,6 @@ int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 static int rt288x_pci_probe(struct platform_device *pdev)
 {
        void __iomem *io_map_base;
-       int i;
 
        rt2880_pci_base = ioremap_nocache(RT2880_PCI_BASE, PAGE_SIZE);
 
index 78b2ef49dbc7a45adc720264f66cc9922453ceb2..9d293b3e9130152af49f964e530ece27e482fd7b 100644 (file)
@@ -39,7 +39,6 @@ extern void msp_serial_setup(void);
 void msp7120_reset(void)
 {
        void *start, *end, *iptr;
-       register int i;
 
        /* Diasble all interrupts */
        local_irq_disable();
index db8f88b6a3af9cb52dcb2a2a23df94a49cc0eccd..6afa34346b8148040a84e0a54ecd7af8d7ac608c 100644 (file)
@@ -26,7 +26,7 @@ static inline void kb_wait(void)
 /* XXX This ends up at the ARC firmware prompt ...  */
 void sni_machine_restart(char *command)
 {
-       int i, j;
+       int i;
 
        /* This does a normal via the keyboard controller like a PC.
           We can do that easier ...  */
index ef5f348f386a1ec4c5aef0a566a334a40e8f763b..14568900fc1d14ec2e0ff6b2d7152232c8b867bb 100644 (file)
@@ -26,8 +26,8 @@ aflags-vdso := $(ccflags-vdso) \
 # the comments on that file.
 #
 ifndef CONFIG_CPU_MIPSR6
-  ifeq ($(call ld-ifversion, -gt, 22400000, y),)
-    $(warning MIPS VDSO requires binutils > 2.24)
+  ifeq ($(call ld-ifversion, -lt, 22500000, y),y)
+    $(warning MIPS VDSO requires binutils >= 2.25)
     obj-vdso-y := $(filter-out gettimeofday.o, $(obj-vdso-y))
     ccflags-vdso += -DDISABLE_MIPS_VDSO
   endif
index d8534f95915a3754c233fd14466aef6cbfba40dc..291cee28ccb60da84576ba1d9e103a0dc6e78ba5 100644 (file)
@@ -372,7 +372,8 @@ static inline pte_t pte_mkspecial(pte_t pte)        { return pte; }
  */
 #ifdef CONFIG_HUGETLB_PAGE
 #define pte_huge(pte)           (pte_val(pte) & _PAGE_HUGE)
-#define pte_mkhuge(pte)         (__pte(pte_val(pte) | _PAGE_HUGE))
+#define pte_mkhuge(pte)         (__pte(pte_val(pte) | \
+                                (parisc_requires_coherency() ? 0 : _PAGE_HUGE)))
 #else
 #define pte_huge(pte)           (0)
 #define pte_mkhuge(pte)         (pte)
index 33170384d3ac1a7fdd835c7b8f04484aaf1f244c..35bdccbb203622e116f288741ac4a9bc173034b0 100644 (file)
 #define __NR_execveat          (__NR_Linux + 342)
 #define __NR_membarrier                (__NR_Linux + 343)
 #define __NR_userfaultfd       (__NR_Linux + 344)
+#define __NR_mlock2            (__NR_Linux + 345)
 
-#define __NR_Linux_syscalls    (__NR_userfaultfd + 1)
+#define __NR_Linux_syscalls    (__NR_mlock2 + 1)
 
 
 #define __IGNORE_select                /* newselect */
index 64f2764a8cef8778a0602262a5c5b10e4d68975d..c99f3dde455ce5979ee4e17830704710ba4683af 100644 (file)
@@ -171,24 +171,6 @@ void pcibios_set_master(struct pci_dev *dev)
 }
 
 
-void __init pcibios_init_bus(struct pci_bus *bus)
-{
-       struct pci_dev *dev = bus->self;
-       unsigned short bridge_ctl;
-
-       /* We deal only with pci controllers and pci-pci bridges. */
-       if (!dev || (dev->class >> 8) != PCI_CLASS_BRIDGE_PCI)
-               return;
-
-       /* PCI-PCI bridge - set the cache line and default latency
-          (32) for primary and secondary buses. */
-       pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER, 32);
-
-       pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &bridge_ctl);
-       bridge_ctl |= PCI_BRIDGE_CTL_PARITY | PCI_BRIDGE_CTL_SERR;
-       pci_write_config_word(dev, PCI_BRIDGE_CONTROL, bridge_ctl);
-}
-
 /*
  * pcibios align resources() is called every time generic PCI code
  * wants to generate a new address. The process of looking for
index dc1ea796fd605c257c7ce1196a63773a3e3e7987..2264f68f3c2f9716030cb8fab53487f6db22e667 100644 (file)
@@ -435,6 +435,55 @@ handle_signal(struct ksignal *ksig, struct pt_regs *regs, int in_syscall)
                regs->gr[28]);
 }
 
+/*
+ * Check how the syscall number gets loaded into %r20 within
+ * the delay branch in userspace and adjust as needed.
+ */
+
+static void check_syscallno_in_delay_branch(struct pt_regs *regs)
+{
+       u32 opcode, source_reg;
+       u32 __user *uaddr;
+       int err;
+
+       /* Usually we don't have to restore %r20 (the system call number)
+        * because it gets loaded in the delay slot of the branch external
+        * instruction via the ldi instruction.
+        * In some cases a register-to-register copy instruction might have
+        * been used instead, in which case we need to copy the syscall
+        * number into the source register before returning to userspace.
+        */
+
+       /* A syscall is just a branch, so all we have to do is fiddle the
+        * return pointer so that the ble instruction gets executed again.
+        */
+       regs->gr[31] -= 8; /* delayed branching */
+
+       /* Get assembler opcode of code in delay branch */
+       uaddr = (unsigned int *) ((regs->gr[31] & ~3) + 4);
+       err = get_user(opcode, uaddr);
+       if (err)
+               return;
+
+       /* Check if delay branch uses "ldi int,%r20" */
+       if ((opcode & 0xffff0000) == 0x34140000)
+               return; /* everything ok, just return */
+
+       /* Check if delay branch uses "nop" */
+       if (opcode == INSN_NOP)
+               return;
+
+       /* Check if delay branch uses "copy %rX,%r20" */
+       if ((opcode & 0xffe0ffff) == 0x08000254) {
+               source_reg = (opcode >> 16) & 31;
+               regs->gr[source_reg] = regs->gr[20];
+               return;
+       }
+
+       pr_warn("syscall restart: %s (pid %d): unexpected opcode 0x%08x\n",
+               current->comm, task_pid_nr(current), opcode);
+}
+
 static inline void
 syscall_restart(struct pt_regs *regs, struct k_sigaction *ka)
 {
@@ -457,10 +506,7 @@ syscall_restart(struct pt_regs *regs, struct k_sigaction *ka)
                }
                /* fallthrough */
        case -ERESTARTNOINTR:
-               /* A syscall is just a branch, so all
-                * we have to do is fiddle the return pointer.
-                */
-               regs->gr[31] -= 8; /* delayed branching */
+               check_syscallno_in_delay_branch(regs);
                break;
        }
 }
@@ -510,15 +556,9 @@ insert_restart_trampoline(struct pt_regs *regs)
        }
        case -ERESTARTNOHAND:
        case -ERESTARTSYS:
-       case -ERESTARTNOINTR: {
-               /* Hooray for delayed branching.  We don't
-                * have to restore %r20 (the system call
-                * number) because it gets loaded in the delay
-                * slot of the branch external instruction.
-                */
-               regs->gr[31] -= 8;
+       case -ERESTARTNOINTR:
+               check_syscallno_in_delay_branch(regs);
                return;
-       }
        default:
                break;
        }
index 78c3ef8c348d5cfdef2b50670a1da348ee49566e..d4ffcfbc98851e7c3f0707ec9d82470d918bed2e 100644 (file)
        ENTRY_COMP(execveat)
        ENTRY_SAME(membarrier)
        ENTRY_SAME(userfaultfd)
+       ENTRY_SAME(mlock2)              /* 345 */
 
 
 .ifne (. - 90b) - (__NR_Linux_syscalls * (91b - 90b))
index 631ede72e226c31c8d9f610bc583fc9f93802191..68f0ed7626bd96252f768c7dcca12e8e0294ef69 100644 (file)
                                reg = <0x520 0x20>;
 
                                phy0: ethernet-phy@1f {
-                                       interrupt-parent = <&mpic>;
-                                       interrupts = <10 1>;
                                        reg = <0x1f>;
                                };
                                phy1: ethernet-phy@0 {
-                                       interrupt-parent = <&mpic>;
-                                       interrupts = <10 1>;
                                        reg = <0>;
                                };
                                phy2: ethernet-phy@1 {
-                                       interrupt-parent = <&mpic>;
-                                       interrupts = <10 1>;
                                        reg = <1>;
                                };
                                phy3: ethernet-phy@2 {
-                                       interrupt-parent = <&mpic>;
-                                       interrupts = <10 1>;
                                        reg = <2>;
                                };
                                tbi0: tbi-phy@11 {
index f2b0b1b0c72acf49373310288fcb330d726740e7..5654ece02c0db5ee41da441c30d8a2c5f1cdcbc4 100644 (file)
@@ -370,16 +370,16 @@ COMPAT_SYS(execveat)
 PPC64ONLY(switch_endian)
 SYSCALL_SPU(userfaultfd)
 SYSCALL_SPU(membarrier)
-SYSCALL(semop)
-SYSCALL(semget)
-COMPAT_SYS(semctl)
-COMPAT_SYS(semtimedop)
-COMPAT_SYS(msgsnd)
-COMPAT_SYS(msgrcv)
-SYSCALL(msgget)
-COMPAT_SYS(msgctl)
-COMPAT_SYS(shmat)
-SYSCALL(shmdt)
-SYSCALL(shmget)
-COMPAT_SYS(shmctl)
+SYSCALL(ni_syscall)
+SYSCALL(ni_syscall)
+SYSCALL(ni_syscall)
+SYSCALL(ni_syscall)
+SYSCALL(ni_syscall)
+SYSCALL(ni_syscall)
+SYSCALL(ni_syscall)
+SYSCALL(ni_syscall)
+SYSCALL(ni_syscall)
+SYSCALL(ni_syscall)
+SYSCALL(ni_syscall)
+SYSCALL(ni_syscall)
 SYSCALL(mlock2)
index 1effea5193d6861cb0074a5c682965b4e4f6a13e..12a05652377a28799a89ae59e3d38a7ddeaade92 100644 (file)
 #define __NR_switch_endian     363
 #define __NR_userfaultfd       364
 #define __NR_membarrier                365
-#define __NR_semop             366
-#define __NR_semget            367
-#define __NR_semctl            368
-#define __NR_semtimedop                369
-#define __NR_msgsnd            370
-#define __NR_msgrcv            371
-#define __NR_msgget            372
-#define __NR_msgctl            373
-#define __NR_shmat             374
-#define __NR_shmdt             375
-#define __NR_shmget            376
-#define __NR_shmctl            377
 #define __NR_mlock2            378
 
 #endif /* _UAPI_ASM_POWERPC_UNISTD_H_ */
index 80dfe8965df9f7d49fc57a1f1d6773f0c5ffd736..8d14feb40f121129854a7760818e926f7b5b742c 100644 (file)
@@ -590,16 +590,10 @@ static int eeh_reset_device(struct eeh_pe *pe, struct pci_bus *bus)
        eeh_ops->configure_bridge(pe);
        eeh_pe_restore_bars(pe);
 
-       /*
-        * If it's PHB PE, the frozen state on all available PEs should have
-        * been cleared by the PHB reset. Otherwise, we unfreeze the PE and its
-        * child PEs because they might be in frozen state.
-        */
-       if (!(pe->type & EEH_PE_PHB)) {
-               rc = eeh_clear_pe_frozen_state(pe, false);
-               if (rc)
-                       return rc;
-       }
+       /* Clear frozen state */
+       rc = eeh_clear_pe_frozen_state(pe, false);
+       if (rc)
+               return rc;
 
        /* Give the system 5 seconds to finish running the user-space
         * hotplug shutdown scripts, e.g. ifdown for ethernet.  Yes,
index 54b45b73195f912688ec4afe8e9fb4c9c3d5723c..a7352b59e6f9b5c74f37556e6858c9ac9c5bb30b 100644 (file)
@@ -224,6 +224,12 @@ static void kvmppc_core_vcpu_put_hv(struct kvm_vcpu *vcpu)
 
 static void kvmppc_set_msr_hv(struct kvm_vcpu *vcpu, u64 msr)
 {
+       /*
+        * Check for illegal transactional state bit combination
+        * and if we find it, force the TS field to a safe state.
+        */
+       if ((msr & MSR_TS_MASK) == MSR_TS_MASK)
+               msr &= ~MSR_TS_MASK;
        vcpu->arch.shregs.msr = msr;
        kvmppc_end_cede(vcpu);
 }
index 04782164ee67d8a570bcb4b4ee166dc6809753de..2d66a8446198dfcf48849c61a561cf7527f79e56 100644 (file)
@@ -78,18 +78,9 @@ static void bpf_jit_build_prologue(struct bpf_prog *fp, u32 *image,
                PPC_LI(r_X, 0);
        }
 
-       switch (filter[0].code) {
-       case BPF_RET | BPF_K:
-       case BPF_LD | BPF_W | BPF_LEN:
-       case BPF_LD | BPF_W | BPF_ABS:
-       case BPF_LD | BPF_H | BPF_ABS:
-       case BPF_LD | BPF_B | BPF_ABS:
-               /* first instruction sets A register (or is RET 'constant') */
-               break;
-       default:
-               /* make sure we dont leak kernel information to user */
+       /* make sure we dont leak kernel information to user */
+       if (bpf_needs_clear_a(&filter[0]))
                PPC_LI(r_A, 0);
-       }
 }
 
 static void bpf_jit_build_epilogue(u32 *image, struct codegen_context *ctx)
index 6ccfb6c1c707b40e9fd6ba4cb202d70c1faf57cb..e505223b4ec5ed2d82bcb08b2e718a6b64601f18 100644 (file)
@@ -43,11 +43,34 @@ static unsigned int opal_irq_count;
 static unsigned int *opal_irqs;
 
 static void opal_handle_irq_work(struct irq_work *work);
-static __be64 last_outstanding_events;
+static u64 last_outstanding_events;
 static struct irq_work opal_event_irq_work = {
        .func = opal_handle_irq_work,
 };
 
+void opal_handle_events(uint64_t events)
+{
+       int virq, hwirq = 0;
+       u64 mask = opal_event_irqchip.mask;
+
+       if (!in_irq() && (events & mask)) {
+               last_outstanding_events = events;
+               irq_work_queue(&opal_event_irq_work);
+               return;
+       }
+
+       while (events & mask) {
+               hwirq = fls64(events) - 1;
+               if (BIT_ULL(hwirq) & mask) {
+                       virq = irq_find_mapping(opal_event_irqchip.domain,
+                                               hwirq);
+                       if (virq)
+                               generic_handle_irq(virq);
+               }
+               events &= ~BIT_ULL(hwirq);
+       }
+}
+
 static void opal_event_mask(struct irq_data *d)
 {
        clear_bit(d->hwirq, &opal_event_irqchip.mask);
@@ -55,9 +78,21 @@ static void opal_event_mask(struct irq_data *d)
 
 static void opal_event_unmask(struct irq_data *d)
 {
+       __be64 events;
+
        set_bit(d->hwirq, &opal_event_irqchip.mask);
 
-       opal_poll_events(&last_outstanding_events);
+       opal_poll_events(&events);
+       last_outstanding_events = be64_to_cpu(events);
+
+       /*
+        * We can't just handle the events now with opal_handle_events().
+        * If we did we would deadlock when opal_event_unmask() is called from
+        * handle_level_irq() with the irq descriptor lock held, because
+        * calling opal_handle_events() would call generic_handle_irq() and
+        * then handle_level_irq() which would try to take the descriptor lock
+        * again. Instead queue the events for later.
+        */
        if (last_outstanding_events & opal_event_irqchip.mask)
                /* Need to retrigger the interrupt */
                irq_work_queue(&opal_event_irq_work);
@@ -96,29 +131,6 @@ static int opal_event_map(struct irq_domain *d, unsigned int irq,
        return 0;
 }
 
-void opal_handle_events(uint64_t events)
-{
-       int virq, hwirq = 0;
-       u64 mask = opal_event_irqchip.mask;
-
-       if (!in_irq() && (events & mask)) {
-               last_outstanding_events = events;
-               irq_work_queue(&opal_event_irq_work);
-               return;
-       }
-
-       while (events & mask) {
-               hwirq = fls64(events) - 1;
-               if (BIT_ULL(hwirq) & mask) {
-                       virq = irq_find_mapping(opal_event_irqchip.domain,
-                                               hwirq);
-                       if (virq)
-                               generic_handle_irq(virq);
-               }
-               events &= ~BIT_ULL(hwirq);
-       }
-}
-
 static irqreturn_t opal_interrupt(int irq, void *data)
 {
        __be64 events;
@@ -131,7 +143,7 @@ static irqreturn_t opal_interrupt(int irq, void *data)
 
 static void opal_handle_irq_work(struct irq_work *work)
 {
-       opal_handle_events(be64_to_cpu(last_outstanding_events));
+       opal_handle_events(last_outstanding_events);
 }
 
 static int opal_event_match(struct irq_domain *h, struct device_node *node,
index 4296d55e88f30afa7cb91fd54d06e6b2a532d577..57cffb80bc36a85d975dc993235c02efda1d7be8 100644 (file)
@@ -278,7 +278,7 @@ static void opal_handle_message(void)
 
        /* Sanity check */
        if (type >= OPAL_MSG_TYPE_MAX) {
-               pr_warning("%s: Unknown message type: %u\n", __func__, type);
+               pr_warn_once("%s: Unknown message type: %u\n", __func__, type);
                return;
        }
        opal_message_do_notify(type, (void *)&msg);
index 8140d10c67850902d9f60c967000dff7bdcd26a7..6e72961608f0d42f800a4f57b15d08c8456a38ab 100644 (file)
@@ -1920,16 +1920,23 @@ static int print_insn(char *buffer, unsigned char *code, unsigned long addr)
                        }
                        if (separator)
                                ptr += sprintf(ptr, "%c", separator);
+                       /*
+                        * Use four '%' characters below because of the
+                        * following two conversions:
+                        *
+                        *  1) sprintf: %%%%r -> %%r
+                        *  2) printk : %%r   -> %r
+                        */
                        if (operand->flags & OPERAND_GPR)
-                               ptr += sprintf(ptr, "%%r%i", value);
+                               ptr += sprintf(ptr, "%%%%r%i", value);
                        else if (operand->flags & OPERAND_FPR)
-                               ptr += sprintf(ptr, "%%f%i", value);
+                               ptr += sprintf(ptr, "%%%%f%i", value);
                        else if (operand->flags & OPERAND_AR)
-                               ptr += sprintf(ptr, "%%a%i", value);
+                               ptr += sprintf(ptr, "%%%%a%i", value);
                        else if (operand->flags & OPERAND_CR)
-                               ptr += sprintf(ptr, "%%c%i", value);
+                               ptr += sprintf(ptr, "%%%%c%i", value);
                        else if (operand->flags & OPERAND_VR)
-                               ptr += sprintf(ptr, "%%v%i", value);
+                               ptr += sprintf(ptr, "%%%%v%i", value);
                        else if (operand->flags & OPERAND_PCREL)
                                ptr += sprintf(ptr, "%lx", (signed int) value
                                                                      + addr);
index e6820c86e8c7bc1c0daf34cd9a891c45b3a5775f..47ebd5b5ed55e018343e0c577eb2ca21e885bc17 100644 (file)
 #define __NR_fsetxattr         256
 #define __NR_getxattr          257
 #define __NR_lgetxattr         258
-#define __NR_fgetxattr         269
+#define __NR_fgetxattr         259
 #define __NR_listxattr         260
 #define __NR_llistxattr                261
 #define __NR_flistxattr                262
index 370ca1e71ffbc8dc2fb4cd9567b44f95cf61eee6..93310837c2dfaa27ce384a32d2e7cec3c75c15fa 100644 (file)
@@ -95,6 +95,7 @@
  * really available.  So we simply advertise only "crypto" support.
  */
 #define HWCAP_SPARC_CRYPTO     0x04000000 /* CRYPTO insns available */
+#define HWCAP_SPARC_ADI                0x08000000 /* ADI available */
 
 #define CORE_DUMP_USE_REGSET
 
index efe9479f837bb50d289106cd22128292dd19ef5f..1c26d440d288dfb8d28579fda55e2a76ccf4c139 100644 (file)
 #define __NR_bpf               349
 #define __NR_execveat          350
 #define __NR_membarrier                351
+#define __NR_userfaultfd       352
+#define __NR_bind              353
+#define __NR_listen            354
+#define __NR_setsockopt                355
+#define __NR_mlock2            356
 
-#define NR_syscalls            352
+#define NR_syscalls            357
 
 /* Bitmask values returned from kern_features system call.  */
 #define KERN_FEATURE_MIXED_MODE_STACK  0x00000001
index 3d61fcae7ee38beaabe1b6f66bbdd781c43f1353..f2d30cab5b3f388fa9b446cf5b12afda92fa0a9d 100644 (file)
@@ -946,6 +946,12 @@ ENTRY(__retl_one)
         mov    1, %o0
 ENDPROC(__retl_one)
 
+ENTRY(__retl_one_fp)
+       VISExitHalf
+       retl
+        mov    1, %o0
+ENDPROC(__retl_one_fp)
+
 ENTRY(__ret_one_asi)
        wr      %g0, ASI_AIUS, %asi
        ret
@@ -958,6 +964,13 @@ ENTRY(__retl_one_asi)
         mov    1, %o0
 ENDPROC(__retl_one_asi)
 
+ENTRY(__retl_one_asi_fp)
+       wr      %g0, ASI_AIUS, %asi
+       VISExitHalf
+       retl
+        mov    1, %o0
+ENDPROC(__retl_one_asi_fp)
+
 ENTRY(__retl_o1)
        retl
         mov    %o1, %o0
index 3091267c5cc3d30dba854f152ff8d9bbc06c65a2..6596f66ce1126fa487b7ce8eec19ef17dc4912e7 100644 (file)
@@ -1828,11 +1828,18 @@ static void perf_callchain_user_32(struct perf_callchain_entry *entry,
 void
 perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs)
 {
+       u64 saved_fault_address = current_thread_info()->fault_address;
+       u8 saved_fault_code = get_thread_fault_code();
+       mm_segment_t old_fs;
+
        perf_callchain_store(entry, regs->tpc);
 
        if (!current->mm)
                return;
 
+       old_fs = get_fs();
+       set_fs(USER_DS);
+
        flushw_user();
 
        pagefault_disable();
@@ -1843,4 +1850,8 @@ perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs)
                perf_callchain_user_64(entry, regs);
 
        pagefault_enable();
+
+       set_fs(old_fs);
+       set_thread_fault_code(saved_fault_code);
+       current_thread_info()->fault_address = saved_fault_address;
 }
index 39f0c662f4c81dcdf3050926a5a9525d352933a3..d08bdaffdbfccbafc9b3d67c30267fe397eb917f 100644 (file)
@@ -73,7 +73,13 @@ rtrap_nmi:   ldx                     [%sp + PTREGS_OFF + PT_V9_TSTATE], %l1
                andn                    %l1, %l4, %l1
                srl                     %l4, 20, %l4
                ba,pt                   %xcc, rtrap_no_irq_enable
-                wrpr                   %l4, %pil
+               nop
+               /* Do not actually set the %pil here.  We will do that
+                * below after we clear PSTATE_IE in the %pstate register.
+                * If we re-enable interrupts here, we can recurse down
+                * the hardirq stack potentially endlessly, causing a
+                * stack overflow.
+                */
 
                .align                  64
                .globl                  rtrap_irq, rtrap, irqsz_patchme, rtrap_xcall
index f7b261749383b4992300ba4418b1d16ef7251360..f3185e2b028b86886a2a185faee9d99fa5c5c47f 100644 (file)
@@ -380,7 +380,8 @@ static const char *hwcaps[] = {
         */
        "mul32", "div32", "fsmuld", "v8plus", "popc", "vis", "vis2",
        "ASIBlkInit", "fmaf", "vis3", "hpc", "random", "trans", "fjfmau",
-       "ima", "cspare", "pause", "cbcond",
+       "ima", "cspare", "pause", "cbcond", NULL /*reserved for crypto */,
+       "adp",
 };
 
 static const char *crypto_hwcaps[] = {
@@ -396,7 +397,7 @@ void cpucap_info(struct seq_file *m)
        seq_puts(m, "cpucaps\t\t: ");
        for (i = 0; i < ARRAY_SIZE(hwcaps); i++) {
                unsigned long bit = 1UL << i;
-               if (caps & bit) {
+               if (hwcaps[i] && (caps & bit)) {
                        seq_printf(m, "%s%s",
                                   printed ? "," : "", hwcaps[i]);
                        printed++;
@@ -450,7 +451,7 @@ static void __init report_hwcaps(unsigned long caps)
 
        for (i = 0; i < ARRAY_SIZE(hwcaps); i++) {
                unsigned long bit = 1UL << i;
-               if (caps & bit)
+               if (hwcaps[i] && (caps & bit))
                        report_one_hwcap(&printed, hwcaps[i]);
        }
        if (caps & HWCAP_SPARC_CRYPTO)
@@ -485,7 +486,7 @@ static unsigned long __init mdesc_cpu_hwcap_list(void)
                for (i = 0; i < ARRAY_SIZE(hwcaps); i++) {
                        unsigned long bit = 1UL << i;
 
-                       if (!strcmp(prop, hwcaps[i])) {
+                       if (hwcaps[i] && !strcmp(prop, hwcaps[i])) {
                                caps |= bit;
                                break;
                        }
index cc23b62b6e38a858c7e077c6b2c0757a63803b3d..e663b6c78de2e6498a5a458f1129504cae3ab2a8 100644 (file)
@@ -35,18 +35,18 @@ sys_call_table:
 /*80*/ .long sys_setgroups16, sys_getpgrp, sys_setgroups, sys_setitimer, sys_ftruncate64
 /*85*/ .long sys_swapon, sys_getitimer, sys_setuid, sys_sethostname, sys_setgid
 /*90*/ .long sys_dup2, sys_setfsuid, sys_fcntl, sys_select, sys_setfsgid
-/*95*/ .long sys_fsync, sys_setpriority, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall
+/*95*/ .long sys_fsync, sys_setpriority, sys_socket, sys_connect, sys_accept
 /*100*/        .long sys_getpriority, sys_rt_sigreturn, sys_rt_sigaction, sys_rt_sigprocmask, sys_rt_sigpending
 /*105*/        .long sys_rt_sigtimedwait, sys_rt_sigqueueinfo, sys_rt_sigsuspend, sys_setresuid, sys_getresuid
-/*110*/        .long sys_setresgid, sys_getresgid, sys_setregid, sys_nis_syscall, sys_nis_syscall
-/*115*/        .long sys_getgroups, sys_gettimeofday, sys_getrusage, sys_nis_syscall, sys_getcwd
+/*110*/        .long sys_setresgid, sys_getresgid, sys_setregid, sys_recvmsg, sys_sendmsg
+/*115*/        .long sys_getgroups, sys_gettimeofday, sys_getrusage, sys_getsockopt, sys_getcwd
 /*120*/        .long sys_readv, sys_writev, sys_settimeofday, sys_fchown16, sys_fchmod
-/*125*/        .long sys_nis_syscall, sys_setreuid16, sys_setregid16, sys_rename, sys_truncate
-/*130*/        .long sys_ftruncate, sys_flock, sys_lstat64, sys_nis_syscall, sys_nis_syscall
-/*135*/        .long sys_nis_syscall, sys_mkdir, sys_rmdir, sys_utimes, sys_stat64
-/*140*/        .long sys_sendfile64, sys_nis_syscall, sys_futex, sys_gettid, sys_getrlimit
+/*125*/        .long sys_recvfrom, sys_setreuid16, sys_setregid16, sys_rename, sys_truncate
+/*130*/        .long sys_ftruncate, sys_flock, sys_lstat64, sys_sendto, sys_shutdown
+/*135*/        .long sys_socketpair, sys_mkdir, sys_rmdir, sys_utimes, sys_stat64
+/*140*/        .long sys_sendfile64, sys_getpeername, sys_futex, sys_gettid, sys_getrlimit
 /*145*/        .long sys_setrlimit, sys_pivot_root, sys_prctl, sys_pciconfig_read, sys_pciconfig_write
-/*150*/        .long sys_nis_syscall, sys_inotify_init, sys_inotify_add_watch, sys_poll, sys_getdents64
+/*150*/        .long sys_getsockname, sys_inotify_init, sys_inotify_add_watch, sys_poll, sys_getdents64
 /*155*/        .long sys_fcntl64, sys_inotify_rm_watch, sys_statfs, sys_fstatfs, sys_oldumount
 /*160*/        .long sys_sched_setaffinity, sys_sched_getaffinity, sys_getdomainname, sys_setdomainname, sys_nis_syscall
 /*165*/        .long sys_quotactl, sys_set_tid_address, sys_mount, sys_ustat, sys_setxattr
@@ -87,4 +87,5 @@ sys_call_table:
 /*335*/        .long sys_syncfs, sys_sendmmsg, sys_setns, sys_process_vm_readv, sys_process_vm_writev
 /*340*/        .long sys_ni_syscall, sys_kcmp, sys_finit_module, sys_sched_setattr, sys_sched_getattr
 /*345*/        .long sys_renameat2, sys_seccomp, sys_getrandom, sys_memfd_create, sys_bpf
-/*350*/        .long sys_execveat, sys_membarrier
+/*350*/        .long sys_execveat, sys_membarrier, sys_userfaultfd, sys_bind, sys_listen
+/*355*/        .long sys_setsockopt, sys_mlock2
index f229468a747975ea7eb0dac89886747efb52f773..1557121f4cdce8a6ae21c31fb33e9aa2d7cbc443 100644 (file)
@@ -37,15 +37,15 @@ sys_call_table32:
 /*80*/ .word sys_setgroups16, sys_getpgrp, sys_setgroups, compat_sys_setitimer, sys32_ftruncate64
        .word sys_swapon, compat_sys_getitimer, sys_setuid, sys_sethostname, sys_setgid
 /*90*/ .word sys_dup2, sys_setfsuid, compat_sys_fcntl, sys32_select, sys_setfsgid
-       .word sys_fsync, sys_setpriority, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall
+       .word sys_fsync, sys_setpriority, sys_socket, sys_connect, sys_accept
 /*100*/ .word sys_getpriority, sys32_rt_sigreturn, compat_sys_rt_sigaction, compat_sys_rt_sigprocmask, compat_sys_rt_sigpending
        .word compat_sys_rt_sigtimedwait, compat_sys_rt_sigqueueinfo, compat_sys_rt_sigsuspend, sys_setresuid, sys_getresuid
-/*110*/        .word sys_setresgid, sys_getresgid, sys_setregid, sys_nis_syscall, sys_nis_syscall
-       .word sys_getgroups, compat_sys_gettimeofday, compat_sys_getrusage, sys_nis_syscall, sys_getcwd
+/*110*/        .word sys_setresgid, sys_getresgid, sys_setregid, compat_sys_recvmsg, compat_sys_sendmsg
+       .word sys_getgroups, compat_sys_gettimeofday, compat_sys_getrusage, compat_sys_getsockopt, sys_getcwd
 /*120*/        .word compat_sys_readv, compat_sys_writev, compat_sys_settimeofday, sys_fchown16, sys_fchmod
-       .word sys_nis_syscall, sys_setreuid16, sys_setregid16, sys_rename, compat_sys_truncate
-/*130*/        .word compat_sys_ftruncate, sys_flock, compat_sys_lstat64, sys_nis_syscall, sys_nis_syscall
-       .word sys_nis_syscall, sys_mkdir, sys_rmdir, compat_sys_utimes, compat_sys_stat64
+       .word sys_recvfrom, sys_setreuid16, sys_setregid16, sys_rename, compat_sys_truncate
+/*130*/        .word compat_sys_ftruncate, sys_flock, compat_sys_lstat64, sys_sendto, sys_shutdown
+       .word sys_socketpair, sys_mkdir, sys_rmdir, compat_sys_utimes, compat_sys_stat64
 /*140*/        .word sys_sendfile64, sys_nis_syscall, sys32_futex, sys_gettid, compat_sys_getrlimit
        .word compat_sys_setrlimit, sys_pivot_root, sys_prctl, sys_pciconfig_read, sys_pciconfig_write
 /*150*/        .word sys_nis_syscall, sys_inotify_init, sys_inotify_add_watch, sys_poll, sys_getdents64
@@ -88,7 +88,8 @@ sys_call_table32:
        .word sys_syncfs, compat_sys_sendmmsg, sys_setns, compat_sys_process_vm_readv, compat_sys_process_vm_writev
 /*340*/        .word sys_kern_features, sys_kcmp, sys_finit_module, sys_sched_setattr, sys_sched_getattr
        .word sys32_renameat2, sys_seccomp, sys_getrandom, sys_memfd_create, sys_bpf
-/*350*/        .word sys32_execveat, sys_membarrier
+/*350*/        .word sys32_execveat, sys_membarrier, sys_userfaultfd, sys_bind, sys_listen
+       .word compat_sys_setsockopt, sys_mlock2
 
 #endif /* CONFIG_COMPAT */
 
@@ -168,4 +169,5 @@ sys_call_table:
        .word sys_syncfs, sys_sendmmsg, sys_setns, sys_process_vm_readv, sys_process_vm_writev
 /*340*/        .word sys_kern_features, sys_kcmp, sys_finit_module, sys_sched_setattr, sys_sched_getattr
        .word sys_renameat2, sys_seccomp, sys_getrandom, sys_memfd_create, sys_bpf
-/*350*/        .word sys64_execveat, sys_membarrier
+/*350*/        .word sys64_execveat, sys_membarrier, sys_userfaultfd, sys_bind, sys_listen
+       .word sys_setsockopt, sys_mlock2
index 119ccb9a54f49e2ac2724650060eb7a1d70e8d9e..d5242b8c4f9495fe4241ee39de01255364e877af 100644 (file)
        .text;                  \
        .align 4;
 
+#define EX_LD_FP(x)            \
+98:    x;                      \
+       .section __ex_table,"a";\
+       .align 4;               \
+       .word 98b, __retl_one_asi_fp;\
+       .text;                  \
+       .align 4;
+
 #ifndef ASI_AIUS
 #define ASI_AIUS       0x11
 #endif
index 7fe1ccefd9d056a104407c8d1595095c7fc5add8..4e962d993b10cdff7677f8d51e61ad877901facc 100644 (file)
        .text;                  \
        .align 4;
 
+#define EX_ST_FP(x)            \
+98:    x;                      \
+       .section __ex_table,"a";\
+       .align 4;               \
+       .word 98b, __retl_one_asi_fp;\
+       .text;                  \
+       .align 4;
+
 #ifndef ASI_AIUS
 #define ASI_AIUS       0x11
 #endif
index 30eee6e8a81b2d45797aab304914b10571573b1a..d5f585df2f3fc345c87f04fb1a420fa766816cb5 100644 (file)
 #ifndef EX_LD
 #define EX_LD(x)       x
 #endif
+#ifndef EX_LD_FP
+#define EX_LD_FP(x)    x
+#endif
 
 #ifndef EX_ST
 #define EX_ST(x)       x
 #endif
+#ifndef EX_ST_FP
+#define EX_ST_FP(x)    x
+#endif
 
 #ifndef EX_RETVAL
 #define EX_RETVAL(x)   x
        fsrc2           %x6, %f12; \
        fsrc2           %x7, %f14;
 #define FREG_LOAD_1(base, x0) \
-       EX_LD(LOAD(ldd, base + 0x00, %x0))
+       EX_LD_FP(LOAD(ldd, base + 0x00, %x0))
 #define FREG_LOAD_2(base, x0, x1) \
-       EX_LD(LOAD(ldd, base + 0x00, %x0)); \
-       EX_LD(LOAD(ldd, base + 0x08, %x1));
+       EX_LD_FP(LOAD(ldd, base + 0x00, %x0)); \
+       EX_LD_FP(LOAD(ldd, base + 0x08, %x1));
 #define FREG_LOAD_3(base, x0, x1, x2) \
-       EX_LD(LOAD(ldd, base + 0x00, %x0)); \
-       EX_LD(LOAD(ldd, base + 0x08, %x1)); \
-       EX_LD(LOAD(ldd, base + 0x10, %x2));
+       EX_LD_FP(LOAD(ldd, base + 0x00, %x0)); \
+       EX_LD_FP(LOAD(ldd, base + 0x08, %x1)); \
+       EX_LD_FP(LOAD(ldd, base + 0x10, %x2));
 #define FREG_LOAD_4(base, x0, x1, x2, x3) \
-       EX_LD(LOAD(ldd, base + 0x00, %x0)); \
-       EX_LD(LOAD(ldd, base + 0x08, %x1)); \
-       EX_LD(LOAD(ldd, base + 0x10, %x2)); \
-       EX_LD(LOAD(ldd, base + 0x18, %x3));
+       EX_LD_FP(LOAD(ldd, base + 0x00, %x0)); \
+       EX_LD_FP(LOAD(ldd, base + 0x08, %x1)); \
+       EX_LD_FP(LOAD(ldd, base + 0x10, %x2)); \
+       EX_LD_FP(LOAD(ldd, base + 0x18, %x3));
 #define FREG_LOAD_5(base, x0, x1, x2, x3, x4) \
-       EX_LD(LOAD(ldd, base + 0x00, %x0)); \
-       EX_LD(LOAD(ldd, base + 0x08, %x1)); \
-       EX_LD(LOAD(ldd, base + 0x10, %x2)); \
-       EX_LD(LOAD(ldd, base + 0x18, %x3)); \
-       EX_LD(LOAD(ldd, base + 0x20, %x4));
+       EX_LD_FP(LOAD(ldd, base + 0x00, %x0)); \
+       EX_LD_FP(LOAD(ldd, base + 0x08, %x1)); \
+       EX_LD_FP(LOAD(ldd, base + 0x10, %x2)); \
+       EX_LD_FP(LOAD(ldd, base + 0x18, %x3)); \
+       EX_LD_FP(LOAD(ldd, base + 0x20, %x4));
 #define FREG_LOAD_6(base, x0, x1, x2, x3, x4, x5) \
-       EX_LD(LOAD(ldd, base + 0x00, %x0)); \
-       EX_LD(LOAD(ldd, base + 0x08, %x1)); \
-       EX_LD(LOAD(ldd, base + 0x10, %x2)); \
-       EX_LD(LOAD(ldd, base + 0x18, %x3)); \
-       EX_LD(LOAD(ldd, base + 0x20, %x4)); \
-       EX_LD(LOAD(ldd, base + 0x28, %x5));
+       EX_LD_FP(LOAD(ldd, base + 0x00, %x0)); \
+       EX_LD_FP(LOAD(ldd, base + 0x08, %x1)); \
+       EX_LD_FP(LOAD(ldd, base + 0x10, %x2)); \
+       EX_LD_FP(LOAD(ldd, base + 0x18, %x3)); \
+       EX_LD_FP(LOAD(ldd, base + 0x20, %x4)); \
+       EX_LD_FP(LOAD(ldd, base + 0x28, %x5));
 #define FREG_LOAD_7(base, x0, x1, x2, x3, x4, x5, x6) \
-       EX_LD(LOAD(ldd, base + 0x00, %x0)); \
-       EX_LD(LOAD(ldd, base + 0x08, %x1)); \
-       EX_LD(LOAD(ldd, base + 0x10, %x2)); \
-       EX_LD(LOAD(ldd, base + 0x18, %x3)); \
-       EX_LD(LOAD(ldd, base + 0x20, %x4)); \
-       EX_LD(LOAD(ldd, base + 0x28, %x5)); \
-       EX_LD(LOAD(ldd, base + 0x30, %x6));
+       EX_LD_FP(LOAD(ldd, base + 0x00, %x0)); \
+       EX_LD_FP(LOAD(ldd, base + 0x08, %x1)); \
+       EX_LD_FP(LOAD(ldd, base + 0x10, %x2)); \
+       EX_LD_FP(LOAD(ldd, base + 0x18, %x3)); \
+       EX_LD_FP(LOAD(ldd, base + 0x20, %x4)); \
+       EX_LD_FP(LOAD(ldd, base + 0x28, %x5)); \
+       EX_LD_FP(LOAD(ldd, base + 0x30, %x6));
 
        .register       %g2,#scratch
        .register       %g3,#scratch
@@ -275,11 +281,11 @@ FUNC_NAME:        /* %o0=dst, %o1=src, %o2=len */
         nop
        /* fall through for 0 < low bits < 8 */
 110:   sub             %o4, 64, %g2
-       EX_LD(LOAD_BLK(%g2, %f0))
-1:     EX_ST(STORE_INIT(%g0, %o4 + %g3))
-       EX_LD(LOAD_BLK(%o4, %f16))
+       EX_LD_FP(LOAD_BLK(%g2, %f0))
+1:     EX_ST_FP(STORE_INIT(%g0, %o4 + %g3))
+       EX_LD_FP(LOAD_BLK(%o4, %f16))
        FREG_FROB(f0, f2, f4, f6, f8, f10, f12, f14, f16)
-       EX_ST(STORE_BLK(%f0, %o4 + %g3))
+       EX_ST_FP(STORE_BLK(%f0, %o4 + %g3))
        FREG_MOVE_8(f16, f18, f20, f22, f24, f26, f28, f30)
        subcc           %g1, 64, %g1
        add             %o4, 64, %o4
@@ -290,10 +296,10 @@ FUNC_NAME:        /* %o0=dst, %o1=src, %o2=len */
 
 120:   sub             %o4, 56, %g2
        FREG_LOAD_7(%g2, f0, f2, f4, f6, f8, f10, f12)
-1:     EX_ST(STORE_INIT(%g0, %o4 + %g3))
-       EX_LD(LOAD_BLK(%o4, %f16))
+1:     EX_ST_FP(STORE_INIT(%g0, %o4 + %g3))
+       EX_LD_FP(LOAD_BLK(%o4, %f16))
        FREG_FROB(f0, f2, f4, f6, f8, f10, f12, f16, f18)
-       EX_ST(STORE_BLK(%f0, %o4 + %g3))
+       EX_ST_FP(STORE_BLK(%f0, %o4 + %g3))
        FREG_MOVE_7(f18, f20, f22, f24, f26, f28, f30)
        subcc           %g1, 64, %g1
        add             %o4, 64, %o4
@@ -304,10 +310,10 @@ FUNC_NAME:        /* %o0=dst, %o1=src, %o2=len */
 
 130:   sub             %o4, 48, %g2
        FREG_LOAD_6(%g2, f0, f2, f4, f6, f8, f10)
-1:     EX_ST(STORE_INIT(%g0, %o4 + %g3))
-       EX_LD(LOAD_BLK(%o4, %f16))
+1:     EX_ST_FP(STORE_INIT(%g0, %o4 + %g3))
+       EX_LD_FP(LOAD_BLK(%o4, %f16))
        FREG_FROB(f0, f2, f4, f6, f8, f10, f16, f18, f20)
-       EX_ST(STORE_BLK(%f0, %o4 + %g3))
+       EX_ST_FP(STORE_BLK(%f0, %o4 + %g3))
        FREG_MOVE_6(f20, f22, f24, f26, f28, f30)
        subcc           %g1, 64, %g1
        add             %o4, 64, %o4
@@ -318,10 +324,10 @@ FUNC_NAME:        /* %o0=dst, %o1=src, %o2=len */
 
 140:   sub             %o4, 40, %g2
        FREG_LOAD_5(%g2, f0, f2, f4, f6, f8)
-1:     EX_ST(STORE_INIT(%g0, %o4 + %g3))
-       EX_LD(LOAD_BLK(%o4, %f16))
+1:     EX_ST_FP(STORE_INIT(%g0, %o4 + %g3))
+       EX_LD_FP(LOAD_BLK(%o4, %f16))
        FREG_FROB(f0, f2, f4, f6, f8, f16, f18, f20, f22)
-       EX_ST(STORE_BLK(%f0, %o4 + %g3))
+       EX_ST_FP(STORE_BLK(%f0, %o4 + %g3))
        FREG_MOVE_5(f22, f24, f26, f28, f30)
        subcc           %g1, 64, %g1
        add             %o4, 64, %o4
@@ -332,10 +338,10 @@ FUNC_NAME:        /* %o0=dst, %o1=src, %o2=len */
 
 150:   sub             %o4, 32, %g2
        FREG_LOAD_4(%g2, f0, f2, f4, f6)
-1:     EX_ST(STORE_INIT(%g0, %o4 + %g3))
-       EX_LD(LOAD_BLK(%o4, %f16))
+1:     EX_ST_FP(STORE_INIT(%g0, %o4 + %g3))
+       EX_LD_FP(LOAD_BLK(%o4, %f16))
        FREG_FROB(f0, f2, f4, f6, f16, f18, f20, f22, f24)
-       EX_ST(STORE_BLK(%f0, %o4 + %g3))
+       EX_ST_FP(STORE_BLK(%f0, %o4 + %g3))
        FREG_MOVE_4(f24, f26, f28, f30)
        subcc           %g1, 64, %g1
        add             %o4, 64, %o4
@@ -346,10 +352,10 @@ FUNC_NAME:        /* %o0=dst, %o1=src, %o2=len */
 
 160:   sub             %o4, 24, %g2
        FREG_LOAD_3(%g2, f0, f2, f4)
-1:     EX_ST(STORE_INIT(%g0, %o4 + %g3))
-       EX_LD(LOAD_BLK(%o4, %f16))
+1:     EX_ST_FP(STORE_INIT(%g0, %o4 + %g3))
+       EX_LD_FP(LOAD_BLK(%o4, %f16))
        FREG_FROB(f0, f2, f4, f16, f18, f20, f22, f24, f26)
-       EX_ST(STORE_BLK(%f0, %o4 + %g3))
+       EX_ST_FP(STORE_BLK(%f0, %o4 + %g3))
        FREG_MOVE_3(f26, f28, f30)
        subcc           %g1, 64, %g1
        add             %o4, 64, %o4
@@ -360,10 +366,10 @@ FUNC_NAME:        /* %o0=dst, %o1=src, %o2=len */
 
 170:   sub             %o4, 16, %g2
        FREG_LOAD_2(%g2, f0, f2)
-1:     EX_ST(STORE_INIT(%g0, %o4 + %g3))
-       EX_LD(LOAD_BLK(%o4, %f16))
+1:     EX_ST_FP(STORE_INIT(%g0, %o4 + %g3))
+       EX_LD_FP(LOAD_BLK(%o4, %f16))
        FREG_FROB(f0, f2, f16, f18, f20, f22, f24, f26, f28)
-       EX_ST(STORE_BLK(%f0, %o4 + %g3))
+       EX_ST_FP(STORE_BLK(%f0, %o4 + %g3))
        FREG_MOVE_2(f28, f30)
        subcc           %g1, 64, %g1
        add             %o4, 64, %o4
@@ -374,10 +380,10 @@ FUNC_NAME:        /* %o0=dst, %o1=src, %o2=len */
 
 180:   sub             %o4, 8, %g2
        FREG_LOAD_1(%g2, f0)
-1:     EX_ST(STORE_INIT(%g0, %o4 + %g3))
-       EX_LD(LOAD_BLK(%o4, %f16))
+1:     EX_ST_FP(STORE_INIT(%g0, %o4 + %g3))
+       EX_LD_FP(LOAD_BLK(%o4, %f16))
        FREG_FROB(f0, f16, f18, f20, f22, f24, f26, f28, f30)
-       EX_ST(STORE_BLK(%f0, %o4 + %g3))
+       EX_ST_FP(STORE_BLK(%f0, %o4 + %g3))
        FREG_MOVE_1(f30)
        subcc           %g1, 64, %g1
        add             %o4, 64, %o4
@@ -387,10 +393,10 @@ FUNC_NAME:        /* %o0=dst, %o1=src, %o2=len */
         nop
 
 190:
-1:     EX_ST(STORE_INIT(%g0, %o4 + %g3))
+1:     EX_ST_FP(STORE_INIT(%g0, %o4 + %g3))
        subcc           %g1, 64, %g1
-       EX_LD(LOAD_BLK(%o4, %f0))
-       EX_ST(STORE_BLK(%f0, %o4 + %g3))
+       EX_LD_FP(LOAD_BLK(%o4, %f0))
+       EX_ST_FP(STORE_BLK(%f0, %o4 + %g3))
        add             %o4, 64, %o4
        bne,pt          %xcc, 1b
         LOAD(prefetch, %o4 + 64, #one_read)
index fd9f903ffa3269713dcec781a0ed93a77ae70c1b..2e8ee7ad07a9ce06129cd63c4129ccade674ab77 100644 (file)
        .text;                  \
        .align 4;
 
+#define EX_LD_FP(x)            \
+98:    x;                      \
+       .section __ex_table,"a";\
+       .align 4;               \
+       .word 98b, __retl_one_asi_fp;\
+       .text;                  \
+       .align 4;
+
 #ifndef ASI_AIUS
 #define ASI_AIUS       0x11
 #endif
index 9744c4540a8d99f6010a859aa1ef1510f7b70827..be0bf4590df8971ddf29a81153f05de7c0ef30da 100644 (file)
        .text;                  \
        .align 4;
 
+#define EX_ST_FP(x)            \
+98:    x;                      \
+       .section __ex_table,"a";\
+       .align 4;               \
+       .word 98b, __retl_one_asi_fp;\
+       .text;                  \
+       .align 4;
+
 #ifndef ASI_AIUS
 #define ASI_AIUS       0x11
 #endif
index 83aeeb1dffdb3b4c29293d5924cd5259e2269ce5..8e13ee1f4454ea2b6478d302a9a1048bfeb60aff 100644 (file)
 #ifndef EX_LD
 #define EX_LD(x)       x
 #endif
+#ifndef EX_LD_FP
+#define EX_LD_FP(x)    x
+#endif
 
 #ifndef EX_ST
 #define EX_ST(x)       x
 #endif
+#ifndef EX_ST_FP
+#define EX_ST_FP(x)    x
+#endif
 
 #ifndef EX_RETVAL
 #define EX_RETVAL(x)   x
@@ -210,17 +216,17 @@ FUNC_NAME:        /* %o0=dst, %o1=src, %o2=len */
        sub             %o2, %o4, %o2
        alignaddr       %o1, %g0, %g1
        add             %o1, %o4, %o1
-       EX_LD(LOAD(ldd, %g1 + 0x00, %f0))
-1:     EX_LD(LOAD(ldd, %g1 + 0x08, %f2))
+       EX_LD_FP(LOAD(ldd, %g1 + 0x00, %f0))
+1:     EX_LD_FP(LOAD(ldd, %g1 + 0x08, %f2))
        subcc           %o4, 0x40, %o4
-       EX_LD(LOAD(ldd, %g1 + 0x10, %f4))
-       EX_LD(LOAD(ldd, %g1 + 0x18, %f6))
-       EX_LD(LOAD(ldd, %g1 + 0x20, %f8))
-       EX_LD(LOAD(ldd, %g1 + 0x28, %f10))
-       EX_LD(LOAD(ldd, %g1 + 0x30, %f12))
-       EX_LD(LOAD(ldd, %g1 + 0x38, %f14))
+       EX_LD_FP(LOAD(ldd, %g1 + 0x10, %f4))
+       EX_LD_FP(LOAD(ldd, %g1 + 0x18, %f6))
+       EX_LD_FP(LOAD(ldd, %g1 + 0x20, %f8))
+       EX_LD_FP(LOAD(ldd, %g1 + 0x28, %f10))
+       EX_LD_FP(LOAD(ldd, %g1 + 0x30, %f12))
+       EX_LD_FP(LOAD(ldd, %g1 + 0x38, %f14))
        faligndata      %f0, %f2, %f16
-       EX_LD(LOAD(ldd, %g1 + 0x40, %f0))
+       EX_LD_FP(LOAD(ldd, %g1 + 0x40, %f0))
        faligndata      %f2, %f4, %f18
        add             %g1, 0x40, %g1
        faligndata      %f4, %f6, %f20
@@ -229,14 +235,14 @@ FUNC_NAME:        /* %o0=dst, %o1=src, %o2=len */
        faligndata      %f10, %f12, %f26
        faligndata      %f12, %f14, %f28
        faligndata      %f14, %f0, %f30
-       EX_ST(STORE(std, %f16, %o0 + 0x00))
-       EX_ST(STORE(std, %f18, %o0 + 0x08))
-       EX_ST(STORE(std, %f20, %o0 + 0x10))
-       EX_ST(STORE(std, %f22, %o0 + 0x18))
-       EX_ST(STORE(std, %f24, %o0 + 0x20))
-       EX_ST(STORE(std, %f26, %o0 + 0x28))
-       EX_ST(STORE(std, %f28, %o0 + 0x30))
-       EX_ST(STORE(std, %f30, %o0 + 0x38))
+       EX_ST_FP(STORE(std, %f16, %o0 + 0x00))
+       EX_ST_FP(STORE(std, %f18, %o0 + 0x08))
+       EX_ST_FP(STORE(std, %f20, %o0 + 0x10))
+       EX_ST_FP(STORE(std, %f22, %o0 + 0x18))
+       EX_ST_FP(STORE(std, %f24, %o0 + 0x20))
+       EX_ST_FP(STORE(std, %f26, %o0 + 0x28))
+       EX_ST_FP(STORE(std, %f28, %o0 + 0x30))
+       EX_ST_FP(STORE(std, %f30, %o0 + 0x38))
        add             %o0, 0x40, %o0
        bne,pt          %icc, 1b
         LOAD(prefetch, %g1 + 0x200, #n_reads_strong)
index a6ae2ea04bf5dfbffda2884a6a46b051ae2ac2a8..ecc5692fa2b49a3acfc6a6592c6c247835417b4c 100644 (file)
        .text;                  \
        .align 4;
 
+#define EX_LD_FP(x)            \
+98:    x;                      \
+       .section __ex_table,"a";\
+       .align 4;               \
+       .word 98b, __retl_one_fp;\
+       .text;                  \
+       .align 4;
+
 #define FUNC_NAME              ___copy_from_user
 #define LOAD(type,addr,dest)   type##a [addr] %asi, dest
 #define LOAD_BLK(addr,dest)    ldda [addr] ASI_BLK_AIUS, dest
index f4b970eeb485f838ce23dc5507a5bccd6defd348..9eea392e44d471679ba85c22867a9767b34912a5 100644 (file)
        .text;                  \
        .align 4;
 
+#define EX_ST_FP(x)            \
+98:    x;                      \
+       .section __ex_table,"a";\
+       .align 4;               \
+       .word 98b, __retl_one_fp;\
+       .text;                  \
+       .align 4;
+
 #define FUNC_NAME              ___copy_to_user
 #define STORE(type,src,addr)   type##a src, [addr] ASI_AIUS
 #define STORE_BLK(src,addr)    stda src, [addr] ASI_BLK_AIUS
index b67142b7768e50e20fb28d5c4ed562435ab145f5..3e6209ebb7d7865fd62bb21df56dabda07fe4f5f 100644 (file)
 #ifndef EX_LD
 #define EX_LD(x)       x
 #endif
+#ifndef EX_LD_FP
+#define EX_LD_FP(x)    x
+#endif
 
 #ifndef EX_ST
 #define EX_ST(x)       x
 #endif
+#ifndef EX_ST_FP
+#define EX_ST_FP(x)    x
+#endif
 
 #ifndef EX_RETVAL
 #define EX_RETVAL(x)   x
@@ -73,8 +79,8 @@
        faligndata              %f8, %f9, %f62;
 
 #define MAIN_LOOP_CHUNK(src, dest, fdest, fsrc, len, jmptgt)   \
-       EX_LD(LOAD_BLK(%src, %fdest));                          \
-       EX_ST(STORE_BLK(%fsrc, %dest));                         \
+       EX_LD_FP(LOAD_BLK(%src, %fdest));                               \
+       EX_ST_FP(STORE_BLK(%fsrc, %dest));                              \
        add                     %src, 0x40, %src;               \
        subcc                   %len, 0x40, %len;               \
        be,pn                   %xcc, jmptgt;                   \
 
 #define DO_SYNC                        membar  #Sync;
 #define STORE_SYNC(dest, fsrc)                         \
-       EX_ST(STORE_BLK(%fsrc, %dest));                 \
+       EX_ST_FP(STORE_BLK(%fsrc, %dest));                      \
        add                     %dest, 0x40, %dest;     \
        DO_SYNC
 
 #define STORE_JUMP(dest, fsrc, target)                 \
-       EX_ST(STORE_BLK(%fsrc, %dest));                 \
+       EX_ST_FP(STORE_BLK(%fsrc, %dest));                      \
        add                     %dest, 0x40, %dest;     \
        ba,pt                   %xcc, target;           \
         nop;
        subcc                   %left, 8, %left;\
        bl,pn                   %xcc, 95f;      \
         faligndata             %f0, %f1, %f48; \
-       EX_ST(STORE(std, %f48, %dest));         \
+       EX_ST_FP(STORE(std, %f48, %dest));              \
        add                     %dest, 8, %dest;
 
 #define UNEVEN_VISCHUNK_LAST(dest, f0, f1, left)       \
@@ -160,8 +166,8 @@ FUNC_NAME:          /* %o0=dst, %o1=src, %o2=len */
         and            %g2, 0x38, %g2
 
 1:     subcc           %g1, 0x1, %g1
-       EX_LD(LOAD(ldub, %o1 + 0x00, %o3))
-       EX_ST(STORE(stb, %o3, %o1 + %GLOBAL_SPARE))
+       EX_LD_FP(LOAD(ldub, %o1 + 0x00, %o3))
+       EX_ST_FP(STORE(stb, %o3, %o1 + %GLOBAL_SPARE))
        bgu,pt          %XCC, 1b
         add            %o1, 0x1, %o1
 
@@ -172,20 +178,20 @@ FUNC_NAME:                /* %o0=dst, %o1=src, %o2=len */
        be,pt           %icc, 3f
         alignaddr      %o1, %g0, %o1
 
-       EX_LD(LOAD(ldd, %o1, %f4))
-1:     EX_LD(LOAD(ldd, %o1 + 0x8, %f6))
+       EX_LD_FP(LOAD(ldd, %o1, %f4))
+1:     EX_LD_FP(LOAD(ldd, %o1 + 0x8, %f6))
        add             %o1, 0x8, %o1
        subcc           %g2, 0x8, %g2
        faligndata      %f4, %f6, %f0
-       EX_ST(STORE(std, %f0, %o0))
+       EX_ST_FP(STORE(std, %f0, %o0))
        be,pn           %icc, 3f
         add            %o0, 0x8, %o0
 
-       EX_LD(LOAD(ldd, %o1 + 0x8, %f4))
+       EX_LD_FP(LOAD(ldd, %o1 + 0x8, %f4))
        add             %o1, 0x8, %o1
        subcc           %g2, 0x8, %g2
        faligndata      %f6, %f4, %f0
-       EX_ST(STORE(std, %f0, %o0))
+       EX_ST_FP(STORE(std, %f0, %o0))
        bne,pt          %icc, 1b
         add            %o0, 0x8, %o0
 
@@ -208,13 +214,13 @@ FUNC_NAME:                /* %o0=dst, %o1=src, %o2=len */
        add             %g1, %GLOBAL_SPARE, %g1
        subcc           %o2, %g3, %o2
 
-       EX_LD(LOAD_BLK(%o1, %f0))
+       EX_LD_FP(LOAD_BLK(%o1, %f0))
        add             %o1, 0x40, %o1
        add             %g1, %g3, %g1
-       EX_LD(LOAD_BLK(%o1, %f16))
+       EX_LD_FP(LOAD_BLK(%o1, %f16))
        add             %o1, 0x40, %o1
        sub             %GLOBAL_SPARE, 0x80, %GLOBAL_SPARE
-       EX_LD(LOAD_BLK(%o1, %f32))
+       EX_LD_FP(LOAD_BLK(%o1, %f32))
        add             %o1, 0x40, %o1
 
        /* There are 8 instances of the unrolled loop,
@@ -426,28 +432,28 @@ FUNC_NAME:                /* %o0=dst, %o1=src, %o2=len */
 62:    FINISH_VISCHUNK(o0, f44, f46, g3)
 63:    UNEVEN_VISCHUNK_LAST(o0, f46, f0,  g3)
 
-93:    EX_LD(LOAD(ldd, %o1, %f2))
+93:    EX_LD_FP(LOAD(ldd, %o1, %f2))
        add             %o1, 8, %o1
        subcc           %g3, 8, %g3
        faligndata      %f0, %f2, %f8
-       EX_ST(STORE(std, %f8, %o0))
+       EX_ST_FP(STORE(std, %f8, %o0))
        bl,pn           %xcc, 95f
         add            %o0, 8, %o0
-       EX_LD(LOAD(ldd, %o1, %f0))
+       EX_LD_FP(LOAD(ldd, %o1, %f0))
        add             %o1, 8, %o1
        subcc           %g3, 8, %g3
        faligndata      %f2, %f0, %f8
-       EX_ST(STORE(std, %f8, %o0))
+       EX_ST_FP(STORE(std, %f8, %o0))
        bge,pt          %xcc, 93b
         add            %o0, 8, %o0
 
 95:    brz,pt          %o2, 2f
         mov            %g1, %o1
 
-1:     EX_LD(LOAD(ldub, %o1, %o3))
+1:     EX_LD_FP(LOAD(ldub, %o1, %o3))
        add             %o1, 1, %o1
        subcc           %o2, 1, %o2
-       EX_ST(STORE(stb, %o3, %o0))
+       EX_ST_FP(STORE(stb, %o3, %o0))
        bne,pt          %xcc, 1b
         add            %o0, 1, %o0
 
index b1acd1331c338fce1a70e6a13f597509b28501a7..88ad73d86fe44b64c2313483e7490cc8ae0ee438 100644 (file)
        .text;                  \
        .align 4;
 
+#define EX_LD_FP(x)            \
+98:    x;                      \
+       .section __ex_table,"a";\
+       .align 4;               \
+       .word 98b, __retl_one_fp;\
+       .text;                  \
+       .align 4;
+
 #define FUNC_NAME              U3copy_from_user
 #define LOAD(type,addr,dest)   type##a [addr] %asi, dest
 #define EX_RETVAL(x)           0
index ef1e493afdfa900a1b32863c2bf2995560cbe0cd..845139d7553720ce5fe98d6e30bcb11215f71e2f 100644 (file)
        .text;                  \
        .align 4;
 
+#define EX_ST_FP(x)            \
+98:    x;                      \
+       .section __ex_table,"a";\
+       .align 4;               \
+       .word 98b, __retl_one_fp;\
+       .text;                  \
+       .align 4;
+
 #define FUNC_NAME              U3copy_to_user
 #define STORE(type,src,addr)   type##a src, [addr] ASI_AIUS
 #define STORE_BLK(src,addr)    stda src, [addr] ASI_BLK_AIUS
index 7cae9cc6a204a46e535c8c651176ccc873778700..491ee69e49951fc2040640e77b896552872c8a0a 100644 (file)
 #ifndef EX_LD
 #define EX_LD(x)       x
 #endif
+#ifndef EX_LD_FP
+#define EX_LD_FP(x)    x
+#endif
 
 #ifndef EX_ST
 #define EX_ST(x)       x
 #endif
+#ifndef EX_ST_FP
+#define EX_ST_FP(x)    x
+#endif
 
 #ifndef EX_RETVAL
 #define EX_RETVAL(x)   x
@@ -120,8 +126,8 @@ FUNC_NAME:  /* %o0=dst, %o1=src, %o2=len */
         and            %g2, 0x38, %g2
 
 1:     subcc           %g1, 0x1, %g1
-       EX_LD(LOAD(ldub, %o1 + 0x00, %o3))
-       EX_ST(STORE(stb, %o3, %o1 + GLOBAL_SPARE))
+       EX_LD_FP(LOAD(ldub, %o1 + 0x00, %o3))
+       EX_ST_FP(STORE(stb, %o3, %o1 + GLOBAL_SPARE))
        bgu,pt          %XCC, 1b
         add            %o1, 0x1, %o1
 
@@ -132,20 +138,20 @@ FUNC_NAME:        /* %o0=dst, %o1=src, %o2=len */
        be,pt           %icc, 3f
         alignaddr      %o1, %g0, %o1
 
-       EX_LD(LOAD(ldd, %o1, %f4))
-1:     EX_LD(LOAD(ldd, %o1 + 0x8, %f6))
+       EX_LD_FP(LOAD(ldd, %o1, %f4))
+1:     EX_LD_FP(LOAD(ldd, %o1 + 0x8, %f6))
        add             %o1, 0x8, %o1
        subcc           %g2, 0x8, %g2
        faligndata      %f4, %f6, %f0
-       EX_ST(STORE(std, %f0, %o0))
+       EX_ST_FP(STORE(std, %f0, %o0))
        be,pn           %icc, 3f
         add            %o0, 0x8, %o0
 
-       EX_LD(LOAD(ldd, %o1 + 0x8, %f4))
+       EX_LD_FP(LOAD(ldd, %o1 + 0x8, %f4))
        add             %o1, 0x8, %o1
        subcc           %g2, 0x8, %g2
        faligndata      %f6, %f4, %f2
-       EX_ST(STORE(std, %f2, %o0))
+       EX_ST_FP(STORE(std, %f2, %o0))
        bne,pt          %icc, 1b
         add            %o0, 0x8, %o0
 
@@ -155,25 +161,25 @@ FUNC_NAME:        /* %o0=dst, %o1=src, %o2=len */
        LOAD(prefetch, %o1 + 0x080, #one_read)
        LOAD(prefetch, %o1 + 0x0c0, #one_read)
        LOAD(prefetch, %o1 + 0x100, #one_read)
-       EX_LD(LOAD(ldd, %o1 + 0x000, %f0))
+       EX_LD_FP(LOAD(ldd, %o1 + 0x000, %f0))
        LOAD(prefetch, %o1 + 0x140, #one_read)
-       EX_LD(LOAD(ldd, %o1 + 0x008, %f2))
+       EX_LD_FP(LOAD(ldd, %o1 + 0x008, %f2))
        LOAD(prefetch, %o1 + 0x180, #one_read)
-       EX_LD(LOAD(ldd, %o1 + 0x010, %f4))
+       EX_LD_FP(LOAD(ldd, %o1 + 0x010, %f4))
        LOAD(prefetch, %o1 + 0x1c0, #one_read)
        faligndata      %f0, %f2, %f16
-       EX_LD(LOAD(ldd, %o1 + 0x018, %f6))
+       EX_LD_FP(LOAD(ldd, %o1 + 0x018, %f6))
        faligndata      %f2, %f4, %f18
-       EX_LD(LOAD(ldd, %o1 + 0x020, %f8))
+       EX_LD_FP(LOAD(ldd, %o1 + 0x020, %f8))
        faligndata      %f4, %f6, %f20
-       EX_LD(LOAD(ldd, %o1 + 0x028, %f10))
+       EX_LD_FP(LOAD(ldd, %o1 + 0x028, %f10))
        faligndata      %f6, %f8, %f22
 
-       EX_LD(LOAD(ldd, %o1 + 0x030, %f12))
+       EX_LD_FP(LOAD(ldd, %o1 + 0x030, %f12))
        faligndata      %f8, %f10, %f24
-       EX_LD(LOAD(ldd, %o1 + 0x038, %f14))
+       EX_LD_FP(LOAD(ldd, %o1 + 0x038, %f14))
        faligndata      %f10, %f12, %f26
-       EX_LD(LOAD(ldd, %o1 + 0x040, %f0))
+       EX_LD_FP(LOAD(ldd, %o1 + 0x040, %f0))
 
        subcc           GLOBAL_SPARE, 0x80, GLOBAL_SPARE
        add             %o1, 0x40, %o1
@@ -184,26 +190,26 @@ FUNC_NAME:        /* %o0=dst, %o1=src, %o2=len */
 
        .align          64
 1:
-       EX_LD(LOAD(ldd, %o1 + 0x008, %f2))
+       EX_LD_FP(LOAD(ldd, %o1 + 0x008, %f2))
        faligndata      %f12, %f14, %f28
-       EX_LD(LOAD(ldd, %o1 + 0x010, %f4))
+       EX_LD_FP(LOAD(ldd, %o1 + 0x010, %f4))
        faligndata      %f14, %f0, %f30
-       EX_ST(STORE_BLK(%f16, %o0))
-       EX_LD(LOAD(ldd, %o1 + 0x018, %f6))
+       EX_ST_FP(STORE_BLK(%f16, %o0))
+       EX_LD_FP(LOAD(ldd, %o1 + 0x018, %f6))
        faligndata      %f0, %f2, %f16
        add             %o0, 0x40, %o0
 
-       EX_LD(LOAD(ldd, %o1 + 0x020, %f8))
+       EX_LD_FP(LOAD(ldd, %o1 + 0x020, %f8))
        faligndata      %f2, %f4, %f18
-       EX_LD(LOAD(ldd, %o1 + 0x028, %f10))
+       EX_LD_FP(LOAD(ldd, %o1 + 0x028, %f10))
        faligndata      %f4, %f6, %f20
-       EX_LD(LOAD(ldd, %o1 + 0x030, %f12))
+       EX_LD_FP(LOAD(ldd, %o1 + 0x030, %f12))
        subcc           %o3, 0x01, %o3
        faligndata      %f6, %f8, %f22
-       EX_LD(LOAD(ldd, %o1 + 0x038, %f14))
+       EX_LD_FP(LOAD(ldd, %o1 + 0x038, %f14))
 
        faligndata      %f8, %f10, %f24
-       EX_LD(LOAD(ldd, %o1 + 0x040, %f0))
+       EX_LD_FP(LOAD(ldd, %o1 + 0x040, %f0))
        LOAD(prefetch, %o1 + 0x1c0, #one_read)
        faligndata      %f10, %f12, %f26
        bg,pt           %XCC, 1b
@@ -211,29 +217,29 @@ FUNC_NAME:        /* %o0=dst, %o1=src, %o2=len */
 
        /* Finally we copy the last full 64-byte block. */
 2:
-       EX_LD(LOAD(ldd, %o1 + 0x008, %f2))
+       EX_LD_FP(LOAD(ldd, %o1 + 0x008, %f2))
        faligndata      %f12, %f14, %f28
-       EX_LD(LOAD(ldd, %o1 + 0x010, %f4))
+       EX_LD_FP(LOAD(ldd, %o1 + 0x010, %f4))
        faligndata      %f14, %f0, %f30
-       EX_ST(STORE_BLK(%f16, %o0))
-       EX_LD(LOAD(ldd, %o1 + 0x018, %f6))
+       EX_ST_FP(STORE_BLK(%f16, %o0))
+       EX_LD_FP(LOAD(ldd, %o1 + 0x018, %f6))
        faligndata      %f0, %f2, %f16
-       EX_LD(LOAD(ldd, %o1 + 0x020, %f8))
+       EX_LD_FP(LOAD(ldd, %o1 + 0x020, %f8))
        faligndata      %f2, %f4, %f18
-       EX_LD(LOAD(ldd, %o1 + 0x028, %f10))
+       EX_LD_FP(LOAD(ldd, %o1 + 0x028, %f10))
        faligndata      %f4, %f6, %f20
-       EX_LD(LOAD(ldd, %o1 + 0x030, %f12))
+       EX_LD_FP(LOAD(ldd, %o1 + 0x030, %f12))
        faligndata      %f6, %f8, %f22
-       EX_LD(LOAD(ldd, %o1 + 0x038, %f14))
+       EX_LD_FP(LOAD(ldd, %o1 + 0x038, %f14))
        faligndata      %f8, %f10, %f24
        cmp             %g1, 0
        be,pt           %XCC, 1f
         add            %o0, 0x40, %o0
-       EX_LD(LOAD(ldd, %o1 + 0x040, %f0))
+       EX_LD_FP(LOAD(ldd, %o1 + 0x040, %f0))
 1:     faligndata      %f10, %f12, %f26
        faligndata      %f12, %f14, %f28
        faligndata      %f14, %f0, %f30
-       EX_ST(STORE_BLK(%f16, %o0))
+       EX_ST_FP(STORE_BLK(%f16, %o0))
        add             %o0, 0x40, %o0
        add             %o1, 0x40, %o1
        membar          #Sync
@@ -253,20 +259,20 @@ FUNC_NAME:        /* %o0=dst, %o1=src, %o2=len */
 
        sub             %o2, %g2, %o2
        be,a,pt         %XCC, 1f
-        EX_LD(LOAD(ldd, %o1 + 0x00, %f0))
+        EX_LD_FP(LOAD(ldd, %o1 + 0x00, %f0))
 
-1:     EX_LD(LOAD(ldd, %o1 + 0x08, %f2))
+1:     EX_LD_FP(LOAD(ldd, %o1 + 0x08, %f2))
        add             %o1, 0x8, %o1
        subcc           %g2, 0x8, %g2
        faligndata      %f0, %f2, %f8
-       EX_ST(STORE(std, %f8, %o0))
+       EX_ST_FP(STORE(std, %f8, %o0))
        be,pn           %XCC, 2f
         add            %o0, 0x8, %o0
-       EX_LD(LOAD(ldd, %o1 + 0x08, %f0))
+       EX_LD_FP(LOAD(ldd, %o1 + 0x08, %f0))
        add             %o1, 0x8, %o1
        subcc           %g2, 0x8, %g2
        faligndata      %f2, %f0, %f8
-       EX_ST(STORE(std, %f8, %o0))
+       EX_ST_FP(STORE(std, %f8, %o0))
        bne,pn          %XCC, 1b
         add            %o0, 0x8, %o0
 
index 22564f5f23647a6f54752052091d2c74c194bccf..3e6e05a7c4c22b297861eb82871d92b7217cffee 100644 (file)
@@ -420,22 +420,9 @@ void bpf_jit_compile(struct bpf_prog *fp)
                }
                emit_reg_move(O7, r_saved_O7);
 
-               switch (filter[0].code) {
-               case BPF_RET | BPF_K:
-               case BPF_LD | BPF_W | BPF_LEN:
-               case BPF_LD | BPF_W | BPF_ABS:
-               case BPF_LD | BPF_H | BPF_ABS:
-               case BPF_LD | BPF_B | BPF_ABS:
-                       /* The first instruction sets the A register (or is
-                        * a "RET 'constant'")
-                        */
-                       break;
-               default:
-                       /* Make sure we dont leak kernel information to the
-                        * user.
-                        */
+               /* Make sure we dont leak kernel information to the user. */
+               if (bpf_needs_clear_a(&filter[0]))
                        emit_clear(r_A); /* A = 0 */
-               }
 
                for (i = 0; i < flen; i++) {
                        unsigned int K = filter[i].k;
index 106c21bd7f449d947094db5fdefce8a9a6e1b142..8ec7a4599c085dd0d05f7ad819c11d4659223c51 100644 (file)
@@ -176,8 +176,6 @@ config NR_CPUS
          smaller kernel memory footprint results from using a smaller
          value on chips with fewer tiles.
 
-if TILEGX
-
 choice
        prompt "Kernel page size"
        default PAGE_SIZE_64KB
@@ -188,8 +186,11 @@ choice
          connections, etc., it may be better to select 16KB, which uses
          memory more efficiently at some cost in TLB performance.
 
-         Note that this option is TILE-Gx specific; currently
-         TILEPro page size is set by rebuilding the hypervisor.
+         Note that for TILEPro, you must also rebuild the hypervisor
+         with a matching page size.
+
+config PAGE_SIZE_4KB
+       bool "4KB" if TILEPRO
 
 config PAGE_SIZE_16KB
        bool "16KB"
@@ -199,8 +200,6 @@ config PAGE_SIZE_64KB
 
 endchoice
 
-endif
-
 source "kernel/Kconfig.hz"
 
 config KEXEC
index a213a8d84a95ac48a149de807558290c21dbe2cb..8eca6a0e176200c3604151c4168b0553a0002768 100644 (file)
 #include <arch/chip.h>
 
 /* PAGE_SHIFT and HPAGE_SHIFT determine the page sizes. */
-#if defined(CONFIG_PAGE_SIZE_16KB)
+#if defined(CONFIG_PAGE_SIZE_4KB)  /* tilepro only */
+#define PAGE_SHIFT     12
+#define CTX_PAGE_FLAG  HV_CTX_PG_SM_4K
+#elif defined(CONFIG_PAGE_SIZE_16KB)
 #define PAGE_SHIFT     14
 #define CTX_PAGE_FLAG  HV_CTX_PG_SM_16K
 #elif defined(CONFIG_PAGE_SIZE_64KB)
 #define PAGE_SHIFT     16
 #define CTX_PAGE_FLAG  HV_CTX_PG_SM_64K
 #else
-#define PAGE_SHIFT     HV_LOG2_DEFAULT_PAGE_SIZE_SMALL
-#define CTX_PAGE_FLAG  0
+#error Page size not specified in Kconfig
 #endif
 #define HPAGE_SHIFT    HV_LOG2_DEFAULT_PAGE_SIZE_LARGE
 
index 06332cb7e7d1d79c5af04eba698ad8642c2762b5..3f5c48ddba453064ff6dbe91731d1d0c7776be53 100644 (file)
@@ -38,6 +38,14 @@ static inline bool guest_cpuid_has_xsave(struct kvm_vcpu *vcpu)
        return best && (best->ecx & bit(X86_FEATURE_XSAVE));
 }
 
+static inline bool guest_cpuid_has_mtrr(struct kvm_vcpu *vcpu)
+{
+       struct kvm_cpuid_entry2 *best;
+
+       best = kvm_find_cpuid_entry(vcpu, 1, 0);
+       return best && (best->edx & bit(X86_FEATURE_MTRR));
+}
+
 static inline bool guest_cpuid_has_tsc_adjust(struct kvm_vcpu *vcpu)
 {
        struct kvm_cpuid_entry2 *best;
index 9e8bf13572e6dc3f95d33d24f079d63e256a3a7a..3f8c732117eccf73140fded817e1b155dfa76073 100644 (file)
@@ -120,14 +120,22 @@ static u8 mtrr_default_type(struct kvm_mtrr *mtrr_state)
        return mtrr_state->deftype & IA32_MTRR_DEF_TYPE_TYPE_MASK;
 }
 
-static u8 mtrr_disabled_type(void)
+static u8 mtrr_disabled_type(struct kvm_vcpu *vcpu)
 {
        /*
         * Intel SDM 11.11.2.2: all MTRRs are disabled when
         * IA32_MTRR_DEF_TYPE.E bit is cleared, and the UC
         * memory type is applied to all of physical memory.
+        *
+        * However, virtual machines can be run with CPUID such that
+        * there are no MTRRs.  In that case, the firmware will never
+        * enable MTRRs and it is obviously undesirable to run the
+        * guest entirely with UC memory and we use WB.
         */
-       return MTRR_TYPE_UNCACHABLE;
+       if (guest_cpuid_has_mtrr(vcpu))
+               return MTRR_TYPE_UNCACHABLE;
+       else
+               return MTRR_TYPE_WRBACK;
 }
 
 /*
@@ -267,7 +275,7 @@ static int fixed_mtrr_addr_to_seg(u64 addr)
 
        for (seg = 0; seg < seg_num; seg++) {
                mtrr_seg = &fixed_seg_table[seg];
-               if (mtrr_seg->start >= addr && addr < mtrr_seg->end)
+               if (mtrr_seg->start <= addr && addr < mtrr_seg->end)
                        return seg;
        }
 
@@ -300,7 +308,6 @@ static void var_mtrr_range(struct kvm_mtrr_range *range, u64 *start, u64 *end)
        *start = range->base & PAGE_MASK;
 
        mask = range->mask & PAGE_MASK;
-       mask |= ~0ULL << boot_cpu_data.x86_phys_bits;
 
        /* This cannot overflow because writing to the reserved bits of
         * variable MTRRs causes a #GP.
@@ -356,10 +363,14 @@ static void set_var_mtrr_msr(struct kvm_vcpu *vcpu, u32 msr, u64 data)
        if (var_mtrr_range_is_valid(cur))
                list_del(&mtrr_state->var_ranges[index].node);
 
+       /* Extend the mask with all 1 bits to the left, since those
+        * bits must implicitly be 0.  The bits are then cleared
+        * when reading them.
+        */
        if (!is_mtrr_mask)
                cur->base = data;
        else
-               cur->mask = data;
+               cur->mask = data | (-1LL << cpuid_maxphyaddr(vcpu));
 
        /* add it to the list if it's enabled. */
        if (var_mtrr_range_is_valid(cur)) {
@@ -426,6 +437,8 @@ int kvm_mtrr_get_msr(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
                        *pdata = vcpu->arch.mtrr_state.var_ranges[index].base;
                else
                        *pdata = vcpu->arch.mtrr_state.var_ranges[index].mask;
+
+               *pdata &= (1ULL << cpuid_maxphyaddr(vcpu)) - 1;
        }
 
        return 0;
@@ -670,7 +683,7 @@ u8 kvm_mtrr_get_guest_memory_type(struct kvm_vcpu *vcpu, gfn_t gfn)
        }
 
        if (iter.mtrr_disabled)
-               return mtrr_disabled_type();
+               return mtrr_disabled_type(vcpu);
 
        /* not contained in any MTRRs. */
        if (type == -1)
index 83a1c643f9a50fd3fa0ffc041c40d9f4d25aa5b5..899c40f826dd9a5f10c57e0758153cdbb1d9f1a6 100644 (file)
@@ -3422,6 +3422,8 @@ static int handle_exit(struct kvm_vcpu *vcpu)
        struct kvm_run *kvm_run = vcpu->run;
        u32 exit_code = svm->vmcb->control.exit_code;
 
+       trace_kvm_exit(exit_code, vcpu, KVM_ISA_SVM);
+
        if (!is_cr_intercept(svm, INTERCEPT_CR0_WRITE))
                vcpu->arch.cr0 = svm->vmcb->save.cr0;
        if (npt_enabled)
@@ -3892,8 +3894,6 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu)
        vcpu->arch.regs[VCPU_REGS_RSP] = svm->vmcb->save.rsp;
        vcpu->arch.regs[VCPU_REGS_RIP] = svm->vmcb->save.rip;
 
-       trace_kvm_exit(svm->vmcb->control.exit_code, vcpu, KVM_ISA_SVM);
-
        if (unlikely(svm->vmcb->control.exit_code == SVM_EXIT_NMI))
                kvm_before_handle_nmi(&svm->vcpu);
 
index af823a388c1994ba244e3ef0098f1a578408101e..44976a596fa65d2ca90421a7f7f06cfb2d0b17be 100644 (file)
@@ -2803,7 +2803,7 @@ static int vmx_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
                msr_info->data = vcpu->arch.ia32_xss;
                break;
        case MSR_TSC_AUX:
-               if (!guest_cpuid_has_rdtscp(vcpu))
+               if (!guest_cpuid_has_rdtscp(vcpu) && !msr_info->host_initiated)
                        return 1;
                /* Otherwise falls through */
        default:
@@ -2909,7 +2909,7 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
                        clear_atomic_switch_msr(vmx, MSR_IA32_XSS);
                break;
        case MSR_TSC_AUX:
-               if (!guest_cpuid_has_rdtscp(vcpu))
+               if (!guest_cpuid_has_rdtscp(vcpu) && !msr_info->host_initiated)
                        return 1;
                /* Check reserved bit, higher 32 bits should be zero */
                if ((data >> 32) != 0)
@@ -8042,6 +8042,8 @@ static int vmx_handle_exit(struct kvm_vcpu *vcpu)
        u32 exit_reason = vmx->exit_reason;
        u32 vectoring_info = vmx->idt_vectoring_info;
 
+       trace_kvm_exit(exit_reason, vcpu, KVM_ISA_VMX);
+
        /*
         * Flush logged GPAs PML buffer, this will make dirty_bitmap more
         * updated. Another good is, in kvm_vm_ioctl_get_dirty_log, before
@@ -8668,7 +8670,6 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu)
        vmx->loaded_vmcs->launched = 1;
 
        vmx->exit_reason = vmcs_read32(VM_EXIT_REASON);
-       trace_kvm_exit(vmx->exit_reason, vcpu, KVM_ISA_VMX);
 
        /*
         * the KVM_REQ_EVENT optimization bit is only on for one entry, and if
index eed32283d22cc0cafbff75e8f2a246887d4cbb5f..7ffc224bbe4127a90ef7741f09ae94f75e17feec 100644 (file)
@@ -3572,9 +3572,11 @@ static int kvm_vm_ioctl_get_pit(struct kvm *kvm, struct kvm_pit_state *ps)
 
 static int kvm_vm_ioctl_set_pit(struct kvm *kvm, struct kvm_pit_state *ps)
 {
+       int i;
        mutex_lock(&kvm->arch.vpit->pit_state.lock);
        memcpy(&kvm->arch.vpit->pit_state, ps, sizeof(struct kvm_pit_state));
-       kvm_pit_load_count(kvm, 0, ps->channels[0].count, 0);
+       for (i = 0; i < 3; i++)
+               kvm_pit_load_count(kvm, i, ps->channels[i].count, 0);
        mutex_unlock(&kvm->arch.vpit->pit_state.lock);
        return 0;
 }
@@ -3593,6 +3595,7 @@ static int kvm_vm_ioctl_get_pit2(struct kvm *kvm, struct kvm_pit_state2 *ps)
 static int kvm_vm_ioctl_set_pit2(struct kvm *kvm, struct kvm_pit_state2 *ps)
 {
        int start = 0;
+       int i;
        u32 prev_legacy, cur_legacy;
        mutex_lock(&kvm->arch.vpit->pit_state.lock);
        prev_legacy = kvm->arch.vpit->pit_state.flags & KVM_PIT_FLAGS_HPET_LEGACY;
@@ -3602,7 +3605,8 @@ static int kvm_vm_ioctl_set_pit2(struct kvm *kvm, struct kvm_pit_state2 *ps)
        memcpy(&kvm->arch.vpit->pit_state.channels, &ps->channels,
               sizeof(kvm->arch.vpit->pit_state.channels));
        kvm->arch.vpit->pit_state.flags = ps->flags;
-       kvm_pit_load_count(kvm, 0, kvm->arch.vpit->pit_state.channels[0].count, start);
+       for (i = 0; i < 3; i++)
+               kvm_pit_load_count(kvm, i, kvm->arch.vpit->pit_state.channels[i].count, start);
        mutex_unlock(&kvm->arch.vpit->pit_state.lock);
        return 0;
 }
@@ -6515,6 +6519,8 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
        if (req_immediate_exit)
                smp_send_reschedule(vcpu->cpu);
 
+       trace_kvm_entry(vcpu->vcpu_id);
+       wait_lapic_expire(vcpu);
        __kvm_guest_enter();
 
        if (unlikely(vcpu->arch.switch_db_regs)) {
@@ -6527,8 +6533,6 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
                vcpu->arch.switch_db_regs &= ~KVM_DEBUGREG_RELOAD;
        }
 
-       trace_kvm_entry(vcpu->vcpu_id);
-       wait_lapic_expire(vcpu);
        kvm_x86_ops->run(vcpu);
 
        /*
index a035c2aa780190c8c198e1bd8c2bec20a18d8ecb..0f1c6fc3ddd88948646963772ac0fa12c492c212 100644 (file)
@@ -89,7 +89,7 @@ static struct addr_marker address_markers[] = {
        { 0/* VMALLOC_START */, "vmalloc() Area" },
        { 0/*VMALLOC_END*/,     "vmalloc() End" },
 # ifdef CONFIG_HIGHMEM
-       { 0/*PKMAP_BASE*/,      "Persisent kmap() Area" },
+       { 0/*PKMAP_BASE*/,      "Persistent kmap() Area" },
 # endif
        { 0/*FIXADDR_START*/,   "Fixmap Area" },
 #endif
index e5f854ce2d72404237067031a09297c8f0d3f424..14fcd01ed99293c162582438b4755a47fff59f43 100644 (file)
@@ -470,7 +470,7 @@ long sys_sigreturn(void)
        struct sigcontext __user *sc = &frame->sc;
        int sig_size = (_NSIG_WORDS - 1) * sizeof(unsigned long);
 
-       if (copy_from_user(&set.sig[0], (void *)sc->oldmask, sizeof(set.sig[0])) ||
+       if (copy_from_user(&set.sig[0], &sc->oldmask, sizeof(set.sig[0])) ||
            copy_from_user(&set.sig[1], frame->extramask, sig_size))
                goto segfault;
 
index ac161db633885872fdebdce976d05b978e1235da..cb5e266a8bf752297eaf6fc0d822c9398239fadf 100644 (file)
@@ -2495,14 +2495,9 @@ void __init xen_init_mmu_ops(void)
 {
        x86_init.paging.pagetable_init = xen_pagetable_init;
 
-       /* Optimization - we can use the HVM one but it has no idea which
-        * VCPUs are descheduled - which means that it will needlessly IPI
-        * them. Xen knows so let it do the job.
-        */
-       if (xen_feature(XENFEAT_auto_translated_physmap)) {
-               pv_mmu_ops.flush_tlb_others = xen_flush_tlb_others;
+       if (xen_feature(XENFEAT_auto_translated_physmap))
                return;
-       }
+
        pv_mmu_ops = xen_mmu_ops;
 
        memset(dummy_mapping, 0xff, PAGE_SIZE);
index feddabdab4488c54784aa5a64067d09b50b3cb22..df0c4055958379753aac957dd2c9e4c68fbaf765 100644 (file)
@@ -1,6 +1,7 @@
 #include <linux/types.h>
 #include <linux/tick.h>
 
+#include <xen/xen.h>
 #include <xen/interface/xen.h>
 #include <xen/grant_table.h>
 #include <xen/events.h>
@@ -68,26 +69,16 @@ static void xen_pv_post_suspend(int suspend_cancelled)
 
 void xen_arch_pre_suspend(void)
 {
-       int cpu;
-
-       for_each_online_cpu(cpu)
-               xen_pmu_finish(cpu);
-
        if (xen_pv_domain())
                xen_pv_pre_suspend();
 }
 
 void xen_arch_post_suspend(int cancelled)
 {
-       int cpu;
-
        if (xen_pv_domain())
                xen_pv_post_suspend(cancelled);
        else
                xen_hvm_post_suspend(cancelled);
-
-       for_each_online_cpu(cpu)
-               xen_pmu_init(cpu);
 }
 
 static void xen_vcpu_notify_restore(void *data)
@@ -106,10 +97,20 @@ static void xen_vcpu_notify_suspend(void *data)
 
 void xen_arch_resume(void)
 {
+       int cpu;
+
        on_each_cpu(xen_vcpu_notify_restore, NULL, 1);
+
+       for_each_online_cpu(cpu)
+               xen_pmu_init(cpu);
 }
 
 void xen_arch_suspend(void)
 {
+       int cpu;
+
+       for_each_online_cpu(cpu)
+               xen_pmu_finish(cpu);
+
        on_each_cpu(xen_vcpu_notify_suspend, NULL, 1);
 }
index a0af4043dda2bbe953b3550c07ac40f88148958b..33e2f62d50622ea8b40153175d0f44d96df399a6 100644 (file)
@@ -206,6 +206,22 @@ void blk_delay_queue(struct request_queue *q, unsigned long msecs)
 }
 EXPORT_SYMBOL(blk_delay_queue);
 
+/**
+ * blk_start_queue_async - asynchronously restart a previously stopped queue
+ * @q:    The &struct request_queue in question
+ *
+ * Description:
+ *   blk_start_queue_async() will clear the stop flag on the queue, and
+ *   ensure that the request_fn for the queue is run from an async
+ *   context.
+ **/
+void blk_start_queue_async(struct request_queue *q)
+{
+       queue_flag_clear(QUEUE_FLAG_STOPPED, q);
+       blk_run_queue_async(q);
+}
+EXPORT_SYMBOL(blk_start_queue_async);
+
 /**
  * blk_start_queue - restart a previously stopped queue
  * @q:    The &struct request_queue in question
@@ -1689,8 +1705,6 @@ static blk_qc_t blk_queue_bio(struct request_queue *q, struct bio *bio)
        struct request *req;
        unsigned int request_count = 0;
 
-       blk_queue_split(q, &bio, q->bio_split);
-
        /*
         * low level driver can indicate that it wants pages above a
         * certain limit bounced to low memory (ie for highmem, or even
@@ -1698,6 +1712,8 @@ static blk_qc_t blk_queue_bio(struct request_queue *q, struct bio *bio)
         */
        blk_queue_bounce(q, &bio);
 
+       blk_queue_split(q, &bio, q->bio_split);
+
        if (bio_integrity_enabled(bio) && bio_integrity_prep(bio)) {
                bio->bi_error = -EIO;
                bio_endio(bio);
@@ -3405,6 +3421,9 @@ int blk_pre_runtime_suspend(struct request_queue *q)
 {
        int ret = 0;
 
+       if (!q->dev)
+               return ret;
+
        spin_lock_irq(q->queue_lock);
        if (q->nr_pending) {
                ret = -EBUSY;
@@ -3432,6 +3451,9 @@ EXPORT_SYMBOL(blk_pre_runtime_suspend);
  */
 void blk_post_runtime_suspend(struct request_queue *q, int err)
 {
+       if (!q->dev)
+               return;
+
        spin_lock_irq(q->queue_lock);
        if (!err) {
                q->rpm_status = RPM_SUSPENDED;
@@ -3456,6 +3478,9 @@ EXPORT_SYMBOL(blk_post_runtime_suspend);
  */
 void blk_pre_runtime_resume(struct request_queue *q)
 {
+       if (!q->dev)
+               return;
+
        spin_lock_irq(q->queue_lock);
        q->rpm_status = RPM_RESUMING;
        spin_unlock_irq(q->queue_lock);
@@ -3478,6 +3503,9 @@ EXPORT_SYMBOL(blk_pre_runtime_resume);
  */
 void blk_post_runtime_resume(struct request_queue *q, int err)
 {
+       if (!q->dev)
+               return;
+
        spin_lock_irq(q->queue_lock);
        if (!err) {
                q->rpm_status = RPM_ACTIVE;
index b4ffc5be1a93c1ff0bceb6b9a5cc3dc1b5101d97..e5b5721809e21d5d379e6e711e23ef709252e0ed 100644 (file)
@@ -277,12 +277,12 @@ static int ablkcipher_walk_first(struct ablkcipher_request *req,
        if (WARN_ON_ONCE(in_irq()))
                return -EDEADLK;
 
+       walk->iv = req->info;
        walk->nbytes = walk->total;
        if (unlikely(!walk->total))
                return 0;
 
        walk->iv_buffer = NULL;
-       walk->iv = req->info;
        if (unlikely(((unsigned long)walk->iv & alignmask))) {
                int err = ablkcipher_copy_iv(walk, tfm, alignmask);
 
index ca9efe17db1ac4e9e2806528ea28d2d87a954b8f..634b4d1ab6817d56343d5b8b24b29cd34de422d1 100644 (file)
@@ -47,7 +47,7 @@ struct skcipher_ctx {
        bool merge;
        bool enc;
 
-       struct ablkcipher_request req;
+       struct skcipher_request req;
 };
 
 struct skcipher_async_rsgl {
@@ -64,13 +64,13 @@ struct skcipher_async_req {
 };
 
 #define GET_SREQ(areq, ctx) (struct skcipher_async_req *)((char *)areq + \
-       crypto_ablkcipher_reqsize(crypto_ablkcipher_reqtfm(&ctx->req)))
+       crypto_skcipher_reqsize(crypto_skcipher_reqtfm(&ctx->req)))
 
 #define GET_REQ_SIZE(ctx) \
-       crypto_ablkcipher_reqsize(crypto_ablkcipher_reqtfm(&ctx->req))
+       crypto_skcipher_reqsize(crypto_skcipher_reqtfm(&ctx->req))
 
 #define GET_IV_SIZE(ctx) \
-       crypto_ablkcipher_ivsize(crypto_ablkcipher_reqtfm(&ctx->req))
+       crypto_skcipher_ivsize(crypto_skcipher_reqtfm(&ctx->req))
 
 #define MAX_SGL_ENTS ((4096 - sizeof(struct skcipher_sg_list)) / \
                      sizeof(struct scatterlist) - 1)
@@ -302,8 +302,8 @@ static int skcipher_sendmsg(struct socket *sock, struct msghdr *msg,
        struct sock *sk = sock->sk;
        struct alg_sock *ask = alg_sk(sk);
        struct skcipher_ctx *ctx = ask->private;
-       struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(&ctx->req);
-       unsigned ivsize = crypto_ablkcipher_ivsize(tfm);
+       struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(&ctx->req);
+       unsigned ivsize = crypto_skcipher_ivsize(tfm);
        struct skcipher_sg_list *sgl;
        struct af_alg_control con = {};
        long copied = 0;
@@ -507,7 +507,7 @@ static int skcipher_recvmsg_async(struct socket *sock, struct msghdr *msg,
        struct skcipher_sg_list *sgl;
        struct scatterlist *sg;
        struct skcipher_async_req *sreq;
-       struct ablkcipher_request *req;
+       struct skcipher_request *req;
        struct skcipher_async_rsgl *last_rsgl = NULL;
        unsigned int txbufs = 0, len = 0, tx_nents = skcipher_all_sg_nents(ctx);
        unsigned int reqlen = sizeof(struct skcipher_async_req) +
@@ -531,9 +531,9 @@ static int skcipher_recvmsg_async(struct socket *sock, struct msghdr *msg,
        }
        sg_init_table(sreq->tsg, tx_nents);
        memcpy(sreq->iv, ctx->iv, GET_IV_SIZE(ctx));
-       ablkcipher_request_set_tfm(req, crypto_ablkcipher_reqtfm(&ctx->req));
-       ablkcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
-                                       skcipher_async_cb, sk);
+       skcipher_request_set_tfm(req, crypto_skcipher_reqtfm(&ctx->req));
+       skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
+                                     skcipher_async_cb, sk);
 
        while (iov_iter_count(&msg->msg_iter)) {
                struct skcipher_async_rsgl *rsgl;
@@ -608,10 +608,10 @@ static int skcipher_recvmsg_async(struct socket *sock, struct msghdr *msg,
        if (mark)
                sg_mark_end(sreq->tsg + txbufs - 1);
 
-       ablkcipher_request_set_crypt(req, sreq->tsg, sreq->first_sgl.sgl.sg,
-                                    len, sreq->iv);
-       err = ctx->enc ? crypto_ablkcipher_encrypt(req) :
-                        crypto_ablkcipher_decrypt(req);
+       skcipher_request_set_crypt(req, sreq->tsg, sreq->first_sgl.sgl.sg,
+                                  len, sreq->iv);
+       err = ctx->enc ? crypto_skcipher_encrypt(req) :
+                        crypto_skcipher_decrypt(req);
        if (err == -EINPROGRESS) {
                atomic_inc(&ctx->inflight);
                err = -EIOCBQUEUED;
@@ -632,7 +632,7 @@ static int skcipher_recvmsg_sync(struct socket *sock, struct msghdr *msg,
        struct sock *sk = sock->sk;
        struct alg_sock *ask = alg_sk(sk);
        struct skcipher_ctx *ctx = ask->private;
-       unsigned bs = crypto_ablkcipher_blocksize(crypto_ablkcipher_reqtfm(
+       unsigned bs = crypto_skcipher_blocksize(crypto_skcipher_reqtfm(
                &ctx->req));
        struct skcipher_sg_list *sgl;
        struct scatterlist *sg;
@@ -669,14 +669,13 @@ static int skcipher_recvmsg_sync(struct socket *sock, struct msghdr *msg,
                if (!used)
                        goto free;
 
-               ablkcipher_request_set_crypt(&ctx->req, sg,
-                                            ctx->rsgl.sg, used,
-                                            ctx->iv);
+               skcipher_request_set_crypt(&ctx->req, sg, ctx->rsgl.sg, used,
+                                          ctx->iv);
 
                err = af_alg_wait_for_completion(
                                ctx->enc ?
-                                       crypto_ablkcipher_encrypt(&ctx->req) :
-                                       crypto_ablkcipher_decrypt(&ctx->req),
+                                       crypto_skcipher_encrypt(&ctx->req) :
+                                       crypto_skcipher_decrypt(&ctx->req),
                                &ctx->completion);
 
 free:
@@ -751,17 +750,17 @@ static struct proto_ops algif_skcipher_ops = {
 
 static void *skcipher_bind(const char *name, u32 type, u32 mask)
 {
-       return crypto_alloc_ablkcipher(name, type, mask);
+       return crypto_alloc_skcipher(name, type, mask);
 }
 
 static void skcipher_release(void *private)
 {
-       crypto_free_ablkcipher(private);
+       crypto_free_skcipher(private);
 }
 
 static int skcipher_setkey(void *private, const u8 *key, unsigned int keylen)
 {
-       return crypto_ablkcipher_setkey(private, key, keylen);
+       return crypto_skcipher_setkey(private, key, keylen);
 }
 
 static void skcipher_wait(struct sock *sk)
@@ -778,13 +777,13 @@ static void skcipher_sock_destruct(struct sock *sk)
 {
        struct alg_sock *ask = alg_sk(sk);
        struct skcipher_ctx *ctx = ask->private;
-       struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(&ctx->req);
+       struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(&ctx->req);
 
        if (atomic_read(&ctx->inflight))
                skcipher_wait(sk);
 
        skcipher_free_sgl(sk);
-       sock_kzfree_s(sk, ctx->iv, crypto_ablkcipher_ivsize(tfm));
+       sock_kzfree_s(sk, ctx->iv, crypto_skcipher_ivsize(tfm));
        sock_kfree_s(sk, ctx, ctx->len);
        af_alg_release_parent(sk);
 }
@@ -793,20 +792,20 @@ static int skcipher_accept_parent(void *private, struct sock *sk)
 {
        struct skcipher_ctx *ctx;
        struct alg_sock *ask = alg_sk(sk);
-       unsigned int len = sizeof(*ctx) + crypto_ablkcipher_reqsize(private);
+       unsigned int len = sizeof(*ctx) + crypto_skcipher_reqsize(private);
 
        ctx = sock_kmalloc(sk, len, GFP_KERNEL);
        if (!ctx)
                return -ENOMEM;
 
-       ctx->iv = sock_kmalloc(sk, crypto_ablkcipher_ivsize(private),
+       ctx->iv = sock_kmalloc(sk, crypto_skcipher_ivsize(private),
                               GFP_KERNEL);
        if (!ctx->iv) {
                sock_kfree_s(sk, ctx, len);
                return -ENOMEM;
        }
 
-       memset(ctx->iv, 0, crypto_ablkcipher_ivsize(private));
+       memset(ctx->iv, 0, crypto_skcipher_ivsize(private));
 
        INIT_LIST_HEAD(&ctx->tsgl);
        ctx->len = len;
@@ -819,9 +818,9 @@ static int skcipher_accept_parent(void *private, struct sock *sk)
 
        ask->private = ctx;
 
-       ablkcipher_request_set_tfm(&ctx->req, private);
-       ablkcipher_request_set_callback(&ctx->req, CRYPTO_TFM_REQ_MAY_BACKLOG,
-                                       af_alg_complete, &ctx->completion);
+       skcipher_request_set_tfm(&ctx->req, private);
+       skcipher_request_set_callback(&ctx->req, CRYPTO_TFM_REQ_MAY_BACKLOG,
+                                     af_alg_complete, &ctx->completion);
 
        sk->sk_destruct = skcipher_sock_destruct;
 
index f8c0b8dbeb7582beca1ee7fd5c7aaac58aba23cd..88bc8e6b2a545b9667f3d5fb390854a19f0be778 100644 (file)
@@ -53,7 +53,7 @@ async_memcpy(struct page *dest, struct page *src, unsigned int dest_offset,
        struct dmaengine_unmap_data *unmap = NULL;
 
        if (device)
-               unmap = dmaengine_get_unmap_data(device->dev, 2, GFP_NOIO);
+               unmap = dmaengine_get_unmap_data(device->dev, 2, GFP_NOWAIT);
 
        if (unmap && is_dma_copy_aligned(device, src_offset, dest_offset, len)) {
                unsigned long dma_prep_flags = 0;
index 5d355e0c263339b5bd179ad61aad63c9b7efb3a3..c0748bbd4c083b47f78c662cdd7cb490590a2587 100644 (file)
@@ -188,7 +188,7 @@ async_gen_syndrome(struct page **blocks, unsigned int offset, int disks,
        BUG_ON(disks > 255 || !(P(blocks, disks) || Q(blocks, disks)));
 
        if (device)
-               unmap = dmaengine_get_unmap_data(device->dev, disks, GFP_NOIO);
+               unmap = dmaengine_get_unmap_data(device->dev, disks, GFP_NOWAIT);
 
        /* XORing P/Q is only implemented in software */
        if (unmap && !(submit->flags & ASYNC_TX_PQ_XOR_DST) &&
@@ -307,7 +307,7 @@ async_syndrome_val(struct page **blocks, unsigned int offset, int disks,
        BUG_ON(disks < 4);
 
        if (device)
-               unmap = dmaengine_get_unmap_data(device->dev, disks, GFP_NOIO);
+               unmap = dmaengine_get_unmap_data(device->dev, disks, GFP_NOWAIT);
 
        if (unmap && disks <= dma_maxpq(device, 0) &&
            is_dma_pq_aligned(device, offset, 0, len)) {
index 934a849814958e6ea37b9dbdb96abc820c4fe9e1..8fab6275ea1facaae8730a8f676f2578c792e7c3 100644 (file)
@@ -41,7 +41,7 @@ async_sum_product(struct page *dest, struct page **srcs, unsigned char *coef,
        u8 *a, *b, *c;
 
        if (dma)
-               unmap = dmaengine_get_unmap_data(dma->dev, 3, GFP_NOIO);
+               unmap = dmaengine_get_unmap_data(dma->dev, 3, GFP_NOWAIT);
 
        if (unmap) {
                struct device *dev = dma->dev;
@@ -105,7 +105,7 @@ async_mult(struct page *dest, struct page *src, u8 coef, size_t len,
        u8 *d, *s;
 
        if (dma)
-               unmap = dmaengine_get_unmap_data(dma->dev, 3, GFP_NOIO);
+               unmap = dmaengine_get_unmap_data(dma->dev, 3, GFP_NOWAIT);
 
        if (unmap) {
                dma_addr_t dma_dest[2];
index e1bce26cd4f9098f2765ffbf0f8e2f00017a9219..da75777f2b3f04f09a3fc025da9e38102b2211e8 100644 (file)
@@ -182,7 +182,7 @@ async_xor(struct page *dest, struct page **src_list, unsigned int offset,
        BUG_ON(src_cnt <= 1);
 
        if (device)
-               unmap = dmaengine_get_unmap_data(device->dev, src_cnt+1, GFP_NOIO);
+               unmap = dmaengine_get_unmap_data(device->dev, src_cnt+1, GFP_NOWAIT);
 
        if (unmap && is_dma_xor_aligned(device, offset, 0, len)) {
                struct dma_async_tx_descriptor *tx;
@@ -278,7 +278,7 @@ async_xor_val(struct page *dest, struct page **src_list, unsigned int offset,
        BUG_ON(src_cnt <= 1);
 
        if (device)
-               unmap = dmaengine_get_unmap_data(device->dev, src_cnt, GFP_NOIO);
+               unmap = dmaengine_get_unmap_data(device->dev, src_cnt, GFP_NOWAIT);
 
        if (unmap && src_cnt <= device->max_xor &&
            is_dma_xor_aligned(device, offset, 0, len)) {
index 11b981492031361f7cdf336b58ecbb98b8951196..8cc1622b2ee008ef7f5ff31a3ea7d8777f3f5f1b 100644 (file)
@@ -326,12 +326,12 @@ static int blkcipher_walk_first(struct blkcipher_desc *desc,
        if (WARN_ON_ONCE(in_irq()))
                return -EDEADLK;
 
+       walk->iv = desc->info;
        walk->nbytes = walk->total;
        if (unlikely(!walk->total))
                return 0;
 
        walk->buffer = NULL;
-       walk->iv = desc->info;
        if (unlikely(((unsigned long)walk->iv & walk->alignmask))) {
                int err = blkcipher_copy_iv(walk);
                if (err)
index e7ed39bab97d5d0a97d03919bd615eb5fba4105e..aa45d480270721280a9e8085574a14d086a079fc 100644 (file)
@@ -1810,7 +1810,7 @@ static void acpi_nfit_notify(struct acpi_device *adev, u32 event)
        if (!dev->driver) {
                /* dev->driver may be null if we're being removed */
                dev_dbg(dev, "%s: no driver found for dev\n", __func__);
-               return;
+               goto out_unlock;
        }
 
        if (!acpi_desc) {
index f4e02ae93f585fbb8de42c09d4d0fb32d2751887..11154a330f075dc04c0fec99299d6f5000e901be 100644 (file)
@@ -200,7 +200,8 @@ static int acpi_pss_perf_init(struct acpi_processor *pr,
                goto err_remove_sysfs_thermal;
        }
 
-       sysfs_remove_link(&pr->cdev->device.kobj, "device");
+       return 0;
+
  err_remove_sysfs_thermal:
        sysfs_remove_link(&device->dev.kobj, "thermal_cooling");
  err_thermal_unregister:
index 2804aed3f416aea878efde04937937e238ff4e5e..25425d3f257536b291f27aa975bb8f164c0c437c 100644 (file)
@@ -303,6 +303,10 @@ static int memory_subsys_offline(struct device *dev)
        if (mem->state == MEM_OFFLINE)
                return 0;
 
+       /* Can't offline block with non-present sections */
+       if (mem->section_count != sections_per_block)
+               return -EINVAL;
+
        return memory_block_change_state(mem, MEM_OFFLINE, MEM_ONLINE);
 }
 
index 167418e73445a4f69b372f9205f65ca43f525c9d..65f50eccd49b0aa4b6801912fd8d21a73f79a7b9 100644 (file)
@@ -390,6 +390,7 @@ static int pm_genpd_runtime_suspend(struct device *dev)
        struct generic_pm_domain *genpd;
        bool (*stop_ok)(struct device *__dev);
        struct gpd_timing_data *td = &dev_gpd_data(dev)->td;
+       bool runtime_pm = pm_runtime_enabled(dev);
        ktime_t time_start;
        s64 elapsed_ns;
        int ret;
@@ -400,12 +401,19 @@ static int pm_genpd_runtime_suspend(struct device *dev)
        if (IS_ERR(genpd))
                return -EINVAL;
 
+       /*
+        * A runtime PM centric subsystem/driver may re-use the runtime PM
+        * callbacks for other purposes than runtime PM. In those scenarios
+        * runtime PM is disabled. Under these circumstances, we shall skip
+        * validating/measuring the PM QoS latency.
+        */
        stop_ok = genpd->gov ? genpd->gov->stop_ok : NULL;
-       if (stop_ok && !stop_ok(dev))
+       if (runtime_pm && stop_ok && !stop_ok(dev))
                return -EBUSY;
 
        /* Measure suspend latency. */
-       time_start = ktime_get();
+       if (runtime_pm)
+               time_start = ktime_get();
 
        ret = genpd_save_dev(genpd, dev);
        if (ret)
@@ -418,13 +426,15 @@ static int pm_genpd_runtime_suspend(struct device *dev)
        }
 
        /* Update suspend latency value if the measured time exceeds it. */
-       elapsed_ns = ktime_to_ns(ktime_sub(ktime_get(), time_start));
-       if (elapsed_ns > td->suspend_latency_ns) {
-               td->suspend_latency_ns = elapsed_ns;
-               dev_dbg(dev, "suspend latency exceeded, %lld ns\n",
-                       elapsed_ns);
-               genpd->max_off_time_changed = true;
-               td->constraint_changed = true;
+       if (runtime_pm) {
+               elapsed_ns = ktime_to_ns(ktime_sub(ktime_get(), time_start));
+               if (elapsed_ns > td->suspend_latency_ns) {
+                       td->suspend_latency_ns = elapsed_ns;
+                       dev_dbg(dev, "suspend latency exceeded, %lld ns\n",
+                               elapsed_ns);
+                       genpd->max_off_time_changed = true;
+                       td->constraint_changed = true;
+               }
        }
 
        /*
@@ -453,6 +463,7 @@ static int pm_genpd_runtime_resume(struct device *dev)
 {
        struct generic_pm_domain *genpd;
        struct gpd_timing_data *td = &dev_gpd_data(dev)->td;
+       bool runtime_pm = pm_runtime_enabled(dev);
        ktime_t time_start;
        s64 elapsed_ns;
        int ret;
@@ -479,14 +490,14 @@ static int pm_genpd_runtime_resume(struct device *dev)
 
  out:
        /* Measure resume latency. */
-       if (timed)
+       if (timed && runtime_pm)
                time_start = ktime_get();
 
        genpd_start_dev(genpd, dev);
        genpd_restore_dev(genpd, dev);
 
        /* Update resume latency value if the measured time exceeds it. */
-       if (timed) {
+       if (timed && runtime_pm) {
                elapsed_ns = ktime_to_ns(ktime_sub(ktime_get(), time_start));
                if (elapsed_ns > td->resume_latency_ns) {
                        td->resume_latency_ns = elapsed_ns;
index 0c3940ec5e62c070b393a5f187ac22674e262c3b..09e3c0d87eccff2d526666b99d3036f3921662a8 100644 (file)
@@ -219,6 +219,9 @@ static void end_cmd(struct nullb_cmd *cmd)
 {
        struct request_queue *q = NULL;
 
+       if (cmd->rq)
+               q = cmd->rq->q;
+
        switch (queue_mode)  {
        case NULL_Q_MQ:
                blk_mq_end_request(cmd->rq, 0);
@@ -229,23 +232,19 @@ static void end_cmd(struct nullb_cmd *cmd)
                break;
        case NULL_Q_BIO:
                bio_endio(cmd->bio);
-               goto free_cmd;
+               break;
        }
 
-       if (cmd->rq)
-               q = cmd->rq->q;
+       free_cmd(cmd);
 
        /* Restart queue if needed, as we are freeing a tag */
-       if (q && !q->mq_ops && blk_queue_stopped(q)) {
+       if (queue_mode == NULL_Q_RQ && blk_queue_stopped(q)) {
                unsigned long flags;
 
                spin_lock_irqsave(q->queue_lock, flags);
-               if (blk_queue_stopped(q))
-                       blk_start_queue(q);
+               blk_start_queue_async(q);
                spin_unlock_irqrestore(q->queue_lock, flags);
        }
-free_cmd:
-       free_cmd(cmd);
 }
 
 static enum hrtimer_restart null_cmd_timer_expired(struct hrtimer *timer)
@@ -444,8 +443,9 @@ static void null_lnvm_end_io(struct request *rq, int error)
        blk_put_request(rq);
 }
 
-static int null_lnvm_submit_io(struct request_queue *q, struct nvm_rq *rqd)
+static int null_lnvm_submit_io(struct nvm_dev *dev, struct nvm_rq *rqd)
 {
+       struct request_queue *q = dev->q;
        struct request *rq;
        struct bio *bio = rqd->bio;
 
@@ -470,7 +470,7 @@ static int null_lnvm_submit_io(struct request_queue *q, struct nvm_rq *rqd)
        return 0;
 }
 
-static int null_lnvm_id(struct request_queue *q, struct nvm_id *id)
+static int null_lnvm_id(struct nvm_dev *dev, struct nvm_id *id)
 {
        sector_t size = gb * 1024 * 1024 * 1024ULL;
        sector_t blksize;
@@ -523,7 +523,7 @@ static int null_lnvm_id(struct request_queue *q, struct nvm_id *id)
        return 0;
 }
 
-static void *null_lnvm_create_dma_pool(struct request_queue *q, char *name)
+static void *null_lnvm_create_dma_pool(struct nvm_dev *dev, char *name)
 {
        mempool_t *virtmem_pool;
 
@@ -541,7 +541,7 @@ static void null_lnvm_destroy_dma_pool(void *pool)
        mempool_destroy(pool);
 }
 
-static void *null_lnvm_dev_dma_alloc(struct request_queue *q, void *pool,
+static void *null_lnvm_dev_dma_alloc(struct nvm_dev *dev, void *pool,
                                gfp_t mem_flags, dma_addr_t *dma_handler)
 {
        return mempool_alloc(pool, mem_flags);
@@ -765,7 +765,9 @@ out:
 
 static int __init null_init(void)
 {
+       int ret = 0;
        unsigned int i;
+       struct nullb *nullb;
 
        if (bs > PAGE_SIZE) {
                pr_warn("null_blk: invalid block size\n");
@@ -807,22 +809,29 @@ static int __init null_init(void)
                                                                0, 0, NULL);
                if (!ppa_cache) {
                        pr_err("null_blk: unable to create ppa cache\n");
-                       return -ENOMEM;
+                       ret = -ENOMEM;
+                       goto err_ppa;
                }
        }
 
        for (i = 0; i < nr_devices; i++) {
-               if (null_add_dev()) {
-                       unregister_blkdev(null_major, "nullb");
-                       goto err_ppa;
-               }
+               ret = null_add_dev();
+               if (ret)
+                       goto err_dev;
        }
 
        pr_info("null: module loaded\n");
        return 0;
-err_ppa:
+
+err_dev:
+       while (!list_empty(&nullb_list)) {
+               nullb = list_entry(nullb_list.next, struct nullb, list);
+               null_del_dev(nullb);
+       }
        kmem_cache_destroy(ppa_cache);
-       return -EINVAL;
+err_ppa:
+       unregister_blkdev(null_major, "nullb");
+       return ret;
 }
 
 static void __exit null_exit(void)
index f9099940c2720f95874e6621b4c7e5e1e798fe2c..41fb1a917b172dc9446495d84357060847c2b569 100644 (file)
@@ -950,6 +950,8 @@ static int xen_blkbk_parse_indirect(struct blkif_request *req,
                goto unmap;
 
        for (n = 0, i = 0; n < nseg; n++) {
+               uint8_t first_sect, last_sect;
+
                if ((n % SEGS_PER_INDIRECT_FRAME) == 0) {
                        /* Map indirect segments */
                        if (segments)
@@ -957,15 +959,18 @@ static int xen_blkbk_parse_indirect(struct blkif_request *req,
                        segments = kmap_atomic(pages[n/SEGS_PER_INDIRECT_FRAME]->page);
                }
                i = n % SEGS_PER_INDIRECT_FRAME;
+
                pending_req->segments[n]->gref = segments[i].gref;
-               seg[n].nsec = segments[i].last_sect -
-                       segments[i].first_sect + 1;
-               seg[n].offset = (segments[i].first_sect << 9);
-               if ((segments[i].last_sect >= (XEN_PAGE_SIZE >> 9)) ||
-                   (segments[i].last_sect < segments[i].first_sect)) {
+
+               first_sect = READ_ONCE(segments[i].first_sect);
+               last_sect = READ_ONCE(segments[i].last_sect);
+               if (last_sect >= (XEN_PAGE_SIZE >> 9) || last_sect < first_sect) {
                        rc = -EINVAL;
                        goto unmap;
                }
+
+               seg[n].nsec = last_sect - first_sect + 1;
+               seg[n].offset = first_sect << 9;
                preq->nr_sects += seg[n].nsec;
        }
 
index 68e87a037b992df8c64d6894719b5b390ef1d10a..c929ae22764c9dd4345195a1542df997c5a8e29b 100644 (file)
@@ -408,8 +408,8 @@ static inline void blkif_get_x86_32_req(struct blkif_request *dst,
                                        struct blkif_x86_32_request *src)
 {
        int i, n = BLKIF_MAX_SEGMENTS_PER_REQUEST, j;
-       dst->operation = src->operation;
-       switch (src->operation) {
+       dst->operation = READ_ONCE(src->operation);
+       switch (dst->operation) {
        case BLKIF_OP_READ:
        case BLKIF_OP_WRITE:
        case BLKIF_OP_WRITE_BARRIER:
@@ -456,8 +456,8 @@ static inline void blkif_get_x86_64_req(struct blkif_request *dst,
                                        struct blkif_x86_64_request *src)
 {
        int i, n = BLKIF_MAX_SEGMENTS_PER_REQUEST, j;
-       dst->operation = src->operation;
-       switch (src->operation) {
+       dst->operation = READ_ONCE(src->operation);
+       switch (dst->operation) {
        case BLKIF_OP_READ:
        case BLKIF_OP_WRITE:
        case BLKIF_OP_WRITE_BARRIER:
index 846bc29c157dcca1bde81f288a5d323476042295..25996e2561105ac615cf4cc99c468f7a8db0f3df 100644 (file)
@@ -342,13 +342,13 @@ static int sunxi_rsb_read(struct sunxi_rsb *rsb, u8 rtaddr, u8 addr,
 
        ret = _sunxi_rsb_run_xfer(rsb);
        if (ret)
-               goto out;
+               goto unlock;
 
        *buf = readl(rsb->regs + RSB_DATA);
 
+unlock:
        mutex_unlock(&rsb->lock);
 
-out:
        return ret;
 }
 
@@ -527,9 +527,9 @@ static int sunxi_rsb_init_device_mode(struct sunxi_rsb *rsb)
  */
 
 static const struct sunxi_rsb_addr_map sunxi_rsb_addr_maps[] = {
-       { 0x3e3, 0x2d }, /* Primary PMIC: AXP223, AXP809, AXP81X, ... */
+       { 0x3a3, 0x2d }, /* Primary PMIC: AXP223, AXP809, AXP81X, ... */
        { 0x745, 0x3a }, /* Secondary PMIC: AXP806, ... */
-       { 0xe89, 0x45 }, /* Peripheral IC: AC100, ... */
+       { 0xe89, 0x4e }, /* Peripheral IC: AC100, ... */
 };
 
 static u8 sunxi_rsb_get_rtaddr(u16 hwaddr)
index d1b1c95177bbeb577c88bf06c06121db76477f24..0a94d9661d9123551b5b84cd5764cb9b91a6c176 100644 (file)
@@ -335,22 +335,22 @@ static void __init vf610_clocks_init(struct device_node *ccm_node)
        clk[VF610_CLK_SAI0_SEL] = imx_clk_mux("sai0_sel", CCM_CSCMR1, 0, 2, sai_sels, 4);
        clk[VF610_CLK_SAI0_EN] = imx_clk_gate("sai0_en", "sai0_sel", CCM_CSCDR1, 16);
        clk[VF610_CLK_SAI0_DIV] = imx_clk_divider("sai0_div", "sai0_en", CCM_CSCDR1, 0, 4);
-       clk[VF610_CLK_SAI0] = imx_clk_gate2("sai0", "sai0_div", CCM_CCGR0, CCM_CCGRx_CGn(15));
+       clk[VF610_CLK_SAI0] = imx_clk_gate2("sai0", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(15));
 
        clk[VF610_CLK_SAI1_SEL] = imx_clk_mux("sai1_sel", CCM_CSCMR1, 2, 2, sai_sels, 4);
        clk[VF610_CLK_SAI1_EN] = imx_clk_gate("sai1_en", "sai1_sel", CCM_CSCDR1, 17);
        clk[VF610_CLK_SAI1_DIV] = imx_clk_divider("sai1_div", "sai1_en", CCM_CSCDR1, 4, 4);
-       clk[VF610_CLK_SAI1] = imx_clk_gate2("sai1", "sai1_div", CCM_CCGR1, CCM_CCGRx_CGn(0));
+       clk[VF610_CLK_SAI1] = imx_clk_gate2("sai1", "ipg_bus", CCM_CCGR1, CCM_CCGRx_CGn(0));
 
        clk[VF610_CLK_SAI2_SEL] = imx_clk_mux("sai2_sel", CCM_CSCMR1, 4, 2, sai_sels, 4);
        clk[VF610_CLK_SAI2_EN] = imx_clk_gate("sai2_en", "sai2_sel", CCM_CSCDR1, 18);
        clk[VF610_CLK_SAI2_DIV] = imx_clk_divider("sai2_div", "sai2_en", CCM_CSCDR1, 8, 4);
-       clk[VF610_CLK_SAI2] = imx_clk_gate2("sai2", "sai2_div", CCM_CCGR1, CCM_CCGRx_CGn(1));
+       clk[VF610_CLK_SAI2] = imx_clk_gate2("sai2", "ipg_bus", CCM_CCGR1, CCM_CCGRx_CGn(1));
 
        clk[VF610_CLK_SAI3_SEL] = imx_clk_mux("sai3_sel", CCM_CSCMR1, 6, 2, sai_sels, 4);
        clk[VF610_CLK_SAI3_EN] = imx_clk_gate("sai3_en", "sai3_sel", CCM_CSCDR1, 19);
        clk[VF610_CLK_SAI3_DIV] = imx_clk_divider("sai3_div", "sai3_en", CCM_CSCDR1, 12, 4);
-       clk[VF610_CLK_SAI3] = imx_clk_gate2("sai3", "sai3_div", CCM_CCGR1, CCM_CCGRx_CGn(2));
+       clk[VF610_CLK_SAI3] = imx_clk_gate2("sai3", "ipg_bus", CCM_CCGR1, CCM_CCGRx_CGn(2));
 
        clk[VF610_CLK_NFC_SEL] = imx_clk_mux("nfc_sel", CCM_CSCMR1, 12, 2, nfc_sels, 4);
        clk[VF610_CLK_NFC_EN] = imx_clk_gate("nfc_en", "nfc_sel", CCM_CSCDR2, 9);
index 1593ade2a8154da8840236bd9a0debb931ebfa5a..c4f7d7a9b68987e861bb52ea807f919ca785a1c9 100644 (file)
@@ -55,7 +55,7 @@ int __init clocksource_mmio_init(void __iomem *base, const char *name,
 {
        struct clocksource_mmio *cs;
 
-       if (bits > 32 || bits < 16)
+       if (bits > 64 || bits < 16)
                return -EINVAL;
 
        cs = kzalloc(sizeof(struct clocksource_mmio), GFP_KERNEL);
index d7373ca69c9947a83dd8a1d67b77c7fc9e77209e..25693b0453714ca8bb1e610fdda0786a1fc3798e 100644 (file)
@@ -179,26 +179,21 @@ static int cn_call_callback(struct sk_buff *skb)
  *
  * It checks skb, netlink header and msg sizes, and calls callback helper.
  */
-static void cn_rx_skb(struct sk_buff *__skb)
+static void cn_rx_skb(struct sk_buff *skb)
 {
        struct nlmsghdr *nlh;
-       struct sk_buff *skb;
        int len, err;
 
-       skb = skb_get(__skb);
-
        if (skb->len >= NLMSG_HDRLEN) {
                nlh = nlmsg_hdr(skb);
                len = nlmsg_len(nlh);
 
                if (len < (int)sizeof(struct cn_msg) ||
                    skb->len < nlh->nlmsg_len ||
-                   len > CONNECTOR_MAX_MSG_SIZE) {
-                       kfree_skb(skb);
+                   len > CONNECTOR_MAX_MSG_SIZE)
                        return;
-               }
 
-               err = cn_call_callback(skb);
+               err = cn_call_callback(skb_get(skb));
                if (err < 0)
                        kfree_skb(skb);
        }
index 235a1ba73d92d577bbf605f5dab9d737fe246797..b1f8a73e5a943e8fc692dfcba7f28d1e08dba4f2 100644 (file)
@@ -226,7 +226,7 @@ config ARM_TEGRA20_CPUFREQ
 
 config ARM_TEGRA124_CPUFREQ
        tristate "Tegra124 CPUFreq support"
-       depends on ARCH_TEGRA && CPUFREQ_DT
+       depends on ARCH_TEGRA && CPUFREQ_DT && REGULATOR
        default y
        help
          This adds the CPUFreq driver support for Tegra124 SOCs.
index 4d07cbd2b23cfb80ddc40fc0822ce37464991498..98fb8821382d8fc145c6bf9227b62236fdabedb1 100644 (file)
@@ -1123,7 +1123,7 @@ static int intel_pstate_set_policy(struct cpufreq_policy *policy)
                                   limits->max_sysfs_pct);
        limits->max_perf_pct = max(limits->min_policy_pct,
                                   limits->max_perf_pct);
-       limits->max_perf = round_up(limits->max_perf, 8);
+       limits->max_perf = round_up(limits->max_perf, FRAC_BITS);
 
        /* Make sure min_perf_pct <= max_perf_pct */
        limits->min_perf_pct = min(limits->max_perf_pct, limits->min_perf_pct);
index 733aa5153e7451f645a65e3452ed44d6d488054a..68ef8fd9482fd2532762789973b8d4dfa98cfdd5 100644 (file)
@@ -648,7 +648,7 @@ late_initcall(s3c_cpufreq_initcall);
  *
  * Register the given set of PLLs with the system.
  */
-int __init s3c_plltab_register(struct cpufreq_frequency_table *plls,
+int s3c_plltab_register(struct cpufreq_frequency_table *plls,
                               unsigned int plls_no)
 {
        struct cpufreq_frequency_table *vals;
index 2c3b16fd3a01fc1c521f8201bd698dab2d6d1215..de5e89b2eaaa3db13413eec5762620c21623738c 100644 (file)
@@ -31,7 +31,7 @@ static struct scpi_ops *scpi_ops;
 
 static struct scpi_dvfs_info *scpi_get_dvfs_info(struct device *cpu_dev)
 {
-       u8 domain = topology_physical_package_id(cpu_dev->id);
+       int domain = topology_physical_package_id(cpu_dev->id);
 
        if (domain < 0)
                return ERR_PTR(-EINVAL);
index 7f039de143f0d07ba3e59cfcf6469082fdeef831..370c661c7d7b25c237a3376dd18da79fbd44eadd 100644 (file)
 #define                AT_XDMAC_CC_WRIP        (0x1 << 23)     /* Write in Progress (read only) */
 #define                        AT_XDMAC_CC_WRIP_DONE           (0x0 << 23)
 #define                        AT_XDMAC_CC_WRIP_IN_PROGRESS    (0x1 << 23)
-#define                AT_XDMAC_CC_PERID(i)    (0x7f & (h) << 24)      /* Channel Peripheral Identifier */
+#define                AT_XDMAC_CC_PERID(i)    (0x7f & (i) << 24)      /* Channel Peripheral Identifier */
 #define AT_XDMAC_CDS_MSP       0x2C    /* Channel Data Stride Memory Set Pattern */
 #define AT_XDMAC_CSUS          0x30    /* Channel Source Microblock Stride */
 #define AT_XDMAC_CDUS          0x34    /* Channel Destination Microblock Stride */
@@ -965,7 +965,9 @@ at_xdmac_prep_interleaved(struct dma_chan *chan,
                                                        NULL,
                                                        src_addr, dst_addr,
                                                        xt, xt->sgl);
-               for (i = 0; i < xt->numf; i++)
+
+               /* Length of the block is (BLEN+1) microblocks. */
+               for (i = 0; i < xt->numf - 1; i++)
                        at_xdmac_increment_block_count(chan, first);
 
                dev_dbg(chan2dev(chan), "%s: add desc 0x%p to descs_list 0x%p\n",
@@ -1086,6 +1088,7 @@ at_xdmac_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src,
                /* Check remaining length and change data width if needed. */
                dwidth = at_xdmac_align_width(chan,
                                              src_addr | dst_addr | xfer_size);
+               chan_cc &= ~AT_XDMAC_CC_DWIDTH_MASK;
                chan_cc |= AT_XDMAC_CC_DWIDTH(dwidth);
 
                ublen = xfer_size >> dwidth;
@@ -1333,7 +1336,7 @@ at_xdmac_prep_dma_memset_sg(struct dma_chan *chan, struct scatterlist *sgl,
                 * since we don't care about the stride anymore.
                 */
                if ((i == (sg_len - 1)) &&
-                   sg_dma_len(ppsg) == sg_dma_len(psg)) {
+                   sg_dma_len(psg) == sg_dma_len(sg)) {
                        dev_dbg(chan2dev(chan),
                                "%s: desc 0x%p can be merged with desc 0x%p\n",
                                __func__, desc, pdesc);
index c92d6a70ccf303c69cfdb127210a09a1262122bc..996c4b00d323ed5c2dd6455f80eb36ed8e9a8b23 100644 (file)
@@ -31,6 +31,7 @@
  */
 #include <linux/dmaengine.h>
 #include <linux/dma-mapping.h>
+#include <linux/dmapool.h>
 #include <linux/err.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
@@ -62,6 +63,11 @@ struct bcm2835_dma_cb {
        uint32_t pad[2];
 };
 
+struct bcm2835_cb_entry {
+       struct bcm2835_dma_cb *cb;
+       dma_addr_t paddr;
+};
+
 struct bcm2835_chan {
        struct virt_dma_chan vc;
        struct list_head node;
@@ -72,18 +78,18 @@ struct bcm2835_chan {
 
        int ch;
        struct bcm2835_desc *desc;
+       struct dma_pool *cb_pool;
 
        void __iomem *chan_base;
        int irq_number;
 };
 
 struct bcm2835_desc {
+       struct bcm2835_chan *c;
        struct virt_dma_desc vd;
        enum dma_transfer_direction dir;
 
-       unsigned int control_block_size;
-       struct bcm2835_dma_cb *control_block_base;
-       dma_addr_t control_block_base_phys;
+       struct bcm2835_cb_entry *cb_list;
 
        unsigned int frames;
        size_t size;
@@ -143,10 +149,13 @@ static inline struct bcm2835_desc *to_bcm2835_dma_desc(
 static void bcm2835_dma_desc_free(struct virt_dma_desc *vd)
 {
        struct bcm2835_desc *desc = container_of(vd, struct bcm2835_desc, vd);
-       dma_free_coherent(desc->vd.tx.chan->device->dev,
-                       desc->control_block_size,
-                       desc->control_block_base,
-                       desc->control_block_base_phys);
+       int i;
+
+       for (i = 0; i < desc->frames; i++)
+               dma_pool_free(desc->c->cb_pool, desc->cb_list[i].cb,
+                             desc->cb_list[i].paddr);
+
+       kfree(desc->cb_list);
        kfree(desc);
 }
 
@@ -199,7 +208,7 @@ static void bcm2835_dma_start_desc(struct bcm2835_chan *c)
 
        c->desc = d = to_bcm2835_dma_desc(&vd->tx);
 
-       writel(d->control_block_base_phys, c->chan_base + BCM2835_DMA_ADDR);
+       writel(d->cb_list[0].paddr, c->chan_base + BCM2835_DMA_ADDR);
        writel(BCM2835_DMA_ACTIVE, c->chan_base + BCM2835_DMA_CS);
 }
 
@@ -232,9 +241,16 @@ static irqreturn_t bcm2835_dma_callback(int irq, void *data)
 static int bcm2835_dma_alloc_chan_resources(struct dma_chan *chan)
 {
        struct bcm2835_chan *c = to_bcm2835_dma_chan(chan);
+       struct device *dev = c->vc.chan.device->dev;
+
+       dev_dbg(dev, "Allocating DMA channel %d\n", c->ch);
 
-       dev_dbg(c->vc.chan.device->dev,
-                       "Allocating DMA channel %d\n", c->ch);
+       c->cb_pool = dma_pool_create(dev_name(dev), dev,
+                                    sizeof(struct bcm2835_dma_cb), 0, 0);
+       if (!c->cb_pool) {
+               dev_err(dev, "unable to allocate descriptor pool\n");
+               return -ENOMEM;
+       }
 
        return request_irq(c->irq_number,
                        bcm2835_dma_callback, 0, "DMA IRQ", c);
@@ -246,6 +262,7 @@ static void bcm2835_dma_free_chan_resources(struct dma_chan *chan)
 
        vchan_free_chan_resources(&c->vc);
        free_irq(c->irq_number, c);
+       dma_pool_destroy(c->cb_pool);
 
        dev_dbg(c->vc.chan.device->dev, "Freeing DMA channel %u\n", c->ch);
 }
@@ -261,8 +278,7 @@ static size_t bcm2835_dma_desc_size_pos(struct bcm2835_desc *d, dma_addr_t addr)
        size_t size;
 
        for (size = i = 0; i < d->frames; i++) {
-               struct bcm2835_dma_cb *control_block =
-                       &d->control_block_base[i];
+               struct bcm2835_dma_cb *control_block = d->cb_list[i].cb;
                size_t this_size = control_block->length;
                dma_addr_t dma;
 
@@ -343,6 +359,7 @@ static struct dma_async_tx_descriptor *bcm2835_dma_prep_dma_cyclic(
        dma_addr_t dev_addr;
        unsigned int es, sync_type;
        unsigned int frame;
+       int i;
 
        /* Grab configuration */
        if (!is_slave_direction(direction)) {
@@ -374,27 +391,31 @@ static struct dma_async_tx_descriptor *bcm2835_dma_prep_dma_cyclic(
        if (!d)
                return NULL;
 
+       d->c = c;
        d->dir = direction;
        d->frames = buf_len / period_len;
 
-       /* Allocate memory for control blocks */
-       d->control_block_size = d->frames * sizeof(struct bcm2835_dma_cb);
-       d->control_block_base = dma_zalloc_coherent(chan->device->dev,
-                       d->control_block_size, &d->control_block_base_phys,
-                       GFP_NOWAIT);
-
-       if (!d->control_block_base) {
+       d->cb_list = kcalloc(d->frames, sizeof(*d->cb_list), GFP_KERNEL);
+       if (!d->cb_list) {
                kfree(d);
                return NULL;
        }
+       /* Allocate memory for control blocks */
+       for (i = 0; i < d->frames; i++) {
+               struct bcm2835_cb_entry *cb_entry = &d->cb_list[i];
+
+               cb_entry->cb = dma_pool_zalloc(c->cb_pool, GFP_ATOMIC,
+                                              &cb_entry->paddr);
+               if (!cb_entry->cb)
+                       goto error_cb;
+       }
 
        /*
         * Iterate over all frames, create a control block
         * for each frame and link them together.
         */
        for (frame = 0; frame < d->frames; frame++) {
-               struct bcm2835_dma_cb *control_block =
-                       &d->control_block_base[frame];
+               struct bcm2835_dma_cb *control_block = d->cb_list[frame].cb;
 
                /* Setup adresses */
                if (d->dir == DMA_DEV_TO_MEM) {
@@ -428,12 +449,21 @@ static struct dma_async_tx_descriptor *bcm2835_dma_prep_dma_cyclic(
                 * This DMA engine driver currently only supports cyclic DMA.
                 * Therefore, wrap around at number of frames.
                 */
-               control_block->next = d->control_block_base_phys +
-                       sizeof(struct bcm2835_dma_cb)
-                       * ((frame + 1) % d->frames);
+               control_block->next = d->cb_list[((frame + 1) % d->frames)].paddr;
        }
 
        return vchan_tx_prep(&c->vc, &d->vd, flags);
+error_cb:
+       i--;
+       for (; i >= 0; i--) {
+               struct bcm2835_cb_entry *cb_entry = &d->cb_list[i];
+
+               dma_pool_free(c->cb_pool, cb_entry->cb, cb_entry->paddr);
+       }
+
+       kfree(d->cb_list);
+       kfree(d);
+       return NULL;
 }
 
 static int bcm2835_dma_slave_config(struct dma_chan *chan,
index 0675e268d5777967489bf25b30f5d217290fa441..16fe773fb846b5e9c9cb70b625715a5f5f888237 100644 (file)
@@ -1752,16 +1752,14 @@ static enum dma_status edma_tx_status(struct dma_chan *chan,
        return ret;
 }
 
-static bool edma_is_memcpy_channel(int ch_num, u16 *memcpy_channels)
+static bool edma_is_memcpy_channel(int ch_num, s32 *memcpy_channels)
 {
-       s16 *memcpy_ch = memcpy_channels;
-
        if (!memcpy_channels)
                return false;
-       while (*memcpy_ch != -1) {
-               if (*memcpy_ch == ch_num)
+       while (*memcpy_channels != -1) {
+               if (*memcpy_channels == ch_num)
                        return true;
-               memcpy_ch++;
+               memcpy_channels++;
        }
        return false;
 }
@@ -1775,7 +1773,7 @@ static void edma_dma_init(struct edma_cc *ecc, bool legacy_mode)
 {
        struct dma_device *s_ddev = &ecc->dma_slave;
        struct dma_device *m_ddev = NULL;
-       s16 *memcpy_channels = ecc->info->memcpy_channels;
+       s32 *memcpy_channels = ecc->info->memcpy_channels;
        int i, j;
 
        dma_cap_zero(s_ddev->cap_mask);
@@ -1996,16 +1994,16 @@ static struct edma_soc_info *edma_setup_info_from_dt(struct device *dev,
        prop = of_find_property(dev->of_node, "ti,edma-memcpy-channels", &sz);
        if (prop) {
                const char pname[] = "ti,edma-memcpy-channels";
-               size_t nelm = sz / sizeof(s16);
-               s16 *memcpy_ch;
+               size_t nelm = sz / sizeof(s32);
+               s32 *memcpy_ch;
 
-               memcpy_ch = devm_kcalloc(dev, nelm + 1, sizeof(s16),
+               memcpy_ch = devm_kcalloc(dev, nelm + 1, sizeof(s32),
                                         GFP_KERNEL);
                if (!memcpy_ch)
                        return ERR_PTR(-ENOMEM);
 
-               ret = of_property_read_u16_array(dev->of_node, pname,
-                                                (u16 *)memcpy_ch, nelm);
+               ret = of_property_read_u32_array(dev->of_node, pname,
+                                                (u32 *)memcpy_ch, nelm);
                if (ret)
                        return ERR_PTR(ret);
 
@@ -2017,31 +2015,50 @@ static struct edma_soc_info *edma_setup_info_from_dt(struct device *dev,
                                &sz);
        if (prop) {
                const char pname[] = "ti,edma-reserved-slot-ranges";
+               u32 (*tmp)[2];
                s16 (*rsv_slots)[2];
-               size_t nelm = sz / sizeof(*rsv_slots);
+               size_t nelm = sz / sizeof(*tmp);
                struct edma_rsv_info *rsv_info;
+               int i;
 
                if (!nelm)
                        return info;
 
+               tmp = kcalloc(nelm, sizeof(*tmp), GFP_KERNEL);
+               if (!tmp)
+                       return ERR_PTR(-ENOMEM);
+
                rsv_info = devm_kzalloc(dev, sizeof(*rsv_info), GFP_KERNEL);
-               if (!rsv_info)
+               if (!rsv_info) {
+                       kfree(tmp);
                        return ERR_PTR(-ENOMEM);
+               }
 
                rsv_slots = devm_kcalloc(dev, nelm + 1, sizeof(*rsv_slots),
                                         GFP_KERNEL);
-               if (!rsv_slots)
+               if (!rsv_slots) {
+                       kfree(tmp);
                        return ERR_PTR(-ENOMEM);
+               }
 
-               ret = of_property_read_u16_array(dev->of_node, pname,
-                                                (u16 *)rsv_slots, nelm * 2);
-               if (ret)
+               ret = of_property_read_u32_array(dev->of_node, pname,
+                                                (u32 *)tmp, nelm * 2);
+               if (ret) {
+                       kfree(tmp);
                        return ERR_PTR(ret);
+               }
 
+               for (i = 0; i < nelm; i++) {
+                       rsv_slots[i][0] = tmp[i][0];
+                       rsv_slots[i][1] = tmp[i][1];
+               }
                rsv_slots[nelm][0] = -1;
                rsv_slots[nelm][1] = -1;
+
                info->rsv = rsv_info;
                info->rsv->rsv_slots = (const s16 (*)[2])rsv_slots;
+
+               kfree(tmp);
        }
 
        return info;
index 9dfa2b0fa5daf0e395b69fce370c6ba5889d3715..9cb93c5b655d80f411079aff95e02f612b7f3ec0 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/dmapool.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
+#include <linux/irq.h>
 #include <linux/module.h>
 #include <linux/of_device.h>
 
@@ -1610,6 +1611,7 @@ static int xgene_dma_request_irqs(struct xgene_dma *pdma)
        /* Register DMA channel rx irq */
        for (i = 0; i < XGENE_DMA_MAX_CHANNEL; i++) {
                chan = &pdma->chan[i];
+               irq_set_status_flags(chan->rx_irq, IRQ_DISABLE_UNLAZY);
                ret = devm_request_irq(chan->dev, chan->rx_irq,
                                       xgene_dma_chan_ring_isr,
                                       0, chan->name, chan);
@@ -1620,6 +1622,7 @@ static int xgene_dma_request_irqs(struct xgene_dma *pdma)
 
                        for (j = 0; j < i; j++) {
                                chan = &pdma->chan[i];
+                               irq_clear_status_flags(chan->rx_irq, IRQ_DISABLE_UNLAZY);
                                devm_free_irq(chan->dev, chan->rx_irq, chan);
                        }
 
@@ -1640,6 +1643,7 @@ static void xgene_dma_free_irqs(struct xgene_dma *pdma)
 
        for (i = 0; i < XGENE_DMA_MAX_CHANNEL; i++) {
                chan = &pdma->chan[i];
+               irq_clear_status_flags(chan->rx_irq, IRQ_DISABLE_UNLAZY);
                devm_free_irq(chan->dev, chan->rx_irq, chan);
        }
 }
index ac1ce4a73edfc6160924f3ebcb1b0ddb2baf3792..0e08e665f715fb1de98b3118553f858c5b4c2c64 100644 (file)
@@ -521,6 +521,7 @@ static int __init dmi_present(const u8 *buf)
                        dmi_ver = smbios_ver;
                else
                        dmi_ver = (buf[14] & 0xF0) << 4 | (buf[14] & 0x0F);
+               dmi_ver <<= 8;
                dmi_num = get_unaligned_le16(buf + 12);
                dmi_len = get_unaligned_le16(buf + 6);
                dmi_base = get_unaligned_le32(buf + 8);
@@ -528,15 +529,14 @@ static int __init dmi_present(const u8 *buf)
                if (dmi_walk_early(dmi_decode) == 0) {
                        if (smbios_ver) {
                                pr_info("SMBIOS %d.%d present.\n",
-                                      dmi_ver >> 8, dmi_ver & 0xFF);
+                                       dmi_ver >> 16, (dmi_ver >> 8) & 0xFF);
                        } else {
                                smbios_entry_point_size = 15;
                                memcpy(smbios_entry_point, buf,
                                       smbios_entry_point_size);
                                pr_info("Legacy DMI %d.%d present.\n",
-                                      dmi_ver >> 8, dmi_ver & 0xFF);
+                                       dmi_ver >> 16, (dmi_ver >> 8) & 0xFF);
                        }
-                       dmi_ver <<= 8;
                        dmi_format_ids(dmi_ids_string, sizeof(dmi_ids_string));
                        printk(KERN_DEBUG "DMI: %s\n", dmi_ids_string);
                        return 0;
index a24f5cb877e0a2b32fcfccc14b80e01f2028a08d..953dc9195937d39bb1def7c7bfaa3f905f8d4032 100644 (file)
@@ -122,12 +122,10 @@ int fpga_mgr_firmware_load(struct fpga_manager *mgr, u32 flags,
        }
 
        ret = fpga_mgr_buf_load(mgr, flags, fw->data, fw->size);
-       if (ret)
-               return ret;
 
        release_firmware(fw);
 
-       return 0;
+       return ret;
 }
 EXPORT_SYMBOL_GPL(fpga_mgr_firmware_load);
 
@@ -256,7 +254,6 @@ int fpga_mgr_register(struct device *dev, const char *name,
                      void *priv)
 {
        struct fpga_manager *mgr;
-       const char *dt_label;
        int id, ret;
 
        if (!mops || !mops->write_init || !mops->write ||
@@ -300,11 +297,9 @@ int fpga_mgr_register(struct device *dev, const char *name,
        mgr->dev.id = id;
        dev_set_drvdata(dev, mgr);
 
-       dt_label = of_get_property(mgr->dev.of_node, "label", NULL);
-       if (dt_label)
-               ret = dev_set_name(&mgr->dev, "%s", dt_label);
-       else
-               ret = dev_set_name(&mgr->dev, "fpga%d", id);
+       ret = dev_set_name(&mgr->dev, "fpga%d", id);
+       if (ret)
+               goto error_device;
 
        ret = device_add(&mgr->dev);
        if (ret)
index e5827a56ff3b5eda451202849c41b2d8b0e54f31..5eaea8b812cf39515c3e7132d90d4f3d7e0fba17 100644 (file)
@@ -113,7 +113,7 @@ static int ar934x_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
                __raw_writel(BIT(offset), ctrl->base + AR71XX_GPIO_REG_CLEAR);
 
        __raw_writel(
-               __raw_readl(ctrl->base + AR71XX_GPIO_REG_OE) & BIT(offset),
+               __raw_readl(ctrl->base + AR71XX_GPIO_REG_OE) & ~BIT(offset),
                ctrl->base + AR71XX_GPIO_REG_OE);
 
        spin_unlock_irqrestore(&ctrl->lock, flags);
index bd5193c67a9c272cb0bebf779ce3277d22aac479..88ae70ddb1274b11f31bad5dcb344d3a57f9c6e3 100644 (file)
@@ -141,9 +141,9 @@ static int bgpio_get_set(struct gpio_chip *gc, unsigned int gpio)
        unsigned long pinmask = bgc->pin2mask(bgc, gpio);
 
        if (bgc->dir & pinmask)
-               return bgc->read_reg(bgc->reg_set) & pinmask;
+               return !!(bgc->read_reg(bgc->reg_set) & pinmask);
        else
-               return bgc->read_reg(bgc->reg_dat) & pinmask;
+               return !!(bgc->read_reg(bgc->reg_dat) & pinmask);
 }
 
 static int bgpio_get(struct gpio_chip *gc, unsigned int gpio)
index 2a91f3287e3b7e52f2f6e16d108af07d4343be0b..4e4c3083ae567f02db4ff15444ec173ac53ebe0c 100644 (file)
@@ -1279,7 +1279,13 @@ static int _gpiod_get_raw_value(const struct gpio_desc *desc)
        chip = desc->chip;
        offset = gpio_chip_hwgpio(desc);
        value = chip->get ? chip->get(chip, offset) : -EIO;
-       value = value < 0 ? value : !!value;
+       /*
+        * FIXME: fix all drivers to clamp to [0,1] or return negative,
+        * then change this to:
+        * value = value < 0 ? value : !!value;
+        * so we can properly propagate error codes.
+        */
+       value = !!value;
        trace_gpio_value(desc_to_gpio(desc), 1, value);
        return value;
 }
index 5a5f04d0902d662548ebae9f82525e1363e8457c..048cfe073dae6a1e89112b219c6a130b3d513be9 100644 (file)
@@ -1264,7 +1264,8 @@ struct amdgpu_cs_parser {
        struct ww_acquire_ctx   ticket;
 
        /* user fence */
-       struct amdgpu_user_fence uf;
+       struct amdgpu_user_fence        uf;
+       struct amdgpu_bo_list_entry     uf_entry;
 };
 
 struct amdgpu_job {
index 4f352ec9dec4e2fb7c3bb5bd062e674291fc8d5a..25a3e2485cc2e9572943638d1975f678fbc26e38 100644 (file)
@@ -127,6 +127,37 @@ int amdgpu_cs_get_ring(struct amdgpu_device *adev, u32 ip_type,
        return 0;
 }
 
+static int amdgpu_cs_user_fence_chunk(struct amdgpu_cs_parser *p,
+                                     struct drm_amdgpu_cs_chunk_fence *fence_data)
+{
+       struct drm_gem_object *gobj;
+       uint32_t handle;
+
+       handle = fence_data->handle;
+       gobj = drm_gem_object_lookup(p->adev->ddev, p->filp,
+                                    fence_data->handle);
+       if (gobj == NULL)
+               return -EINVAL;
+
+       p->uf.bo = amdgpu_bo_ref(gem_to_amdgpu_bo(gobj));
+       p->uf.offset = fence_data->offset;
+
+       if (amdgpu_ttm_tt_has_userptr(p->uf.bo->tbo.ttm)) {
+               drm_gem_object_unreference_unlocked(gobj);
+               return -EINVAL;
+       }
+
+       p->uf_entry.robj = amdgpu_bo_ref(p->uf.bo);
+       p->uf_entry.prefered_domains = AMDGPU_GEM_DOMAIN_GTT;
+       p->uf_entry.allowed_domains = AMDGPU_GEM_DOMAIN_GTT;
+       p->uf_entry.priority = 0;
+       p->uf_entry.tv.bo = &p->uf_entry.robj->tbo;
+       p->uf_entry.tv.shared = true;
+
+       drm_gem_object_unreference_unlocked(gobj);
+       return 0;
+}
+
 int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data)
 {
        union drm_amdgpu_cs *cs = data;
@@ -207,28 +238,15 @@ int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data)
 
                case AMDGPU_CHUNK_ID_FENCE:
                        size = sizeof(struct drm_amdgpu_cs_chunk_fence);
-                       if (p->chunks[i].length_dw * sizeof(uint32_t) >= size) {
-                               uint32_t handle;
-                               struct drm_gem_object *gobj;
-                               struct drm_amdgpu_cs_chunk_fence *fence_data;
-
-                               fence_data = (void *)p->chunks[i].kdata;
-                               handle = fence_data->handle;
-                               gobj = drm_gem_object_lookup(p->adev->ddev,
-                                                            p->filp, handle);
-                               if (gobj == NULL) {
-                                       ret = -EINVAL;
-                                       goto free_partial_kdata;
-                               }
-
-                               p->uf.bo = gem_to_amdgpu_bo(gobj);
-                               amdgpu_bo_ref(p->uf.bo);
-                               drm_gem_object_unreference_unlocked(gobj);
-                               p->uf.offset = fence_data->offset;
-                       } else {
+                       if (p->chunks[i].length_dw * sizeof(uint32_t) < size) {
                                ret = -EINVAL;
                                goto free_partial_kdata;
                        }
+
+                       ret = amdgpu_cs_user_fence_chunk(p, (void *)p->chunks[i].kdata);
+                       if (ret)
+                               goto free_partial_kdata;
+
                        break;
 
                case AMDGPU_CHUNK_ID_DEPENDENCIES:
@@ -391,6 +409,9 @@ static int amdgpu_cs_parser_relocs(struct amdgpu_cs_parser *p)
        p->vm_bos = amdgpu_vm_get_bos(p->adev, &fpriv->vm,
                                      &p->validated);
 
+       if (p->uf.bo)
+               list_add(&p->uf_entry.tv.head, &p->validated);
+
        if (need_mmap_lock)
                down_read(&current->mm->mmap_sem);
 
@@ -488,8 +509,8 @@ static void amdgpu_cs_parser_fini(struct amdgpu_cs_parser *parser, int error, bo
                for (i = 0; i < parser->num_ibs; i++)
                        amdgpu_ib_free(parser->adev, &parser->ibs[i]);
        kfree(parser->ibs);
-       if (parser->uf.bo)
-               amdgpu_bo_unref(&parser->uf.bo);
+       amdgpu_bo_unref(&parser->uf.bo);
+       amdgpu_bo_unref(&parser->uf_entry.robj);
 }
 
 static int amdgpu_bo_vm_update_pte(struct amdgpu_cs_parser *p,
index f6ea4b43a60c59b144bc5ff9916d96af38a59b24..9c253c535d26053ae80244a68617675c9b19fc3c 100644 (file)
@@ -477,6 +477,14 @@ static void amdgpu_gem_va_update_vm(struct amdgpu_device *adev,
                if (domain == AMDGPU_GEM_DOMAIN_CPU)
                        goto error_unreserve;
        }
+       list_for_each_entry(entry, &duplicates, head) {
+               domain = amdgpu_mem_type_to_domain(entry->bo->mem.mem_type);
+               /* if anything is swapped out don't swap it in here,
+                  just abort and wait for the next CS */
+               if (domain == AMDGPU_GEM_DOMAIN_CPU)
+                       goto error_unreserve;
+       }
+
        r = amdgpu_vm_update_page_directory(adev, bo_va->vm);
        if (r)
                goto error_unreserve;
index a18164f2f6d28290c09462dd7a755168873a42d3..f8b5fcfa91a27521d40e52b818b15dc3c6a6bbaf 100644 (file)
@@ -229,7 +229,8 @@ static int drm_helper_probe_single_connector_modes_merge_bits(struct drm_connect
                mode_flags |= DRM_MODE_FLAG_3D_MASK;
 
        list_for_each_entry(mode, &connector->modes, head) {
-               mode->status = drm_mode_validate_basic(mode);
+               if (mode->status == MODE_OK)
+                       mode->status = drm_mode_validate_basic(mode);
 
                if (mode->status == MODE_OK)
                        mode->status = drm_mode_validate_size(mode, maxX, maxY);
index b3ba27fd9a6bc880d7e061039e61ca42babc148f..e69357172ffb56d2e5f5e86ff551b599196079ba 100644 (file)
@@ -55,6 +55,9 @@ static int exynos_crtc_atomic_check(struct drm_crtc *crtc,
 {
        struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
 
+       if (!state->enable)
+               return 0;
+
        if (exynos_crtc->ops->atomic_check)
                return exynos_crtc->ops->atomic_check(exynos_crtc, state);
 
index a01e51581c4c466a000e2aa6b22f42e97ec31b85..f4af19a0d5696324c307617adfb0c86a3fdfed38 100644 (file)
@@ -2193,8 +2193,17 @@ struct drm_i915_gem_request {
        struct drm_i915_private *i915;
        struct intel_engine_cs *ring;
 
-       /** GEM sequence number associated with this request. */
-       uint32_t seqno;
+        /** GEM sequence number associated with the previous request,
+         * when the HWS breadcrumb is equal to this the GPU is processing
+         * this request.
+         */
+       u32 previous_seqno;
+
+        /** GEM sequence number associated with this request,
+         * when the HWS breadcrumb is equal or greater than this the GPU
+         * has finished processing this request.
+         */
+       u32 seqno;
 
        /** Position in the ringbuffer of the start of the request */
        u32 head;
@@ -2839,6 +2848,7 @@ i915_gem_object_ggtt_pin(struct drm_i915_gem_object *obj,
 
 int i915_vma_bind(struct i915_vma *vma, enum i915_cache_level cache_level,
                  u32 flags);
+void __i915_vma_set_map_and_fenceable(struct i915_vma *vma);
 int __must_check i915_vma_unbind(struct i915_vma *vma);
 /*
  * BEWARE: Do not use the function below unless you can _absolutely_
@@ -2910,15 +2920,17 @@ i915_seqno_passed(uint32_t seq1, uint32_t seq2)
        return (int32_t)(seq1 - seq2) >= 0;
 }
 
+static inline bool i915_gem_request_started(struct drm_i915_gem_request *req,
+                                          bool lazy_coherency)
+{
+       u32 seqno = req->ring->get_seqno(req->ring, lazy_coherency);
+       return i915_seqno_passed(seqno, req->previous_seqno);
+}
+
 static inline bool i915_gem_request_completed(struct drm_i915_gem_request *req,
                                              bool lazy_coherency)
 {
-       u32 seqno;
-
-       BUG_ON(req == NULL);
-
-       seqno = req->ring->get_seqno(req->ring, lazy_coherency);
-
+       u32 seqno = req->ring->get_seqno(req->ring, lazy_coherency);
        return i915_seqno_passed(seqno, req->seqno);
 }
 
index 32e6aade62238be511237c9ffad1933e18e561cb..f56af0aaafde511c1add59ce5f89fe2fa9be5c42 100644 (file)
@@ -1146,23 +1146,74 @@ static bool missed_irq(struct drm_i915_private *dev_priv,
        return test_bit(ring->id, &dev_priv->gpu_error.missed_irq_rings);
 }
 
-static int __i915_spin_request(struct drm_i915_gem_request *req)
+static unsigned long local_clock_us(unsigned *cpu)
+{
+       unsigned long t;
+
+       /* Cheaply and approximately convert from nanoseconds to microseconds.
+        * The result and subsequent calculations are also defined in the same
+        * approximate microseconds units. The principal source of timing
+        * error here is from the simple truncation.
+        *
+        * Note that local_clock() is only defined wrt to the current CPU;
+        * the comparisons are no longer valid if we switch CPUs. Instead of
+        * blocking preemption for the entire busywait, we can detect the CPU
+        * switch and use that as indicator of system load and a reason to
+        * stop busywaiting, see busywait_stop().
+        */
+       *cpu = get_cpu();
+       t = local_clock() >> 10;
+       put_cpu();
+
+       return t;
+}
+
+static bool busywait_stop(unsigned long timeout, unsigned cpu)
+{
+       unsigned this_cpu;
+
+       if (time_after(local_clock_us(&this_cpu), timeout))
+               return true;
+
+       return this_cpu != cpu;
+}
+
+static int __i915_spin_request(struct drm_i915_gem_request *req, int state)
 {
        unsigned long timeout;
+       unsigned cpu;
+
+       /* When waiting for high frequency requests, e.g. during synchronous
+        * rendering split between the CPU and GPU, the finite amount of time
+        * required to set up the irq and wait upon it limits the response
+        * rate. By busywaiting on the request completion for a short while we
+        * can service the high frequency waits as quick as possible. However,
+        * if it is a slow request, we want to sleep as quickly as possible.
+        * The tradeoff between waiting and sleeping is roughly the time it
+        * takes to sleep on a request, on the order of a microsecond.
+        */
 
-       if (i915_gem_request_get_ring(req)->irq_refcount)
+       if (req->ring->irq_refcount)
                return -EBUSY;
 
-       timeout = jiffies + 1;
+       /* Only spin if we know the GPU is processing this request */
+       if (!i915_gem_request_started(req, true))
+               return -EAGAIN;
+
+       timeout = local_clock_us(&cpu) + 5;
        while (!need_resched()) {
                if (i915_gem_request_completed(req, true))
                        return 0;
 
-               if (time_after_eq(jiffies, timeout))
+               if (signal_pending_state(state, current))
+                       break;
+
+               if (busywait_stop(timeout, cpu))
                        break;
 
                cpu_relax_lowlatency();
        }
+
        if (i915_gem_request_completed(req, false))
                return 0;
 
@@ -1197,6 +1248,7 @@ int __i915_wait_request(struct drm_i915_gem_request *req,
        struct drm_i915_private *dev_priv = dev->dev_private;
        const bool irq_test_in_progress =
                ACCESS_ONCE(dev_priv->gpu_error.test_irq_rings) & intel_ring_flag(ring);
+       int state = interruptible ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE;
        DEFINE_WAIT(wait);
        unsigned long timeout_expire;
        s64 before, now;
@@ -1229,7 +1281,7 @@ int __i915_wait_request(struct drm_i915_gem_request *req,
        before = ktime_get_raw_ns();
 
        /* Optimistic spin for the next jiffie before touching IRQs */
-       ret = __i915_spin_request(req);
+       ret = __i915_spin_request(req, state);
        if (ret == 0)
                goto out;
 
@@ -1241,8 +1293,7 @@ int __i915_wait_request(struct drm_i915_gem_request *req,
        for (;;) {
                struct timer_list timer;
 
-               prepare_to_wait(&ring->irq_queue, &wait,
-                               interruptible ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE);
+               prepare_to_wait(&ring->irq_queue, &wait, state);
 
                /* We need to check whether any gpu reset happened in between
                 * the caller grabbing the seqno and now ... */
@@ -1260,7 +1311,7 @@ int __i915_wait_request(struct drm_i915_gem_request *req,
                        break;
                }
 
-               if (interruptible && signal_pending(current)) {
+               if (signal_pending_state(state, current)) {
                        ret = -ERESTARTSYS;
                        break;
                }
@@ -2554,6 +2605,7 @@ void __i915_add_request(struct drm_i915_gem_request *request,
        request->batch_obj = obj;
 
        request->emitted_jiffies = jiffies;
+       request->previous_seqno = ring->last_submitted_seqno;
        ring->last_submitted_seqno = request->seqno;
        list_add_tail(&request->list, &ring->request_list);
 
@@ -4080,6 +4132,29 @@ i915_vma_misplaced(struct i915_vma *vma, uint32_t alignment, uint64_t flags)
        return false;
 }
 
+void __i915_vma_set_map_and_fenceable(struct i915_vma *vma)
+{
+       struct drm_i915_gem_object *obj = vma->obj;
+       bool mappable, fenceable;
+       u32 fence_size, fence_alignment;
+
+       fence_size = i915_gem_get_gtt_size(obj->base.dev,
+                                          obj->base.size,
+                                          obj->tiling_mode);
+       fence_alignment = i915_gem_get_gtt_alignment(obj->base.dev,
+                                                    obj->base.size,
+                                                    obj->tiling_mode,
+                                                    true);
+
+       fenceable = (vma->node.size == fence_size &&
+                    (vma->node.start & (fence_alignment - 1)) == 0);
+
+       mappable = (vma->node.start + fence_size <=
+                   to_i915(obj->base.dev)->gtt.mappable_end);
+
+       obj->map_and_fenceable = mappable && fenceable;
+}
+
 static int
 i915_gem_object_do_pin(struct drm_i915_gem_object *obj,
                       struct i915_address_space *vm,
@@ -4147,25 +4222,7 @@ i915_gem_object_do_pin(struct drm_i915_gem_object *obj,
 
        if (ggtt_view && ggtt_view->type == I915_GGTT_VIEW_NORMAL &&
            (bound ^ vma->bound) & GLOBAL_BIND) {
-               bool mappable, fenceable;
-               u32 fence_size, fence_alignment;
-
-               fence_size = i915_gem_get_gtt_size(obj->base.dev,
-                                                  obj->base.size,
-                                                  obj->tiling_mode);
-               fence_alignment = i915_gem_get_gtt_alignment(obj->base.dev,
-                                                            obj->base.size,
-                                                            obj->tiling_mode,
-                                                            true);
-
-               fenceable = (vma->node.size == fence_size &&
-                            (vma->node.start & (fence_alignment - 1)) == 0);
-
-               mappable = (vma->node.start + fence_size <=
-                           dev_priv->gtt.mappable_end);
-
-               obj->map_and_fenceable = mappable && fenceable;
-
+               __i915_vma_set_map_and_fenceable(vma);
                WARN_ON(flags & PIN_MAPPABLE && !obj->map_and_fenceable);
        }
 
index 8c688a5f1589316b3f303d9a5b90857af7e112f8..02ceb7a4b4815e52a825a290aa8e6d2cd78d25b5 100644 (file)
@@ -141,8 +141,6 @@ static void i915_gem_context_clean(struct intel_context *ctx)
        if (!ppgtt)
                return;
 
-       WARN_ON(!list_empty(&ppgtt->base.active_list));
-
        list_for_each_entry_safe(vma, next, &ppgtt->base.inactive_list,
                                 mm_list) {
                if (WARN_ON(__i915_vma_unbind_no_wait(vma)))
index 43f35d12b677606d43b96cedc3cae476067946ab..86c7500454b4d1b3928dc41f37ab9aa6917fd557 100644 (file)
@@ -2676,6 +2676,7 @@ static int i915_gem_setup_global_gtt(struct drm_device *dev,
                        return ret;
                }
                vma->bound |= GLOBAL_BIND;
+               __i915_vma_set_map_and_fenceable(vma);
                list_add_tail(&vma->mm_list, &ggtt_vm->inactive_list);
        }
 
index cdacf3f5b77a571086024deae067bf32edc3a988..87e919a06b277fea6cfade79445a165bac925056 100644 (file)
@@ -687,6 +687,7 @@ i915_gem_object_create_stolen_for_preallocated(struct drm_device *dev,
                }
 
                vma->bound |= GLOBAL_BIND;
+               __i915_vma_set_map_and_fenceable(vma);
                list_add_tail(&vma->mm_list, &ggtt->inactive_list);
        }
 
index 22e86d2e408d9493e6c2ea6a60e689a5c03934a9..32cf973469785cb916eb3c2bdd125a741efb5e4c 100644 (file)
@@ -116,6 +116,7 @@ static void skylake_pfit_enable(struct intel_crtc *crtc);
 static void ironlake_pfit_disable(struct intel_crtc *crtc, bool force);
 static void ironlake_pfit_enable(struct intel_crtc *crtc);
 static void intel_modeset_setup_hw_state(struct drm_device *dev);
+static void intel_pre_disable_primary(struct drm_crtc *crtc);
 
 typedef struct {
        int     min, max;
@@ -2607,6 +2608,8 @@ intel_find_initial_plane_obj(struct intel_crtc *intel_crtc,
        struct drm_i915_gem_object *obj;
        struct drm_plane *primary = intel_crtc->base.primary;
        struct drm_plane_state *plane_state = primary->state;
+       struct drm_crtc_state *crtc_state = intel_crtc->base.state;
+       struct intel_plane *intel_plane = to_intel_plane(primary);
        struct drm_framebuffer *fb;
 
        if (!plane_config->fb)
@@ -2643,6 +2646,18 @@ intel_find_initial_plane_obj(struct intel_crtc *intel_crtc,
                }
        }
 
+       /*
+        * We've failed to reconstruct the BIOS FB.  Current display state
+        * indicates that the primary plane is visible, but has a NULL FB,
+        * which will lead to problems later if we don't fix it up.  The
+        * simplest solution is to just disable the primary plane now and
+        * pretend the BIOS never had it enabled.
+        */
+       to_intel_plane_state(plane_state)->visible = false;
+       crtc_state->plane_mask &= ~(1 << drm_plane_index(primary));
+       intel_pre_disable_primary(&intel_crtc->base);
+       intel_plane->disable_plane(primary, &intel_crtc->base);
+
        return;
 
 valid_fb:
@@ -6309,9 +6324,11 @@ static void intel_crtc_disable_noatomic(struct drm_crtc *crtc)
        if (to_intel_plane_state(crtc->primary->state)->visible) {
                intel_crtc_wait_for_pending_flips(crtc);
                intel_pre_disable_primary(crtc);
+
+               intel_crtc_disable_planes(crtc, 1 << drm_plane_index(crtc->primary));
+               to_intel_plane_state(crtc->primary->state)->visible = false;
        }
 
-       intel_crtc_disable_planes(crtc, crtc->state->plane_mask);
        dev_priv->display.crtc_disable(crtc);
        intel_crtc->active = false;
        intel_update_watermarks(crtc);
@@ -9908,14 +9925,14 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc,
        return true;
 }
 
-static void i845_update_cursor(struct drm_crtc *crtc, u32 base)
+static void i845_update_cursor(struct drm_crtc *crtc, u32 base, bool on)
 {
        struct drm_device *dev = crtc->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
        uint32_t cntl = 0, size = 0;
 
-       if (base) {
+       if (on) {
                unsigned int width = intel_crtc->base.cursor->state->crtc_w;
                unsigned int height = intel_crtc->base.cursor->state->crtc_h;
                unsigned int stride = roundup_pow_of_two(width) * 4;
@@ -9970,16 +9987,15 @@ static void i845_update_cursor(struct drm_crtc *crtc, u32 base)
        }
 }
 
-static void i9xx_update_cursor(struct drm_crtc *crtc, u32 base)
+static void i9xx_update_cursor(struct drm_crtc *crtc, u32 base, bool on)
 {
        struct drm_device *dev = crtc->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
        int pipe = intel_crtc->pipe;
-       uint32_t cntl;
+       uint32_t cntl = 0;
 
-       cntl = 0;
-       if (base) {
+       if (on) {
                cntl = MCURSOR_GAMMA_ENABLE;
                switch (intel_crtc->base.cursor->state->crtc_w) {
                        case 64:
@@ -10030,18 +10046,17 @@ static void intel_crtc_update_cursor(struct drm_crtc *crtc,
        int y = cursor_state->crtc_y;
        u32 base = 0, pos = 0;
 
-       if (on)
-               base = intel_crtc->cursor_addr;
+       base = intel_crtc->cursor_addr;
 
        if (x >= intel_crtc->config->pipe_src_w)
-               base = 0;
+               on = false;
 
        if (y >= intel_crtc->config->pipe_src_h)
-               base = 0;
+               on = false;
 
        if (x < 0) {
                if (x + cursor_state->crtc_w <= 0)
-                       base = 0;
+                       on = false;
 
                pos |= CURSOR_POS_SIGN << CURSOR_X_SHIFT;
                x = -x;
@@ -10050,16 +10065,13 @@ static void intel_crtc_update_cursor(struct drm_crtc *crtc,
 
        if (y < 0) {
                if (y + cursor_state->crtc_h <= 0)
-                       base = 0;
+                       on = false;
 
                pos |= CURSOR_POS_SIGN << CURSOR_Y_SHIFT;
                y = -y;
        }
        pos |= y << CURSOR_Y_SHIFT;
 
-       if (base == 0 && intel_crtc->cursor_base == 0)
-               return;
-
        I915_WRITE(CURPOS(pipe), pos);
 
        /* ILK+ do this automagically */
@@ -10070,9 +10082,9 @@ static void intel_crtc_update_cursor(struct drm_crtc *crtc,
        }
 
        if (IS_845G(dev) || IS_I865G(dev))
-               i845_update_cursor(crtc, base);
+               i845_update_cursor(crtc, base, on);
        else
-               i9xx_update_cursor(crtc, base);
+               i9xx_update_cursor(crtc, base, on);
 }
 
 static bool cursor_size_ok(struct drm_device *dev,
@@ -12111,18 +12123,22 @@ static void intel_dump_pipe_config(struct intel_crtc *crtc,
 static bool check_digital_port_conflicts(struct drm_atomic_state *state)
 {
        struct drm_device *dev = state->dev;
-       struct intel_encoder *encoder;
        struct drm_connector *connector;
-       struct drm_connector_state *connector_state;
        unsigned int used_ports = 0;
-       int i;
 
        /*
         * Walk the connector list instead of the encoder
         * list to detect the problem on ddi platforms
         * where there's just one encoder per digital port.
         */
-       for_each_connector_in_state(state, connector, connector_state, i) {
+       drm_for_each_connector(connector, dev) {
+               struct drm_connector_state *connector_state;
+               struct intel_encoder *encoder;
+
+               connector_state = drm_atomic_get_existing_connector_state(state, connector);
+               if (!connector_state)
+                       connector_state = connector->state;
+
                if (!connector_state->best_encoder)
                        continue;
 
@@ -13716,6 +13732,7 @@ intel_check_cursor_plane(struct drm_plane *plane,
        struct drm_crtc *crtc = crtc_state->base.crtc;
        struct drm_framebuffer *fb = state->base.fb;
        struct drm_i915_gem_object *obj = intel_fb_obj(fb);
+       enum pipe pipe = to_intel_plane(plane)->pipe;
        unsigned stride;
        int ret;
 
@@ -13749,6 +13766,22 @@ intel_check_cursor_plane(struct drm_plane *plane,
                return -EINVAL;
        }
 
+       /*
+        * There's something wrong with the cursor on CHV pipe C.
+        * If it straddles the left edge of the screen then
+        * moving it away from the edge or disabling it often
+        * results in a pipe underrun, and often that can lead to
+        * dead pipe (constant underrun reported, and it scans
+        * out just a solid color). To recover from that, the
+        * display power well must be turned off and on again.
+        * Refuse the put the cursor into that compromised position.
+        */
+       if (IS_CHERRYVIEW(plane->dev) && pipe == PIPE_C &&
+           state->visible && state->base.crtc_x < 0) {
+               DRM_DEBUG_KMS("CHV cursor C not allowed to straddle the left screen edge\n");
+               return -EINVAL;
+       }
+
        return 0;
 }
 
@@ -13772,9 +13805,6 @@ intel_commit_cursor_plane(struct drm_plane *plane,
        crtc = crtc ? crtc : plane->crtc;
        intel_crtc = to_intel_crtc(crtc);
 
-       if (intel_crtc->cursor_bo == obj)
-               goto update;
-
        if (!obj)
                addr = 0;
        else if (!INTEL_INFO(dev)->cursor_needs_physical)
@@ -13783,9 +13813,7 @@ intel_commit_cursor_plane(struct drm_plane *plane,
                addr = obj->phys_handle->busaddr;
 
        intel_crtc->cursor_addr = addr;
-       intel_crtc->cursor_bo = obj;
 
-update:
        if (crtc->state->active)
                intel_crtc_update_cursor(crtc, state->visible);
 }
index f2a1142bff34310a40abd262a59106bffdecba6f..0d00f07b7163c90c10d8e994b037b7b24b508d34 100644 (file)
@@ -550,7 +550,6 @@ struct intel_crtc {
        int adjusted_x;
        int adjusted_y;
 
-       struct drm_i915_gem_object *cursor_bo;
        uint32_t cursor_addr;
        uint32_t cursor_cntl;
        uint32_t cursor_size;
index 81cdd9ff38922397171e91558136ae0765229106..e6c035b0fc1ce2d2e674aec93cb50c0ad7b7db67 100644 (file)
@@ -1374,17 +1374,18 @@ intel_hdmi_detect(struct drm_connector *connector, bool force)
        struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
        struct drm_i915_private *dev_priv = to_i915(connector->dev);
        bool live_status = false;
-       unsigned int retry = 3;
+       unsigned int try;
 
        DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
                      connector->base.id, connector->name);
 
        intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS);
 
-       while (!live_status && --retry) {
+       for (try = 0; !live_status && try < 9; try++) {
+               if (try)
+                       msleep(10);
                live_status = intel_digital_port_connected(dev_priv,
                                hdmi_to_dig_port(intel_hdmi));
-               mdelay(10);
        }
 
        if (!live_status)
index 071a76b9ac523355e296836f81969374caaa6d86..f091ad12d694a43ebb0dce69b31089ffd4abe366 100644 (file)
@@ -4782,8 +4782,7 @@ static void gen9_enable_rc6(struct drm_device *dev)
        /* 2b: Program RC6 thresholds.*/
 
        /* WaRsDoubleRc6WrlWithCoarsePowerGating: Doubling WRL only when CPG is enabled */
-       if (IS_SKYLAKE(dev) && !((IS_SKL_GT3(dev) || IS_SKL_GT4(dev)) &&
-                                (INTEL_REVID(dev) <= SKL_REVID_E0)))
+       if (IS_SKYLAKE(dev))
                I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 108 << 16);
        else
                I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 54 << 16);
@@ -4825,7 +4824,7 @@ static void gen9_enable_rc6(struct drm_device *dev)
         * WaRsDisableCoarsePowerGating:skl,bxt - Render/Media PG need to be disabled with RC6.
         */
        if ((IS_BROXTON(dev) && (INTEL_REVID(dev) < BXT_REVID_B0)) ||
-           ((IS_SKL_GT3(dev) || IS_SKL_GT4(dev)) && (INTEL_REVID(dev) <= SKL_REVID_E0)))
+           ((IS_SKL_GT3(dev) || IS_SKL_GT4(dev)) && (INTEL_REVID(dev) <= SKL_REVID_F0)))
                I915_WRITE(GEN9_PG_ENABLE, 0);
        else
                I915_WRITE(GEN9_PG_ENABLE, (rc6_mask & GEN6_RC_CTL_RC6_ENABLE) ?
index 8f760002e4018ba05a6fb18a6ecc0d0cf53605fc..913192c94876febb1bf274213c92244b6af6b92d 100644 (file)
@@ -159,7 +159,6 @@ struct nvkm_device_func {
 struct nvkm_device_quirk {
        u8 tv_pin_mask;
        u8 tv_gpio;
-       bool War00C800_0;
 };
 
 struct nvkm_device_chip {
index caf22b589edc3389247abaa724fdb41d7407c2f9..62ad0300cfa5ab0af8610773ae7d5c4b49e310bb 100644 (file)
@@ -258,12 +258,6 @@ nvkm_device_pci_10de_0df4[] = {
        {}
 };
 
-static const struct nvkm_device_pci_vendor
-nvkm_device_pci_10de_0fcd[] = {
-       { 0x17aa, 0x3801, NULL, { .War00C800_0 = true } }, /* Lenovo Y510P */
-       {}
-};
-
 static const struct nvkm_device_pci_vendor
 nvkm_device_pci_10de_0fd2[] = {
        { 0x1028, 0x0595, "GeForce GT 640M LE" },
@@ -278,12 +272,6 @@ nvkm_device_pci_10de_0fe3[] = {
        {}
 };
 
-static const struct nvkm_device_pci_vendor
-nvkm_device_pci_10de_0fe4[] = {
-       { 0x144d, 0xc740, NULL, { .War00C800_0 = true } },
-       {}
-};
-
 static const struct nvkm_device_pci_vendor
 nvkm_device_pci_10de_104b[] = {
        { 0x1043, 0x844c, "GeForce GT 625" },
@@ -690,13 +678,6 @@ nvkm_device_pci_10de_1189[] = {
 static const struct nvkm_device_pci_vendor
 nvkm_device_pci_10de_1199[] = {
        { 0x1458, 0xd001, "GeForce GTX 760" },
-       { 0x1462, 0x1106, "GeForce GTX 780M", { .War00C800_0 = true } }, /* Medion Erazer X7827 */
-       {}
-};
-
-static const struct nvkm_device_pci_vendor
-nvkm_device_pci_10de_11e0[] = {
-       { 0x1558, 0x5106, NULL, { .War00C800_0 = true } },
        {}
 };
 
@@ -706,14 +687,6 @@ nvkm_device_pci_10de_11e3[] = {
        {}
 };
 
-static const struct nvkm_device_pci_vendor
-nvkm_device_pci_10de_11fc[] = {
-       { 0x1179, 0x0001, NULL, { .War00C800_0 = true } }, /* Toshiba Tecra W50 */
-       { 0x17aa, 0x2211, NULL, { .War00C800_0 = true } }, /* Lenovo W541 */
-       { 0x17aa, 0x221e, NULL, { .War00C800_0 = true } }, /* Lenovo W541 */
-       {}
-};
-
 static const struct nvkm_device_pci_vendor
 nvkm_device_pci_10de_1247[] = {
        { 0x1043, 0x212a, "GeForce GT 635M" },
@@ -1368,7 +1341,7 @@ nvkm_device_pci_10de[] = {
        { 0x0fc6, "GeForce GTX 650" },
        { 0x0fc8, "GeForce GT 740" },
        { 0x0fc9, "GeForce GT 730" },
-       { 0x0fcd, "GeForce GT 755M", nvkm_device_pci_10de_0fcd },
+       { 0x0fcd, "GeForce GT 755M" },
        { 0x0fce, "GeForce GT 640M LE" },
        { 0x0fd1, "GeForce GT 650M" },
        { 0x0fd2, "GeForce GT 640M", nvkm_device_pci_10de_0fd2 },
@@ -1382,7 +1355,7 @@ nvkm_device_pci_10de[] = {
        { 0x0fe1, "GeForce GT 730M" },
        { 0x0fe2, "GeForce GT 745M" },
        { 0x0fe3, "GeForce GT 745M", nvkm_device_pci_10de_0fe3 },
-       { 0x0fe4, "GeForce GT 750M", nvkm_device_pci_10de_0fe4 },
+       { 0x0fe4, "GeForce GT 750M" },
        { 0x0fe9, "GeForce GT 750M" },
        { 0x0fea, "GeForce GT 755M" },
        { 0x0fec, "GeForce 710A" },
@@ -1497,12 +1470,12 @@ nvkm_device_pci_10de[] = {
        { 0x11c6, "GeForce GTX 650 Ti" },
        { 0x11c8, "GeForce GTX 650" },
        { 0x11cb, "GeForce GT 740" },
-       { 0x11e0, "GeForce GTX 770M", nvkm_device_pci_10de_11e0 },
+       { 0x11e0, "GeForce GTX 770M" },
        { 0x11e1, "GeForce GTX 765M" },
        { 0x11e2, "GeForce GTX 765M" },
        { 0x11e3, "GeForce GTX 760M", nvkm_device_pci_10de_11e3 },
        { 0x11fa, "Quadro K4000" },
-       { 0x11fc, "Quadro K2100M", nvkm_device_pci_10de_11fc },
+       { 0x11fc, "Quadro K2100M" },
        { 0x1200, "GeForce GTX 560 Ti" },
        { 0x1201, "GeForce GTX 560" },
        { 0x1203, "GeForce GTX 460 SE v2" },
index ffa902ece87234420d2b25d1603995f5679b5245..05a895496fc66f6f96efd64cbdbe822e4baaf1cc 100644 (file)
@@ -156,6 +156,7 @@ nv40_gr_chan_new(struct nvkm_gr *base, struct nvkm_fifo_chan *fifoch,
                return -ENOMEM;
        nvkm_object_ctor(&nv40_gr_chan, oclass, &chan->object);
        chan->gr = gr;
+       chan->fifo = fifoch;
        *pobject = &chan->object;
 
        spin_lock_irqsave(&chan->gr->base.engine.lock, flags);
index 43006db6fd58252830842c02543ca1659ae23df2..80fed7e78dcbe0bc1e7df6a864c3efb475c2733a 100644 (file)
@@ -83,6 +83,7 @@ nvbios_fan_parse(struct nvkm_bios *bios, struct nvbios_therm_fan *fan)
                        fan->type = NVBIOS_THERM_FAN_UNK;
                }
 
+               fan->fan_mode = NVBIOS_THERM_FAN_LINEAR;
                fan->min_duty = nvbios_rd08(bios, data + 0x02);
                fan->max_duty = nvbios_rd08(bios, data + 0x03);
 
index d942fa7b9f1871b362809baf0bac9c8c7d6ced2b..86f9f3b13f71f7caead9206f9cfcdab6bf88c728 100644 (file)
@@ -81,9 +81,7 @@ gk104_pmu_pgob(struct nvkm_pmu *pmu, bool enable)
        nvkm_mask(device, 0x000200, 0x00001000, 0x00001000);
        nvkm_rd32(device, 0x000200);
 
-       if ( nvkm_boolopt(device->cfgopt, "War00C800_0",
-           device->quirk ? device->quirk->War00C800_0 : false)) {
-               nvkm_info(&pmu->subdev, "hw bug workaround enabled\n");
+       if (nvkm_boolopt(device->cfgopt, "War00C800_0", true)) {
                switch (device->chipset) {
                case 0xe4:
                        magic(device, 0x04000000);
index b8e4cdec28c363c7e5c10881be4ea61461023ace..24f92bea39c7d731365be1464b5b551f3a278f49 100644 (file)
@@ -112,11 +112,8 @@ static int omap_fbdev_create(struct drm_fb_helper *helper,
        dma_addr_t paddr;
        int ret;
 
-       /* only doing ARGB32 since this is what is needed to alpha-blend
-        * with video overlays:
-        */
        sizes->surface_bpp = 32;
-       sizes->surface_depth = 32;
+       sizes->surface_depth = 24;
 
        DBG("create fbdev: %dx%d@%d (%dx%d)", sizes->surface_width,
                        sizes->surface_height, sizes->surface_bpp,
index 0154db43860c7ec6ca9d0aeb828650a88e91a718..f81fb26410976840b02811de9693b875edfa3efa 100644 (file)
@@ -4173,11 +4173,7 @@ void cik_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib)
        control |= ib->length_dw | (vm_id << 24);
 
        radeon_ring_write(ring, header);
-       radeon_ring_write(ring,
-#ifdef __BIG_ENDIAN
-                         (2 << 0) |
-#endif
-                         (ib->gpu_addr & 0xFFFFFFFC));
+       radeon_ring_write(ring, (ib->gpu_addr & 0xFFFFFFFC));
        radeon_ring_write(ring, upper_32_bits(ib->gpu_addr) & 0xFFFF);
        radeon_ring_write(ring, control);
 }
index 574f62bbd215bcf58c125861f7718aaabba7c423..7eb1ae758906142b86f5c7fd1c01dcc50ce74946 100644 (file)
@@ -361,31 +361,31 @@ int radeon_vce_get_create_msg(struct radeon_device *rdev, int ring,
 
        /* stitch together an VCE create msg */
        ib.length_dw = 0;
-       ib.ptr[ib.length_dw++] = 0x0000000c; /* len */
-       ib.ptr[ib.length_dw++] = 0x00000001; /* session cmd */
-       ib.ptr[ib.length_dw++] = handle;
-
-       ib.ptr[ib.length_dw++] = 0x00000030; /* len */
-       ib.ptr[ib.length_dw++] = 0x01000001; /* create cmd */
-       ib.ptr[ib.length_dw++] = 0x00000000;
-       ib.ptr[ib.length_dw++] = 0x00000042;
-       ib.ptr[ib.length_dw++] = 0x0000000a;
-       ib.ptr[ib.length_dw++] = 0x00000001;
-       ib.ptr[ib.length_dw++] = 0x00000080;
-       ib.ptr[ib.length_dw++] = 0x00000060;
-       ib.ptr[ib.length_dw++] = 0x00000100;
-       ib.ptr[ib.length_dw++] = 0x00000100;
-       ib.ptr[ib.length_dw++] = 0x0000000c;
-       ib.ptr[ib.length_dw++] = 0x00000000;
-
-       ib.ptr[ib.length_dw++] = 0x00000014; /* len */
-       ib.ptr[ib.length_dw++] = 0x05000005; /* feedback buffer */
-       ib.ptr[ib.length_dw++] = upper_32_bits(dummy);
-       ib.ptr[ib.length_dw++] = dummy;
-       ib.ptr[ib.length_dw++] = 0x00000001;
+       ib.ptr[ib.length_dw++] = cpu_to_le32(0x0000000c); /* len */
+       ib.ptr[ib.length_dw++] = cpu_to_le32(0x00000001); /* session cmd */
+       ib.ptr[ib.length_dw++] = cpu_to_le32(handle);
+
+       ib.ptr[ib.length_dw++] = cpu_to_le32(0x00000030); /* len */
+       ib.ptr[ib.length_dw++] = cpu_to_le32(0x01000001); /* create cmd */
+       ib.ptr[ib.length_dw++] = cpu_to_le32(0x00000000);
+       ib.ptr[ib.length_dw++] = cpu_to_le32(0x00000042);
+       ib.ptr[ib.length_dw++] = cpu_to_le32(0x0000000a);
+       ib.ptr[ib.length_dw++] = cpu_to_le32(0x00000001);
+       ib.ptr[ib.length_dw++] = cpu_to_le32(0x00000080);
+       ib.ptr[ib.length_dw++] = cpu_to_le32(0x00000060);
+       ib.ptr[ib.length_dw++] = cpu_to_le32(0x00000100);
+       ib.ptr[ib.length_dw++] = cpu_to_le32(0x00000100);
+       ib.ptr[ib.length_dw++] = cpu_to_le32(0x0000000c);
+       ib.ptr[ib.length_dw++] = cpu_to_le32(0x00000000);
+
+       ib.ptr[ib.length_dw++] = cpu_to_le32(0x00000014); /* len */
+       ib.ptr[ib.length_dw++] = cpu_to_le32(0x05000005); /* feedback buffer */
+       ib.ptr[ib.length_dw++] = cpu_to_le32(upper_32_bits(dummy));
+       ib.ptr[ib.length_dw++] = cpu_to_le32(dummy);
+       ib.ptr[ib.length_dw++] = cpu_to_le32(0x00000001);
 
        for (i = ib.length_dw; i < ib_size_dw; ++i)
-               ib.ptr[i] = 0x0;
+               ib.ptr[i] = cpu_to_le32(0x0);
 
        r = radeon_ib_schedule(rdev, &ib, NULL, false);
        if (r) {
@@ -428,21 +428,21 @@ int radeon_vce_get_destroy_msg(struct radeon_device *rdev, int ring,
 
        /* stitch together an VCE destroy msg */
        ib.length_dw = 0;
-       ib.ptr[ib.length_dw++] = 0x0000000c; /* len */
-       ib.ptr[ib.length_dw++] = 0x00000001; /* session cmd */
-       ib.ptr[ib.length_dw++] = handle;
+       ib.ptr[ib.length_dw++] = cpu_to_le32(0x0000000c); /* len */
+       ib.ptr[ib.length_dw++] = cpu_to_le32(0x00000001); /* session cmd */
+       ib.ptr[ib.length_dw++] = cpu_to_le32(handle);
 
-       ib.ptr[ib.length_dw++] = 0x00000014; /* len */
-       ib.ptr[ib.length_dw++] = 0x05000005; /* feedback buffer */
-       ib.ptr[ib.length_dw++] = upper_32_bits(dummy);
-       ib.ptr[ib.length_dw++] = dummy;
-       ib.ptr[ib.length_dw++] = 0x00000001;
+       ib.ptr[ib.length_dw++] = cpu_to_le32(0x00000014); /* len */
+       ib.ptr[ib.length_dw++] = cpu_to_le32(0x05000005); /* feedback buffer */
+       ib.ptr[ib.length_dw++] = cpu_to_le32(upper_32_bits(dummy));
+       ib.ptr[ib.length_dw++] = cpu_to_le32(dummy);
+       ib.ptr[ib.length_dw++] = cpu_to_le32(0x00000001);
 
-       ib.ptr[ib.length_dw++] = 0x00000008; /* len */
-       ib.ptr[ib.length_dw++] = 0x02000001; /* destroy cmd */
+       ib.ptr[ib.length_dw++] = cpu_to_le32(0x00000008); /* len */
+       ib.ptr[ib.length_dw++] = cpu_to_le32(0x02000001); /* destroy cmd */
 
        for (i = ib.length_dw; i < ib_size_dw; ++i)
-               ib.ptr[i] = 0x0;
+               ib.ptr[i] = cpu_to_le32(0x0);
 
        r = radeon_ib_schedule(rdev, &ib, NULL, false);
        if (r) {
@@ -699,12 +699,12 @@ bool radeon_vce_semaphore_emit(struct radeon_device *rdev,
 {
        uint64_t addr = semaphore->gpu_addr;
 
-       radeon_ring_write(ring, VCE_CMD_SEMAPHORE);
-       radeon_ring_write(ring, (addr >> 3) & 0x000FFFFF);
-       radeon_ring_write(ring, (addr >> 23) & 0x000FFFFF);
-       radeon_ring_write(ring, 0x01003000 | (emit_wait ? 1 : 0));
+       radeon_ring_write(ring, cpu_to_le32(VCE_CMD_SEMAPHORE));
+       radeon_ring_write(ring, cpu_to_le32((addr >> 3) & 0x000FFFFF));
+       radeon_ring_write(ring, cpu_to_le32((addr >> 23) & 0x000FFFFF));
+       radeon_ring_write(ring, cpu_to_le32(0x01003000 | (emit_wait ? 1 : 0)));
        if (!emit_wait)
-               radeon_ring_write(ring, VCE_CMD_END);
+               radeon_ring_write(ring, cpu_to_le32(VCE_CMD_END));
 
        return true;
 }
@@ -719,10 +719,10 @@ bool radeon_vce_semaphore_emit(struct radeon_device *rdev,
 void radeon_vce_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib)
 {
        struct radeon_ring *ring = &rdev->ring[ib->ring];
-       radeon_ring_write(ring, VCE_CMD_IB);
-       radeon_ring_write(ring, ib->gpu_addr);
-       radeon_ring_write(ring, upper_32_bits(ib->gpu_addr));
-       radeon_ring_write(ring, ib->length_dw);
+       radeon_ring_write(ring, cpu_to_le32(VCE_CMD_IB));
+       radeon_ring_write(ring, cpu_to_le32(ib->gpu_addr));
+       radeon_ring_write(ring, cpu_to_le32(upper_32_bits(ib->gpu_addr)));
+       radeon_ring_write(ring, cpu_to_le32(ib->length_dw));
 }
 
 /**
@@ -738,12 +738,12 @@ void radeon_vce_fence_emit(struct radeon_device *rdev,
        struct radeon_ring *ring = &rdev->ring[fence->ring];
        uint64_t addr = rdev->fence_drv[fence->ring].gpu_addr;
 
-       radeon_ring_write(ring, VCE_CMD_FENCE);
-       radeon_ring_write(ring, addr);
-       radeon_ring_write(ring, upper_32_bits(addr));
-       radeon_ring_write(ring, fence->seq);
-       radeon_ring_write(ring, VCE_CMD_TRAP);
-       radeon_ring_write(ring, VCE_CMD_END);
+       radeon_ring_write(ring, cpu_to_le32(VCE_CMD_FENCE));
+       radeon_ring_write(ring, cpu_to_le32(addr));
+       radeon_ring_write(ring, cpu_to_le32(upper_32_bits(addr)));
+       radeon_ring_write(ring, cpu_to_le32(fence->seq));
+       radeon_ring_write(ring, cpu_to_le32(VCE_CMD_TRAP));
+       radeon_ring_write(ring, cpu_to_le32(VCE_CMD_END));
 }
 
 /**
@@ -765,7 +765,7 @@ int radeon_vce_ring_test(struct radeon_device *rdev, struct radeon_ring *ring)
                          ring->idx, r);
                return r;
        }
-       radeon_ring_write(ring, VCE_CMD_END);
+       radeon_ring_write(ring, cpu_to_le32(VCE_CMD_END));
        radeon_ring_unlock_commit(rdev, ring, false);
 
        for (i = 0; i < rdev->usec_timeout; i++) {
index 6a954544727f3f13cfa8d9be0b8ff4cbf39d9367..f154fb1929bd18e300e226d8fe89925b9e8b3754 100644 (file)
@@ -180,7 +180,7 @@ int ttm_write_lock(struct ttm_lock *lock, bool interruptible)
                        spin_unlock(&lock->lock);
                }
        } else
-               wait_event(lock->queue, __ttm_read_lock(lock));
+               wait_event(lock->queue, __ttm_write_lock(lock));
 
        return ret;
 }
index a09cf8529b9f6374649e2f943ef84e3cf08eeda1..c49812b80dd0dae82c77096f75fbd4cced19ffb1 100644 (file)
@@ -1233,6 +1233,7 @@ static void vmw_master_drop(struct drm_device *dev,
 
        vmw_fp->locked_master = drm_master_get(file_priv->master);
        ret = ttm_vt_lock(&vmaster->lock, false, vmw_fp->tfile);
+       vmw_kms_legacy_hotspot_clear(dev_priv);
        if (unlikely((ret != 0))) {
                DRM_ERROR("Unable to lock TTM at VT switch.\n");
                drm_master_put(&vmw_fp->locked_master);
index a8ae9dfb83b7d4916023d9e8e3835da42f0c3979..469cdd520615d036fdb99b0f7e27ed67ce3abd67 100644 (file)
@@ -925,6 +925,7 @@ int vmw_kms_present(struct vmw_private *dev_priv,
                    uint32_t num_clips);
 int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data,
                                struct drm_file *file_priv);
+void vmw_kms_legacy_hotspot_clear(struct vmw_private *dev_priv);
 
 int vmw_dumb_create(struct drm_file *file_priv,
                    struct drm_device *dev,
index a8baf5f5e76558679d128de151d2caaea193bc6c..b6a0806b06bffaf6da9178905f9b2f6bb037d384 100644 (file)
@@ -390,7 +390,7 @@ void *vmw_fifo_reserve_dx(struct vmw_private *dev_priv, uint32_t bytes,
        else if (ctx_id == SVGA3D_INVALID_ID)
                ret = vmw_local_fifo_reserve(dev_priv, bytes);
        else {
-               WARN_ON("Command buffer has not been allocated.\n");
+               WARN(1, "Command buffer has not been allocated.\n");
                ret = NULL;
        }
        if (IS_ERR_OR_NULL(ret)) {
index 9fcd7f82995c3e1a517930cb8a89a23351c55c15..9b4bb9e74d7300793f3ecb1c0feef42085780819 100644 (file)
@@ -133,13 +133,19 @@ void vmw_cursor_update_position(struct vmw_private *dev_priv,
        vmw_mmio_write(++count, fifo_mem + SVGA_FIFO_CURSOR_COUNT);
 }
 
-int vmw_du_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv,
-                          uint32_t handle, uint32_t width, uint32_t height)
+
+/*
+ * vmw_du_crtc_cursor_set2 - Driver cursor_set2 callback.
+ */
+int vmw_du_crtc_cursor_set2(struct drm_crtc *crtc, struct drm_file *file_priv,
+                           uint32_t handle, uint32_t width, uint32_t height,
+                           int32_t hot_x, int32_t hot_y)
 {
        struct vmw_private *dev_priv = vmw_priv(crtc->dev);
        struct vmw_display_unit *du = vmw_crtc_to_du(crtc);
        struct vmw_surface *surface = NULL;
        struct vmw_dma_buffer *dmabuf = NULL;
+       s32 hotspot_x, hotspot_y;
        int ret;
 
        /*
@@ -151,6 +157,8 @@ int vmw_du_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv,
         */
        drm_modeset_unlock_crtc(crtc);
        drm_modeset_lock_all(dev_priv->dev);
+       hotspot_x = hot_x + du->hotspot_x;
+       hotspot_y = hot_y + du->hotspot_y;
 
        /* A lot of the code assumes this */
        if (handle && (width != 64 || height != 64)) {
@@ -187,31 +195,34 @@ int vmw_du_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv,
                vmw_dmabuf_unreference(&du->cursor_dmabuf);
 
        /* setup new image */
+       ret = 0;
        if (surface) {
                /* vmw_user_surface_lookup takes one reference */
                du->cursor_surface = surface;
 
                du->cursor_surface->snooper.crtc = crtc;
                du->cursor_age = du->cursor_surface->snooper.age;
-               vmw_cursor_update_image(dev_priv, surface->snooper.image,
-                                       64, 64, du->hotspot_x, du->hotspot_y);
+               ret = vmw_cursor_update_image(dev_priv, surface->snooper.image,
+                                             64, 64, hotspot_x, hotspot_y);
        } else if (dmabuf) {
                /* vmw_user_surface_lookup takes one reference */
                du->cursor_dmabuf = dmabuf;
 
                ret = vmw_cursor_update_dmabuf(dev_priv, dmabuf, width, height,
-                                              du->hotspot_x, du->hotspot_y);
+                                              hotspot_x, hotspot_y);
        } else {
                vmw_cursor_update_position(dev_priv, false, 0, 0);
-               ret = 0;
                goto out;
        }
 
-       vmw_cursor_update_position(dev_priv, true,
-                                  du->cursor_x + du->hotspot_x,
-                                  du->cursor_y + du->hotspot_y);
+       if (!ret) {
+               vmw_cursor_update_position(dev_priv, true,
+                                          du->cursor_x + hotspot_x,
+                                          du->cursor_y + hotspot_y);
+               du->core_hotspot_x = hot_x;
+               du->core_hotspot_y = hot_y;
+       }
 
-       ret = 0;
 out:
        drm_modeset_unlock_all(dev_priv->dev);
        drm_modeset_lock_crtc(crtc, crtc->cursor);
@@ -239,8 +250,10 @@ int vmw_du_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
        drm_modeset_lock_all(dev_priv->dev);
 
        vmw_cursor_update_position(dev_priv, shown,
-                                  du->cursor_x + du->hotspot_x,
-                                  du->cursor_y + du->hotspot_y);
+                                  du->cursor_x + du->hotspot_x +
+                                  du->core_hotspot_x,
+                                  du->cursor_y + du->hotspot_y +
+                                  du->core_hotspot_y);
 
        drm_modeset_unlock_all(dev_priv->dev);
        drm_modeset_lock_crtc(crtc, crtc->cursor);
@@ -334,6 +347,29 @@ err_unreserve:
        ttm_bo_unreserve(bo);
 }
 
+/**
+ * vmw_kms_legacy_hotspot_clear - Clear legacy hotspots
+ *
+ * @dev_priv: Pointer to the device private struct.
+ *
+ * Clears all legacy hotspots.
+ */
+void vmw_kms_legacy_hotspot_clear(struct vmw_private *dev_priv)
+{
+       struct drm_device *dev = dev_priv->dev;
+       struct vmw_display_unit *du;
+       struct drm_crtc *crtc;
+
+       drm_modeset_lock_all(dev);
+       drm_for_each_crtc(crtc, dev) {
+               du = vmw_crtc_to_du(crtc);
+
+               du->hotspot_x = 0;
+               du->hotspot_y = 0;
+       }
+       drm_modeset_unlock_all(dev);
+}
+
 void vmw_kms_cursor_post_execbuf(struct vmw_private *dev_priv)
 {
        struct drm_device *dev = dev_priv->dev;
@@ -351,7 +387,9 @@ void vmw_kms_cursor_post_execbuf(struct vmw_private *dev_priv)
                du->cursor_age = du->cursor_surface->snooper.age;
                vmw_cursor_update_image(dev_priv,
                                        du->cursor_surface->snooper.image,
-                                       64, 64, du->hotspot_x, du->hotspot_y);
+                                       64, 64,
+                                       du->hotspot_x + du->core_hotspot_x,
+                                       du->hotspot_y + du->core_hotspot_y);
        }
 
        mutex_unlock(&dev->mode_config.mutex);
index 782df7ca97946220414dd66a2afbe4f94b6d403a..edd81503516dbbda1fab84ecd53ecc0df689f24e 100644 (file)
@@ -159,6 +159,8 @@ struct vmw_display_unit {
 
        int hotspot_x;
        int hotspot_y;
+       s32 core_hotspot_x;
+       s32 core_hotspot_y;
 
        unsigned unit;
 
@@ -193,8 +195,9 @@ void vmw_du_crtc_restore(struct drm_crtc *crtc);
 void vmw_du_crtc_gamma_set(struct drm_crtc *crtc,
                           u16 *r, u16 *g, u16 *b,
                           uint32_t start, uint32_t size);
-int vmw_du_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv,
-                          uint32_t handle, uint32_t width, uint32_t height);
+int vmw_du_crtc_cursor_set2(struct drm_crtc *crtc, struct drm_file *file_priv,
+                           uint32_t handle, uint32_t width, uint32_t height,
+                           int32_t hot_x, int32_t hot_y);
 int vmw_du_crtc_cursor_move(struct drm_crtc *crtc, int x, int y);
 int vmw_du_connector_dpms(struct drm_connector *connector, int mode);
 void vmw_du_connector_save(struct drm_connector *connector);
index bb63e4d795fae43bc07599babe45bedf26f6e114..52caecb4502ed3086b8ea6e15fac9e45a08d4659 100644 (file)
@@ -297,7 +297,7 @@ static int vmw_ldu_crtc_set_config(struct drm_mode_set *set)
 static struct drm_crtc_funcs vmw_legacy_crtc_funcs = {
        .save = vmw_du_crtc_save,
        .restore = vmw_du_crtc_restore,
-       .cursor_set = vmw_du_crtc_cursor_set,
+       .cursor_set2 = vmw_du_crtc_cursor_set2,
        .cursor_move = vmw_du_crtc_cursor_move,
        .gamma_set = vmw_du_crtc_gamma_set,
        .destroy = vmw_ldu_crtc_destroy,
index b96d1ab610c5527fb190ea476cdbbb82a2b2e158..13926ff192e3d6ce55b0e741ef66a04c9377596b 100644 (file)
@@ -533,7 +533,7 @@ out_no_fence:
 static struct drm_crtc_funcs vmw_screen_object_crtc_funcs = {
        .save = vmw_du_crtc_save,
        .restore = vmw_du_crtc_restore,
-       .cursor_set = vmw_du_crtc_cursor_set,
+       .cursor_set2 = vmw_du_crtc_cursor_set2,
        .cursor_move = vmw_du_crtc_cursor_move,
        .gamma_set = vmw_du_crtc_gamma_set,
        .destroy = vmw_sou_crtc_destroy,
index b1fc1c02792d4c3f89cb76a0dfb0f16f3dce2c47..f823fc3efed72473108acab83d65191a00e40e9a 100644 (file)
@@ -1043,7 +1043,7 @@ out_finish:
 static struct drm_crtc_funcs vmw_stdu_crtc_funcs = {
        .save = vmw_du_crtc_save,
        .restore = vmw_du_crtc_restore,
-       .cursor_set = vmw_du_crtc_cursor_set,
+       .cursor_set2 = vmw_du_crtc_cursor_set2,
        .cursor_move = vmw_du_crtc_cursor_move,
        .gamma_set = vmw_du_crtc_gamma_set,
        .destroy = vmw_stdu_crtc_destroy,
index 3166e4bc4eb6daea9a9fcad4eb5fce4b62b1b418..9abcaa53bd25a4149e850562628bdc17e81161ed 100644 (file)
@@ -395,8 +395,10 @@ int vga_get(struct pci_dev *pdev, unsigned int rsrc, int interruptible)
                set_current_state(interruptible ?
                                  TASK_INTERRUPTIBLE :
                                  TASK_UNINTERRUPTIBLE);
-               if (signal_pending(current)) {
-                       rc = -EINTR;
+               if (interruptible && signal_pending(current)) {
+                       __set_current_state(TASK_RUNNING);
+                       remove_wait_queue(&vga_wait_queue, &wait);
+                       rc = -ERESTARTSYS;
                        break;
                }
                schedule();
index 9024a3de403253ad03955544dec063430523deb0..8b78a7f1f779faa586abd156a0f9ce7082616bc5 100644 (file)
 #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_A001      0xa001
 
 #define USB_VENDOR_ID_ELAN             0x04f3
-#define USB_DEVICE_ID_ELAN_TOUCHSCREEN 0x0089
-#define USB_DEVICE_ID_ELAN_TOUCHSCREEN_009B    0x009b
-#define USB_DEVICE_ID_ELAN_TOUCHSCREEN_0103    0x0103
-#define USB_DEVICE_ID_ELAN_TOUCHSCREEN_010c    0x010c
-#define USB_DEVICE_ID_ELAN_TOUCHSCREEN_016F    0x016f
 
 #define USB_VENDOR_ID_ELECOM           0x056e
 #define USB_DEVICE_ID_ELECOM_BM084     0x0061
index 2324520b006dc7cf24dd2af11a36780c3f989bfd..7dd0953cd70f222f037c72b7c217b76eff8d2942 100644 (file)
@@ -72,11 +72,7 @@ static const struct hid_blacklist {
        { USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_PIXART_USB_OPTICAL_MOUSE, HID_QUIRK_ALWAYS_POLL },
        { USB_VENDOR_ID_DMI, USB_DEVICE_ID_DMI_ENC, HID_QUIRK_NOGET },
        { USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_WIIU, HID_QUIRK_MULTI_INPUT },
-       { USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ELAN_TOUCHSCREEN, HID_QUIRK_ALWAYS_POLL },
-       { USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ELAN_TOUCHSCREEN_009B, HID_QUIRK_ALWAYS_POLL },
-       { USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ELAN_TOUCHSCREEN_0103, HID_QUIRK_ALWAYS_POLL },
-       { USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ELAN_TOUCHSCREEN_010c, HID_QUIRK_ALWAYS_POLL },
-       { USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ELAN_TOUCHSCREEN_016F, HID_QUIRK_ALWAYS_POLL },
+       { USB_VENDOR_ID_ELAN, HID_ANY_ID, HID_QUIRK_ALWAYS_POLL },
        { USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2700, HID_QUIRK_NOGET },
        { USB_VENDOR_ID_FORMOSA, USB_DEVICE_ID_FORMOSA_IR_RECEIVER, HID_QUIRK_NO_INIT_REPORTS },
        { USB_VENDOR_ID_FREESCALE, USB_DEVICE_ID_FREESCALE_MX28, HID_QUIRK_NOGET },
@@ -340,7 +336,8 @@ static const struct hid_blacklist *usbhid_exists_squirk(const u16 idVendor,
 
        for (; hid_blacklist[n].idVendor; n++)
                if (hid_blacklist[n].idVendor == idVendor &&
-                               hid_blacklist[n].idProduct == idProduct)
+                       (hid_blacklist[n].idProduct == (__u16) HID_ANY_ID ||
+                               hid_blacklist[n].idProduct == idProduct))
                        bl_entry = &hid_blacklist[n];
 
        if (bl_entry != NULL)
index 8f59f057cdf4a336cf29cd32803dff2b50143be2..80a73bfc1a65807db6fc276e3027f11500d2f96b 100644 (file)
@@ -1217,6 +1217,7 @@ config SENSORS_PWM_FAN
 config SENSORS_SHT15
        tristate "Sensiron humidity and temperature sensors. SHT15 and compat."
        depends on GPIOLIB || COMPILE_TEST
+       select BITREVERSE
        help
          If you say yes here you get support for the Sensiron SHT10, SHT11,
          SHT15, SHT71, SHT75 humidity and temperature sensors.
index 65482624ea2c81a2ef2b5487d6a0470cc90fead7..5289aa0980a8fac074822ddb412f35e7a9380bd5 100644 (file)
@@ -58,6 +58,7 @@ struct tmp102 {
        u16 config_orig;
        unsigned long last_update;
        int temp[3];
+       bool first_time;
 };
 
 /* convert left adjusted 13-bit TMP102 register value to milliCelsius */
@@ -93,6 +94,7 @@ static struct tmp102 *tmp102_update_device(struct device *dev)
                                tmp102->temp[i] = tmp102_reg_to_mC(status);
                }
                tmp102->last_update = jiffies;
+               tmp102->first_time = false;
        }
        mutex_unlock(&tmp102->lock);
        return tmp102;
@@ -102,6 +104,12 @@ static int tmp102_read_temp(void *dev, int *temp)
 {
        struct tmp102 *tmp102 = tmp102_update_device(dev);
 
+       /* Is it too early even to return a conversion? */
+       if (tmp102->first_time) {
+               dev_dbg(dev, "%s: Conversion not ready yet..\n", __func__);
+               return -EAGAIN;
+       }
+
        *temp = tmp102->temp[0];
 
        return 0;
@@ -114,6 +122,10 @@ static ssize_t tmp102_show_temp(struct device *dev,
        struct sensor_device_attribute *sda = to_sensor_dev_attr(attr);
        struct tmp102 *tmp102 = tmp102_update_device(dev);
 
+       /* Is it too early even to return a read? */
+       if (tmp102->first_time)
+               return -EAGAIN;
+
        return sprintf(buf, "%d\n", tmp102->temp[sda->index]);
 }
 
@@ -207,7 +219,9 @@ static int tmp102_probe(struct i2c_client *client,
                status = -ENODEV;
                goto fail_restore_config;
        }
-       tmp102->last_update = jiffies - HZ;
+       tmp102->last_update = jiffies;
+       /* Mark that we are not ready with data until conversion is complete */
+       tmp102->first_time = true;
        mutex_init(&tmp102->lock);
 
        hwmon_dev = hwmon_device_register_with_groups(dev, client->name,
index c5628a42170acf83d0a2c5d2dffa6a50e6572c59..a8bdcb5292f5b30a925c40f28c8d193395b443c6 100644 (file)
@@ -202,8 +202,15 @@ static void i2c_davinci_calc_clk_dividers(struct davinci_i2c_dev *dev)
         * d is always 6 on Keystone I2C controller
         */
 
-       /* get minimum of 7 MHz clock, but max of 12 MHz */
-       psc = (input_clock / 7000000) - 1;
+       /*
+        * Both Davinci and current Keystone User Guides recommend a value
+        * between 7MHz and 12MHz. In reality 7MHz module clock doesn't
+        * always produce enough margin between SDA and SCL transitions.
+        * Measurements show that the higher the module clock is, the
+        * bigger is the margin, providing more reliable communication.
+        * So we better target for 12MHz.
+        */
+       psc = (input_clock / 12000000) - 1;
        if ((input_clock / (psc + 1)) > 12000000)
                psc++;  /* better to run under spec than over */
        d = (psc >= 2) ? 5 : 7 - psc;
index 8c48b27ba05975e51a40ddaab979e7b23302e3e0..de7fbbb374cd34fce1cc8fffb11c45b21755bead 100644 (file)
@@ -813,6 +813,12 @@ static irqreturn_t i2c_dw_isr(int this_irq, void *dev_id)
 tx_aborted:
        if ((stat & (DW_IC_INTR_TX_ABRT | DW_IC_INTR_STOP_DET)) || dev->msg_err)
                complete(&dev->cmd_complete);
+       else if (unlikely(dev->accessor_flags & ACCESS_INTR_MASK)) {
+               /* workaround to trigger pending interrupt */
+               stat = dw_readl(dev, DW_IC_INTR_MASK);
+               i2c_dw_disable_int(dev);
+               dw_writel(dev, stat, DW_IC_INTR_MASK);
+       }
 
        return IRQ_HANDLED;
 }
index 1d50898e7b2403868c239f2ebc236a240a755bc7..9ffb63a60f95454ebbaf43f6a12bbe922de66179 100644 (file)
@@ -111,6 +111,7 @@ struct dw_i2c_dev {
 
 #define ACCESS_SWAP            0x00000001
 #define ACCESS_16BIT           0x00000002
+#define ACCESS_INTR_MASK       0x00000004
 
 extern int i2c_dw_init(struct dw_i2c_dev *dev);
 extern void i2c_dw_disable(struct dw_i2c_dev *dev);
index 809579ecb5a44fed6745af1274ed46864763651c..6b00061c37469b98613880ffe71d26118c76d92a 100644 (file)
@@ -93,6 +93,7 @@ static void dw_i2c_acpi_params(struct platform_device *pdev, char method[],
 static int dw_i2c_acpi_configure(struct platform_device *pdev)
 {
        struct dw_i2c_dev *dev = platform_get_drvdata(pdev);
+       const struct acpi_device_id *id;
 
        dev->adapter.nr = -1;
        dev->tx_fifo_depth = 32;
@@ -106,6 +107,10 @@ static int dw_i2c_acpi_configure(struct platform_device *pdev)
        dw_i2c_acpi_params(pdev, "FMCN", &dev->fs_hcnt, &dev->fs_lcnt,
                           &dev->sda_hold_time);
 
+       id = acpi_match_device(pdev->dev.driver->acpi_match_table, &pdev->dev);
+       if (id && id->driver_data)
+               dev->accessor_flags |= (u32)id->driver_data;
+
        return 0;
 }
 
@@ -116,7 +121,7 @@ static const struct acpi_device_id dw_i2c_acpi_match[] = {
        { "INT3433", 0 },
        { "80860F41", 0 },
        { "808622C1", 0 },
-       { "AMD0010", 0 },
+       { "AMD0010", ACCESS_INTR_MASK },
        { }
 };
 MODULE_DEVICE_TABLE(acpi, dw_i2c_acpi_match);
@@ -240,12 +245,10 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)
        }
 
        r = i2c_dw_probe(dev);
-       if (r) {
+       if (r && !dev->pm_runtime_disabled)
                pm_runtime_disable(&pdev->dev);
-               return r;
-       }
 
-       return 0;
+       return r;
 }
 
 static int dw_i2c_plat_remove(struct platform_device *pdev)
@@ -260,7 +263,8 @@ static int dw_i2c_plat_remove(struct platform_device *pdev)
 
        pm_runtime_dont_use_autosuspend(&pdev->dev);
        pm_runtime_put_sync(&pdev->dev);
-       pm_runtime_disable(&pdev->dev);
+       if (!dev->pm_runtime_disabled)
+               pm_runtime_disable(&pdev->dev);
 
        return 0;
 }
index 9bb0b056b25f235085df0e994c7c6584581a5a6d..d4d853680ae47881151effb56269e4e660d522e1 100644 (file)
@@ -1119,6 +1119,8 @@ static int i2c_imx_probe(struct platform_device *pdev)
                        i2c_imx, IMX_I2C_I2CR);
        imx_i2c_write_reg(i2c_imx->hwdata->i2sr_clr_opcode, i2c_imx, IMX_I2C_I2SR);
 
+       i2c_imx_init_recovery_info(i2c_imx, pdev);
+
        /* Add I2C adapter */
        ret = i2c_add_numbered_adapter(&i2c_imx->adapter);
        if (ret < 0) {
@@ -1126,8 +1128,6 @@ static int i2c_imx_probe(struct platform_device *pdev)
                goto clk_disable;
        }
 
-       i2c_imx_init_recovery_info(i2c_imx, pdev);
-
        /* Set up platform driver data */
        platform_set_drvdata(pdev, i2c_imx);
        clk_disable_unprepare(i2c_imx->clk);
index 5801227b97ab089022f90608f6fc425ebd13cd87..43207f52e5a3733f5d405da921fb5d32b331321f 100644 (file)
@@ -146,6 +146,8 @@ struct mv64xxx_i2c_data {
        bool                    errata_delay;
        struct reset_control    *rstc;
        bool                    irq_clear_inverted;
+       /* Clk div is 2 to the power n, not 2 to the power n + 1 */
+       bool                    clk_n_base_0;
 };
 
 static struct mv64xxx_i2c_regs mv64xxx_i2c_regs_mv64xxx = {
@@ -757,25 +759,29 @@ MODULE_DEVICE_TABLE(of, mv64xxx_i2c_of_match_table);
 #ifdef CONFIG_OF
 #ifdef CONFIG_HAVE_CLK
 static int
-mv64xxx_calc_freq(const int tclk, const int n, const int m)
+mv64xxx_calc_freq(struct mv64xxx_i2c_data *drv_data,
+                 const int tclk, const int n, const int m)
 {
-       return tclk / (10 * (m + 1) * (2 << n));
+       if (drv_data->clk_n_base_0)
+               return tclk / (10 * (m + 1) * (1 << n));
+       else
+               return tclk / (10 * (m + 1) * (2 << n));
 }
 
 static bool
-mv64xxx_find_baud_factors(const u32 req_freq, const u32 tclk, u32 *best_n,
-                         u32 *best_m)
+mv64xxx_find_baud_factors(struct mv64xxx_i2c_data *drv_data,
+                         const u32 req_freq, const u32 tclk)
 {
        int freq, delta, best_delta = INT_MAX;
        int m, n;
 
        for (n = 0; n <= 7; n++)
                for (m = 0; m <= 15; m++) {
-                       freq = mv64xxx_calc_freq(tclk, n, m);
+                       freq = mv64xxx_calc_freq(drv_data, tclk, n, m);
                        delta = req_freq - freq;
                        if (delta >= 0 && delta < best_delta) {
-                               *best_m = m;
-                               *best_n = n;
+                               drv_data->freq_m = m;
+                               drv_data->freq_n = n;
                                best_delta = delta;
                        }
                        if (best_delta == 0)
@@ -813,8 +819,11 @@ mv64xxx_of_config(struct mv64xxx_i2c_data *drv_data,
        if (of_property_read_u32(np, "clock-frequency", &bus_freq))
                bus_freq = 100000; /* 100kHz by default */
 
-       if (!mv64xxx_find_baud_factors(bus_freq, tclk,
-                                      &drv_data->freq_n, &drv_data->freq_m)) {
+       if (of_device_is_compatible(np, "allwinner,sun4i-a10-i2c") ||
+           of_device_is_compatible(np, "allwinner,sun6i-a31-i2c"))
+               drv_data->clk_n_base_0 = true;
+
+       if (!mv64xxx_find_baud_factors(drv_data, bus_freq, tclk)) {
                rc = -EINVAL;
                goto out;
        }
index b0ae560b38c308335229f0f9b2317f0361b6b8a3..599c0d7bd906d19afc89417afc74d939e6985252 100644 (file)
@@ -576,7 +576,7 @@ static int rcar_reg_slave(struct i2c_client *slave)
        if (slave->flags & I2C_CLIENT_TEN)
                return -EAFNOSUPPORT;
 
-       pm_runtime_forbid(rcar_i2c_priv_to_dev(priv));
+       pm_runtime_get_sync(rcar_i2c_priv_to_dev(priv));
 
        priv->slave = slave;
        rcar_i2c_write(priv, ICSAR, slave->addr);
@@ -598,7 +598,7 @@ static int rcar_unreg_slave(struct i2c_client *slave)
 
        priv->slave = NULL;
 
-       pm_runtime_allow(rcar_i2c_priv_to_dev(priv));
+       pm_runtime_put(rcar_i2c_priv_to_dev(priv));
 
        return 0;
 }
index c1935ebd6a9c38971b6539cc1d1ae03dfc276d17..9096d17beb5bb002d914010a77f156a3f3f97f32 100644 (file)
@@ -908,7 +908,7 @@ static int rk3x_i2c_probe(struct platform_device *pdev)
                                 &i2c->scl_fall_ns))
                i2c->scl_fall_ns = 300;
        if (of_property_read_u32(pdev->dev.of_node, "i2c-sda-falling-time-ns",
-                                &i2c->scl_fall_ns))
+                                &i2c->sda_fall_ns))
                i2c->sda_fall_ns = i2c->scl_fall_ns;
 
        strlcpy(i2c->adap.name, "rk3x-i2c", sizeof(i2c->adap.name));
index ea72dca32fdfde83cfdd223525a915a5721d6816..25020ec777c9783bf5c62853051707bace5c4483 100644 (file)
@@ -822,7 +822,7 @@ static int st_i2c_probe(struct platform_device *pdev)
 
        adap = &i2c_dev->adap;
        i2c_set_adapdata(adap, i2c_dev);
-       snprintf(adap->name, sizeof(adap->name), "ST I2C(0x%pa)", &res->start);
+       snprintf(adap->name, sizeof(adap->name), "ST I2C(%pa)", &res->start);
        adap->owner = THIS_MODULE;
        adap->timeout = 2 * HZ;
        adap->retries = 0;
index 0c4618b4d51549cb7bfe8fead1e3ce61c1882366..c2babe50a0d8f59464f8b77837132192e70e3726 100644 (file)
@@ -839,8 +839,10 @@ static int vadc_get_dt_data(struct vadc_priv *vadc, struct device_node *node)
 
        for_each_available_child_of_node(node, child) {
                ret = vadc_get_dt_channel_data(vadc->dev, &prop, child);
-               if (ret)
+               if (ret) {
+                       of_node_put(child);
                        return ret;
+               }
 
                vadc->chan_props[index] = prop;
 
index d7e908acb48020b3f5390030e5a3687b03ba9878..0f6f63b2026379ffd968a764e3309f8fb792eda5 100644 (file)
@@ -302,7 +302,7 @@ static int iio_scan_mask_set(struct iio_dev *indio_dev,
        if (trialmask == NULL)
                return -ENOMEM;
        if (!indio_dev->masklength) {
-               WARN_ON("Trying to set scanmask prior to registering buffer\n");
+               WARN(1, "Trying to set scanmask prior to registering buffer\n");
                goto err_invalid_mask;
        }
        bitmap_copy(trialmask, buffer->scan_mask, indio_dev->masklength);
index 208358f9e7e36582152cad8c4f4924d9667a58cc..159ede61f79318d4ee8e581a8a61df2028680aba 100644 (file)
@@ -655,7 +655,7 @@ int __iio_device_attr_init(struct device_attribute *dev_attr,
                        break;
                case IIO_SEPARATE:
                        if (!chan->indexed) {
-                               WARN_ON("Differential channels must be indexed\n");
+                               WARN(1, "Differential channels must be indexed\n");
                                ret = -EINVAL;
                                goto error_free_full_postfix;
                        }
index 7d269ef9e0625a81cdf1832c53667e9ed1039f18..f6a07dc32ae486a045b97cfb4406783a9aa05ab8 100644 (file)
@@ -453,6 +453,7 @@ static int apds9960_set_power_state(struct apds9960_data *data, bool on)
                        usleep_range(data->als_adc_int_us,
                                     APDS9960_MAX_INT_TIME_IN_US);
        } else {
+               pm_runtime_mark_last_busy(dev);
                ret = pm_runtime_put_autosuspend(dev);
        }
 
index 961f9f990faffa67fccf54dfa01118ce4339f3b9..e544fcfd5cedf4f3a1d806204b7bcdfbe0d0deb3 100644 (file)
@@ -130,10 +130,10 @@ static int lidar_get_measurement(struct lidar_data *data, u16 *reg)
                if (ret < 0)
                        break;
 
-               /* return 0 since laser is likely pointed out of range */
+               /* return -EINVAL since laser is likely pointed out of range */
                if (ret & LIDAR_REG_STATUS_INVALID) {
                        *reg = 0;
-                       ret = 0;
+                       ret = -EINVAL;
                        break;
                }
 
@@ -197,7 +197,7 @@ static irqreturn_t lidar_trigger_handler(int irq, void *private)
        if (!ret) {
                iio_push_to_buffers_with_timestamp(indio_dev, data->buffer,
                                                   iio_get_time_ns());
-       } else {
+       } else if (ret != -EINVAL) {
                dev_err(&data->client->dev, "cannot read LIDAR measurement");
        }
 
index 944cd90417bcc9b2a51d27f903feffad6f2307ea..2d762a2ecd81252cde34cbc2dbc1083c1d8832dc 100644 (file)
@@ -1126,10 +1126,7 @@ static bool validate_ipv4_net_dev(struct net_device *net_dev,
 
        rcu_read_lock();
        err = fib_lookup(dev_net(net_dev), &fl4, &res, 0);
-       if (err)
-               return false;
-
-       ret = FIB_RES_DEV(res) == net_dev;
+       ret = err == 0 && FIB_RES_DEV(res) == net_dev;
        rcu_read_unlock();
 
        return ret;
@@ -1268,15 +1265,17 @@ static bool cma_protocol_roce(const struct rdma_cm_id *id)
        return cma_protocol_roce_dev_port(device, port_num);
 }
 
-static bool cma_match_net_dev(const struct rdma_id_private *id_priv,
-                             const struct net_device *net_dev)
+static bool cma_match_net_dev(const struct rdma_cm_id *id,
+                             const struct net_device *net_dev,
+                             u8 port_num)
 {
-       const struct rdma_addr *addr = &id_priv->id.route.addr;
+       const struct rdma_addr *addr = &id->route.addr;
 
        if (!net_dev)
                /* This request is an AF_IB request or a RoCE request */
-               return addr->src_addr.ss_family == AF_IB ||
-                      cma_protocol_roce(&id_priv->id);
+               return (!id->port_num || id->port_num == port_num) &&
+                      (addr->src_addr.ss_family == AF_IB ||
+                       cma_protocol_roce_dev_port(id->device, port_num));
 
        return !addr->dev_addr.bound_dev_if ||
               (net_eq(dev_net(net_dev), addr->dev_addr.net) &&
@@ -1298,13 +1297,13 @@ static struct rdma_id_private *cma_find_listener(
        hlist_for_each_entry(id_priv, &bind_list->owners, node) {
                if (cma_match_private_data(id_priv, ib_event->private_data)) {
                        if (id_priv->id.device == cm_id->device &&
-                           cma_match_net_dev(id_priv, net_dev))
+                           cma_match_net_dev(&id_priv->id, net_dev, req->port))
                                return id_priv;
                        list_for_each_entry(id_priv_dev,
                                            &id_priv->listen_list,
                                            listen_list) {
                                if (id_priv_dev->id.device == cm_id->device &&
-                                   cma_match_net_dev(id_priv_dev, net_dev))
+                                   cma_match_net_dev(&id_priv_dev->id, net_dev, req->port))
                                        return id_priv_dev;
                        }
                }
index 8d8af7a41a30fae4ceb520ce0d11b6f541905c96..2281de122038e45a5c375f7d7669111ab2aee2de 100644 (file)
@@ -1811,6 +1811,11 @@ static int validate_mad(const struct ib_mad_hdr *mad_hdr,
                if (qp_num == 0)
                        valid = 1;
        } else {
+               /* CM attributes other than ClassPortInfo only use Send method */
+               if ((mad_hdr->mgmt_class == IB_MGMT_CLASS_CM) &&
+                   (mad_hdr->attr_id != IB_MGMT_CLASSPORTINFO_ATTR_ID) &&
+                   (mad_hdr->method != IB_MGMT_METHOD_SEND))
+                       goto out;
                /* Filter GSI packets sent to QP0 */
                if (qp_num != 0)
                        valid = 1;
index 2aba774f835b9caca8e9e1645d1efd6cf6f08bf9..a95a32ba596edc03728cf7790a6752c951cde951 100644 (file)
@@ -512,7 +512,7 @@ static int ib_nl_get_path_rec_attrs_len(ib_sa_comp_mask comp_mask)
        return len;
 }
 
-static int ib_nl_send_msg(struct ib_sa_query *query)
+static int ib_nl_send_msg(struct ib_sa_query *query, gfp_t gfp_mask)
 {
        struct sk_buff *skb = NULL;
        struct nlmsghdr *nlh;
@@ -526,7 +526,7 @@ static int ib_nl_send_msg(struct ib_sa_query *query)
        if (len <= 0)
                return -EMSGSIZE;
 
-       skb = nlmsg_new(len, GFP_KERNEL);
+       skb = nlmsg_new(len, gfp_mask);
        if (!skb)
                return -ENOMEM;
 
@@ -544,7 +544,7 @@ static int ib_nl_send_msg(struct ib_sa_query *query)
        /* Repair the nlmsg header length */
        nlmsg_end(skb, nlh);
 
-       ret = ibnl_multicast(skb, nlh, RDMA_NL_GROUP_LS, GFP_KERNEL);
+       ret = ibnl_multicast(skb, nlh, RDMA_NL_GROUP_LS, gfp_mask);
        if (!ret)
                ret = len;
        else
@@ -553,7 +553,7 @@ static int ib_nl_send_msg(struct ib_sa_query *query)
        return ret;
 }
 
-static int ib_nl_make_request(struct ib_sa_query *query)
+static int ib_nl_make_request(struct ib_sa_query *query, gfp_t gfp_mask)
 {
        unsigned long flags;
        unsigned long delay;
@@ -562,25 +562,27 @@ static int ib_nl_make_request(struct ib_sa_query *query)
        INIT_LIST_HEAD(&query->list);
        query->seq = (u32)atomic_inc_return(&ib_nl_sa_request_seq);
 
+       /* Put the request on the list first.*/
        spin_lock_irqsave(&ib_nl_request_lock, flags);
-       ret = ib_nl_send_msg(query);
-       if (ret <= 0) {
-               ret = -EIO;
-               goto request_out;
-       } else {
-               ret = 0;
-       }
-
        delay = msecs_to_jiffies(sa_local_svc_timeout_ms);
        query->timeout = delay + jiffies;
        list_add_tail(&query->list, &ib_nl_request_list);
        /* Start the timeout if this is the only request */
        if (ib_nl_request_list.next == &query->list)
                queue_delayed_work(ib_nl_wq, &ib_nl_timed_work, delay);
-
-request_out:
        spin_unlock_irqrestore(&ib_nl_request_lock, flags);
 
+       ret = ib_nl_send_msg(query, gfp_mask);
+       if (ret <= 0) {
+               ret = -EIO;
+               /* Remove the request */
+               spin_lock_irqsave(&ib_nl_request_lock, flags);
+               list_del(&query->list);
+               spin_unlock_irqrestore(&ib_nl_request_lock, flags);
+       } else {
+               ret = 0;
+       }
+
        return ret;
 }
 
@@ -1108,7 +1110,7 @@ static int send_mad(struct ib_sa_query *query, int timeout_ms, gfp_t gfp_mask)
 
        if (query->flags & IB_SA_ENABLE_LOCAL_SERVICE) {
                if (!ibnl_chk_listeners(RDMA_NL_GROUP_LS)) {
-                       if (!ib_nl_make_request(query))
+                       if (!ib_nl_make_request(query, gfp_mask))
                                return id;
                }
                ib_sa_disable_local_svc(query);
index 94816aeb95a0a186760fbe98de55edc69266a54c..1c02deab068fbf1031d5b21db960feb9b06865c5 100644 (file)
@@ -62,9 +62,11 @@ static struct uverbs_lock_class rule_lock_class = { .name = "RULE-uobj" };
  * The ib_uobject locking scheme is as follows:
  *
  * - ib_uverbs_idr_lock protects the uverbs idrs themselves, so it
- *   needs to be held during all idr operations.  When an object is
+ *   needs to be held during all idr write operations.  When an object is
  *   looked up, a reference must be taken on the object's kref before
- *   dropping this lock.
+ *   dropping this lock.  For read operations, the rcu_read_lock()
+ *   and rcu_write_lock() but similarly the kref reference is grabbed
+ *   before the rcu_read_unlock().
  *
  * - Each object also has an rwsem.  This rwsem must be held for
  *   reading while an operation that uses the object is performed.
@@ -96,7 +98,7 @@ static void init_uobj(struct ib_uobject *uobj, u64 user_handle,
 
 static void release_uobj(struct kref *kref)
 {
-       kfree(container_of(kref, struct ib_uobject, ref));
+       kfree_rcu(container_of(kref, struct ib_uobject, ref), rcu);
 }
 
 static void put_uobj(struct ib_uobject *uobj)
@@ -145,7 +147,7 @@ static struct ib_uobject *__idr_get_uobj(struct idr *idr, int id,
 {
        struct ib_uobject *uobj;
 
-       spin_lock(&ib_uverbs_idr_lock);
+       rcu_read_lock();
        uobj = idr_find(idr, id);
        if (uobj) {
                if (uobj->context == context)
@@ -153,7 +155,7 @@ static struct ib_uobject *__idr_get_uobj(struct idr *idr, int id,
                else
                        uobj = NULL;
        }
-       spin_unlock(&ib_uverbs_idr_lock);
+       rcu_read_unlock();
 
        return uobj;
 }
@@ -2446,6 +2448,7 @@ ssize_t ib_uverbs_post_send(struct ib_uverbs_file *file,
        int                             i, sg_ind;
        int                             is_ud;
        ssize_t                         ret = -EINVAL;
+       size_t                          next_size;
 
        if (copy_from_user(&cmd, buf, sizeof cmd))
                return -EFAULT;
@@ -2490,7 +2493,8 @@ ssize_t ib_uverbs_post_send(struct ib_uverbs_file *file,
                                goto out_put;
                        }
 
-                       ud = alloc_wr(sizeof(*ud), user_wr->num_sge);
+                       next_size = sizeof(*ud);
+                       ud = alloc_wr(next_size, user_wr->num_sge);
                        if (!ud) {
                                ret = -ENOMEM;
                                goto out_put;
@@ -2511,7 +2515,8 @@ ssize_t ib_uverbs_post_send(struct ib_uverbs_file *file,
                           user_wr->opcode == IB_WR_RDMA_READ) {
                        struct ib_rdma_wr *rdma;
 
-                       rdma = alloc_wr(sizeof(*rdma), user_wr->num_sge);
+                       next_size = sizeof(*rdma);
+                       rdma = alloc_wr(next_size, user_wr->num_sge);
                        if (!rdma) {
                                ret = -ENOMEM;
                                goto out_put;
@@ -2525,7 +2530,8 @@ ssize_t ib_uverbs_post_send(struct ib_uverbs_file *file,
                           user_wr->opcode == IB_WR_ATOMIC_FETCH_AND_ADD) {
                        struct ib_atomic_wr *atomic;
 
-                       atomic = alloc_wr(sizeof(*atomic), user_wr->num_sge);
+                       next_size = sizeof(*atomic);
+                       atomic = alloc_wr(next_size, user_wr->num_sge);
                        if (!atomic) {
                                ret = -ENOMEM;
                                goto out_put;
@@ -2540,7 +2546,8 @@ ssize_t ib_uverbs_post_send(struct ib_uverbs_file *file,
                } else if (user_wr->opcode == IB_WR_SEND ||
                           user_wr->opcode == IB_WR_SEND_WITH_IMM ||
                           user_wr->opcode == IB_WR_SEND_WITH_INV) {
-                       next = alloc_wr(sizeof(*next), user_wr->num_sge);
+                       next_size = sizeof(*next);
+                       next = alloc_wr(next_size, user_wr->num_sge);
                        if (!next) {
                                ret = -ENOMEM;
                                goto out_put;
@@ -2572,7 +2579,7 @@ ssize_t ib_uverbs_post_send(struct ib_uverbs_file *file,
 
                if (next->num_sge) {
                        next->sg_list = (void *) next +
-                               ALIGN(sizeof *next, sizeof (struct ib_sge));
+                               ALIGN(next_size, sizeof(struct ib_sge));
                        if (copy_from_user(next->sg_list,
                                           buf + sizeof cmd +
                                           cmd.wr_count * cmd.wqe_size +
index 043a60ee6836db72e498410ebd80e004ed220c7d..545906dec26dc5e936df37c635c68b94bb27e226 100644 (file)
@@ -1516,7 +1516,7 @@ EXPORT_SYMBOL(ib_map_mr_sg);
  * @sg_nents:      number of entries in sg
  * @set_page:      driver page assignment function pointer
  *
- * Core service helper for drivers to covert the largest
+ * Core service helper for drivers to convert the largest
  * prefix of given sg list to a page vector. The sg list
  * prefix converted is the prefix that meet the requirements
  * of ib_map_mr_sg.
@@ -1533,7 +1533,7 @@ int ib_sg_to_pages(struct ib_mr *mr,
        u64 last_end_dma_addr = 0, last_page_addr = 0;
        unsigned int last_page_off = 0;
        u64 page_mask = ~((u64)mr->page_size - 1);
-       int i;
+       int i, ret;
 
        mr->iova = sg_dma_address(&sgl[0]);
        mr->length = 0;
@@ -1544,27 +1544,29 @@ int ib_sg_to_pages(struct ib_mr *mr,
                u64 end_dma_addr = dma_addr + dma_len;
                u64 page_addr = dma_addr & page_mask;
 
-               if (i && page_addr != dma_addr) {
-                       if (last_end_dma_addr != dma_addr) {
-                               /* gap */
-                               goto done;
-
-                       } else if (last_page_off + dma_len <= mr->page_size) {
-                               /* chunk this fragment with the last */
-                               mr->length += dma_len;
-                               last_end_dma_addr += dma_len;
-                               last_page_off += dma_len;
-                               continue;
-                       } else {
-                               /* map starting from the next page */
-                               page_addr = last_page_addr + mr->page_size;
-                               dma_len -= mr->page_size - last_page_off;
-                       }
+               /*
+                * For the second and later elements, check whether either the
+                * end of element i-1 or the start of element i is not aligned
+                * on a page boundary.
+                */
+               if (i && (last_page_off != 0 || page_addr != dma_addr)) {
+                       /* Stop mapping if there is a gap. */
+                       if (last_end_dma_addr != dma_addr)
+                               break;
+
+                       /*
+                        * Coalesce this element with the last. If it is small
+                        * enough just update mr->length. Otherwise start
+                        * mapping from the next page.
+                        */
+                       goto next_page;
                }
 
                do {
-                       if (unlikely(set_page(mr, page_addr)))
-                               goto done;
+                       ret = set_page(mr, page_addr);
+                       if (unlikely(ret < 0))
+                               return i ? : ret;
+next_page:
                        page_addr += mr->page_size;
                } while (page_addr < end_dma_addr);
 
@@ -1574,7 +1576,6 @@ int ib_sg_to_pages(struct ib_mr *mr,
                last_page_off = end_dma_addr & ~page_mask;
        }
 
-done:
        return i;
 }
 EXPORT_SYMBOL(ib_sg_to_pages);
index f567160a4a56ed141320b2d153d21f2031cbb464..97d6878f993828085a0f26f941572674ce68b967 100644 (file)
@@ -456,7 +456,7 @@ static int mlx4_ib_query_device(struct ib_device *ibdev,
        props->max_qp_wr           = dev->dev->caps.max_wqes - MLX4_IB_SQ_MAX_SPARE;
        props->max_sge             = min(dev->dev->caps.max_sq_sg,
                                         dev->dev->caps.max_rq_sg);
-       props->max_sge_rd = props->max_sge;
+       props->max_sge_rd          = MLX4_MAX_SGE_RD;
        props->max_cq              = dev->dev->quotas.cq;
        props->max_cqe             = dev->dev->caps.max_cqes;
        props->max_mr              = dev->dev->quotas.mpt;
index a2e4ca56da44e5d9cec5ee4b6a02cf6ab9d7356c..13eaaf45288f80d4bb6658d5a18985a978e8c98d 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/log2.h>
 #include <linux/slab.h>
 #include <linux/netdevice.h>
+#include <linux/vmalloc.h>
 
 #include <rdma/ib_cache.h>
 #include <rdma/ib_pack.h>
@@ -795,8 +796,14 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd,
                if (err)
                        goto err_mtt;
 
-               qp->sq.wrid  = kmalloc(qp->sq.wqe_cnt * sizeof (u64), gfp);
-               qp->rq.wrid  = kmalloc(qp->rq.wqe_cnt * sizeof (u64), gfp);
+               qp->sq.wrid = kmalloc(qp->sq.wqe_cnt * sizeof(u64), gfp);
+               if (!qp->sq.wrid)
+                       qp->sq.wrid = __vmalloc(qp->sq.wqe_cnt * sizeof(u64),
+                                               gfp, PAGE_KERNEL);
+               qp->rq.wrid = kmalloc(qp->rq.wqe_cnt * sizeof(u64), gfp);
+               if (!qp->rq.wrid)
+                       qp->rq.wrid = __vmalloc(qp->rq.wqe_cnt * sizeof(u64),
+                                               gfp, PAGE_KERNEL);
                if (!qp->sq.wrid || !qp->rq.wrid) {
                        err = -ENOMEM;
                        goto err_wrid;
@@ -886,8 +893,8 @@ err_wrid:
                if (qp_has_rq(init_attr))
                        mlx4_ib_db_unmap_user(to_mucontext(pd->uobject->context), &qp->db);
        } else {
-               kfree(qp->sq.wrid);
-               kfree(qp->rq.wrid);
+               kvfree(qp->sq.wrid);
+               kvfree(qp->rq.wrid);
        }
 
 err_mtt:
@@ -1062,8 +1069,8 @@ static void destroy_qp_common(struct mlx4_ib_dev *dev, struct mlx4_ib_qp *qp,
                                              &qp->db);
                ib_umem_release(qp->umem);
        } else {
-               kfree(qp->sq.wrid);
-               kfree(qp->rq.wrid);
+               kvfree(qp->sq.wrid);
+               kvfree(qp->rq.wrid);
                if (qp->mlx4_ib_qp_type & (MLX4_IB_QPT_PROXY_SMI_OWNER |
                    MLX4_IB_QPT_PROXY_SMI | MLX4_IB_QPT_PROXY_GSI))
                        free_proxy_bufs(&dev->ib_dev, qp);
index dce5dfe3a70ea957a6780eca47e0c15e0d054300..c394376ebe06f159aebca07ef899ef5933386713 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/mlx4/qp.h>
 #include <linux/mlx4/srq.h>
 #include <linux/slab.h>
+#include <linux/vmalloc.h>
 
 #include "mlx4_ib.h"
 #include "user.h"
@@ -172,8 +173,12 @@ struct ib_srq *mlx4_ib_create_srq(struct ib_pd *pd,
 
                srq->wrid = kmalloc(srq->msrq.max * sizeof (u64), GFP_KERNEL);
                if (!srq->wrid) {
-                       err = -ENOMEM;
-                       goto err_mtt;
+                       srq->wrid = __vmalloc(srq->msrq.max * sizeof(u64),
+                                             GFP_KERNEL, PAGE_KERNEL);
+                       if (!srq->wrid) {
+                               err = -ENOMEM;
+                               goto err_mtt;
+                       }
                }
        }
 
@@ -204,7 +209,7 @@ err_wrid:
        if (pd->uobject)
                mlx4_ib_db_unmap_user(to_mucontext(pd->uobject->context), &srq->db);
        else
-               kfree(srq->wrid);
+               kvfree(srq->wrid);
 
 err_mtt:
        mlx4_mtt_cleanup(dev->dev, &srq->mtt);
@@ -281,7 +286,7 @@ int mlx4_ib_destroy_srq(struct ib_srq *srq)
                mlx4_ib_db_unmap_user(to_mucontext(srq->uobject->context), &msrq->db);
                ib_umem_release(msrq->umem);
        } else {
-               kfree(msrq->wrid);
+               kvfree(msrq->wrid);
                mlx4_buf_free(dev->dev, msrq->msrq.max << msrq->msrq.wqe_shift,
                              &msrq->buf);
                mlx4_db_free(dev->dev, &msrq->db);
index ec8993a7b3beea5a91370c1f66979dae583f49d4..6000f7aeede94301cbb7c281bfaae26299770106 100644 (file)
@@ -381,7 +381,19 @@ static void __cache_work_func(struct mlx5_cache_ent *ent)
                        }
                }
        } else if (ent->cur > 2 * ent->limit) {
-               if (!someone_adding(cache) &&
+               /*
+                * The remove_keys() logic is performed as garbage collection
+                * task. Such task is intended to be run when no other active
+                * processes are running.
+                *
+                * The need_resched() will return TRUE if there are user tasks
+                * to be activated in near future.
+                *
+                * In such case, we don't execute remove_keys() and postpone
+                * the garbage collection work to try to run in next cycle,
+                * in order to free CPU resources to other tasks.
+                */
+               if (!need_resched() && !someone_adding(cache) &&
                    time_after(jiffies, cache->last_add + 300 * HZ)) {
                        remove_keys(dev, i, 1);
                        if (ent->cur > ent->limit)
index ae80590aabdf7db6df756c0ee07afa4721f6c37c..040bb8b5cb15a65c34b15ab67c3c5fe14e27524c 100644 (file)
@@ -232,6 +232,10 @@ struct phy_info {
        u16 interface_type;
 };
 
+enum ocrdma_flags {
+       OCRDMA_FLAGS_LINK_STATUS_INIT = 0x01
+};
+
 struct ocrdma_dev {
        struct ib_device ibdev;
        struct ocrdma_dev_attr attr;
@@ -287,6 +291,7 @@ struct ocrdma_dev {
        atomic_t update_sl;
        u16 pvid;
        u32 asic_id;
+       u32 flags;
 
        ulong last_stats_time;
        struct mutex stats_lock; /* provide synch for debugfs operations */
@@ -591,4 +596,9 @@ static inline u8 ocrdma_is_enabled_and_synced(u32 state)
                (state & OCRDMA_STATE_FLAG_SYNC);
 }
 
+static inline u8 ocrdma_get_ae_link_state(u32 ae_state)
+{
+       return ((ae_state & OCRDMA_AE_LSC_LS_MASK) >> OCRDMA_AE_LSC_LS_SHIFT);
+}
+
 #endif
index 30f67bebffa35742189c4fc08b91654f75bfdcfa..283ca842ff7498b308fcec85a1268dcb452d56b0 100644 (file)
@@ -579,6 +579,8 @@ static int ocrdma_mbx_create_mq(struct ocrdma_dev *dev,
 
        cmd->async_event_bitmap = BIT(OCRDMA_ASYNC_GRP5_EVE_CODE);
        cmd->async_event_bitmap |= BIT(OCRDMA_ASYNC_RDMA_EVE_CODE);
+       /* Request link events on this  MQ. */
+       cmd->async_event_bitmap |= BIT(OCRDMA_ASYNC_LINK_EVE_CODE);
 
        cmd->async_cqid_ringsize = cq->id;
        cmd->async_cqid_ringsize |= (ocrdma_encoded_q_len(mq->len) <<
@@ -819,20 +821,42 @@ static void ocrdma_process_grp5_aync(struct ocrdma_dev *dev,
        }
 }
 
+static void ocrdma_process_link_state(struct ocrdma_dev *dev,
+                                     struct ocrdma_ae_mcqe *cqe)
+{
+       struct ocrdma_ae_lnkst_mcqe *evt;
+       u8 lstate;
+
+       evt = (struct ocrdma_ae_lnkst_mcqe *)cqe;
+       lstate = ocrdma_get_ae_link_state(evt->speed_state_ptn);
+
+       if (!(lstate & OCRDMA_AE_LSC_LLINK_MASK))
+               return;
+
+       if (dev->flags & OCRDMA_FLAGS_LINK_STATUS_INIT)
+               ocrdma_update_link_state(dev, (lstate & OCRDMA_LINK_ST_MASK));
+}
+
 static void ocrdma_process_acqe(struct ocrdma_dev *dev, void *ae_cqe)
 {
        /* async CQE processing */
        struct ocrdma_ae_mcqe *cqe = ae_cqe;
        u32 evt_code = (cqe->valid_ae_event & OCRDMA_AE_MCQE_EVENT_CODE_MASK) >>
                        OCRDMA_AE_MCQE_EVENT_CODE_SHIFT;
-
-       if (evt_code == OCRDMA_ASYNC_RDMA_EVE_CODE)
+       switch (evt_code) {
+       case OCRDMA_ASYNC_LINK_EVE_CODE:
+               ocrdma_process_link_state(dev, cqe);
+               break;
+       case OCRDMA_ASYNC_RDMA_EVE_CODE:
                ocrdma_dispatch_ibevent(dev, cqe);
-       else if (evt_code == OCRDMA_ASYNC_GRP5_EVE_CODE)
+               break;
+       case OCRDMA_ASYNC_GRP5_EVE_CODE:
                ocrdma_process_grp5_aync(dev, cqe);
-       else
+               break;
+       default:
                pr_err("%s(%d) invalid evt code=0x%x\n", __func__,
                       dev->id, evt_code);
+       }
 }
 
 static void ocrdma_process_mcqe(struct ocrdma_dev *dev, struct ocrdma_mcqe *cqe)
@@ -1363,7 +1387,8 @@ mbx_err:
        return status;
 }
 
-int ocrdma_mbx_get_link_speed(struct ocrdma_dev *dev, u8 *lnk_speed)
+int ocrdma_mbx_get_link_speed(struct ocrdma_dev *dev, u8 *lnk_speed,
+                             u8 *lnk_state)
 {
        int status = -ENOMEM;
        struct ocrdma_get_link_speed_rsp *rsp;
@@ -1384,8 +1409,11 @@ int ocrdma_mbx_get_link_speed(struct ocrdma_dev *dev, u8 *lnk_speed)
                goto mbx_err;
 
        rsp = (struct ocrdma_get_link_speed_rsp *)cmd;
-       *lnk_speed = (rsp->pflt_pps_ld_pnum & OCRDMA_PHY_PS_MASK)
-                       >> OCRDMA_PHY_PS_SHIFT;
+       if (lnk_speed)
+               *lnk_speed = (rsp->pflt_pps_ld_pnum & OCRDMA_PHY_PS_MASK)
+                             >> OCRDMA_PHY_PS_SHIFT;
+       if (lnk_state)
+               *lnk_state = (rsp->res_lnk_st & OCRDMA_LINK_ST_MASK);
 
 mbx_err:
        kfree(cmd);
@@ -2515,9 +2543,10 @@ static int ocrdma_set_av_params(struct ocrdma_qp *qp,
        ocrdma_cpu_to_le32(&cmd->params.sgid[0], sizeof(cmd->params.sgid));
        cmd->params.vlan_dmac_b4_to_b5 = mac_addr[4] | (mac_addr[5] << 8);
 
-       if (vlan_id < 0x1000) {
-               if (dev->pfc_state) {
-                       vlan_id = 0;
+       if (vlan_id == 0xFFFF)
+               vlan_id = 0;
+       if (vlan_id || dev->pfc_state) {
+               if (!vlan_id) {
                        pr_err("ocrdma%d:Using VLAN with PFC is recommended\n",
                               dev->id);
                        pr_err("ocrdma%d:Using VLAN 0 for this connection\n",
index 7ed885c1851e28740b81a0588493c0d0ca92bc42..ebc1f442aec37aabd691d374deb3fdd41acc4302 100644 (file)
@@ -106,7 +106,8 @@ void ocrdma_ring_cq_db(struct ocrdma_dev *, u16 cq_id, bool armed,
                       bool solicited, u16 cqe_popped);
 
 /* verbs specific mailbox commands */
-int ocrdma_mbx_get_link_speed(struct ocrdma_dev *dev, u8 *lnk_speed);
+int ocrdma_mbx_get_link_speed(struct ocrdma_dev *dev, u8 *lnk_speed,
+                             u8 *lnk_st);
 int ocrdma_query_config(struct ocrdma_dev *,
                        struct ocrdma_mbx_query_config *config);
 
@@ -153,5 +154,6 @@ char *port_speed_string(struct ocrdma_dev *dev);
 void ocrdma_init_service_level(struct ocrdma_dev *);
 void ocrdma_alloc_pd_pool(struct ocrdma_dev *dev);
 void ocrdma_free_pd_range(struct ocrdma_dev *dev);
+void ocrdma_update_link_state(struct ocrdma_dev *dev, u8 lstate);
 
 #endif                         /* __OCRDMA_HW_H__ */
index 62b7009daa6c18a4d21002636637b5a2d258b231..3afb40b85159bd2c10559443536f83af5e4fa9ca 100644 (file)
@@ -290,6 +290,7 @@ static void ocrdma_remove_sysfiles(struct ocrdma_dev *dev)
 static struct ocrdma_dev *ocrdma_add(struct be_dev_info *dev_info)
 {
        int status = 0, i;
+       u8 lstate = 0;
        struct ocrdma_dev *dev;
 
        dev = (struct ocrdma_dev *)ib_alloc_device(sizeof(struct ocrdma_dev));
@@ -319,6 +320,11 @@ static struct ocrdma_dev *ocrdma_add(struct be_dev_info *dev_info)
        if (status)
                goto alloc_err;
 
+       /* Query Link state and update */
+       status = ocrdma_mbx_get_link_speed(dev, NULL, &lstate);
+       if (!status)
+               ocrdma_update_link_state(dev, lstate);
+
        for (i = 0; i < ARRAY_SIZE(ocrdma_attributes); i++)
                if (device_create_file(&dev->ibdev.dev, ocrdma_attributes[i]))
                        goto sysfs_err;
@@ -373,7 +379,7 @@ static void ocrdma_remove(struct ocrdma_dev *dev)
        ocrdma_remove_free(dev);
 }
 
-static int ocrdma_open(struct ocrdma_dev *dev)
+static int ocrdma_dispatch_port_active(struct ocrdma_dev *dev)
 {
        struct ib_event port_event;
 
@@ -384,32 +390,9 @@ static int ocrdma_open(struct ocrdma_dev *dev)
        return 0;
 }
 
-static int ocrdma_close(struct ocrdma_dev *dev)
+static int ocrdma_dispatch_port_error(struct ocrdma_dev *dev)
 {
-       int i;
-       struct ocrdma_qp *qp, **cur_qp;
        struct ib_event err_event;
-       struct ib_qp_attr attrs;
-       int attr_mask = IB_QP_STATE;
-
-       attrs.qp_state = IB_QPS_ERR;
-       mutex_lock(&dev->dev_lock);
-       if (dev->qp_tbl) {
-               cur_qp = dev->qp_tbl;
-               for (i = 0; i < OCRDMA_MAX_QP; i++) {
-                       qp = cur_qp[i];
-                       if (qp && qp->ibqp.qp_type != IB_QPT_GSI) {
-                               /* change the QP state to ERROR */
-                               _ocrdma_modify_qp(&qp->ibqp, &attrs, attr_mask);
-
-                               err_event.event = IB_EVENT_QP_FATAL;
-                               err_event.element.qp = &qp->ibqp;
-                               err_event.device = &dev->ibdev;
-                               ib_dispatch_event(&err_event);
-                       }
-               }
-       }
-       mutex_unlock(&dev->dev_lock);
 
        err_event.event = IB_EVENT_PORT_ERR;
        err_event.element.port_num = 1;
@@ -420,7 +403,7 @@ static int ocrdma_close(struct ocrdma_dev *dev)
 
 static void ocrdma_shutdown(struct ocrdma_dev *dev)
 {
-       ocrdma_close(dev);
+       ocrdma_dispatch_port_error(dev);
        ocrdma_remove(dev);
 }
 
@@ -431,18 +414,28 @@ static void ocrdma_shutdown(struct ocrdma_dev *dev)
 static void ocrdma_event_handler(struct ocrdma_dev *dev, u32 event)
 {
        switch (event) {
-       case BE_DEV_UP:
-               ocrdma_open(dev);
-               break;
-       case BE_DEV_DOWN:
-               ocrdma_close(dev);
-               break;
        case BE_DEV_SHUTDOWN:
                ocrdma_shutdown(dev);
                break;
+       default:
+               break;
        }
 }
 
+void ocrdma_update_link_state(struct ocrdma_dev *dev, u8 lstate)
+{
+       if (!(dev->flags & OCRDMA_FLAGS_LINK_STATUS_INIT)) {
+               dev->flags |= OCRDMA_FLAGS_LINK_STATUS_INIT;
+               if (!lstate)
+                       return;
+       }
+
+       if (!lstate)
+               ocrdma_dispatch_port_error(dev);
+       else
+               ocrdma_dispatch_port_active(dev);
+}
+
 static struct ocrdma_driver ocrdma_drv = {
        .name                   = "ocrdma_driver",
        .add                    = ocrdma_add,
index 6a38268bbe9fb6b981e27f2ec42da8fd10adbfc2..99dd6fdf06d7b44bcea2f0fb28b90edf54aefcc0 100644 (file)
@@ -465,8 +465,11 @@ struct ocrdma_ae_qp_mcqe {
        u32 valid_ae_event;
 };
 
-#define OCRDMA_ASYNC_RDMA_EVE_CODE 0x14
-#define OCRDMA_ASYNC_GRP5_EVE_CODE 0x5
+enum ocrdma_async_event_code {
+       OCRDMA_ASYNC_LINK_EVE_CODE      = 0x01,
+       OCRDMA_ASYNC_GRP5_EVE_CODE      = 0x05,
+       OCRDMA_ASYNC_RDMA_EVE_CODE      = 0x14
+};
 
 enum ocrdma_async_grp5_events {
        OCRDMA_ASYNC_EVENT_QOS_VALUE    = 0x01,
@@ -489,6 +492,44 @@ enum OCRDMA_ASYNC_EVENT_TYPE {
        OCRDMA_MAX_ASYNC_ERRORS
 };
 
+struct ocrdma_ae_lnkst_mcqe {
+       u32 speed_state_ptn;
+       u32 qos_reason_falut;
+       u32 evt_tag;
+       u32 valid_ae_event;
+};
+
+enum {
+       OCRDMA_AE_LSC_PORT_NUM_MASK     = 0x3F,
+       OCRDMA_AE_LSC_PT_SHIFT          = 0x06,
+       OCRDMA_AE_LSC_PT_MASK           = (0x03 <<
+                       OCRDMA_AE_LSC_PT_SHIFT),
+       OCRDMA_AE_LSC_LS_SHIFT          = 0x08,
+       OCRDMA_AE_LSC_LS_MASK           = (0xFF <<
+                       OCRDMA_AE_LSC_LS_SHIFT),
+       OCRDMA_AE_LSC_LD_SHIFT          = 0x10,
+       OCRDMA_AE_LSC_LD_MASK           = (0xFF <<
+                       OCRDMA_AE_LSC_LD_SHIFT),
+       OCRDMA_AE_LSC_PPS_SHIFT         = 0x18,
+       OCRDMA_AE_LSC_PPS_MASK          = (0xFF <<
+                       OCRDMA_AE_LSC_PPS_SHIFT),
+       OCRDMA_AE_LSC_PPF_MASK          = 0xFF,
+       OCRDMA_AE_LSC_ER_SHIFT          = 0x08,
+       OCRDMA_AE_LSC_ER_MASK           = (0xFF <<
+                       OCRDMA_AE_LSC_ER_SHIFT),
+       OCRDMA_AE_LSC_QOS_SHIFT         = 0x10,
+       OCRDMA_AE_LSC_QOS_MASK          = (0xFFFF <<
+                       OCRDMA_AE_LSC_QOS_SHIFT)
+};
+
+enum {
+       OCRDMA_AE_LSC_PLINK_DOWN        = 0x00,
+       OCRDMA_AE_LSC_PLINK_UP          = 0x01,
+       OCRDMA_AE_LSC_LLINK_DOWN        = 0x02,
+       OCRDMA_AE_LSC_LLINK_MASK        = 0x02,
+       OCRDMA_AE_LSC_LLINK_UP          = 0x03
+};
+
 /* mailbox command request and responses */
 enum {
        OCRDMA_MBX_QUERY_CFG_CQ_OVERFLOW_SHIFT          = 2,
@@ -676,7 +717,7 @@ enum {
        OCRDMA_PHY_PFLT_SHIFT   = 0x18,
        OCRDMA_QOS_LNKSP_MASK   = 0xFFFF0000,
        OCRDMA_QOS_LNKSP_SHIFT  = 0x10,
-       OCRDMA_LLST_MASK        = 0xFF,
+       OCRDMA_LINK_ST_MASK     = 0x01,
        OCRDMA_PLFC_MASK        = 0x00000400,
        OCRDMA_PLFC_SHIFT       = 0x8,
        OCRDMA_PLRFC_MASK       = 0x00000200,
@@ -691,7 +732,7 @@ struct ocrdma_get_link_speed_rsp {
 
        u32 pflt_pps_ld_pnum;
        u32 qos_lsp;
-       u32 res_lls;
+       u32 res_lnk_st;
 };
 
 enum {
index 583001bcfb8fc8c10a1e088b451d7de12adc2aa8..76e96f97b3f6459e68d13c444be6e1beb6b578a9 100644 (file)
@@ -171,7 +171,7 @@ static inline void get_link_speed_and_width(struct ocrdma_dev *dev,
        int status;
        u8 speed;
 
-       status = ocrdma_mbx_get_link_speed(dev, &speed);
+       status = ocrdma_mbx_get_link_speed(dev, &speed, NULL);
        if (status)
                speed = OCRDMA_PHYS_LINK_SPEED_ZERO;
 
index 5e27f76805e28af0c0e0acdc9864360f8cf09b41..4c7c3c84a7417c32f2f348f7c91c2ce0e4b4e1b0 100644 (file)
@@ -292,7 +292,7 @@ int qib_refresh_qsfp_cache(struct qib_pportdata *ppd, struct qib_qsfp_cache *cp)
                qib_dev_porterr(ppd->dd, ppd->port,
                                "QSFP byte0 is 0x%02X, S/B 0x0C/D\n", peek[0]);
 
-       if ((peek[2] & 2) == 0) {
+       if ((peek[2] & 4) == 0) {
                /*
                 * If cable is paged, rather than "flat memory", we need to
                 * set the page to zero, Even if it already appears to be zero.
@@ -538,7 +538,7 @@ int qib_qsfp_dump(struct qib_pportdata *ppd, char *buf, int len)
        sofar += scnprintf(buf + sofar, len - sofar, "Date:%.*s\n",
                           QSFP_DATE_LEN, cd.date);
        sofar += scnprintf(buf + sofar, len - sofar, "Lot:%.*s\n",
-                          QSFP_LOT_LEN, cd.date);
+                          QSFP_LOT_LEN, cd.lot);
 
        while (bidx < QSFP_DEFAULT_HDR_CNT) {
                int iidx;
index 2baf5ad251ed24a02682051058e6d1a406419e04..bc803f33d5f6883200ca21e462febebb94393cd4 100644 (file)
@@ -329,9 +329,9 @@ struct qib_sge {
 struct qib_mr {
        struct ib_mr ibmr;
        struct ib_umem *umem;
-       struct qib_mregion mr;  /* must be last */
        u64 *pages;
        u32 npages;
+       struct qib_mregion mr;  /* must be last */
 };
 
 /*
index a93070210109699909075e02212fc6ae70710960..42f4da620f2e9f97062b9183b6ebf3ed54e56cfe 100644 (file)
@@ -1293,7 +1293,7 @@ u8 iser_check_task_pi_status(struct iscsi_iser_task *iser_task,
                if (mr_status.fail_status & IB_MR_CHECK_SIG_STATUS) {
                        sector_t sector_off = mr_status.sig_err.sig_err_offset;
 
-                       do_div(sector_off, sector_size + 8);
+                       sector_div(sector_off, sector_size + 8);
                        *sector = scsi_get_lba(iser_task->sc) + sector_off;
 
                        pr_err("PI error found type %d at sector %llx "
index dfbbbb28090b2301c7742fd28b145b62054a76af..8a51c3b5d657e5a49ae50c4e5f104a7298d732f2 100644 (file)
@@ -157,16 +157,9 @@ isert_create_qp(struct isert_conn *isert_conn,
        attr.recv_cq = comp->cq;
        attr.cap.max_send_wr = ISERT_QP_MAX_REQ_DTOS;
        attr.cap.max_recv_wr = ISERT_QP_MAX_RECV_DTOS + 1;
-       /*
-        * FIXME: Use devattr.max_sge - 2 for max_send_sge as
-        * work-around for RDMA_READs with ConnectX-2.
-        *
-        * Also, still make sure to have at least two SGEs for
-        * outgoing control PDU responses.
-        */
-       attr.cap.max_send_sge = max(2, device->dev_attr.max_sge - 2);
-       isert_conn->max_sge = attr.cap.max_send_sge;
-
+       attr.cap.max_send_sge = device->dev_attr.max_sge;
+       isert_conn->max_sge = min(device->dev_attr.max_sge,
+                                 device->dev_attr.max_sge_rd);
        attr.cap.max_recv_sge = 1;
        attr.sq_sig_type = IB_SIGNAL_REQ_WR;
        attr.qp_type = IB_QPT_RC;
index 9909022dc6c3eebd4c52ef3e7dca5221dc8b6038..3db9a659719b0f6283af610bf01b8f65d27292a9 100644 (file)
@@ -488,7 +488,7 @@ static int srp_create_ch_ib(struct srp_rdma_ch *ch)
        struct ib_qp *qp;
        struct ib_fmr_pool *fmr_pool = NULL;
        struct srp_fr_pool *fr_pool = NULL;
-       const int m = 1 + dev->use_fast_reg;
+       const int m = dev->use_fast_reg ? 3 : 1;
        struct ib_cq_init_attr cq_attr = {};
        int ret;
 
@@ -994,16 +994,16 @@ static int srp_connect_ch(struct srp_rdma_ch *ch, bool multich)
 
        ret = srp_lookup_path(ch);
        if (ret)
-               return ret;
+               goto out;
 
        while (1) {
                init_completion(&ch->done);
                ret = srp_send_req(ch, multich);
                if (ret)
-                       return ret;
+                       goto out;
                ret = wait_for_completion_interruptible(&ch->done);
                if (ret < 0)
-                       return ret;
+                       goto out;
 
                /*
                 * The CM event handling code will set status to
@@ -1011,15 +1011,16 @@ static int srp_connect_ch(struct srp_rdma_ch *ch, bool multich)
                 * back, or SRP_DLID_REDIRECT if we get a lid/qp
                 * redirect REJ back.
                 */
-               switch (ch->status) {
+               ret = ch->status;
+               switch (ret) {
                case 0:
                        ch->connected = true;
-                       return 0;
+                       goto out;
 
                case SRP_PORT_REDIRECT:
                        ret = srp_lookup_path(ch);
                        if (ret)
-                               return ret;
+                               goto out;
                        break;
 
                case SRP_DLID_REDIRECT:
@@ -1028,13 +1029,16 @@ static int srp_connect_ch(struct srp_rdma_ch *ch, bool multich)
                case SRP_STALE_CONN:
                        shost_printk(KERN_ERR, target->scsi_host, PFX
                                     "giving up on stale connection\n");
-                       ch->status = -ECONNRESET;
-                       return ch->status;
+                       ret = -ECONNRESET;
+                       goto out;
 
                default:
-                       return ch->status;
+                       goto out;
                }
        }
+
+out:
+       return ret <= 0 ? ret : -ENODEV;
 }
 
 static int srp_inv_rkey(struct srp_rdma_ch *ch, u32 rkey)
@@ -1309,7 +1313,7 @@ reset_state:
 }
 
 static int srp_map_finish_fr(struct srp_map_state *state,
-                            struct srp_rdma_ch *ch)
+                            struct srp_rdma_ch *ch, int sg_nents)
 {
        struct srp_target_port *target = ch->target;
        struct srp_device *dev = target->srp_host->srp_dev;
@@ -1324,10 +1328,10 @@ static int srp_map_finish_fr(struct srp_map_state *state,
 
        WARN_ON_ONCE(!dev->use_fast_reg);
 
-       if (state->sg_nents == 0)
+       if (sg_nents == 0)
                return 0;
 
-       if (state->sg_nents == 1 && target->global_mr) {
+       if (sg_nents == 1 && target->global_mr) {
                srp_map_desc(state, sg_dma_address(state->sg),
                             sg_dma_len(state->sg),
                             target->global_mr->rkey);
@@ -1341,8 +1345,7 @@ static int srp_map_finish_fr(struct srp_map_state *state,
        rkey = ib_inc_rkey(desc->mr->rkey);
        ib_update_fast_reg_key(desc->mr, rkey);
 
-       n = ib_map_mr_sg(desc->mr, state->sg, state->sg_nents,
-                        dev->mr_page_size);
+       n = ib_map_mr_sg(desc->mr, state->sg, sg_nents, dev->mr_page_size);
        if (unlikely(n < 0))
                return n;
 
@@ -1448,16 +1451,15 @@ static int srp_map_sg_fr(struct srp_map_state *state, struct srp_rdma_ch *ch,
        state->fr.next = req->fr_list;
        state->fr.end = req->fr_list + ch->target->cmd_sg_cnt;
        state->sg = scat;
-       state->sg_nents = scsi_sg_count(req->scmnd);
 
-       while (state->sg_nents) {
+       while (count) {
                int i, n;
 
-               n = srp_map_finish_fr(state, ch);
+               n = srp_map_finish_fr(state, ch, count);
                if (unlikely(n < 0))
                        return n;
 
-               state->sg_nents -= n;
+               count -= n;
                for (i = 0; i < n; i++)
                        state->sg = sg_next(state->sg);
        }
@@ -1517,10 +1519,12 @@ static int srp_map_idb(struct srp_rdma_ch *ch, struct srp_request *req,
 
        if (dev->use_fast_reg) {
                state.sg = idb_sg;
-               state.sg_nents = 1;
                sg_set_buf(idb_sg, req->indirect_desc, idb_len);
                idb_sg->dma_address = req->indirect_dma_addr; /* hack! */
-               ret = srp_map_finish_fr(&state, ch);
+#ifdef CONFIG_NEED_SG_DMA_LENGTH
+               idb_sg->dma_length = idb_sg->length;          /* hack^2 */
+#endif
+               ret = srp_map_finish_fr(&state, ch, 1);
                if (ret < 0)
                        return ret;
        } else if (dev->use_fmr) {
@@ -1655,7 +1659,7 @@ static int srp_map_data(struct scsi_cmnd *scmnd, struct srp_rdma_ch *ch,
                        return ret;
                req->nmdesc++;
        } else {
-               idb_rkey = target->global_mr->rkey;
+               idb_rkey = cpu_to_be32(target->global_mr->rkey);
        }
 
        indirect_hdr->table_desc.va = cpu_to_be64(req->indirect_dma_addr);
index 87a2a919dc43877141426e6d373d12727dc4b65e..f6af531f9f32c990cd30c7139d247c643144e55d 100644 (file)
@@ -300,10 +300,7 @@ struct srp_map_state {
        dma_addr_t              base_dma_addr;
        u32                     dma_len;
        u32                     total_len;
-       union {
-               unsigned int    npages;
-               int             sg_nents;
-       };
+       unsigned int            npages;
        unsigned int            nmdesc;
        unsigned int            ndesc;
 };
index 932d07307454bd47441da61ff06e3ef03ea93cd4..da326090c2b0e7f07ab4de5668012b1a4d5e92f3 100644 (file)
@@ -592,6 +592,7 @@ static void db9_attach(struct parport *pp)
                return;
        }
 
+       memset(&db9_parport_cb, 0, sizeof(db9_parport_cb));
        db9_parport_cb.flags = PARPORT_FLAG_EXCL;
 
        pd = parport_register_dev_model(pp, "db9", &db9_parport_cb, port_idx);
index 5a672dcac0d8174a151254ac31b591f0189f9d91..eae14d512353aae4902f3ce482c1cf87cba736b6 100644 (file)
@@ -951,6 +951,7 @@ static void gc_attach(struct parport *pp)
        pads = gc_cfg[port_idx].args + 1;
        n_pads = gc_cfg[port_idx].nargs - 1;
 
+       memset(&gc_parport_cb, 0, sizeof(gc_parport_cb));
        gc_parport_cb.flags = PARPORT_FLAG_EXCL;
 
        pd = parport_register_dev_model(pp, "gamecon", &gc_parport_cb,
index 9f5bca26bd2fb85a90ed4fd91bbdcf1a83e84162..77f575dd0901ff2732f47a62ebb7af37b826b608 100644 (file)
@@ -181,6 +181,7 @@ static void tgfx_attach(struct parport *pp)
        n_buttons = tgfx_cfg[port_idx].args + 1;
        n_devs = tgfx_cfg[port_idx].nargs - 1;
 
+       memset(&tgfx_parport_cb, 0, sizeof(tgfx_parport_cb));
        tgfx_parport_cb.flags = PARPORT_FLAG_EXCL;
 
        pd = parport_register_dev_model(pp, "turbografx", &tgfx_parport_cb,
index 9c07fe911075f3e1dba089f07d7d60d10ac327ba..70a893a17467608a103a81546eb7cce4cdf44010 100644 (file)
@@ -218,6 +218,7 @@ static void walkera0701_attach(struct parport *pp)
 
        w->parport = pp;
 
+       memset(&walkera0701_parport_cb, 0, sizeof(walkera0701_parport_cb));
        walkera0701_parport_cb.flags = PARPORT_FLAG_EXCL;
        walkera0701_parport_cb.irq_func = walkera0701_irq_handler;
        walkera0701_parport_cb.private = w;
index 4bf678541496e5971a3aa88cf9ded8e89558786a..d5994a745ffa5b5f4d1b411fec76f0a447a60f94 100644 (file)
@@ -97,8 +97,7 @@ static void arizona_haptics_work(struct work_struct *work)
 
                ret = regmap_update_bits(arizona->regmap,
                                         ARIZONA_HAPTICS_CONTROL_1,
-                                        ARIZONA_HAP_CTRL_MASK,
-                                        1 << ARIZONA_HAP_CTRL_SHIFT);
+                                        ARIZONA_HAP_CTRL_MASK, 0);
                if (ret != 0) {
                        dev_err(arizona->dev, "Failed to stop haptics: %d\n",
                                ret);
index 5e1665bbaa0baca86e2c865ba88162be2f209d2e..2f589857a0395d8c48f685f47bd1c9ceb8445213 100644 (file)
@@ -41,6 +41,7 @@
 
 #define DRIVER_NAME            "elan_i2c"
 #define ELAN_DRIVER_VERSION    "1.6.1"
+#define ELAN_VENDOR_ID         0x04f3
 #define ETP_MAX_PRESSURE       255
 #define ETP_FWIDTH_REDUCE      90
 #define ETP_FINGER_WIDTH       15
@@ -914,6 +915,8 @@ static int elan_setup_input_device(struct elan_tp_data *data)
 
        input->name = "Elan Touchpad";
        input->id.bustype = BUS_I2C;
+       input->id.vendor = ELAN_VENDOR_ID;
+       input->id.product = data->product_id;
        input_set_drvdata(input, data);
 
        error = input_mt_init_slots(input, ETP_MAX_FINGERS,
index 92c31b8f8fb489c317013f1cf77f133993fcc321..1edfac78d4ac742a8fe6d6183660c45652381804 100644 (file)
@@ -145,6 +145,7 @@ static int parkbd_getport(struct parport *pp)
 {
        struct pardev_cb parkbd_parport_cb;
 
+       memset(&parkbd_parport_cb, 0, sizeof(parkbd_parport_cb));
        parkbd_parport_cb.irq_func = parkbd_interrupt;
        parkbd_parport_cb.flags = PARPORT_FLAG_EXCL;
 
index e7f966da6efa318f1901ce912e4e0dd65b5c70f7..78ca44840d60cac1467c90cb563cedf2a05fcaab 100644 (file)
@@ -1819,6 +1819,14 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id)
        input_set_abs_params(inputdev, ABS_TILT_Y, AIPTEK_TILT_MIN, AIPTEK_TILT_MAX, 0, 0);
        input_set_abs_params(inputdev, ABS_WHEEL, AIPTEK_WHEEL_MIN, AIPTEK_WHEEL_MAX - 1, 0, 0);
 
+       /* Verify that a device really has an endpoint */
+       if (intf->altsetting[0].desc.bNumEndpoints < 1) {
+               dev_err(&intf->dev,
+                       "interface has %d endpoints, but must have minimum 1\n",
+                       intf->altsetting[0].desc.bNumEndpoints);
+               err = -EINVAL;
+               goto fail3;
+       }
        endpoint = &intf->altsetting[0].endpoint[0].desc;
 
        /* Go set up our URB, which is called when the tablet receives
@@ -1861,6 +1869,7 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id)
        if (i == ARRAY_SIZE(speeds)) {
                dev_info(&intf->dev,
                         "Aiptek tried all speeds, no sane response\n");
+               err = -EINVAL;
                goto fail3;
        }
 
index c5622058c22bba77b14ed336b764dc7b1ac6c617..2d5794ec338b72a1cea0367bccdaf9654db025d4 100644 (file)
@@ -2487,6 +2487,31 @@ static struct mxt_acpi_platform_data samus_platform_data[] = {
        { }
 };
 
+static unsigned int chromebook_tp_buttons[] = {
+       KEY_RESERVED,
+       KEY_RESERVED,
+       KEY_RESERVED,
+       KEY_RESERVED,
+       KEY_RESERVED,
+       BTN_LEFT
+};
+
+static struct mxt_acpi_platform_data chromebook_platform_data[] = {
+       {
+               /* Touchpad */
+               .hid    = "ATML0000",
+               .pdata  = {
+                       .t19_num_keys   = ARRAY_SIZE(chromebook_tp_buttons),
+                       .t19_keymap     = chromebook_tp_buttons,
+               },
+       },
+       {
+               /* Touchscreen */
+               .hid    = "ATML0001",
+       },
+       { }
+};
+
 static const struct dmi_system_id mxt_dmi_table[] = {
        {
                /* 2015 Google Pixel */
@@ -2497,6 +2522,14 @@ static const struct dmi_system_id mxt_dmi_table[] = {
                },
                .driver_data = samus_platform_data,
        },
+       {
+               /* Other Google Chromebooks */
+               .ident = "Chromebook",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "GOOGLE"),
+               },
+               .driver_data = chromebook_platform_data,
+       },
        { }
 };
 
@@ -2701,6 +2734,7 @@ static const struct i2c_device_id mxt_id[] = {
        { "qt602240_ts", 0 },
        { "atmel_mxt_ts", 0 },
        { "atmel_mxt_tp", 0 },
+       { "maxtouch", 0 },
        { "mXT224", 0 },
        { }
 };
index 17cc20ef4923bdb2fb2edcf770d7c303be9d6af5..ac09855fa435d7fc2d87fb801fb277bb55f086ba 100644 (file)
@@ -1316,7 +1316,13 @@ static int __maybe_unused elants_i2c_suspend(struct device *dev)
 
        disable_irq(client->irq);
 
-       if (device_may_wakeup(dev) || ts->keep_power_in_suspend) {
+       if (device_may_wakeup(dev)) {
+               /*
+                * The device will automatically enter idle mode
+                * that has reduced power consumption.
+                */
+               ts->wake_irq_enabled = (enable_irq_wake(client->irq) == 0);
+       } else if (ts->keep_power_in_suspend) {
                for (retry_cnt = 0; retry_cnt < MAX_RETRIES; retry_cnt++) {
                        error = elants_i2c_send(client, set_sleep_cmd,
                                                sizeof(set_sleep_cmd));
@@ -1326,10 +1332,6 @@ static int __maybe_unused elants_i2c_suspend(struct device *dev)
                        dev_err(&client->dev,
                                "suspend command failed: %d\n", error);
                }
-
-               if (device_may_wakeup(dev))
-                       ts->wake_irq_enabled =
-                                       (enable_irq_wake(client->irq) == 0);
        } else {
                elants_i2c_power_off(ts);
        }
@@ -1345,10 +1347,11 @@ static int __maybe_unused elants_i2c_resume(struct device *dev)
        int retry_cnt;
        int error;
 
-       if (device_may_wakeup(dev) && ts->wake_irq_enabled)
-               disable_irq_wake(client->irq);
-
-       if (ts->keep_power_in_suspend) {
+       if (device_may_wakeup(dev)) {
+               if (ts->wake_irq_enabled)
+                       disable_irq_wake(client->irq);
+               elants_i2c_sw_reset(client);
+       } else if (ts->keep_power_in_suspend) {
                for (retry_cnt = 0; retry_cnt < MAX_RETRIES; retry_cnt++) {
                        error = elants_i2c_send(client, set_active_cmd,
                                                sizeof(set_active_cmd));
index d21d4edf7236abac49072c086290b76d2ae201b5..7caf2fa237f22bd7a3b0932c6387ed52e0b26424 100644 (file)
@@ -494,6 +494,22 @@ static void handle_fault_error(struct fault *fault)
        }
 }
 
+static bool access_error(struct vm_area_struct *vma, struct fault *fault)
+{
+       unsigned long requested = 0;
+
+       if (fault->flags & PPR_FAULT_EXEC)
+               requested |= VM_EXEC;
+
+       if (fault->flags & PPR_FAULT_READ)
+               requested |= VM_READ;
+
+       if (fault->flags & PPR_FAULT_WRITE)
+               requested |= VM_WRITE;
+
+       return (requested & ~vma->vm_flags) != 0;
+}
+
 static void do_fault(struct work_struct *work)
 {
        struct fault *fault = container_of(work, struct fault, work);
@@ -516,8 +532,8 @@ static void do_fault(struct work_struct *work)
                goto out;
        }
 
-       if (!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE))) {
-               /* handle_mm_fault would BUG_ON() */
+       /* Check if we have the right permissions on the vma */
+       if (access_error(vma, fault)) {
                up_read(&mm->mmap_sem);
                handle_fault_error(fault);
                goto out;
index 3a20db4f8604f77d7bd374c9b9278f65a8c2cb5c..72d6182666cbd24ba785fc59572c655b6f0c2c8f 100644 (file)
 
 #include <linux/device.h>
 #include <linux/dma-iommu.h>
+#include <linux/gfp.h>
 #include <linux/huge_mm.h>
 #include <linux/iommu.h>
 #include <linux/iova.h>
 #include <linux/mm.h>
+#include <linux/scatterlist.h>
+#include <linux/vmalloc.h>
 
 int iommu_dma_init(void)
 {
@@ -191,6 +194,7 @@ static struct page **__iommu_dma_alloc_pages(unsigned int count, gfp_t gfp)
 {
        struct page **pages;
        unsigned int i = 0, array_size = count * sizeof(*pages);
+       unsigned int order = MAX_ORDER;
 
        if (array_size <= PAGE_SIZE)
                pages = kzalloc(array_size, GFP_KERNEL);
@@ -204,14 +208,15 @@ static struct page **__iommu_dma_alloc_pages(unsigned int count, gfp_t gfp)
 
        while (count) {
                struct page *page = NULL;
-               int j, order = __fls(count);
+               int j;
 
                /*
                 * Higher-order allocations are a convenience rather
                 * than a necessity, hence using __GFP_NORETRY until
                 * falling back to single-page allocations.
                 */
-               for (order = min(order, MAX_ORDER); order > 0; order--) {
+               for (order = min_t(unsigned int, order, __fls(count));
+                    order > 0; order--) {
                        page = alloc_pages(gfp | __GFP_NORETRY, order);
                        if (!page)
                                continue;
@@ -453,7 +458,7 @@ int iommu_dma_map_sg(struct device *dev, struct scatterlist *sg,
                size_t s_offset = iova_offset(iovad, s->offset);
                size_t s_length = s->length;
 
-               sg_dma_address(s) = s->offset;
+               sg_dma_address(s) = s_offset;
                sg_dma_len(s) = s_length;
                s->offset -= s_offset;
                s_length = iova_align(iovad, s_length + s_offset);
index f1042daef9ada83e931ae450623ce491ebd55959..ac7387686ddc7b2a7c7757f2cb3fbd003c8a23af 100644 (file)
@@ -2159,7 +2159,7 @@ static int __domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn,
                        sg_res = aligned_nrpages(sg->offset, sg->length);
                        sg->dma_address = ((dma_addr_t)iov_pfn << VTD_PAGE_SHIFT) + sg->offset;
                        sg->dma_length = sg->length;
-                       pteval = (sg_phys(sg) & PAGE_MASK) | prot;
+                       pteval = page_to_phys(sg_page(sg)) | prot;
                        phys_pfn = pteval >> VTD_PAGE_SHIFT;
                }
 
@@ -3704,7 +3704,7 @@ static int intel_nontranslate_map_sg(struct device *hddev,
 
        for_each_sg(sglist, sg, nelems, i) {
                BUG_ON(!sg_page(sg));
-               sg->dma_address = sg_phys(sg);
+               sg->dma_address = page_to_phys(sg_page(sg)) + sg->offset;
                sg->dma_length = sg->length;
        }
        return nelems;
index c69e3f9ec9586bca0cd2ef712a3cf9fc25f4689f..50464833d0b84732a4d397cee8b73ed43a721712 100644 (file)
@@ -484,6 +484,23 @@ struct page_req_dsc {
 };
 
 #define PRQ_RING_MASK ((0x1000 << PRQ_ORDER) - 0x10)
+
+static bool access_error(struct vm_area_struct *vma, struct page_req_dsc *req)
+{
+       unsigned long requested = 0;
+
+       if (req->exe_req)
+               requested |= VM_EXEC;
+
+       if (req->rd_req)
+               requested |= VM_READ;
+
+       if (req->wr_req)
+               requested |= VM_WRITE;
+
+       return (requested & ~vma->vm_flags) != 0;
+}
+
 static irqreturn_t prq_event_thread(int irq, void *d)
 {
        struct intel_iommu *iommu = d;
@@ -539,6 +556,9 @@ static irqreturn_t prq_event_thread(int irq, void *d)
                if (!vma || address < vma->vm_start)
                        goto invalid;
 
+               if (access_error(vma, req))
+                       goto invalid;
+
                ret = handle_mm_fault(svm->mm, vma, address,
                                      req->wr_req ? FAULT_FLAG_WRITE : 0);
                if (ret & VM_FAULT_ERROR)
index abae363c7b9bd8932066e760beea7f76f22e7b8d..0e3b0092ec92c9d4d1dcb06e713edcf99c4a9293 100644 (file)
@@ -1430,7 +1430,7 @@ size_t default_iommu_map_sg(struct iommu_domain *domain, unsigned long iova,
        min_pagesz = 1 << __ffs(domain->ops->pgsize_bitmap);
 
        for_each_sg(sg, s, nents, i) {
-               phys_addr_t phys = sg_phys(s);
+               phys_addr_t phys = page_to_phys(sg_page(s)) + s->offset;
 
                /*
                 * We are mapping on IOMMU page boundaries, so offset within
index 8cf605fa9946013642b2a88f500beb285cc55cfc..dfb868e2d129005d7a7401cea7c6109e7720559d 100644 (file)
@@ -295,7 +295,7 @@ static struct iommu_gather_ops ipmmu_gather_ops = {
 
 static int ipmmu_domain_init_context(struct ipmmu_vmsa_domain *domain)
 {
-       phys_addr_t ttbr;
+       u64 ttbr;
 
        /*
         * Allocate the page table operations.
index 598ab3f0e0ac54b79f1438c2193f8bc112949975..cadf104e30746b34d242eaa6e91637b8f99e5370 100644 (file)
@@ -210,7 +210,12 @@ int __init fpga_irq_of_init(struct device_node *node,
                parent_irq = -1;
        }
 
+#ifdef CONFIG_ARCH_VERSATILE
+       fpga_irq_init(base, node->name, IRQ_SIC_START, parent_irq, valid_mask,
+                                 node);
+#else
        fpga_irq_init(base, node->name, 0, parent_irq, valid_mask, node);
+#endif
 
        writel(clear_mask, base + IRQ_ENABLE_CLEAR);
        writel(clear_mask, base + FIQ_ENABLE_CLEAR);
index 375be509e95f5bd302da79446cb8867f8ecb8ec7..2a506fe0c8a4500a16e83b1aba70a6ed2d192185 100644 (file)
@@ -67,8 +67,7 @@ static int write_modem(struct cardstate *cs)
        struct sk_buff *skb = bcs->tx_skb;
        int sent = -EOPNOTSUPP;
 
-       if (!tty || !tty->driver || !skb)
-               return -EINVAL;
+       WARN_ON(!tty || !tty->ops || !skb);
 
        if (!skb->len) {
                dev_kfree_skb_any(skb);
@@ -109,8 +108,7 @@ static int send_cb(struct cardstate *cs)
        unsigned long flags;
        int sent = 0;
 
-       if (!tty || !tty->driver)
-               return -EFAULT;
+       WARN_ON(!tty || !tty->ops);
 
        cb = cs->cmdbuf;
        if (!cb)
@@ -370,19 +368,18 @@ static void gigaset_freecshw(struct cardstate *cs)
        tasklet_kill(&cs->write_tasklet);
        if (!cs->hw.ser)
                return;
-       dev_set_drvdata(&cs->hw.ser->dev.dev, NULL);
        platform_device_unregister(&cs->hw.ser->dev);
-       kfree(cs->hw.ser);
-       cs->hw.ser = NULL;
 }
 
 static void gigaset_device_release(struct device *dev)
 {
-       struct platform_device *pdev = to_platform_device(dev);
+       struct cardstate *cs = dev_get_drvdata(dev);
 
-       /* adapted from platform_device_release() in drivers/base/platform.c */
-       kfree(dev->platform_data);
-       kfree(pdev->resource);
+       if (!cs)
+               return;
+       dev_set_drvdata(dev, NULL);
+       kfree(cs->hw.ser);
+       cs->hw.ser = NULL;
 }
 
 /*
@@ -432,7 +429,9 @@ static int gigaset_set_modem_ctrl(struct cardstate *cs, unsigned old_state,
        struct tty_struct *tty = cs->hw.ser->tty;
        unsigned int set, clear;
 
-       if (!tty || !tty->driver || !tty->ops->tiocmset)
+       WARN_ON(!tty || !tty->ops);
+       /* tiocmset is an optional tty driver method */
+       if (!tty->ops->tiocmset)
                return -EINVAL;
        set = new_state & ~old_state;
        clear = old_state & ~new_state;
index a77eea594b695c59c96903bba4be80063eec1ad7..cb428b9ee441b83819b7d6d4f173b725ba67d360 100644 (file)
@@ -1170,7 +1170,7 @@ mISDNipac_irq(struct ipac_hw *ipac, int maxloop)
 
        if (ipac->type & IPAC_TYPE_IPACX) {
                ista = ReadIPAC(ipac, ISACX_ISTA);
-               while (ista && cnt--) {
+               while (ista && --cnt) {
                        pr_debug("%s: ISTA %02x\n", ipac->name, ista);
                        if (ista & IPACX__ICA)
                                ipac_irq(&ipac->hscx[0], ista);
@@ -1182,7 +1182,7 @@ mISDNipac_irq(struct ipac_hw *ipac, int maxloop)
                }
        } else if (ipac->type & IPAC_TYPE_IPAC) {
                ista = ReadIPAC(ipac, IPAC_ISTA);
-               while (ista && cnt--) {
+               while (ista && --cnt) {
                        pr_debug("%s: ISTA %02x\n", ipac->name, ista);
                        if (ista & (IPAC__ICD | IPAC__EXD)) {
                                istad = ReadISAC(isac, ISAC_ISTA);
@@ -1200,7 +1200,7 @@ mISDNipac_irq(struct ipac_hw *ipac, int maxloop)
                        ista = ReadIPAC(ipac, IPAC_ISTA);
                }
        } else if (ipac->type & IPAC_TYPE_HSCX) {
-               while (cnt) {
+               while (--cnt) {
                        ista = ReadIPAC(ipac, IPAC_ISTAB + ipac->hscx[1].off);
                        pr_debug("%s: B2 ISTA %02x\n", ipac->name, ista);
                        if (ista)
@@ -1211,7 +1211,6 @@ mISDNipac_irq(struct ipac_hw *ipac, int maxloop)
                                mISDNisac_irq(isac, istad);
                        if (0 == (ista | istad))
                                break;
-                       cnt--;
                }
        }
        if (cnt > maxloop) /* only for ISAC/HSCX without PCI IRQ test */
index a16bf56d3f283ece1cd204920ca84aff41eec915..85a339030e4b8ec4a85c46185e561576c47268db 100644 (file)
@@ -18,6 +18,7 @@ if NVM
 
 config NVM_DEBUG
        bool "Open-Channel SSD debugging support"
+       default n
        ---help---
        Exposes a debug management interface to create/remove targets at:
 
index 86ce887b2ed6ab16bfe079300f46652fada2af13..8f41b245cd55b55862911baaf2220d885fc30142 100644 (file)
@@ -74,7 +74,7 @@ EXPORT_SYMBOL(nvm_unregister_target);
 void *nvm_dev_dma_alloc(struct nvm_dev *dev, gfp_t mem_flags,
                                                        dma_addr_t *dma_handler)
 {
-       return dev->ops->dev_dma_alloc(dev->q, dev->ppalist_pool, mem_flags,
+       return dev->ops->dev_dma_alloc(dev, dev->ppalist_pool, mem_flags,
                                                                dma_handler);
 }
 EXPORT_SYMBOL(nvm_dev_dma_alloc);
@@ -97,15 +97,47 @@ static struct nvmm_type *nvm_find_mgr_type(const char *name)
        return NULL;
 }
 
+struct nvmm_type *nvm_init_mgr(struct nvm_dev *dev)
+{
+       struct nvmm_type *mt;
+       int ret;
+
+       lockdep_assert_held(&nvm_lock);
+
+       list_for_each_entry(mt, &nvm_mgrs, list) {
+               ret = mt->register_mgr(dev);
+               if (ret < 0) {
+                       pr_err("nvm: media mgr failed to init (%d) on dev %s\n",
+                                                               ret, dev->name);
+                       return NULL; /* initialization failed */
+               } else if (ret > 0)
+                       return mt;
+       }
+
+       return NULL;
+}
+
 int nvm_register_mgr(struct nvmm_type *mt)
 {
+       struct nvm_dev *dev;
        int ret = 0;
 
        down_write(&nvm_lock);
-       if (nvm_find_mgr_type(mt->name))
+       if (nvm_find_mgr_type(mt->name)) {
                ret = -EEXIST;
-       else
+               goto finish;
+       } else {
                list_add(&mt->list, &nvm_mgrs);
+       }
+
+       /* try to register media mgr if any device have none configured */
+       list_for_each_entry(dev, &nvm_devices, devices) {
+               if (dev->mt)
+                       continue;
+
+               dev->mt = nvm_init_mgr(dev);
+       }
+finish:
        up_write(&nvm_lock);
 
        return ret;
@@ -123,26 +155,6 @@ void nvm_unregister_mgr(struct nvmm_type *mt)
 }
 EXPORT_SYMBOL(nvm_unregister_mgr);
 
-/* register with device with a supported manager */
-static int register_mgr(struct nvm_dev *dev)
-{
-       struct nvmm_type *mt;
-       int ret = 0;
-
-       list_for_each_entry(mt, &nvm_mgrs, list) {
-               ret = mt->register_mgr(dev);
-               if (ret > 0) {
-                       dev->mt = mt;
-                       break; /* successfully initialized */
-               }
-       }
-
-       if (!ret)
-               pr_info("nvm: no compatible nvm manager found.\n");
-
-       return ret;
-}
-
 static struct nvm_dev *nvm_find_nvm_dev(const char *name)
 {
        struct nvm_dev *dev;
@@ -246,7 +258,7 @@ static int nvm_init(struct nvm_dev *dev)
        if (!dev->q || !dev->ops)
                return ret;
 
-       if (dev->ops->identity(dev->q, &dev->identity)) {
+       if (dev->ops->identity(dev, &dev->identity)) {
                pr_err("nvm: device could not be identified\n");
                goto err;
        }
@@ -271,14 +283,6 @@ static int nvm_init(struct nvm_dev *dev)
                goto err;
        }
 
-       down_write(&nvm_lock);
-       ret = register_mgr(dev);
-       up_write(&nvm_lock);
-       if (ret < 0)
-               goto err;
-       if (!ret)
-               return 0;
-
        pr_info("nvm: registered %s [%u/%u/%u/%u/%u/%u]\n",
                        dev->name, dev->sec_per_pg, dev->nr_planes,
                        dev->pgs_per_blk, dev->blks_per_lun, dev->nr_luns,
@@ -326,8 +330,7 @@ int nvm_register(struct request_queue *q, char *disk_name,
        }
 
        if (dev->ops->max_phys_sect > 1) {
-               dev->ppalist_pool = dev->ops->create_dma_pool(dev->q,
-                                                               "ppalist");
+               dev->ppalist_pool = dev->ops->create_dma_pool(dev, "ppalist");
                if (!dev->ppalist_pool) {
                        pr_err("nvm: could not create ppa pool\n");
                        ret = -ENOMEM;
@@ -335,7 +338,9 @@ int nvm_register(struct request_queue *q, char *disk_name,
                }
        }
 
+       /* register device with a supported media manager */
        down_write(&nvm_lock);
+       dev->mt = nvm_init_mgr(dev);
        list_add(&dev->devices, &nvm_devices);
        up_write(&nvm_lock);
 
@@ -380,19 +385,13 @@ static int nvm_create_target(struct nvm_dev *dev,
        struct nvm_tgt_type *tt;
        struct nvm_target *t;
        void *targetdata;
-       int ret = 0;
 
-       down_write(&nvm_lock);
        if (!dev->mt) {
-               ret = register_mgr(dev);
-               if (!ret)
-                       ret = -ENODEV;
-               if (ret < 0) {
-                       up_write(&nvm_lock);
-                       return ret;
-               }
+               pr_info("nvm: device has no media manager registered.\n");
+               return -ENODEV;
        }
 
+       down_write(&nvm_lock);
        tt = nvm_find_target_type(create->tgttype);
        if (!tt) {
                pr_err("nvm: target type %s not found\n", create->tgttype);
index 35dde84b71e97a6e530c2058ca0b68cf574424b2..a54b339951a3e695bfa68e96fb6eaf2e3e451c62 100644 (file)
@@ -75,7 +75,7 @@ static int gennvm_block_bb(struct ppa_addr ppa, int nr_blocks, u8 *blks,
        struct nvm_block *blk;
        int i;
 
-       lun = &gn->luns[(dev->nr_luns * ppa.g.ch) + ppa.g.lun];
+       lun = &gn->luns[(dev->luns_per_chnl * ppa.g.ch) + ppa.g.lun];
 
        for (i = 0; i < nr_blocks; i++) {
                if (blks[i] == 0)
@@ -195,7 +195,7 @@ static int gennvm_blocks_init(struct nvm_dev *dev, struct gen_nvm *gn)
        }
 
        if (dev->ops->get_l2p_tbl) {
-               ret = dev->ops->get_l2p_tbl(dev->q, 0, dev->total_pages,
+               ret = dev->ops->get_l2p_tbl(dev, 0, dev->total_pages,
                                                        gennvm_block_map, dev);
                if (ret) {
                        pr_err("gennvm: could not read L2P table.\n");
@@ -219,6 +219,9 @@ static int gennvm_register(struct nvm_dev *dev)
        struct gen_nvm *gn;
        int ret;
 
+       if (!try_module_get(THIS_MODULE))
+               return -ENODEV;
+
        gn = kzalloc(sizeof(struct gen_nvm), GFP_KERNEL);
        if (!gn)
                return -ENOMEM;
@@ -242,12 +245,14 @@ static int gennvm_register(struct nvm_dev *dev)
        return 1;
 err:
        gennvm_free(dev);
+       module_put(THIS_MODULE);
        return ret;
 }
 
 static void gennvm_unregister(struct nvm_dev *dev)
 {
        gennvm_free(dev);
+       module_put(THIS_MODULE);
 }
 
 static struct nvm_block *gennvm_get_blk(struct nvm_dev *dev,
@@ -262,14 +267,11 @@ static struct nvm_block *gennvm_get_blk(struct nvm_dev *dev,
        if (list_empty(&lun->free_list)) {
                pr_err_ratelimited("gennvm: lun %u have no free pages available",
                                                                lun->vlun.id);
-               spin_unlock(&vlun->lock);
                goto out;
        }
 
-       while (!is_gc && lun->vlun.nr_free_blocks < lun->reserved_blocks) {
-               spin_unlock(&vlun->lock);
+       if (!is_gc && lun->vlun.nr_free_blocks < lun->reserved_blocks)
                goto out;
-       }
 
        blk = list_first_entry(&lun->free_list, struct nvm_block, list);
        list_move_tail(&blk->list, &lun->used_list);
@@ -278,8 +280,8 @@ static struct nvm_block *gennvm_get_blk(struct nvm_dev *dev,
        lun->vlun.nr_free_blocks--;
        lun->vlun.nr_inuse_blocks++;
 
-       spin_unlock(&vlun->lock);
 out:
+       spin_unlock(&vlun->lock);
        return blk;
 }
 
@@ -349,7 +351,7 @@ static int gennvm_submit_io(struct nvm_dev *dev, struct nvm_rq *rqd)
        gennvm_generic_to_addr_mode(dev, rqd);
 
        rqd->dev = dev;
-       return dev->ops->submit_io(dev->q, rqd);
+       return dev->ops->submit_io(dev, rqd);
 }
 
 static void gennvm_blk_set_type(struct nvm_dev *dev, struct ppa_addr *ppa,
@@ -385,7 +387,7 @@ static void gennvm_mark_blk_bad(struct nvm_dev *dev, struct nvm_rq *rqd)
        if (!dev->ops->set_bb_tbl)
                return;
 
-       if (dev->ops->set_bb_tbl(dev->q, rqd, 1))
+       if (dev->ops->set_bb_tbl(dev, rqd, 1))
                return;
 
        gennvm_addr_to_generic_mode(dev, rqd);
@@ -453,7 +455,7 @@ static int gennvm_erase_blk(struct nvm_dev *dev, struct nvm_block *blk,
 
        gennvm_generic_to_addr_mode(dev, &rqd);
 
-       ret = dev->ops->erase_block(dev->q, &rqd);
+       ret = dev->ops->erase_block(dev, &rqd);
 
        if (plane_cnt)
                nvm_dev_dma_free(dev, rqd.ppa_list, rqd.dma_ppa_list);
index 75e59c3a3f96d821d93600f2ca698a50e2874182..134e4faba48259434db7d55d446f40f3deb206b9 100644 (file)
@@ -182,7 +182,7 @@ static struct rrpc_block *rrpc_get_blk(struct rrpc *rrpc, struct rrpc_lun *rlun,
        struct nvm_block *blk;
        struct rrpc_block *rblk;
 
-       blk = nvm_get_blk(rrpc->dev, rlun->parent, 0);
+       blk = nvm_get_blk(rrpc->dev, rlun->parent, flags);
        if (!blk)
                return NULL;
 
@@ -202,6 +202,20 @@ static void rrpc_put_blk(struct rrpc *rrpc, struct rrpc_block *rblk)
        nvm_put_blk(rrpc->dev, rblk->parent);
 }
 
+static void rrpc_put_blks(struct rrpc *rrpc)
+{
+       struct rrpc_lun *rlun;
+       int i;
+
+       for (i = 0; i < rrpc->nr_luns; i++) {
+               rlun = &rrpc->luns[i];
+               if (rlun->cur)
+                       rrpc_put_blk(rrpc, rlun->cur);
+               if (rlun->gc_cur)
+                       rrpc_put_blk(rrpc, rlun->gc_cur);
+       }
+}
+
 static struct rrpc_lun *get_next_lun(struct rrpc *rrpc)
 {
        int next = atomic_inc_return(&rrpc->next_lun);
@@ -1002,7 +1016,7 @@ static int rrpc_map_init(struct rrpc *rrpc)
                return 0;
 
        /* Bring up the mapping table from device */
-       ret = dev->ops->get_l2p_tbl(dev->q, 0, dev->total_pages,
+       ret = dev->ops->get_l2p_tbl(dev, 0, dev->total_pages,
                                                        rrpc_l2p_update, rrpc);
        if (ret) {
                pr_err("nvm: rrpc: could not read L2P table.\n");
@@ -1224,18 +1238,21 @@ static int rrpc_luns_configure(struct rrpc *rrpc)
 
                rblk = rrpc_get_blk(rrpc, rlun, 0);
                if (!rblk)
-                       return -EINVAL;
+                       goto err;
 
                rrpc_set_lun_cur(rlun, rblk);
 
                /* Emergency gc block */
                rblk = rrpc_get_blk(rrpc, rlun, 1);
                if (!rblk)
-                       return -EINVAL;
+                       goto err;
                rlun->gc_cur = rblk;
        }
 
        return 0;
+err:
+       rrpc_put_blks(rrpc);
+       return -EINVAL;
 }
 
 static struct nvm_tgt_type tt_rrpc;
index 1fa45695b68a4eb6ed3db388d30f6e88f06fee21..c219a053c7f66d1ebae80a19b005af38914dbe8c 100644 (file)
@@ -1206,6 +1206,12 @@ static int __reserve_metadata_snap(struct dm_pool_metadata *pmd)
        struct dm_block *copy, *sblock;
        dm_block_t held_root;
 
+       /*
+        * We commit to ensure the btree roots which we increment in a
+        * moment are up to date.
+        */
+       __commit_transaction(pmd);
+
        /*
         * Copy the superblock.
         */
@@ -1538,7 +1544,7 @@ static int __remove(struct dm_thin_device *td, dm_block_t block)
 static int __remove_range(struct dm_thin_device *td, dm_block_t begin, dm_block_t end)
 {
        int r;
-       unsigned count;
+       unsigned count, total_count = 0;
        struct dm_pool_metadata *pmd = td->pmd;
        dm_block_t keys[1] = { td->id };
        __le64 value;
@@ -1561,11 +1567,29 @@ static int __remove_range(struct dm_thin_device *td, dm_block_t begin, dm_block_
        if (r)
                return r;
 
-       r = dm_btree_remove_leaves(&pmd->bl_info, mapping_root, &begin, end, &mapping_root, &count);
-       if (r)
-               return r;
+       /*
+        * Remove leaves stops at the first unmapped entry, so we have to
+        * loop round finding mapped ranges.
+        */
+       while (begin < end) {
+               r = dm_btree_lookup_next(&pmd->bl_info, mapping_root, &begin, &begin, &value);
+               if (r == -ENODATA)
+                       break;
+
+               if (r)
+                       return r;
+
+               if (begin >= end)
+                       break;
+
+               r = dm_btree_remove_leaves(&pmd->bl_info, mapping_root, &begin, end, &mapping_root, &count);
+               if (r)
+                       return r;
+
+               total_count += count;
+       }
 
-       td->mapped_blocks -= count;
+       td->mapped_blocks -= total_count;
        td->changed = 1;
 
        /*
index 807095f4c793bb4f1d4119f81abf2653b83240cb..61aacab424cf1860dbb5651f5a4fc6c9f7188027 100644 (file)
@@ -314,8 +314,8 @@ static blk_qc_t md_make_request(struct request_queue *q, struct bio *bio)
  */
 void mddev_suspend(struct mddev *mddev)
 {
-       BUG_ON(mddev->suspended);
-       mddev->suspended = 1;
+       if (mddev->suspended++)
+               return;
        synchronize_rcu();
        wait_event(mddev->sb_wait, atomic_read(&mddev->active_io) == 0);
        mddev->pers->quiesce(mddev, 1);
@@ -326,7 +326,8 @@ EXPORT_SYMBOL_GPL(mddev_suspend);
 
 void mddev_resume(struct mddev *mddev)
 {
-       mddev->suspended = 0;
+       if (--mddev->suspended)
+               return;
        wake_up(&mddev->sb_wait);
        mddev->pers->quiesce(mddev, 0);
 
@@ -1652,7 +1653,7 @@ static int super_1_validate(struct mddev *mddev, struct md_rdev *rdev)
                        rdev->journal_tail = le64_to_cpu(sb->journal_tail);
                        if (mddev->recovery_cp == MaxSector)
                                set_bit(MD_JOURNAL_CLEAN, &mddev->flags);
-                       rdev->raid_disk = mddev->raid_disks;
+                       rdev->raid_disk = 0;
                        break;
                default:
                        rdev->saved_raid_disk = role;
@@ -2773,6 +2774,7 @@ slot_store(struct md_rdev *rdev, const char *buf, size_t len)
                /* Activating a spare .. or possibly reactivating
                 * if we ever get bitmaps working here.
                 */
+               int err;
 
                if (rdev->raid_disk != -1)
                        return -EBUSY;
@@ -2794,9 +2796,15 @@ slot_store(struct md_rdev *rdev, const char *buf, size_t len)
                        rdev->saved_raid_disk = -1;
                clear_bit(In_sync, &rdev->flags);
                clear_bit(Bitmap_sync, &rdev->flags);
-               remove_and_add_spares(rdev->mddev, rdev);
-               if (rdev->raid_disk == -1)
-                       return -EBUSY;
+               err = rdev->mddev->pers->
+                       hot_add_disk(rdev->mddev, rdev);
+               if (err) {
+                       rdev->raid_disk = -1;
+                       return err;
+               } else
+                       sysfs_notify_dirent_safe(rdev->sysfs_state);
+               if (sysfs_link_rdev(rdev->mddev, rdev))
+                       /* failure here is OK */;
                /* don't wakeup anyone, leave that to userspace. */
        } else {
                if (slot >= rdev->mddev->raid_disks &&
@@ -4318,8 +4326,7 @@ action_store(struct mddev *mddev, const char *page, size_t len)
                        }
                        mddev_unlock(mddev);
                }
-       } else if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery) ||
-                  test_bit(MD_RECOVERY_NEEDED, &mddev->recovery))
+       } else if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery))
                return -EBUSY;
        else if (cmd_match(page, "resync"))
                clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
@@ -4332,8 +4339,12 @@ action_store(struct mddev *mddev, const char *page, size_t len)
                        return -EINVAL;
                err = mddev_lock(mddev);
                if (!err) {
-                       clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
-                       err = mddev->pers->start_reshape(mddev);
+                       if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery))
+                               err =  -EBUSY;
+                       else {
+                               clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
+                               err = mddev->pers->start_reshape(mddev);
+                       }
                        mddev_unlock(mddev);
                }
                if (err)
index 2bea51edfab707645a6d6b8a5b6c79bb0c6dde64..ca0b643fe3c18070b417a66daedb571457b440ca 100644 (file)
@@ -566,7 +566,9 @@ static inline char * mdname (struct mddev * mddev)
 static inline int sysfs_link_rdev(struct mddev *mddev, struct md_rdev *rdev)
 {
        char nm[20];
-       if (!test_bit(Replacement, &rdev->flags) && mddev->kobj.sd) {
+       if (!test_bit(Replacement, &rdev->flags) &&
+           !test_bit(Journal, &rdev->flags) &&
+           mddev->kobj.sd) {
                sprintf(nm, "rd%d", rdev->raid_disk);
                return sysfs_create_link(&mddev->kobj, &rdev->kobj, nm);
        } else
@@ -576,7 +578,9 @@ static inline int sysfs_link_rdev(struct mddev *mddev, struct md_rdev *rdev)
 static inline void sysfs_unlink_rdev(struct mddev *mddev, struct md_rdev *rdev)
 {
        char nm[20];
-       if (!test_bit(Replacement, &rdev->flags) && mddev->kobj.sd) {
+       if (!test_bit(Replacement, &rdev->flags) &&
+           !test_bit(Journal, &rdev->flags) &&
+           mddev->kobj.sd) {
                sprintf(nm, "rd%d", rdev->raid_disk);
                sysfs_remove_link(&mddev->kobj, nm);
        }
index c573402033b2dd9e89dc11ad2f6e1b7e8bbb4263..b1ced58eb5e1475b440a15de0e26811fb90b8159 100644 (file)
@@ -63,6 +63,11 @@ int lower_bound(struct btree_node *n, uint64_t key)
        return bsearch(n, key, 0);
 }
 
+static int upper_bound(struct btree_node *n, uint64_t key)
+{
+       return bsearch(n, key, 1);
+}
+
 void inc_children(struct dm_transaction_manager *tm, struct btree_node *n,
                  struct dm_btree_value_type *vt)
 {
@@ -252,6 +257,16 @@ static void pop_frame(struct del_stack *s)
        dm_tm_unlock(s->tm, f->b);
 }
 
+static void unlock_all_frames(struct del_stack *s)
+{
+       struct frame *f;
+
+       while (unprocessed_frames(s)) {
+               f = s->spine + s->top--;
+               dm_tm_unlock(s->tm, f->b);
+       }
+}
+
 int dm_btree_del(struct dm_btree_info *info, dm_block_t root)
 {
        int r;
@@ -308,9 +323,13 @@ int dm_btree_del(struct dm_btree_info *info, dm_block_t root)
                        pop_frame(s);
                }
        }
-
 out:
+       if (r) {
+               /* cleanup all frames of del_stack */
+               unlock_all_frames(s);
+       }
        kfree(s);
+
        return r;
 }
 EXPORT_SYMBOL_GPL(dm_btree_del);
@@ -392,6 +411,82 @@ int dm_btree_lookup(struct dm_btree_info *info, dm_block_t root,
 }
 EXPORT_SYMBOL_GPL(dm_btree_lookup);
 
+static int dm_btree_lookup_next_single(struct dm_btree_info *info, dm_block_t root,
+                                      uint64_t key, uint64_t *rkey, void *value_le)
+{
+       int r, i;
+       uint32_t flags, nr_entries;
+       struct dm_block *node;
+       struct btree_node *n;
+
+       r = bn_read_lock(info, root, &node);
+       if (r)
+               return r;
+
+       n = dm_block_data(node);
+       flags = le32_to_cpu(n->header.flags);
+       nr_entries = le32_to_cpu(n->header.nr_entries);
+
+       if (flags & INTERNAL_NODE) {
+               i = lower_bound(n, key);
+               if (i < 0 || i >= nr_entries) {
+                       r = -ENODATA;
+                       goto out;
+               }
+
+               r = dm_btree_lookup_next_single(info, value64(n, i), key, rkey, value_le);
+               if (r == -ENODATA && i < (nr_entries - 1)) {
+                       i++;
+                       r = dm_btree_lookup_next_single(info, value64(n, i), key, rkey, value_le);
+               }
+
+       } else {
+               i = upper_bound(n, key);
+               if (i < 0 || i >= nr_entries) {
+                       r = -ENODATA;
+                       goto out;
+               }
+
+               *rkey = le64_to_cpu(n->keys[i]);
+               memcpy(value_le, value_ptr(n, i), info->value_type.size);
+       }
+out:
+       dm_tm_unlock(info->tm, node);
+       return r;
+}
+
+int dm_btree_lookup_next(struct dm_btree_info *info, dm_block_t root,
+                        uint64_t *keys, uint64_t *rkey, void *value_le)
+{
+       unsigned level;
+       int r = -ENODATA;
+       __le64 internal_value_le;
+       struct ro_spine spine;
+
+       init_ro_spine(&spine, info);
+       for (level = 0; level < info->levels - 1u; level++) {
+               r = btree_lookup_raw(&spine, root, keys[level],
+                                    lower_bound, rkey,
+                                    &internal_value_le, sizeof(uint64_t));
+               if (r)
+                       goto out;
+
+               if (*rkey != keys[level]) {
+                       r = -ENODATA;
+                       goto out;
+               }
+
+               root = le64_to_cpu(internal_value_le);
+       }
+
+       r = dm_btree_lookup_next_single(info, root, keys[level], rkey, value_le);
+out:
+       exit_ro_spine(&spine);
+       return r;
+}
+
+EXPORT_SYMBOL_GPL(dm_btree_lookup_next);
+
 /*
  * Splits a node by creating a sibling node and shifting half the nodes
  * contents across.  Assumes there is a parent node, and it has room for
@@ -473,8 +568,10 @@ static int btree_split_sibling(struct shadow_spine *s, unsigned parent_index,
 
        r = insert_at(sizeof(__le64), pn, parent_index + 1,
                      le64_to_cpu(rn->keys[0]), &location);
-       if (r)
+       if (r) {
+               unlock_block(s->info, right);
                return r;
+       }
 
        if (key < le64_to_cpu(rn->keys[0])) {
                unlock_block(s->info, right);
index 11d8cf78621dded80328187e1009ca0dc35c6997..c74301fa5a379517b9c37e7e98ab380d97f3b9b0 100644 (file)
@@ -109,6 +109,13 @@ int dm_btree_del(struct dm_btree_info *info, dm_block_t root);
 int dm_btree_lookup(struct dm_btree_info *info, dm_block_t root,
                    uint64_t *keys, void *value_le);
 
+/*
+ * Tries to find the first key where the bottom level key is >= to that
+ * given.  Useful for skipping empty sections of the btree.
+ */
+int dm_btree_lookup_next(struct dm_btree_info *info, dm_block_t root,
+                        uint64_t *keys, uint64_t *rkey, void *value_le);
+
 /*
  * Insertion (or overwrite an existing value).  O(ln(n))
  */
@@ -135,9 +142,10 @@ int dm_btree_remove(struct dm_btree_info *info, dm_block_t root,
                    uint64_t *keys, dm_block_t *new_root);
 
 /*
- * Removes values between 'keys' and keys2, where keys2 is keys with the
- * final key replaced with 'end_key'.  'end_key' is the one-past-the-end
- * value.  'keys' may be altered.
+ * Removes a _contiguous_ run of values starting from 'keys' and not
+ * reaching keys2 (where keys2 is keys with the final key replaced with
+ * 'end_key').  'end_key' is the one-past-the-end value.  'keys' may be
+ * altered.
  */
 int dm_btree_remove_leaves(struct dm_btree_info *info, dm_block_t root,
                           uint64_t *keys, uint64_t end_key,
index 53091295fce9b7d9ffec9b91a6a0bdddd20ed67f..fca6dbcf9a4727f85d61f7d161094870f5db24d5 100644 (file)
@@ -136,7 +136,7 @@ static int brb_push(struct bop_ring_buffer *brb,
        return 0;
 }
 
-static int brb_pop(struct bop_ring_buffer *brb, struct block_op *result)
+static int brb_peek(struct bop_ring_buffer *brb, struct block_op *result)
 {
        struct block_op *bop;
 
@@ -147,6 +147,17 @@ static int brb_pop(struct bop_ring_buffer *brb, struct block_op *result)
        result->type = bop->type;
        result->block = bop->block;
 
+       return 0;
+}
+
+static int brb_pop(struct bop_ring_buffer *brb)
+{
+       struct block_op *bop;
+
+       if (brb_empty(brb))
+               return -ENODATA;
+
+       bop = brb->bops + brb->begin;
        brb->begin = brb_next(brb, brb->begin);
 
        return 0;
@@ -211,7 +222,7 @@ static int apply_bops(struct sm_metadata *smm)
        while (!brb_empty(&smm->uncommitted)) {
                struct block_op bop;
 
-               r = brb_pop(&smm->uncommitted, &bop);
+               r = brb_peek(&smm->uncommitted, &bop);
                if (r) {
                        DMERR("bug in bop ring buffer");
                        break;
@@ -220,6 +231,8 @@ static int apply_bops(struct sm_metadata *smm)
                r = commit_bop(smm, &bop);
                if (r)
                        break;
+
+               brb_pop(&smm->uncommitted);
        }
 
        return r;
@@ -683,7 +696,6 @@ static struct dm_space_map bootstrap_ops = {
 static int sm_metadata_extend(struct dm_space_map *sm, dm_block_t extra_blocks)
 {
        int r, i;
-       enum allocation_event ev;
        struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm);
        dm_block_t old_len = smm->ll.nr_blocks;
 
@@ -705,11 +717,12 @@ static int sm_metadata_extend(struct dm_space_map *sm, dm_block_t extra_blocks)
         * allocate any new blocks.
         */
        do {
-               for (i = old_len; !r && i < smm->begin; i++) {
-                       r = sm_ll_inc(&smm->ll, i, &ev);
-                       if (r)
-                               goto out;
-               }
+               for (i = old_len; !r && i < smm->begin; i++)
+                       r = add_bop(smm, BOP_INC, i);
+
+               if (r)
+                       goto out;
+
                old_len = smm->begin;
 
                r = apply_bops(smm);
@@ -754,7 +767,6 @@ int dm_sm_metadata_create(struct dm_space_map *sm,
 {
        int r;
        dm_block_t i;
-       enum allocation_event ev;
        struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm);
 
        smm->begin = superblock + 1;
@@ -782,7 +794,7 @@ int dm_sm_metadata_create(struct dm_space_map *sm,
         * allocated blocks that they were built from.
         */
        for (i = superblock; !r && i < smm->begin; i++)
-               r = sm_ll_inc(&smm->ll, i, &ev);
+               r = add_bop(smm, BOP_INC, i);
 
        if (r)
                return r;
index 41d70bc9ba2f879a2549868861afb74471140525..84e597e1c4890cd911243c511d1a65e39232e98e 100644 (file)
@@ -1946,6 +1946,8 @@ static void sync_request_write(struct mddev *mddev, struct r10bio *r10_bio)
 
        first = i;
        fbio = r10_bio->devs[i].bio;
+       fbio->bi_iter.bi_size = r10_bio->sectors << 9;
+       fbio->bi_iter.bi_idx = 0;
 
        vcnt = (r10_bio->sectors + (PAGE_SIZE >> 9) - 1) >> (PAGE_SHIFT - 9);
        /* now find blocks with errors */
@@ -1989,7 +1991,7 @@ static void sync_request_write(struct mddev *mddev, struct r10bio *r10_bio)
                bio_reset(tbio);
 
                tbio->bi_vcnt = vcnt;
-               tbio->bi_iter.bi_size = r10_bio->sectors << 9;
+               tbio->bi_iter.bi_size = fbio->bi_iter.bi_size;
                tbio->bi_rw = WRITE;
                tbio->bi_private = r10_bio;
                tbio->bi_iter.bi_sector = r10_bio->devs[i].addr;
index 8616fa8193bca06bb806dc48b14d4e7dc6e21aef..c2e60b4f292d1d8d9791b5c44b0fa76c0ffd854b 100644 (file)
@@ -805,11 +805,11 @@ static void ivtv_init_struct2(struct ivtv *itv)
 {
        int i;
 
-       for (i = 0; i < IVTV_CARD_MAX_VIDEO_INPUTS - 1; i++)
+       for (i = 0; i < IVTV_CARD_MAX_VIDEO_INPUTS; i++)
                if (itv->card->video_inputs[i].video_type == 0)
                        break;
        itv->nof_inputs = i;
-       for (i = 0; i < IVTV_CARD_MAX_AUDIO_INPUTS - 1; i++)
+       for (i = 0; i < IVTV_CARD_MAX_AUDIO_INPUTS; i++)
                if (itv->card->audio_inputs[i].audio_type == 0)
                        break;
        itv->nof_audio_inputs = i;
index fcbb49757614487aa0a88e2740bc0dcd4ff73236..565a59310747680858bb2bf30543e05becd579a0 100644 (file)
@@ -134,7 +134,7 @@ struct airspy {
        int            urbs_submitted;
 
        /* USB control message buffer */
-       #define BUF_SIZE 24
+       #define BUF_SIZE 128
        u8 buf[BUF_SIZE];
 
        /* Current configuration */
index e05bfec90f4608b0d8ebce199351dfe89db11994..0fe5cb2c260c2f771484d99bf25809cc23943ffb 100644 (file)
 #include <media/videobuf2-v4l2.h>
 #include <media/videobuf2-vmalloc.h>
 
+/*
+ * Used Avago MGA-81563 RF amplifier could be destroyed pretty easily with too
+ * strong signal or transmitting to bad antenna.
+ * Set RF gain control to 'grabbed' state by default for sure.
+ */
+static bool hackrf_enable_rf_gain_ctrl;
+module_param_named(enable_rf_gain_ctrl, hackrf_enable_rf_gain_ctrl, bool, 0644);
+MODULE_PARM_DESC(enable_rf_gain_ctrl, "enable RX/TX RF amplifier control (warn: could damage amplifier)");
+
 /* HackRF USB API commands (from HackRF Library) */
 enum {
        CMD_SET_TRANSCEIVER_MODE           = 0x01,
@@ -1451,6 +1460,7 @@ static int hackrf_probe(struct usb_interface *intf,
                dev_err(dev->dev, "Could not initialize controls\n");
                goto err_v4l2_ctrl_handler_free_rx;
        }
+       v4l2_ctrl_grab(dev->rx_rf_gain, !hackrf_enable_rf_gain_ctrl);
        v4l2_ctrl_handler_setup(&dev->rx_ctrl_handler);
 
        /* Register controls for transmitter */
@@ -1471,6 +1481,7 @@ static int hackrf_probe(struct usb_interface *intf,
                dev_err(dev->dev, "Could not initialize controls\n");
                goto err_v4l2_ctrl_handler_free_tx;
        }
+       v4l2_ctrl_grab(dev->tx_rf_gain, !hackrf_enable_rf_gain_ctrl);
        v4l2_ctrl_handler_setup(&dev->tx_ctrl_handler);
 
        /* Register the v4l2_device structure */
@@ -1530,7 +1541,7 @@ err_v4l2_ctrl_handler_free_rx:
 err_kfree:
        kfree(dev);
 err:
-       dev_dbg(dev->dev, "failed=%d\n", ret);
+       dev_dbg(&intf->dev, "failed=%d\n", ret);
        return ret;
 }
 
index e87459f6d686d011d6d11f902b78053f083e1b7a..acd1460cf7871c4ef4cffb0f0e196f41083aae36 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/compiler.h>
+#include <linux/sched.h>
 #include <linux/spinlock.h>
 #include <linux/types.h>
 #include <linux/slab.h>
index d2e75c88f4d2165762913c27c57e5d4487e431ad..f4090979349068b3057d0cd9d8a17d15168ce734 100644 (file)
@@ -497,6 +497,7 @@ static u64 calculate_sr(struct cxl_context *ctx)
 {
        u64 sr = 0;
 
+       set_endian(sr);
        if (ctx->master)
                sr |= CXL_PSL_SR_An_MP;
        if (mfspr(SPRN_LPCR) & LPCR_TC)
@@ -506,7 +507,6 @@ static u64 calculate_sr(struct cxl_context *ctx)
                sr |= CXL_PSL_SR_An_HV;
        } else {
                sr |= CXL_PSL_SR_An_PR | CXL_PSL_SR_An_R;
-               set_endian(sr);
                sr &= ~(CXL_PSL_SR_An_HV);
                if (!test_tsk_thread_flag(current, TIF_32BIT))
                        sr |= CXL_PSL_SR_An_SF;
index 95c13b2ffa799e59f453e8a95813171cd56a13fc..ffa2884748205e26a376712c453b4fca5d3075bf 100644 (file)
@@ -426,15 +426,6 @@ int add_mtd_device(struct mtd_info *mtd)
        mtd->erasesize_mask = (1 << mtd->erasesize_shift) - 1;
        mtd->writesize_mask = (1 << mtd->writesize_shift) - 1;
 
-       if (mtd->dev.parent) {
-               if (!mtd->owner && mtd->dev.parent->driver)
-                       mtd->owner = mtd->dev.parent->driver->owner;
-               if (!mtd->name)
-                       mtd->name = dev_name(mtd->dev.parent);
-       } else {
-               pr_debug("mtd device won't show a device symlink in sysfs\n");
-       }
-
        /* Some chips always power up locked. Unlock them now */
        if ((mtd->flags & MTD_WRITEABLE) && (mtd->flags & MTD_POWERUP_LOCK)) {
                error = mtd_unlock(mtd, 0, mtd->size);
@@ -549,6 +540,21 @@ static int mtd_add_device_partitions(struct mtd_info *mtd,
        return 0;
 }
 
+/*
+ * Set a few defaults based on the parent devices, if not provided by the
+ * driver
+ */
+static void mtd_set_dev_defaults(struct mtd_info *mtd)
+{
+       if (mtd->dev.parent) {
+               if (!mtd->owner && mtd->dev.parent->driver)
+                       mtd->owner = mtd->dev.parent->driver->owner;
+               if (!mtd->name)
+                       mtd->name = dev_name(mtd->dev.parent);
+       } else {
+               pr_debug("mtd device won't show a device symlink in sysfs\n");
+       }
+}
 
 /**
  * mtd_device_parse_register - parse partitions and register an MTD device.
@@ -587,6 +593,8 @@ int mtd_device_parse_register(struct mtd_info *mtd, const char * const *types,
        int ret;
        struct mtd_partition *real_parts = NULL;
 
+       mtd_set_dev_defaults(mtd);
+
        ret = parse_mtd_partitions(mtd, types, &real_parts, parser_data);
        if (ret <= 0 && nr_parts && parts) {
                real_parts = kmemdup(parts, sizeof(*parts) * nr_parts,
index 669c3452f278fb0e365570872893855c9ce21e2c..9ed6038e47d210df74ec678de7cf8220797bf815 100644 (file)
@@ -46,10 +46,18 @@ static int parse_ofpart_partitions(struct mtd_info *master,
 
        ofpart_node = of_get_child_by_name(mtd_node, "partitions");
        if (!ofpart_node) {
-               pr_warn("%s: 'partitions' subnode not found on %s. Trying to parse direct subnodes as partitions.\n",
-                       master->name, mtd_node->full_name);
+               /*
+                * We might get here even when ofpart isn't used at all (e.g.,
+                * when using another parser), so don't be louder than
+                * KERN_DEBUG
+                */
+               pr_debug("%s: 'partitions' subnode not found on %s. Trying to parse direct subnodes as partitions.\n",
+                        master->name, mtd_node->full_name);
                ofpart_node = mtd_node;
                dedicated = false;
+       } else if (!of_device_is_compatible(ofpart_node, "fixed-partitions")) {
+               /* The 'partitions' subnode might be used by another parser */
+               return 0;
        }
 
        /* First count the subnodes */
index 49883905a434b68b98af50e515a0356731c62fa6..32477c4eb421390e250645f94b0eefdab871a043 100644 (file)
@@ -516,8 +516,8 @@ static int stm_unlock(struct spi_nor *nor, loff_t ofs, uint64_t len)
        status_old = read_sr(nor);
 
        /* Cannot unlock; would unlock larger region than requested */
-       if (stm_is_locked_sr(nor, status_old, ofs - mtd->erasesize,
-                            mtd->erasesize))
+       if (stm_is_locked_sr(nor, ofs - mtd->erasesize, mtd->erasesize,
+                            status_old))
                return -EINVAL;
 
        /*
@@ -1200,8 +1200,7 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode)
 
        if (JEDEC_MFR(info) == SNOR_MFR_ATMEL ||
            JEDEC_MFR(info) == SNOR_MFR_INTEL ||
-           JEDEC_MFR(info) == SNOR_MFR_SST ||
-           JEDEC_MFR(info) == SNOR_MFR_WINBOND) {
+           JEDEC_MFR(info) == SNOR_MFR_SST) {
                write_enable(nor);
                write_sr(nor, 0);
        }
@@ -1217,8 +1216,7 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode)
        mtd->_read = spi_nor_read;
 
        /* NOR protection support for STmicro/Micron chips and similar */
-       if (JEDEC_MFR(info) == SNOR_MFR_MICRON ||
-           JEDEC_MFR(info) == SNOR_MFR_WINBOND) {
+       if (JEDEC_MFR(info) == SNOR_MFR_MICRON) {
                nor->flash_lock = stm_lock;
                nor->flash_unlock = stm_unlock;
                nor->flash_is_locked = stm_is_locked;
index b077e43b5ba913b2ba208ed54673c3fe291afc66..c4cb15a3098c0933f607e4f0cba170e978f910ff 100644 (file)
@@ -236,7 +236,7 @@ int ubi_debugfs_init(void)
 
        dfs_rootdir = debugfs_create_dir("ubi", NULL);
        if (IS_ERR_OR_NULL(dfs_rootdir)) {
-               int err = dfs_rootdir ? -ENODEV : PTR_ERR(dfs_rootdir);
+               int err = dfs_rootdir ? PTR_ERR(dfs_rootdir) : -ENODEV;
 
                pr_err("UBI error: cannot create \"ubi\" debugfs directory, error %d\n",
                       err);
index 1fc23e48fe8e49fc947c972cca179399a60a37ec..10cf3b549959ce46f9c517b77fbcdd84e274a3d2 100644 (file)
@@ -1299,7 +1299,7 @@ static int self_check_peb_vid_hdr(const struct ubi_device *ubi, int pnum)
        if (err && err != UBI_IO_BITFLIPS && !mtd_is_eccerr(err))
                goto exit;
 
-       crc = crc32(UBI_CRC32_INIT, vid_hdr, UBI_EC_HDR_SIZE_CRC);
+       crc = crc32(UBI_CRC32_INIT, vid_hdr, UBI_VID_HDR_SIZE_CRC);
        hdr_crc = be32_to_cpu(vid_hdr->hdr_crc);
        if (hdr_crc != crc) {
                ubi_err(ubi, "bad VID header CRC at PEB %d, calculated %#08x, read %#08x",
index eb4489f9082fe84345d2ec68b0f8723888e5c177..56065632a5b85ebf50022f883e1edc968a069f93 100644 (file)
@@ -603,6 +603,7 @@ static int schedule_erase(struct ubi_device *ubi, struct ubi_wl_entry *e,
        return 0;
 }
 
+static int __erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk);
 /**
  * do_sync_erase - run the erase worker synchronously.
  * @ubi: UBI device description object
@@ -615,20 +616,16 @@ static int schedule_erase(struct ubi_device *ubi, struct ubi_wl_entry *e,
 static int do_sync_erase(struct ubi_device *ubi, struct ubi_wl_entry *e,
                         int vol_id, int lnum, int torture)
 {
-       struct ubi_work *wl_wrk;
+       struct ubi_work wl_wrk;
 
        dbg_wl("sync erase of PEB %i", e->pnum);
 
-       wl_wrk = kmalloc(sizeof(struct ubi_work), GFP_NOFS);
-       if (!wl_wrk)
-               return -ENOMEM;
-
-       wl_wrk->e = e;
-       wl_wrk->vol_id = vol_id;
-       wl_wrk->lnum = lnum;
-       wl_wrk->torture = torture;
+       wl_wrk.e = e;
+       wl_wrk.vol_id = vol_id;
+       wl_wrk.lnum = lnum;
+       wl_wrk.torture = torture;
 
-       return erase_worker(ubi, wl_wrk, 0);
+       return __erase_worker(ubi, &wl_wrk);
 }
 
 /**
@@ -1014,7 +1011,7 @@ out_unlock:
 }
 
 /**
- * erase_worker - physical eraseblock erase worker function.
+ * __erase_worker - physical eraseblock erase worker function.
  * @ubi: UBI device description object
  * @wl_wrk: the work object
  * @shutdown: non-zero if the worker has to free memory and exit
@@ -1025,8 +1022,7 @@ out_unlock:
  * needed. Returns zero in case of success and a negative error code in case of
  * failure.
  */
-static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk,
-                       int shutdown)
+static int __erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk)
 {
        struct ubi_wl_entry *e = wl_wrk->e;
        int pnum = e->pnum;
@@ -1034,21 +1030,11 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk,
        int lnum = wl_wrk->lnum;
        int err, available_consumed = 0;
 
-       if (shutdown) {
-               dbg_wl("cancel erasure of PEB %d EC %d", pnum, e->ec);
-               kfree(wl_wrk);
-               wl_entry_destroy(ubi, e);
-               return 0;
-       }
-
        dbg_wl("erase PEB %d EC %d LEB %d:%d",
               pnum, e->ec, wl_wrk->vol_id, wl_wrk->lnum);
 
        err = sync_erase(ubi, e, wl_wrk->torture);
        if (!err) {
-               /* Fine, we've erased it successfully */
-               kfree(wl_wrk);
-
                spin_lock(&ubi->wl_lock);
                wl_tree_add(e, &ubi->free);
                ubi->free_count++;
@@ -1066,7 +1052,6 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk,
        }
 
        ubi_err(ubi, "failed to erase PEB %d, error %d", pnum, err);
-       kfree(wl_wrk);
 
        if (err == -EINTR || err == -ENOMEM || err == -EAGAIN ||
            err == -EBUSY) {
@@ -1075,6 +1060,7 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk,
                /* Re-schedule the LEB for erasure */
                err1 = schedule_erase(ubi, e, vol_id, lnum, 0);
                if (err1) {
+                       wl_entry_destroy(ubi, e);
                        err = err1;
                        goto out_ro;
                }
@@ -1150,6 +1136,25 @@ out_ro:
        return err;
 }
 
+static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk,
+                         int shutdown)
+{
+       int ret;
+
+       if (shutdown) {
+               struct ubi_wl_entry *e = wl_wrk->e;
+
+               dbg_wl("cancel erasure of PEB %d EC %d", e->pnum, e->ec);
+               kfree(wl_wrk);
+               wl_entry_destroy(ubi, e);
+               return 0;
+       }
+
+       ret = __erase_worker(ubi, wl_wrk);
+       kfree(wl_wrk);
+       return ret;
+}
+
 /**
  * ubi_wl_put_peb - return a PEB to the wear-leveling sub-system.
  * @ubi: UBI device description object
index 970781a9e67777a87b0b93f0cf8bf31d4541d855..f6a7161e3b85297eda9503a27280cab93b2ae70b 100644 (file)
@@ -1849,7 +1849,7 @@ static int xgbe_exit(struct xgbe_prv_data *pdata)
        usleep_range(10, 15);
 
        /* Poll Until Poll Condition */
-       while (count-- && XGMAC_IOREAD_BITS(pdata, DMA_MR, SWR))
+       while (--count && XGMAC_IOREAD_BITS(pdata, DMA_MR, SWR))
                usleep_range(500, 600);
 
        if (!count)
@@ -1873,7 +1873,7 @@ static int xgbe_flush_tx_queues(struct xgbe_prv_data *pdata)
        /* Poll Until Poll Condition */
        for (i = 0; i < pdata->tx_q_count; i++) {
                count = 2000;
-               while (count-- && XGMAC_MTL_IOREAD_BITS(pdata, i,
+               while (--count && XGMAC_MTL_IOREAD_BITS(pdata, i,
                                                        MTL_Q_TQOMR, FTQ))
                        usleep_range(500, 600);
 
index 9147a0107c44034f015beba83cfc150398c1ac93..d0ae1a6cc2120cbb4d7d2eb9840e1f552605bd06 100644 (file)
@@ -289,6 +289,7 @@ static int xgene_enet_setup_tx_desc(struct xgene_enet_desc_ring *tx_ring,
                                    struct sk_buff *skb)
 {
        struct device *dev = ndev_to_dev(tx_ring->ndev);
+       struct xgene_enet_pdata *pdata = netdev_priv(tx_ring->ndev);
        struct xgene_enet_raw_desc *raw_desc;
        __le64 *exp_desc = NULL, *exp_bufs = NULL;
        dma_addr_t dma_addr, pbuf_addr, *frag_dma_addr;
@@ -419,6 +420,7 @@ out:
        raw_desc->m0 = cpu_to_le64(SET_VAL(LL, ll) | SET_VAL(NV, nv) |
                                   SET_VAL(USERINFO, tx_ring->tail));
        tx_ring->cp_ring->cp_skb[tx_ring->tail] = skb;
+       pdata->tx_level += count;
        tx_ring->tail = tail;
 
        return count;
@@ -429,14 +431,13 @@ static netdev_tx_t xgene_enet_start_xmit(struct sk_buff *skb,
 {
        struct xgene_enet_pdata *pdata = netdev_priv(ndev);
        struct xgene_enet_desc_ring *tx_ring = pdata->tx_ring;
-       struct xgene_enet_desc_ring *cp_ring = tx_ring->cp_ring;
-       u32 tx_level, cq_level;
+       u32 tx_level = pdata->tx_level;
        int count;
 
-       tx_level = pdata->ring_ops->len(tx_ring);
-       cq_level = pdata->ring_ops->len(cp_ring);
-       if (unlikely(tx_level > pdata->tx_qcnt_hi ||
-                    cq_level > pdata->cp_qcnt_hi)) {
+       if (tx_level < pdata->txc_level)
+               tx_level += ((typeof(pdata->tx_level))~0U);
+
+       if ((tx_level - pdata->txc_level) > pdata->tx_qcnt_hi) {
                netif_stop_queue(ndev);
                return NETDEV_TX_BUSY;
        }
@@ -539,10 +540,13 @@ static int xgene_enet_process_ring(struct xgene_enet_desc_ring *ring,
        struct xgene_enet_raw_desc *raw_desc, *exp_desc;
        u16 head = ring->head;
        u16 slots = ring->slots - 1;
-       int ret, count = 0, processed = 0;
+       int ret, desc_count, count = 0, processed = 0;
+       bool is_completion;
 
        do {
                raw_desc = &ring->raw_desc[head];
+               desc_count = 0;
+               is_completion = false;
                exp_desc = NULL;
                if (unlikely(xgene_enet_is_desc_slot_empty(raw_desc)))
                        break;
@@ -559,18 +563,24 @@ static int xgene_enet_process_ring(struct xgene_enet_desc_ring *ring,
                        }
                        dma_rmb();
                        count++;
+                       desc_count++;
                }
-               if (is_rx_desc(raw_desc))
+               if (is_rx_desc(raw_desc)) {
                        ret = xgene_enet_rx_frame(ring, raw_desc);
-               else
+               } else {
                        ret = xgene_enet_tx_completion(ring, raw_desc);
+                       is_completion = true;
+               }
                xgene_enet_mark_desc_slot_empty(raw_desc);
                if (exp_desc)
                        xgene_enet_mark_desc_slot_empty(exp_desc);
 
                head = (head + 1) & slots;
                count++;
+               desc_count++;
                processed++;
+               if (is_completion)
+                       pdata->txc_level += desc_count;
 
                if (ret)
                        break;
@@ -580,10 +590,8 @@ static int xgene_enet_process_ring(struct xgene_enet_desc_ring *ring,
                pdata->ring_ops->wr_cmd(ring, -count);
                ring->head = head;
 
-               if (netif_queue_stopped(ring->ndev)) {
-                       if (pdata->ring_ops->len(ring) < pdata->cp_qcnt_low)
-                               netif_wake_queue(ring->ndev);
-               }
+               if (netif_queue_stopped(ring->ndev))
+                       netif_start_queue(ring->ndev);
        }
 
        return processed;
@@ -1033,9 +1041,7 @@ static int xgene_enet_create_desc_rings(struct net_device *ndev)
        pdata->tx_ring->cp_ring = cp_ring;
        pdata->tx_ring->dst_ring_num = xgene_enet_dst_ring_num(cp_ring);
 
-       pdata->tx_qcnt_hi = pdata->tx_ring->slots / 2;
-       pdata->cp_qcnt_hi = pdata->rx_ring->slots / 2;
-       pdata->cp_qcnt_low = pdata->cp_qcnt_hi / 2;
+       pdata->tx_qcnt_hi = pdata->tx_ring->slots - 128;
 
        return 0;
 
index a6e56b88c0a07a6bee7a1f0e6a050db802e5e989..1aa72c787f8de9464a22bf66a8ea2081a6679269 100644 (file)
@@ -155,11 +155,11 @@ struct xgene_enet_pdata {
        enum xgene_enet_id enet_id;
        struct xgene_enet_desc_ring *tx_ring;
        struct xgene_enet_desc_ring *rx_ring;
+       u16 tx_level;
+       u16 txc_level;
        char *dev_name;
        u32 rx_buff_cnt;
        u32 tx_qcnt_hi;
-       u32 cp_qcnt_hi;
-       u32 cp_qcnt_low;
        u32 rx_irq;
        u32 txc_irq;
        u8 cq_cnt;
index 2795d6db10e1897e3c3c3b367e28e05ea33858c5..8b5988e210d55bcae21f4c6bb8614696cb7b0b64 100644 (file)
@@ -1016,13 +1016,12 @@ static int atl1c_setup_ring_resources(struct atl1c_adapter *adapter)
                sizeof(struct atl1c_recv_ret_status) * rx_desc_count +
                8 * 4;
 
-       ring_header->desc = pci_alloc_consistent(pdev, ring_header->size,
-                               &ring_header->dma);
+       ring_header->desc = dma_zalloc_coherent(&pdev->dev, ring_header->size,
+                                               &ring_header->dma, GFP_KERNEL);
        if (unlikely(!ring_header->desc)) {
-               dev_err(&pdev->dev, "pci_alloc_consistend failed\n");
+               dev_err(&pdev->dev, "could not get memory for DMA buffer\n");
                goto err_nomem;
        }
-       memset(ring_header->desc, 0, ring_header->size);
        /* init TPD ring */
 
        tpd_ring[0].dma = roundup(ring_header->dma, 8);
index a3c7106fdf85e78f083a4e85b2e809f6e587a360..8ba7f8ff3434000f57f45968d8a70148f4647cc8 100644 (file)
@@ -13,6 +13,7 @@ if NET_VENDOR_AURORA
 
 config AURORA_NB8800
        tristate "Aurora AU-NB8800 support"
+       depends on HAS_DMA
        select PHYLIB
        help
         Support for the AU-NB8800 gigabit Ethernet controller.
index f8d7a2f06950139b936dc7d793bb884bb579980d..c82ab87fcbe8fb09e59be79f866910751f4b4308 100644 (file)
@@ -3430,25 +3430,29 @@ static u32 bnx2x_xmit_type(struct bnx2x *bp, struct sk_buff *skb)
        return rc;
 }
 
-#if (MAX_SKB_FRAGS >= MAX_FETCH_BD - 3)
+/* VXLAN: 4 = 1 (for linear data BD) + 3 (2 for PBD and last BD) */
+#define BNX2X_NUM_VXLAN_TSO_WIN_SUB_BDS         4
+
+/* Regular: 3 = 1 (for linear data BD) + 2 (for PBD and last BD) */
+#define BNX2X_NUM_TSO_WIN_SUB_BDS               3
+
+#if (MAX_SKB_FRAGS >= MAX_FETCH_BD - BDS_PER_TX_PKT)
 /* check if packet requires linearization (packet is too fragmented)
    no need to check fragmentation if page size > 8K (there will be no
    violation to FW restrictions) */
 static int bnx2x_pkt_req_lin(struct bnx2x *bp, struct sk_buff *skb,
                             u32 xmit_type)
 {
-       int to_copy = 0;
-       int hlen = 0;
-       int first_bd_sz = 0;
+       int first_bd_sz = 0, num_tso_win_sub = BNX2X_NUM_TSO_WIN_SUB_BDS;
+       int to_copy = 0, hlen = 0;
 
-       /* 3 = 1 (for linear data BD) + 2 (for PBD and last BD) */
-       if (skb_shinfo(skb)->nr_frags >= (MAX_FETCH_BD - 3)) {
+       if (xmit_type & XMIT_GSO_ENC)
+               num_tso_win_sub = BNX2X_NUM_VXLAN_TSO_WIN_SUB_BDS;
 
+       if (skb_shinfo(skb)->nr_frags >= (MAX_FETCH_BD - num_tso_win_sub)) {
                if (xmit_type & XMIT_GSO) {
                        unsigned short lso_mss = skb_shinfo(skb)->gso_size;
-                       /* Check if LSO packet needs to be copied:
-                          3 = 1 (for headers BD) + 2 (for PBD and last BD) */
-                       int wnd_size = MAX_FETCH_BD - 3;
+                       int wnd_size = MAX_FETCH_BD - num_tso_win_sub;
                        /* Number of windows to check */
                        int num_wnds = skb_shinfo(skb)->nr_frags - wnd_size;
                        int wnd_idx = 0;
index bdf094fb6ef92062d62d428109e277ba9e9d15f5..07f5f239cb65baca35792dd5ba7a979d2b36b763 100644 (file)
@@ -2693,17 +2693,16 @@ static int bnxt_hwrm_func_drv_rgtr(struct bnxt *bp)
        req.ver_upd = DRV_VER_UPD;
 
        if (BNXT_PF(bp)) {
-               unsigned long vf_req_snif_bmap[4];
+               DECLARE_BITMAP(vf_req_snif_bmap, 256);
                u32 *data = (u32 *)vf_req_snif_bmap;
 
-               memset(vf_req_snif_bmap, 0, 32);
+               memset(vf_req_snif_bmap, 0, sizeof(vf_req_snif_bmap));
                for (i = 0; i < ARRAY_SIZE(bnxt_vf_req_snif); i++)
                        __set_bit(bnxt_vf_req_snif[i], vf_req_snif_bmap);
 
-               for (i = 0; i < 8; i++) {
-                       req.vf_req_fwd[i] = cpu_to_le32(*data);
-                       data++;
-               }
+               for (i = 0; i < 8; i++)
+                       req.vf_req_fwd[i] = cpu_to_le32(data[i]);
+
                req.enables |=
                        cpu_to_le32(FUNC_DRV_RGTR_REQ_ENABLES_VF_REQ_FWD);
        }
@@ -4603,7 +4602,7 @@ static int __bnxt_open_nic(struct bnxt *bp, bool irq_re_init, bool link_re_init)
                        bp->nge_port_cnt = 1;
        }
 
-       bp->state = BNXT_STATE_OPEN;
+       set_bit(BNXT_STATE_OPEN, &bp->state);
        bnxt_enable_int(bp);
        /* Enable TX queues */
        bnxt_tx_enable(bp);
@@ -4679,8 +4678,10 @@ int bnxt_close_nic(struct bnxt *bp, bool irq_re_init, bool link_re_init)
        /* Change device state to avoid TX queue wake up's */
        bnxt_tx_disable(bp);
 
-       bp->state = BNXT_STATE_CLOSED;
-       cancel_work_sync(&bp->sp_task);
+       clear_bit(BNXT_STATE_OPEN, &bp->state);
+       smp_mb__after_atomic();
+       while (test_bit(BNXT_STATE_IN_SP_TASK, &bp->state))
+               msleep(20);
 
        /* Flush rings before disabling interrupts */
        bnxt_shutdown_nic(bp, irq_re_init);
@@ -5030,8 +5031,10 @@ static void bnxt_dbg_dump_states(struct bnxt *bp)
 static void bnxt_reset_task(struct bnxt *bp)
 {
        bnxt_dbg_dump_states(bp);
-       if (netif_running(bp->dev))
-               bnxt_tx_disable(bp); /* prevent tx timout again */
+       if (netif_running(bp->dev)) {
+               bnxt_close_nic(bp, false, false);
+               bnxt_open_nic(bp, false, false);
+       }
 }
 
 static void bnxt_tx_timeout(struct net_device *dev)
@@ -5081,8 +5084,12 @@ static void bnxt_sp_task(struct work_struct *work)
        struct bnxt *bp = container_of(work, struct bnxt, sp_task);
        int rc;
 
-       if (bp->state != BNXT_STATE_OPEN)
+       set_bit(BNXT_STATE_IN_SP_TASK, &bp->state);
+       smp_mb__after_atomic();
+       if (!test_bit(BNXT_STATE_OPEN, &bp->state)) {
+               clear_bit(BNXT_STATE_IN_SP_TASK, &bp->state);
                return;
+       }
 
        if (test_and_clear_bit(BNXT_RX_MASK_SP_EVENT, &bp->sp_event))
                bnxt_cfg_rx_mode(bp);
@@ -5106,8 +5113,19 @@ static void bnxt_sp_task(struct work_struct *work)
                bnxt_hwrm_tunnel_dst_port_free(
                        bp, TUNNEL_DST_PORT_FREE_REQ_TUNNEL_TYPE_VXLAN);
        }
-       if (test_and_clear_bit(BNXT_RESET_TASK_SP_EVENT, &bp->sp_event))
+       if (test_and_clear_bit(BNXT_RESET_TASK_SP_EVENT, &bp->sp_event)) {
+               /* bnxt_reset_task() calls bnxt_close_nic() which waits
+                * for BNXT_STATE_IN_SP_TASK to clear.
+                */
+               clear_bit(BNXT_STATE_IN_SP_TASK, &bp->state);
+               rtnl_lock();
                bnxt_reset_task(bp);
+               set_bit(BNXT_STATE_IN_SP_TASK, &bp->state);
+               rtnl_unlock();
+       }
+
+       smp_mb__before_atomic();
+       clear_bit(BNXT_STATE_IN_SP_TASK, &bp->state);
 }
 
 static int bnxt_init_board(struct pci_dev *pdev, struct net_device *dev)
@@ -5186,7 +5204,7 @@ static int bnxt_init_board(struct pci_dev *pdev, struct net_device *dev)
        bp->timer.function = bnxt_timer;
        bp->current_interval = BNXT_TIMER_INTERVAL;
 
-       bp->state = BNXT_STATE_CLOSED;
+       clear_bit(BNXT_STATE_OPEN, &bp->state);
 
        return 0;
 
index 674bc5159b91c7cd4972561fae11dd1bbed7d53c..f199f4cc8ffe05e7c5580dcc8b14b29ab1b8f3e9 100644 (file)
@@ -925,9 +925,9 @@ struct bnxt {
 
        struct timer_list       timer;
 
-       int                     state;
-#define BNXT_STATE_CLOSED      0
-#define BNXT_STATE_OPEN                1
+       unsigned long           state;
+#define BNXT_STATE_OPEN                0
+#define BNXT_STATE_IN_SP_TASK  1
 
        struct bnxt_irq *irq_tbl;
        u8                      mac_addr[ETH_ALEN];
index 7a9af2887d8ed83f6a8672f8c1b6e18cd572c28a..ea044bbcd384886413cea2e2415aea8d25d28cf1 100644 (file)
@@ -21,7 +21,7 @@
 #ifdef CONFIG_BNXT_SRIOV
 static int bnxt_vf_ndo_prep(struct bnxt *bp, int vf_id)
 {
-       if (bp->state != BNXT_STATE_OPEN) {
+       if (!test_bit(BNXT_STATE_OPEN, &bp->state)) {
                netdev_err(bp->dev, "vf ndo called though PF is down\n");
                return -EINVAL;
        }
index 4b7fd63ae57c1d26ab54d9359297c56f35c6105c..5f24d11cb16aad5ae6bd474d538053ac6465c868 100644 (file)
@@ -37,7 +37,6 @@ struct nicpf {
 #define        NIC_GET_BGX_FROM_VF_LMAC_MAP(map)       ((map >> 4) & 0xF)
 #define        NIC_GET_LMAC_FROM_VF_LMAC_MAP(map)      (map & 0xF)
        u8                      vf_lmac_map[MAX_LMAC];
-       u8                      lmac_cnt;
        struct delayed_work     dwork;
        struct workqueue_struct *check_link;
        u8                      link[MAX_LMAC];
@@ -280,7 +279,6 @@ static void nic_set_lmac_vf_mapping(struct nicpf *nic)
        u64 lmac_credit;
 
        nic->num_vf_en = 0;
-       nic->lmac_cnt = 0;
 
        for (bgx = 0; bgx < NIC_MAX_BGX; bgx++) {
                if (!(bgx_map & (1 << bgx)))
@@ -290,7 +288,6 @@ static void nic_set_lmac_vf_mapping(struct nicpf *nic)
                        nic->vf_lmac_map[next_bgx_lmac++] =
                                                NIC_SET_VF_LMAC_MAP(bgx, lmac);
                nic->num_vf_en += lmac_cnt;
-               nic->lmac_cnt += lmac_cnt;
 
                /* Program LMAC credits */
                lmac_credit = (1ull << 1); /* channel credit enable */
@@ -618,6 +615,21 @@ static int nic_config_loopback(struct nicpf *nic, struct set_loopback *lbk)
        return 0;
 }
 
+static void nic_enable_vf(struct nicpf *nic, int vf, bool enable)
+{
+       int bgx, lmac;
+
+       nic->vf_enabled[vf] = enable;
+
+       if (vf >= nic->num_vf_en)
+               return;
+
+       bgx = NIC_GET_BGX_FROM_VF_LMAC_MAP(nic->vf_lmac_map[vf]);
+       lmac = NIC_GET_LMAC_FROM_VF_LMAC_MAP(nic->vf_lmac_map[vf]);
+
+       bgx_lmac_rx_tx_enable(nic->node, bgx, lmac, enable);
+}
+
 /* Interrupt handler to handle mailbox messages from VFs */
 static void nic_handle_mbx_intr(struct nicpf *nic, int vf)
 {
@@ -717,29 +729,14 @@ static void nic_handle_mbx_intr(struct nicpf *nic, int vf)
                break;
        case NIC_MBOX_MSG_CFG_DONE:
                /* Last message of VF config msg sequence */
-               nic->vf_enabled[vf] = true;
-               if (vf >= nic->lmac_cnt)
-                       goto unlock;
-
-               bgx = NIC_GET_BGX_FROM_VF_LMAC_MAP(nic->vf_lmac_map[vf]);
-               lmac = NIC_GET_LMAC_FROM_VF_LMAC_MAP(nic->vf_lmac_map[vf]);
-
-               bgx_lmac_rx_tx_enable(nic->node, bgx, lmac, true);
+               nic_enable_vf(nic, vf, true);
                goto unlock;
        case NIC_MBOX_MSG_SHUTDOWN:
                /* First msg in VF teardown sequence */
-               nic->vf_enabled[vf] = false;
                if (vf >= nic->num_vf_en)
                        nic->sqs_used[vf - nic->num_vf_en] = false;
                nic->pqs_vf[vf] = 0;
-
-               if (vf >= nic->lmac_cnt)
-                       break;
-
-               bgx = NIC_GET_BGX_FROM_VF_LMAC_MAP(nic->vf_lmac_map[vf]);
-               lmac = NIC_GET_LMAC_FROM_VF_LMAC_MAP(nic->vf_lmac_map[vf]);
-
-               bgx_lmac_rx_tx_enable(nic->node, bgx, lmac, false);
+               nic_enable_vf(nic, vf, false);
                break;
        case NIC_MBOX_MSG_ALLOC_SQS:
                nic_alloc_sqs(nic, &mbx.sqs_alloc);
@@ -958,7 +955,7 @@ static void nic_poll_for_link(struct work_struct *work)
 
        mbx.link_status.msg = NIC_MBOX_MSG_BGX_LINK_CHANGE;
 
-       for (vf = 0; vf < nic->lmac_cnt; vf++) {
+       for (vf = 0; vf < nic->num_vf_en; vf++) {
                /* Poll only if VF is UP */
                if (!nic->vf_enabled[vf])
                        continue;
index c308429dd9c7fa0aebf2cee3b951f71f3863d939..11dd91e4db56b061311645567ab8c46f80123a61 100644 (file)
@@ -295,6 +295,10 @@ struct clip_tbl *t4_init_clip_tbl(unsigned int clipt_start,
                INIT_LIST_HEAD(&ctbl->hash_list[i]);
 
        cl_list = t4_alloc_mem(clipt_size*sizeof(struct clip_entry));
+       if (!cl_list) {
+               t4_free_mem(ctbl);
+               return NULL;
+       }
        ctbl->cl_list = (void *)cl_list;
 
        for (i = 0; i < clipt_size; i++) {
index d463563e1f7039ee5176ca36abfdc6bae3f2ed46..6ee78c203ecad7a18ba136e45ea0d2e24ec35930 100644 (file)
@@ -848,8 +848,6 @@ void be_roce_dev_remove(struct be_adapter *);
 /*
  * internal function to open-close roce device during ifup-ifdown.
  */
-void be_roce_dev_open(struct be_adapter *);
-void be_roce_dev_close(struct be_adapter *);
 void be_roce_dev_shutdown(struct be_adapter *);
 
 #endif                         /* BE_H */
index b6ad02909d6b3c87b861d4e35c345426bef30a64..8a1d9fffd7d671ea88023a120c93f4cdefbcff54 100644 (file)
@@ -3299,8 +3299,10 @@ static int be_msix_register(struct be_adapter *adapter)
 
        return 0;
 err_msix:
-       for (i--, eqo = &adapter->eq_obj[i]; i >= 0; i--, eqo--)
+       for (i--; i >= 0; i--) {
+               eqo = &adapter->eq_obj[i];
                free_irq(be_msix_vec_get(adapter, eqo), eqo);
+       }
        dev_warn(&adapter->pdev->dev, "MSIX Request IRQ failed - err %d\n",
                 status);
        be_msix_disable(adapter);
@@ -3432,8 +3434,6 @@ static int be_close(struct net_device *netdev)
 
        be_disable_if_filters(adapter);
 
-       be_roce_dev_close(adapter);
-
        if (adapter->flags & BE_FLAGS_NAPI_ENABLED) {
                for_all_evt_queues(adapter, eqo, i) {
                        napi_disable(&eqo->napi);
@@ -3601,8 +3601,6 @@ static int be_open(struct net_device *netdev)
                be_link_status_update(adapter, link_status);
 
        netif_tx_start_all_queues(netdev);
-       be_roce_dev_open(adapter);
-
 #ifdef CONFIG_BE2NET_VXLAN
        if (skyhawk_chip(adapter))
                vxlan_get_rx_port(netdev);
index 60368207bf584188b4d0293d9f2a8d7235180a8d..4089156a7f5e20177dfee8d29315c404924f4d9e 100644 (file)
@@ -116,40 +116,6 @@ void be_roce_dev_remove(struct be_adapter *adapter)
        }
 }
 
-static void _be_roce_dev_open(struct be_adapter *adapter)
-{
-       if (ocrdma_drv && adapter->ocrdma_dev &&
-           ocrdma_drv->state_change_handler)
-               ocrdma_drv->state_change_handler(adapter->ocrdma_dev,
-                                                BE_DEV_UP);
-}
-
-void be_roce_dev_open(struct be_adapter *adapter)
-{
-       if (be_roce_supported(adapter)) {
-               mutex_lock(&be_adapter_list_lock);
-               _be_roce_dev_open(adapter);
-               mutex_unlock(&be_adapter_list_lock);
-       }
-}
-
-static void _be_roce_dev_close(struct be_adapter *adapter)
-{
-       if (ocrdma_drv && adapter->ocrdma_dev &&
-           ocrdma_drv->state_change_handler)
-               ocrdma_drv->state_change_handler(adapter->ocrdma_dev,
-                                                BE_DEV_DOWN);
-}
-
-void be_roce_dev_close(struct be_adapter *adapter)
-{
-       if (be_roce_supported(adapter)) {
-               mutex_lock(&be_adapter_list_lock);
-               _be_roce_dev_close(adapter);
-               mutex_unlock(&be_adapter_list_lock);
-       }
-}
-
 void be_roce_dev_shutdown(struct be_adapter *adapter)
 {
        if (be_roce_supported(adapter)) {
@@ -177,8 +143,6 @@ int be_roce_register_driver(struct ocrdma_driver *drv)
 
                _be_roce_dev_add(dev);
                netdev = dev->netdev;
-               if (netif_running(netdev) && netif_oper_up(netdev))
-                       _be_roce_dev_open(dev);
        }
        mutex_unlock(&be_adapter_list_lock);
        return 0;
index cde6ef905ec481dce0436858fb1fd78252471146..fde609789483872582bda5a990d6bad357dc25df 100644 (file)
@@ -60,9 +60,7 @@ struct ocrdma_driver {
        void (*state_change_handler) (struct ocrdma_dev *, u32 new_state);
 };
 
-enum {
-       BE_DEV_UP       = 0,
-       BE_DEV_DOWN     = 1,
+enum be_roce_event {
        BE_DEV_SHUTDOWN = 2
 };
 
index 63c2bcf8031a8a8cc39c714bb1510e3f3ae03793..b1026689b78f4075d30b240b4f8dc625d3b9299a 100644 (file)
@@ -48,21 +48,15 @@ static void nps_enet_read_rx_fifo(struct net_device *ndev,
                        *reg = nps_enet_reg_get(priv, NPS_ENET_REG_RX_BUF);
        else { /* !dst_is_aligned */
                for (i = 0; i < len; i++, reg++) {
-                       u32 buf =
-                               nps_enet_reg_get(priv, NPS_ENET_REG_RX_BUF);
-
-                       /* to accommodate word-unaligned address of "reg"
-                        * we have to do memcpy_toio() instead of simple "=".
-                        */
-                       memcpy_toio((void __iomem *)reg, &buf, sizeof(buf));
+                       u32 buf = nps_enet_reg_get(priv, NPS_ENET_REG_RX_BUF);
+                       put_unaligned(buf, reg);
                }
        }
 
        /* copy last bytes (if any) */
        if (last) {
                u32 buf = nps_enet_reg_get(priv, NPS_ENET_REG_RX_BUF);
-
-               memcpy_toio((void __iomem *)reg, &buf, last);
+               memcpy((u8*)reg, &buf, last);
        }
 }
 
@@ -367,7 +361,7 @@ static void nps_enet_send_frame(struct net_device *ndev,
        struct nps_enet_tx_ctl tx_ctrl;
        short length = skb->len;
        u32 i, len = DIV_ROUND_UP(length, sizeof(u32));
-       u32 *src = (u32 *)virt_to_phys(skb->data);
+       u32 *src = (void *)skb->data;
        bool src_is_aligned = IS_ALIGNED((unsigned long)src, sizeof(u32));
 
        tx_ctrl.value = 0;
@@ -375,17 +369,11 @@ static void nps_enet_send_frame(struct net_device *ndev,
        if (src_is_aligned)
                for (i = 0; i < len; i++, src++)
                        nps_enet_reg_set(priv, NPS_ENET_REG_TX_BUF, *src);
-       else { /* !src_is_aligned */
-               for (i = 0; i < len; i++, src++) {
-                       u32 buf;
-
-                       /* to accommodate word-unaligned address of "src"
-                        * we have to do memcpy_fromio() instead of simple "="
-                        */
-                       memcpy_fromio(&buf, (void __iomem *)src, sizeof(buf));
-                       nps_enet_reg_set(priv, NPS_ENET_REG_TX_BUF, buf);
-               }
-       }
+       else /* !src_is_aligned */
+               for (i = 0; i < len; i++, src++)
+                       nps_enet_reg_set(priv, NPS_ENET_REG_TX_BUF,
+                                        get_unaligned(src));
+
        /* Write the length of the Frame */
        tx_ctrl.nt = length;
 
index 08f5b911d96be1b01f99484ee748c24aaed7f483..52e0091b4fb261f983ab0e043d1cb0d48638dc03 100644 (file)
@@ -552,7 +552,7 @@ static void tx_restart(struct net_device *dev)
        cbd_t __iomem *prev_bd;
        cbd_t __iomem *last_tx_bd;
 
-       last_tx_bd = fep->tx_bd_base + (fpi->tx_ring * sizeof(cbd_t));
+       last_tx_bd = fep->tx_bd_base + ((fpi->tx_ring - 1) * sizeof(cbd_t));
 
        /* get the current bd held in TBPTR  and scan back from this point */
        recheck_bd = curr_tbptr = (cbd_t __iomem *)
index 55c36230e17634c3e063bdb20f4bb6a896bce4a6..40071dad1c570686de4d7b062d0b61682c878c2b 100644 (file)
@@ -464,7 +464,7 @@ static int fsl_pq_mdio_probe(struct platform_device *pdev)
                         * address). Print error message but continue anyway.
                         */
                        if ((void *)tbipa > priv->map + resource_size(&res) - 4)
-                               dev_err(&pdev->dev, "invalid register map (should be at least 0x%04x to contain TBI address)\n",
+                               dev_err(&pdev->dev, "invalid register map (should be at least 0x%04zx to contain TBI address)\n",
                                        ((void *)tbipa - priv->map) + 4);
 
                        iowrite32be(be32_to_cpup(prop), tbipa);
index 7cf898455e60076d52c1031422f3d90a3a10f4a3..3e233d924cce3b8bbf6bf5901b61455c5c0cd2dc 100644 (file)
@@ -894,7 +894,8 @@ static int gfar_of_init(struct platform_device *ofdev, struct net_device **pdev)
                                     FSL_GIANFAR_DEV_HAS_VLAN |
                                     FSL_GIANFAR_DEV_HAS_MAGIC_PACKET |
                                     FSL_GIANFAR_DEV_HAS_EXTENDED_HASH |
-                                    FSL_GIANFAR_DEV_HAS_TIMER;
+                                    FSL_GIANFAR_DEV_HAS_TIMER |
+                                    FSL_GIANFAR_DEV_HAS_RX_FILER;
 
        err = of_property_read_string(np, "phy-connection-type", &ctype);
 
@@ -1396,8 +1397,9 @@ static int gfar_probe(struct platform_device *ofdev)
                priv->rx_queue[i]->rxic = DEFAULT_RXIC;
        }
 
-       /* always enable rx filer */
-       priv->rx_filer_enable = 1;
+       /* Always enable rx filer if available */
+       priv->rx_filer_enable =
+           (priv->device_flags & FSL_GIANFAR_DEV_HAS_RX_FILER) ? 1 : 0;
        /* Enable most messages by default */
        priv->msg_enable = (NETIF_MSG_IFUP << 1 ) - 1;
        /* use pritority h/w tx queue scheduling for single queue devices */
index f266b20f9ef5be53e6c55f2579484bb72d8794a1..cb77667971a7e4dd761ada53273f04a2047cf259 100644 (file)
@@ -923,6 +923,7 @@ struct gfar {
 #define FSL_GIANFAR_DEV_HAS_BUF_STASHING       0x00000400
 #define FSL_GIANFAR_DEV_HAS_TIMER              0x00000800
 #define FSL_GIANFAR_DEV_HAS_WAKE_ON_FILER      0x00001000
+#define FSL_GIANFAR_DEV_HAS_RX_FILER           0x00002000
 
 #if (MAXGROUPS == 2)
 #define DEFAULT_MAPPING        0xAA
index 2a98eba660c06a4dc3736bf84686a20d87597e20..b674414a4d725569c87fa577aa23f5b822e80d50 100644 (file)
@@ -1259,12 +1259,8 @@ int hns_dsaf_set_mac_uc_entry(
        if (MAC_IS_ALL_ZEROS(mac_entry->addr) ||
            MAC_IS_BROADCAST(mac_entry->addr) ||
            MAC_IS_MULTICAST(mac_entry->addr)) {
-               dev_err(dsaf_dev->dev,
-                       "set_uc %s Mac %02x:%02x:%02x:%02x:%02x:%02x err!\n",
-                       dsaf_dev->ae_dev.name, mac_entry->addr[0],
-                       mac_entry->addr[1], mac_entry->addr[2],
-                       mac_entry->addr[3], mac_entry->addr[4],
-                       mac_entry->addr[5]);
+               dev_err(dsaf_dev->dev, "set_uc %s Mac %pM err!\n",
+                       dsaf_dev->ae_dev.name, mac_entry->addr);
                return -EINVAL;
        }
 
@@ -1331,12 +1327,8 @@ int hns_dsaf_set_mac_mc_entry(
 
        /* mac addr check */
        if (MAC_IS_ALL_ZEROS(mac_entry->addr)) {
-               dev_err(dsaf_dev->dev,
-                       "set uc %s Mac %02x:%02x:%02x:%02x:%02x:%02x err!\n",
-                       dsaf_dev->ae_dev.name, mac_entry->addr[0],
-                       mac_entry->addr[1], mac_entry->addr[2],
-                       mac_entry->addr[3],
-                       mac_entry->addr[4], mac_entry->addr[5]);
+               dev_err(dsaf_dev->dev, "set uc %s Mac %pM err!\n",
+                       dsaf_dev->ae_dev.name, mac_entry->addr);
                return -EINVAL;
        }
 
@@ -1410,11 +1402,8 @@ int hns_dsaf_add_mac_mc_port(struct dsaf_device *dsaf_dev,
 
        /*chechk mac addr */
        if (MAC_IS_ALL_ZEROS(mac_entry->addr)) {
-               dev_err(dsaf_dev->dev,
-                       "set_entry failed,addr %02x:%02x:%02x:%02x:%02x:%02x!\n",
-                       mac_entry->addr[0], mac_entry->addr[1],
-                       mac_entry->addr[2], mac_entry->addr[3],
-                       mac_entry->addr[4], mac_entry->addr[5]);
+               dev_err(dsaf_dev->dev, "set_entry failed,addr %pM!\n",
+                       mac_entry->addr);
                return -EINVAL;
        }
 
@@ -1497,9 +1486,8 @@ int hns_dsaf_del_mac_entry(struct dsaf_device *dsaf_dev, u16 vlan_id,
 
        /*check mac addr */
        if (MAC_IS_ALL_ZEROS(addr) || MAC_IS_BROADCAST(addr)) {
-               dev_err(dsaf_dev->dev,
-                       "del_entry failed,addr %02x:%02x:%02x:%02x:%02x:%02x!\n",
-                       addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
+               dev_err(dsaf_dev->dev, "del_entry failed,addr %pM!\n",
+                       addr);
                return -EINVAL;
        }
 
@@ -1563,11 +1551,8 @@ int hns_dsaf_del_mac_mc_port(struct dsaf_device *dsaf_dev,
 
        /*check mac addr */
        if (MAC_IS_ALL_ZEROS(mac_entry->addr)) {
-               dev_err(dsaf_dev->dev,
-                       "del_port failed, addr %02x:%02x:%02x:%02x:%02x:%02x!\n",
-                       mac_entry->addr[0], mac_entry->addr[1],
-                       mac_entry->addr[2], mac_entry->addr[3],
-                       mac_entry->addr[4], mac_entry->addr[5]);
+               dev_err(dsaf_dev->dev, "del_port failed, addr %pM!\n",
+                       mac_entry->addr);
                return -EINVAL;
        }
 
@@ -1644,11 +1629,8 @@ int hns_dsaf_get_mac_uc_entry(struct dsaf_device *dsaf_dev,
        /* check macaddr */
        if (MAC_IS_ALL_ZEROS(mac_entry->addr) ||
            MAC_IS_BROADCAST(mac_entry->addr)) {
-               dev_err(dsaf_dev->dev,
-                       "get_entry failed,addr %02x:%02x:%02x:%02x:%02x:%02x\n",
-                       mac_entry->addr[0], mac_entry->addr[1],
-                       mac_entry->addr[2], mac_entry->addr[3],
-                       mac_entry->addr[4], mac_entry->addr[5]);
+               dev_err(dsaf_dev->dev, "get_entry failed,addr %pM\n",
+                       mac_entry->addr);
                return -EINVAL;
        }
 
@@ -1695,11 +1677,8 @@ int hns_dsaf_get_mac_mc_entry(struct dsaf_device *dsaf_dev,
        /*check mac addr */
        if (MAC_IS_ALL_ZEROS(mac_entry->addr) ||
            MAC_IS_BROADCAST(mac_entry->addr)) {
-               dev_err(dsaf_dev->dev,
-                       "get_entry failed,addr %02x:%02x:%02x:%02x:%02x:%02x\n",
-                       mac_entry->addr[0], mac_entry->addr[1],
-                       mac_entry->addr[2], mac_entry->addr[3],
-                       mac_entry->addr[4], mac_entry->addr[5]);
+               dev_err(dsaf_dev->dev, "get_entry failed,addr %pM\n",
+                       mac_entry->addr);
                return -EINVAL;
        }
 
index b475e1bf2e6fdb24d9bade9405aa3e575581664e..bdbd80423b17aaf36d9134109ece6bb8d22c4303 100644 (file)
 #define XGMAC_PAUSE_CTL_RSP_MODE_B     2
 #define XGMAC_PAUSE_CTL_TX_XOFF_B      3
 
-static inline void dsaf_write_reg(void *base, u32 reg, u32 value)
+static inline void dsaf_write_reg(void __iomem *base, u32 reg, u32 value)
 {
        u8 __iomem *reg_addr = ACCESS_ONCE(base);
 
@@ -908,7 +908,7 @@ static inline void dsaf_write_reg(void *base, u32 reg, u32 value)
 #define dsaf_write_dev(a, reg, value) \
        dsaf_write_reg((a)->io_base, (reg), (value))
 
-static inline u32 dsaf_read_reg(u8 *base, u32 reg)
+static inline u32 dsaf_read_reg(u8 __iomem *base, u32 reg)
 {
        u8 __iomem *reg_addr = ACCESS_ONCE(base);
 
@@ -927,8 +927,8 @@ static inline u32 dsaf_read_reg(u8 *base, u32 reg)
 #define dsaf_set_bit(origin, shift, val) \
        dsaf_set_field((origin), (1ull << (shift)), (shift), (val))
 
-static inline void dsaf_set_reg_field(void *base, u32 reg, u32 mask, u32 shift,
-                                     u32 val)
+static inline void dsaf_set_reg_field(void __iomem *base, u32 reg, u32 mask,
+                                     u32 shift, u32 val)
 {
        u32 origin = dsaf_read_reg(base, reg);
 
@@ -947,7 +947,8 @@ static inline void dsaf_set_reg_field(void *base, u32 reg, u32 mask, u32 shift,
 #define dsaf_get_bit(origin, shift) \
        dsaf_get_field((origin), (1ull << (shift)), (shift))
 
-static inline u32 dsaf_get_reg_field(void *base, u32 reg, u32 mask, u32 shift)
+static inline u32 dsaf_get_reg_field(void __iomem *base, u32 reg, u32 mask,
+                                    u32 shift)
 {
        u32 origin;
 
index 0ff8f01e57ee5a4a7de890485e5987fd9eec7f8a..1fd5ea82a9bc88950a29a305e7c4898c3b6b246c 100644 (file)
@@ -567,10 +567,6 @@ i40e_status i40e_init_adminq(struct i40e_hw *hw)
                goto init_adminq_exit;
        }
 
-       /* initialize locks */
-       mutex_init(&hw->aq.asq_mutex);
-       mutex_init(&hw->aq.arq_mutex);
-
        /* Set up register offsets */
        i40e_adminq_init_regs(hw);
 
@@ -664,8 +660,6 @@ i40e_status i40e_shutdown_adminq(struct i40e_hw *hw)
        i40e_shutdown_asq(hw);
        i40e_shutdown_arq(hw);
 
-       /* destroy the locks */
-
        if (hw->nvm_buff.va)
                i40e_free_virt_mem(hw, &hw->nvm_buff);
 
index b825f978d441d1987581b249694298bb5996538d..4a9873ec28c7119d28aabb791bd0628ceccf56ad 100644 (file)
@@ -10295,6 +10295,12 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        /* set up a default setting for link flow control */
        pf->hw.fc.requested_mode = I40E_FC_NONE;
 
+       /* set up the locks for the AQ, do this only once in probe
+        * and destroy them only once in remove
+        */
+       mutex_init(&hw->aq.asq_mutex);
+       mutex_init(&hw->aq.arq_mutex);
+
        err = i40e_init_adminq(hw);
 
        /* provide nvm, fw, api versions */
@@ -10697,7 +10703,6 @@ static void i40e_remove(struct pci_dev *pdev)
        set_bit(__I40E_DOWN, &pf->state);
        del_timer_sync(&pf->service_timer);
        cancel_work_sync(&pf->service_task);
-       i40e_fdir_teardown(pf);
 
        if (pf->flags & I40E_FLAG_SRIOV_ENABLED) {
                i40e_free_vfs(pf);
@@ -10740,6 +10745,10 @@ static void i40e_remove(struct pci_dev *pdev)
                         "Failed to destroy the Admin Queue resources: %d\n",
                         ret_code);
 
+       /* destroy the locks only once, here */
+       mutex_destroy(&hw->aq.arq_mutex);
+       mutex_destroy(&hw->aq.asq_mutex);
+
        /* Clear all dynamic memory lists of rings, q_vectors, and VSIs */
        i40e_clear_interrupt_scheme(pf);
        for (i = 0; i < pf->num_alloc_vsi; i++) {
index fd123ca60761e84721a02ab991ed677925338126..3f65e39b3fe43b9231ab28bfe32b8728aba95ce1 100644 (file)
@@ -551,10 +551,6 @@ i40e_status i40evf_init_adminq(struct i40e_hw *hw)
                goto init_adminq_exit;
        }
 
-       /* initialize locks */
-       mutex_init(&hw->aq.asq_mutex);
-       mutex_init(&hw->aq.arq_mutex);
-
        /* Set up register offsets */
        i40e_adminq_init_regs(hw);
 
@@ -596,8 +592,6 @@ i40e_status i40evf_shutdown_adminq(struct i40e_hw *hw)
        i40e_shutdown_asq(hw);
        i40e_shutdown_arq(hw);
 
-       /* destroy the locks */
-
        if (hw->nvm_buff.va)
                i40e_free_virt_mem(hw, &hw->nvm_buff);
 
index d962164dfb0fbf579a150223b8d594ecb073b51f..99d2cffae0cd8c2b4c583f4453aa3c09cc58f3eb 100644 (file)
@@ -2476,6 +2476,12 @@ static int i40evf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        hw->bus.device = PCI_SLOT(pdev->devfn);
        hw->bus.func = PCI_FUNC(pdev->devfn);
 
+       /* set up the locks for the AQ, do this only once in probe
+        * and destroy them only once in remove
+        */
+       mutex_init(&hw->aq.asq_mutex);
+       mutex_init(&hw->aq.arq_mutex);
+
        INIT_LIST_HEAD(&adapter->mac_filter_list);
        INIT_LIST_HEAD(&adapter->vlan_filter_list);
 
@@ -2629,6 +2635,10 @@ static void i40evf_remove(struct pci_dev *pdev)
        if (hw->aq.asq.count)
                i40evf_shutdown_adminq(hw);
 
+       /* destroy the locks only once, here */
+       mutex_destroy(&hw->aq.arq_mutex);
+       mutex_destroy(&hw->aq.asq_mutex);
+
        iounmap(hw->hw_addr);
        pci_release_regions(pdev);
 
index 47395ff5d908c43174a4c6afc4a8a089ae948c70..aed8d029b23dc53a7a630d74816e37d35bdbbc4a 100644 (file)
@@ -7920,6 +7920,9 @@ int ixgbe_setup_tc(struct net_device *dev, u8 tc)
         */
        if (netif_running(dev))
                ixgbe_close(dev);
+       else
+               ixgbe_reset(adapter);
+
        ixgbe_clear_interrupt_scheme(adapter);
 
 #ifdef CONFIG_IXGBE_DCB
index d9884fd15b453e2486177d58b7fc40bcd5aaf7cc..a4beccf1fd46e26483dc796829d444a15f77723f 100644 (file)
@@ -3413,16 +3413,23 @@ static void mvpp2_bm_pool_bufsize_set(struct mvpp2 *priv,
 }
 
 /* Free all buffers from the pool */
-static void mvpp2_bm_bufs_free(struct mvpp2 *priv, struct mvpp2_bm_pool *bm_pool)
+static void mvpp2_bm_bufs_free(struct device *dev, struct mvpp2 *priv,
+                              struct mvpp2_bm_pool *bm_pool)
 {
        int i;
 
        for (i = 0; i < bm_pool->buf_num; i++) {
+               dma_addr_t buf_phys_addr;
                u32 vaddr;
 
                /* Get buffer virtual address (indirect access) */
-               mvpp2_read(priv, MVPP2_BM_PHY_ALLOC_REG(bm_pool->id));
+               buf_phys_addr = mvpp2_read(priv,
+                                          MVPP2_BM_PHY_ALLOC_REG(bm_pool->id));
                vaddr = mvpp2_read(priv, MVPP2_BM_VIRT_ALLOC_REG);
+
+               dma_unmap_single(dev, buf_phys_addr,
+                                bm_pool->buf_size, DMA_FROM_DEVICE);
+
                if (!vaddr)
                        break;
                dev_kfree_skb_any((struct sk_buff *)vaddr);
@@ -3439,7 +3446,7 @@ static int mvpp2_bm_pool_destroy(struct platform_device *pdev,
 {
        u32 val;
 
-       mvpp2_bm_bufs_free(priv, bm_pool);
+       mvpp2_bm_bufs_free(&pdev->dev, priv, bm_pool);
        if (bm_pool->buf_num) {
                WARN(1, "cannot free all buffers in pool %d\n", bm_pool->id);
                return 0;
@@ -3692,7 +3699,8 @@ mvpp2_bm_pool_use(struct mvpp2_port *port, int pool, enum mvpp2_bm_type type,
                                   MVPP2_BM_LONG_BUF_NUM :
                                   MVPP2_BM_SHORT_BUF_NUM;
                else
-                       mvpp2_bm_bufs_free(port->priv, new_pool);
+                       mvpp2_bm_bufs_free(port->dev->dev.parent,
+                                          port->priv, new_pool);
 
                new_pool->pkt_size = pkt_size;
 
@@ -3756,7 +3764,7 @@ static int mvpp2_bm_update_mtu(struct net_device *dev, int mtu)
        int pkt_size = MVPP2_RX_PKT_SIZE(mtu);
 
        /* Update BM pool with new buffer size */
-       mvpp2_bm_bufs_free(port->priv, port_pool);
+       mvpp2_bm_bufs_free(dev->dev.parent, port->priv, port_pool);
        if (port_pool->buf_num) {
                WARN(1, "cannot free all buffers in pool %d\n", port_pool->id);
                return -EIO;
@@ -4401,11 +4409,10 @@ static void mvpp2_txq_bufs_free(struct mvpp2_port *port,
 
                mvpp2_txq_inc_get(txq_pcpu);
 
-               if (!skb)
-                       continue;
-
                dma_unmap_single(port->dev->dev.parent, buf_phys_addr,
                                 skb_headlen(skb), DMA_TO_DEVICE);
+               if (!skb)
+                       continue;
                dev_kfree_skb_any(skb);
        }
 }
@@ -5092,7 +5099,8 @@ static int mvpp2_rx(struct mvpp2_port *port, int rx_todo,
                    struct mvpp2_rx_queue *rxq)
 {
        struct net_device *dev = port->dev;
-       int rx_received, rx_filled, i;
+       int rx_received;
+       int rx_done = 0;
        u32 rcvd_pkts = 0;
        u32 rcvd_bytes = 0;
 
@@ -5101,17 +5109,18 @@ static int mvpp2_rx(struct mvpp2_port *port, int rx_todo,
        if (rx_todo > rx_received)
                rx_todo = rx_received;
 
-       rx_filled = 0;
-       for (i = 0; i < rx_todo; i++) {
+       while (rx_done < rx_todo) {
                struct mvpp2_rx_desc *rx_desc = mvpp2_rxq_next_desc_get(rxq);
                struct mvpp2_bm_pool *bm_pool;
                struct sk_buff *skb;
+               dma_addr_t phys_addr;
                u32 bm, rx_status;
                int pool, rx_bytes, err;
 
-               rx_filled++;
+               rx_done++;
                rx_status = rx_desc->status;
                rx_bytes = rx_desc->data_size - MVPP2_MH_SIZE;
+               phys_addr = rx_desc->buf_phys_addr;
 
                bm = mvpp2_bm_cookie_build(rx_desc);
                pool = mvpp2_bm_cookie_pool_get(bm);
@@ -5128,8 +5137,10 @@ static int mvpp2_rx(struct mvpp2_port *port, int rx_todo,
                 * comprised by the RX descriptor.
                 */
                if (rx_status & MVPP2_RXD_ERR_SUMMARY) {
+               err_drop_frame:
                        dev->stats.rx_errors++;
                        mvpp2_rx_error(port, rx_desc);
+                       /* Return the buffer to the pool */
                        mvpp2_pool_refill(port, bm, rx_desc->buf_phys_addr,
                                          rx_desc->buf_cookie);
                        continue;
@@ -5137,6 +5148,15 @@ static int mvpp2_rx(struct mvpp2_port *port, int rx_todo,
 
                skb = (struct sk_buff *)rx_desc->buf_cookie;
 
+               err = mvpp2_rx_refill(port, bm_pool, bm, 0);
+               if (err) {
+                       netdev_err(port->dev, "failed to refill BM pools\n");
+                       goto err_drop_frame;
+               }
+
+               dma_unmap_single(dev->dev.parent, phys_addr,
+                                bm_pool->buf_size, DMA_FROM_DEVICE);
+
                rcvd_pkts++;
                rcvd_bytes += rx_bytes;
                atomic_inc(&bm_pool->in_use);
@@ -5147,12 +5167,6 @@ static int mvpp2_rx(struct mvpp2_port *port, int rx_todo,
                mvpp2_rx_csum(port, rx_status, skb);
 
                napi_gro_receive(&port->napi, skb);
-
-               err = mvpp2_rx_refill(port, bm_pool, bm, 0);
-               if (err) {
-                       netdev_err(port->dev, "failed to refill BM pools\n");
-                       rx_filled--;
-               }
        }
 
        if (rcvd_pkts) {
@@ -5166,7 +5180,7 @@ static int mvpp2_rx(struct mvpp2_port *port, int rx_todo,
 
        /* Update Rx queue management counters */
        wmb();
-       mvpp2_rxq_status_update(port, rxq->id, rx_todo, rx_filled);
+       mvpp2_rxq_status_update(port, rxq->id, rx_done, rx_done);
 
        return rx_todo;
 }
index 2177e56ed0be7d18ee40d2428b69003bd6f8cca5..d48d5793407d9ec729fe8548a049a2506d02a934 100644 (file)
@@ -1010,7 +1010,7 @@ static int mlx4_MAD_IFC_wrapper(struct mlx4_dev *dev, int slave,
                if (!(smp->mgmt_class == IB_MGMT_CLASS_SUBN_LID_ROUTED &&
                      smp->method == IB_MGMT_METHOD_GET) || network_view) {
                        mlx4_err(dev, "Unprivileged slave %d is trying to execute a Subnet MGMT MAD, class 0x%x, method 0x%x, view=%s for attr 0x%x. Rejecting\n",
-                                slave, smp->method, smp->mgmt_class,
+                                slave, smp->mgmt_class, smp->method,
                                 network_view ? "Network" : "Host",
                                 be16_to_cpu(smp->attr_id));
                        return -EPERM;
index 8a083d73efdbae61e7d71ee364c816b58a16b2f9..038f9ce391e626f02d3fe2f51a19fbd4b08a2711 100644 (file)
@@ -242,6 +242,13 @@ void mlx4_en_init_timestamp(struct mlx4_en_dev *mdev)
        unsigned long flags;
        u64 ns, zero = 0;
 
+       /* mlx4_en_init_timestamp is called for each netdev.
+        * mdev->ptp_clock is common for all ports, skip initialization if
+        * was done for other port.
+        */
+       if (mdev->ptp_clock)
+               return;
+
        rwlock_init(&mdev->clock_lock);
 
        memset(&mdev->cycles, 0, sizeof(mdev->cycles));
index 005f910ec955ecdaaa398c6edcc6d95c01d6c2c4..e0ec280a7fa13a55fd239f84c6f6c24db2c2e5e5 100644 (file)
@@ -232,9 +232,6 @@ static void mlx4_en_remove(struct mlx4_dev *dev, void *endev_ptr)
                if (mdev->pndev[i])
                        mlx4_en_destroy_netdev(mdev->pndev[i]);
 
-       if (mdev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_TS)
-               mlx4_en_remove_timestamp(mdev);
-
        flush_workqueue(mdev->workqueue);
        destroy_workqueue(mdev->workqueue);
        (void) mlx4_mr_free(dev, &mdev->mr);
@@ -320,10 +317,6 @@ static void *mlx4_en_add(struct mlx4_dev *dev)
        mlx4_foreach_port(i, dev, MLX4_PORT_TYPE_ETH)
                mdev->port_cnt++;
 
-       /* Initialize time stamp mechanism */
-       if (mdev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_TS)
-               mlx4_en_init_timestamp(mdev);
-
        /* Set default number of RX rings*/
        mlx4_en_set_num_rx_rings(mdev);
 
index 886e1bc86374d990fc92655c7e1b40a3d611b45c..7869f97de5daf94cb99554c51a28a610aca76348 100644 (file)
@@ -2072,6 +2072,9 @@ void mlx4_en_destroy_netdev(struct net_device *dev)
        /* flush any pending task for this netdev */
        flush_workqueue(mdev->workqueue);
 
+       if (mdev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_TS)
+               mlx4_en_remove_timestamp(mdev);
+
        /* Detach the netdev so tasks would not attempt to access it */
        mutex_lock(&mdev->state_lock);
        mdev->pndev[priv->port] = NULL;
@@ -3058,9 +3061,12 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
        }
        queue_delayed_work(mdev->workqueue, &priv->stats_task, STATS_DELAY);
 
+       /* Initialize time stamp mechanism */
        if (mdev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_TS)
-               queue_delayed_work(mdev->workqueue, &priv->service_task,
-                                  SERVICE_TASK_DELAY);
+               mlx4_en_init_timestamp(mdev);
+
+       queue_delayed_work(mdev->workqueue, &priv->service_task,
+                          SERVICE_TASK_DELAY);
 
        mlx4_en_set_stats_bitmap(mdev->dev, &priv->stats_bitmap,
                                 mdev->profile.prof[priv->port].rx_ppp,
index 6fec3e993d020e34fb2995a221baeac7c25126c6..cad6c44df91c4de9b97d367ede4f2562c65fc86b 100644 (file)
@@ -4306,9 +4306,10 @@ int mlx4_QP_FLOW_STEERING_ATTACH_wrapper(struct mlx4_dev *dev, int slave,
                return -EOPNOTSUPP;
 
        ctrl = (struct mlx4_net_trans_rule_hw_ctrl *)inbox->buf;
-       ctrl->port = mlx4_slave_convert_port(dev, slave, ctrl->port);
-       if (ctrl->port <= 0)
+       err = mlx4_slave_convert_port(dev, slave, ctrl->port);
+       if (err <= 0)
                return -EINVAL;
+       ctrl->port = err;
        qpn = be32_to_cpu(ctrl->qpn) & 0xffffff;
        err = get_res(dev, slave, qpn, RES_QP, &rqp);
        if (err) {
index b83f7c0fcf9965b30fd179f72fa821b87d928bfd..122c2ee3dfe2aaa5948efd35158bf2fdf32bc0d5 100644 (file)
@@ -1937,6 +1937,12 @@ static void refill_rx(struct net_device *dev)
                                break; /* Better luck next round. */
                        np->rx_dma[entry] = pci_map_single(np->pci_dev,
                                skb->data, buflen, PCI_DMA_FROMDEVICE);
+                       if (pci_dma_mapping_error(np->pci_dev,
+                                                 np->rx_dma[entry])) {
+                               dev_kfree_skb_any(skb);
+                               np->rx_skbuff[entry] = NULL;
+                               break; /* Better luck next round. */
+                       }
                        np->rx_ring[entry].addr = cpu_to_le32(np->rx_dma[entry]);
                }
                np->rx_ring[entry].cmd_status = cpu_to_le32(np->rx_buf_sz);
@@ -2093,6 +2099,12 @@ static netdev_tx_t start_tx(struct sk_buff *skb, struct net_device *dev)
        np->tx_skbuff[entry] = skb;
        np->tx_dma[entry] = pci_map_single(np->pci_dev,
                                skb->data,skb->len, PCI_DMA_TODEVICE);
+       if (pci_dma_mapping_error(np->pci_dev, np->tx_dma[entry])) {
+               np->tx_skbuff[entry] = NULL;
+               dev_kfree_skb_irq(skb);
+               dev->stats.tx_dropped++;
+               return NETDEV_TX_OK;
+       }
 
        np->tx_ring[entry].addr = cpu_to_le32(np->tx_dma[entry]);
 
index ac17d8669b1adad9291a6a39646b51ff80693176..1292c360390cd79d532ca155158858bd630648d5 100644 (file)
@@ -299,6 +299,7 @@ struct qed_hwfn {
 
        /* Flag indicating whether interrupts are enabled or not*/
        bool                            b_int_enabled;
+       bool                            b_int_requested;
 
        struct qed_mcp_info             *mcp_info;
 
@@ -491,6 +492,8 @@ u32 qed_unzip_data(struct qed_hwfn *p_hwfn,
                   u32 input_len, u8 *input_buf,
                   u32 max_size, u8 *unzip_buf);
 
+int qed_slowpath_irq_req(struct qed_hwfn *hwfn);
+
 #define QED_ETH_INTERFACE_VERSION       300
 
 #endif /* _QED_H */
index 803b190ccada97b30b28098666146f9d05ad1c54..817bbd5476ffb5956fca105686fc9029d06339ff 100644 (file)
@@ -1385,52 +1385,63 @@ err0:
        return rc;
 }
 
-static u32 qed_hw_bar_size(struct qed_dev *cdev,
-                          u8 bar_id)
+static u32 qed_hw_bar_size(struct qed_hwfn     *p_hwfn,
+                          u8                   bar_id)
 {
-       u32 size = pci_resource_len(cdev->pdev, (bar_id > 0) ? 2 : 0);
+       u32 bar_reg = (bar_id == 0 ? PGLUE_B_REG_PF_BAR0_SIZE
+                      : PGLUE_B_REG_PF_BAR1_SIZE);
+       u32 val = qed_rd(p_hwfn, p_hwfn->p_main_ptt, bar_reg);
 
-       return size / cdev->num_hwfns;
+       /* Get the BAR size(in KB) from hardware given val */
+       return 1 << (val + 15);
 }
 
 int qed_hw_prepare(struct qed_dev *cdev,
                   int personality)
 {
-       int rc, i;
+       struct qed_hwfn *p_hwfn = QED_LEADING_HWFN(cdev);
+       int rc;
 
        /* Store the precompiled init data ptrs */
        qed_init_iro_array(cdev);
 
        /* Initialize the first hwfn - will learn number of hwfns */
-       rc = qed_hw_prepare_single(&cdev->hwfns[0], cdev->regview,
+       rc = qed_hw_prepare_single(p_hwfn,
+                                  cdev->regview,
                                   cdev->doorbells, personality);
        if (rc)
                return rc;
 
-       personality = cdev->hwfns[0].hw_info.personality;
+       personality = p_hwfn->hw_info.personality;
 
        /* Initialize the rest of the hwfns */
-       for (i = 1; i < cdev->num_hwfns; i++) {
+       if (cdev->num_hwfns > 1) {
                void __iomem *p_regview, *p_doorbell;
+               u8 __iomem *addr;
+
+               /* adjust bar offset for second engine */
+               addr = cdev->regview + qed_hw_bar_size(p_hwfn, 0) / 2;
+               p_regview = addr;
 
-               p_regview =  cdev->regview +
-                            i * qed_hw_bar_size(cdev, 0);
-               p_doorbell = cdev->doorbells +
-                            i * qed_hw_bar_size(cdev, 1);
-               rc = qed_hw_prepare_single(&cdev->hwfns[i], p_regview,
+               /* adjust doorbell bar offset for second engine */
+               addr = cdev->doorbells + qed_hw_bar_size(p_hwfn, 1) / 2;
+               p_doorbell = addr;
+
+               /* prepare second hw function */
+               rc = qed_hw_prepare_single(&cdev->hwfns[1], p_regview,
                                           p_doorbell, personality);
+
+               /* in case of error, need to free the previously
+                * initiliazed hwfn 0.
+                */
                if (rc) {
-                       /* Cleanup previously initialized hwfns */
-                       while (--i >= 0) {
-                               qed_init_free(&cdev->hwfns[i]);
-                               qed_mcp_free(&cdev->hwfns[i]);
-                               qed_hw_hwfn_free(&cdev->hwfns[i]);
-                       }
-                       return rc;
+                       qed_init_free(p_hwfn);
+                       qed_mcp_free(p_hwfn);
+                       qed_hw_hwfn_free(p_hwfn);
                }
        }
 
-       return 0;
+       return rc;
 }
 
 void qed_hw_remove(struct qed_dev *cdev)
index de50e84902afe3b6a26c422d34a687ec9bc523ec..9cc9d62c1fec64844eba85ca10213a77d3158227 100644 (file)
@@ -783,22 +783,16 @@ void qed_int_igu_enable_int(struct qed_hwfn *p_hwfn,
        qed_wr(p_hwfn, p_ptt, IGU_REG_PF_CONFIGURATION, igu_pf_conf);
 }
 
-void qed_int_igu_enable(struct qed_hwfn *p_hwfn,
-                       struct qed_ptt *p_ptt,
-                       enum qed_int_mode int_mode)
+int qed_int_igu_enable(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt,
+                      enum qed_int_mode int_mode)
 {
-       int i;
-
-       p_hwfn->b_int_enabled = 1;
+       int rc, i;
 
        /* Mask non-link attentions */
        for (i = 0; i < 9; i++)
                qed_wr(p_hwfn, p_ptt,
                       MISC_REG_AEU_ENABLE1_IGU_OUT_0 + (i << 2), 0);
 
-       /* Enable interrupt Generation */
-       qed_int_igu_enable_int(p_hwfn, p_ptt, int_mode);
-
        /* Configure AEU signal change to produce attentions for link */
        qed_wr(p_hwfn, p_ptt, IGU_REG_LEADING_EDGE_LATCH, 0xfff);
        qed_wr(p_hwfn, p_ptt, IGU_REG_TRAILING_EDGE_LATCH, 0xfff);
@@ -808,6 +802,19 @@ void qed_int_igu_enable(struct qed_hwfn *p_hwfn,
 
        /* Unmask AEU signals toward IGU */
        qed_wr(p_hwfn, p_ptt, MISC_REG_AEU_MASK_ATTN_IGU, 0xff);
+       if ((int_mode != QED_INT_MODE_INTA) || IS_LEAD_HWFN(p_hwfn)) {
+               rc = qed_slowpath_irq_req(p_hwfn);
+               if (rc != 0) {
+                       DP_NOTICE(p_hwfn, "Slowpath IRQ request failed\n");
+                       return -EINVAL;
+               }
+               p_hwfn->b_int_requested = true;
+       }
+       /* Enable interrupt Generation */
+       qed_int_igu_enable_int(p_hwfn, p_ptt, int_mode);
+       p_hwfn->b_int_enabled = 1;
+
+       return rc;
 }
 
 void qed_int_igu_disable_int(struct qed_hwfn *p_hwfn,
@@ -1127,3 +1134,11 @@ int qed_int_get_num_sbs(struct qed_hwfn *p_hwfn,
 
        return info->igu_sb_cnt;
 }
+
+void qed_int_disable_post_isr_release(struct qed_dev *cdev)
+{
+       int i;
+
+       for_each_hwfn(cdev, i)
+               cdev->hwfns[i].b_int_requested = false;
+}
index 16b57518e706728dde646688fb059a3f8f88bb97..51e0b09a7f47d3da8ca9c1d2d0982aa2e77d51f4 100644 (file)
@@ -169,10 +169,14 @@ int qed_int_get_num_sbs(struct qed_hwfn *p_hwfn,
                        int *p_iov_blks);
 
 /**
- * @file
+ * @brief qed_int_disable_post_isr_release - performs the cleanup post ISR
+ *        release. The API need to be called after releasing all slowpath IRQs
+ *        of the device.
+ *
+ * @param cdev
  *
- * @brief Interrupt handler
  */
+void qed_int_disable_post_isr_release(struct qed_dev *cdev);
 
 #define QED_CAU_DEF_RX_TIMER_RES 0
 #define QED_CAU_DEF_TX_TIMER_RES 0
@@ -366,10 +370,11 @@ void qed_int_setup(struct qed_hwfn *p_hwfn,
  * @param p_hwfn
  * @param p_ptt
  * @param int_mode
+ *
+ * @return int
  */
-void qed_int_igu_enable(struct qed_hwfn *p_hwfn,
-                       struct qed_ptt *p_ptt,
-                       enum qed_int_mode int_mode);
+int qed_int_igu_enable(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt,
+                      enum qed_int_mode int_mode);
 
 /**
  * @brief - Initialize CAU status block entry
index 947c7af72b25b32db163dc3ea47ca7d63db50490..174f7341c5c32c2bbcf81391b02f6d9a6d9327c2 100644 (file)
@@ -476,41 +476,22 @@ static irqreturn_t qed_single_int(int irq, void *dev_instance)
        return rc;
 }
 
-static int qed_slowpath_irq_req(struct qed_dev *cdev)
+int qed_slowpath_irq_req(struct qed_hwfn *hwfn)
 {
-       int i = 0, rc = 0;
+       struct qed_dev *cdev = hwfn->cdev;
+       int rc = 0;
+       u8 id;
 
        if (cdev->int_params.out.int_mode == QED_INT_MODE_MSIX) {
-               /* Request all the slowpath MSI-X vectors */
-               for (i = 0; i < cdev->num_hwfns; i++) {
-                       snprintf(cdev->hwfns[i].name, NAME_SIZE,
-                                "sp-%d-%02x:%02x.%02x",
-                                i, cdev->pdev->bus->number,
-                                PCI_SLOT(cdev->pdev->devfn),
-                                cdev->hwfns[i].abs_pf_id);
-
-                       rc = request_irq(cdev->int_params.msix_table[i].vector,
-                                        qed_msix_sp_int, 0,
-                                        cdev->hwfns[i].name,
-                                        cdev->hwfns[i].sp_dpc);
-                       if (rc)
-                               break;
-
-                       DP_VERBOSE(&cdev->hwfns[i],
-                                  (NETIF_MSG_INTR | QED_MSG_SP),
+               id = hwfn->my_id;
+               snprintf(hwfn->name, NAME_SIZE, "sp-%d-%02x:%02x.%02x",
+                        id, cdev->pdev->bus->number,
+                        PCI_SLOT(cdev->pdev->devfn), hwfn->abs_pf_id);
+               rc = request_irq(cdev->int_params.msix_table[id].vector,
+                                qed_msix_sp_int, 0, hwfn->name, hwfn->sp_dpc);
+               if (!rc)
+                       DP_VERBOSE(hwfn, (NETIF_MSG_INTR | QED_MSG_SP),
                                   "Requested slowpath MSI-X\n");
-               }
-
-               if (i != cdev->num_hwfns) {
-                       /* Free already request MSI-X vectors */
-                       for (i--; i >= 0; i--) {
-                               unsigned int vec =
-                                       cdev->int_params.msix_table[i].vector;
-                               synchronize_irq(vec);
-                               free_irq(cdev->int_params.msix_table[i].vector,
-                                        cdev->hwfns[i].sp_dpc);
-                       }
-               }
        } else {
                unsigned long flags = 0;
 
@@ -534,13 +515,17 @@ static void qed_slowpath_irq_free(struct qed_dev *cdev)
 
        if (cdev->int_params.out.int_mode == QED_INT_MODE_MSIX) {
                for_each_hwfn(cdev, i) {
+                       if (!cdev->hwfns[i].b_int_requested)
+                               break;
                        synchronize_irq(cdev->int_params.msix_table[i].vector);
                        free_irq(cdev->int_params.msix_table[i].vector,
                                 cdev->hwfns[i].sp_dpc);
                }
        } else {
-               free_irq(cdev->pdev->irq, cdev);
+               if (QED_LEADING_HWFN(cdev)->b_int_requested)
+                       free_irq(cdev->pdev->irq, cdev);
        }
+       qed_int_disable_post_isr_release(cdev);
 }
 
 static int qed_nic_stop(struct qed_dev *cdev)
@@ -765,16 +750,11 @@ static int qed_slowpath_start(struct qed_dev *cdev,
        if (rc)
                goto err1;
 
-       /* Request the slowpath IRQ */
-       rc = qed_slowpath_irq_req(cdev);
-       if (rc)
-               goto err2;
-
        /* Allocate stream for unzipping */
        rc = qed_alloc_stream_mem(cdev);
        if (rc) {
                DP_NOTICE(cdev, "Failed to allocate stream memory\n");
-               goto err3;
+               goto err2;
        }
 
        /* Start the slowpath */
index 7a5ce5914ace2287ec73afa20ed2d9d5eb328108..e8df12335a972cd3092cbefa8b675408446f06c9 100644 (file)
                0x7 << 0)
 #define  MCP_REG_NVM_CFG4_FLASH_SIZE_SHIFT \
        0
+#define PGLUE_B_REG_PF_BAR0_SIZE \
+       0x2aae60UL
+#define PGLUE_B_REG_PF_BAR1_SIZE \
+       0x2aae64UL
 #endif
index 31a1f1eb4f56a5d00f0ce3ae75a29af56a96ef12..287fadfab52d754e0a913d4ed044ca7e50cf1a09 100644 (file)
@@ -124,8 +124,12 @@ struct qed_spq {
        dma_addr_t              p_phys;
        struct qed_spq_entry    *p_virt;
 
-       /* Used as index for completions (returns on EQ by FW) */
-       u16                     echo_idx;
+#define SPQ_RING_SIZE \
+       (CORE_SPQE_PAGE_SIZE_BYTES / sizeof(struct slow_path_element))
+
+       /* Bitmap for handling out-of-order completions */
+       DECLARE_BITMAP(p_comp_bitmap, SPQ_RING_SIZE);
+       u8                      comp_bitmap_idx;
 
        /* Statistics */
        u32                     unlimited_pending_count;
index 7c0b8459666ed270ec754a87c9fa1c072d16dd49..3dd548ab8df14aabf9fa6a551cf54aa97f704d12 100644 (file)
@@ -112,8 +112,6 @@ static int
 qed_spq_fill_entry(struct qed_hwfn *p_hwfn,
                   struct qed_spq_entry *p_ent)
 {
-       p_ent->elem.hdr.echo = 0;
-       p_hwfn->p_spq->echo_idx++;
        p_ent->flags = 0;
 
        switch (p_ent->comp_mode) {
@@ -195,10 +193,12 @@ static int qed_spq_hw_post(struct qed_hwfn *p_hwfn,
                           struct qed_spq *p_spq,
                           struct qed_spq_entry *p_ent)
 {
-       struct qed_chain                *p_chain = &p_hwfn->p_spq->chain;
+       struct qed_chain *p_chain = &p_hwfn->p_spq->chain;
+       u16 echo = qed_chain_get_prod_idx(p_chain);
        struct slow_path_element        *elem;
        struct core_db_data             db;
 
+       p_ent->elem.hdr.echo    = cpu_to_le16(echo);
        elem = qed_chain_produce(p_chain);
        if (!elem) {
                DP_NOTICE(p_hwfn, "Failed to produce from SPQ chain\n");
@@ -437,7 +437,9 @@ void qed_spq_setup(struct qed_hwfn *p_hwfn)
        p_spq->comp_count               = 0;
        p_spq->comp_sent_count          = 0;
        p_spq->unlimited_pending_count  = 0;
-       p_spq->echo_idx                 = 0;
+
+       bitmap_zero(p_spq->p_comp_bitmap, SPQ_RING_SIZE);
+       p_spq->comp_bitmap_idx = 0;
 
        /* SPQ cid, cannot fail */
        qed_cxt_acquire_cid(p_hwfn, PROTOCOLID_CORE, &p_spq->cid);
@@ -582,26 +584,32 @@ qed_spq_add_entry(struct qed_hwfn *p_hwfn,
        struct qed_spq *p_spq = p_hwfn->p_spq;
 
        if (p_ent->queue == &p_spq->unlimited_pending) {
-               struct qed_spq_entry *p_en2;
 
                if (list_empty(&p_spq->free_pool)) {
                        list_add_tail(&p_ent->list, &p_spq->unlimited_pending);
                        p_spq->unlimited_pending_count++;
 
                        return 0;
-               }
+               } else {
+                       struct qed_spq_entry *p_en2;
 
-               p_en2 = list_first_entry(&p_spq->free_pool,
-                                        struct qed_spq_entry,
-                                        list);
-               list_del(&p_en2->list);
+                       p_en2 = list_first_entry(&p_spq->free_pool,
+                                                struct qed_spq_entry,
+                                                list);
+                       list_del(&p_en2->list);
+
+                       /* Copy the ring element physical pointer to the new
+                        * entry, since we are about to override the entire ring
+                        * entry and don't want to lose the pointer.
+                        */
+                       p_ent->elem.data_ptr = p_en2->elem.data_ptr;
 
-               /* Strcut assignment */
-               *p_en2 = *p_ent;
+                       *p_en2 = *p_ent;
 
-               kfree(p_ent);
+                       kfree(p_ent);
 
-               p_ent = p_en2;
+                       p_ent = p_en2;
+               }
        }
 
        /* entry is to be placed in 'pending' queue */
@@ -777,13 +785,38 @@ int qed_spq_completion(struct qed_hwfn *p_hwfn,
        list_for_each_entry_safe(p_ent, tmp, &p_spq->completion_pending,
                                 list) {
                if (p_ent->elem.hdr.echo == echo) {
+                       u16 pos = le16_to_cpu(echo) % SPQ_RING_SIZE;
+
                        list_del(&p_ent->list);
 
-                       qed_chain_return_produced(&p_spq->chain);
+                       /* Avoid overriding of SPQ entries when getting
+                        * out-of-order completions, by marking the completions
+                        * in a bitmap and increasing the chain consumer only
+                        * for the first successive completed entries.
+                        */
+                       bitmap_set(p_spq->p_comp_bitmap, pos, SPQ_RING_SIZE);
+
+                       while (test_bit(p_spq->comp_bitmap_idx,
+                                       p_spq->p_comp_bitmap)) {
+                               bitmap_clear(p_spq->p_comp_bitmap,
+                                            p_spq->comp_bitmap_idx,
+                                            SPQ_RING_SIZE);
+                               p_spq->comp_bitmap_idx++;
+                               qed_chain_return_produced(&p_spq->chain);
+                       }
+
                        p_spq->comp_count++;
                        found = p_ent;
                        break;
                }
+
+               /* This is relatively uncommon - depends on scenarios
+                * which have mutliple per-PF sent ramrods.
+                */
+               DP_VERBOSE(p_hwfn, QED_MSG_SPQ,
+                          "Got completion for echo %04x - doesn't match echo %04x in completion pending list\n",
+                          le16_to_cpu(echo),
+                          le16_to_cpu(p_ent->elem.hdr.echo));
        }
 
        /* Release lock before callback, as callback may post
index be7d7a62cc0d8c885c1f669f6c01f0f3a2259ea0..34906750b7e7091f5af122be88c659fd1c77f2e1 100644 (file)
@@ -246,12 +246,13 @@ int qlcnic_83xx_check_vnic_state(struct qlcnic_adapter *adapter)
        u32 state;
 
        state = QLCRDX(ahw, QLC_83XX_VNIC_STATE);
-       while (state != QLCNIC_DEV_NPAR_OPER && idc->vnic_wait_limit--) {
+       while (state != QLCNIC_DEV_NPAR_OPER && idc->vnic_wait_limit) {
+               idc->vnic_wait_limit--;
                msleep(1000);
                state = QLCRDX(ahw, QLC_83XX_VNIC_STATE);
        }
 
-       if (!idc->vnic_wait_limit) {
+       if (state != QLCNIC_DEV_NPAR_OPER) {
                dev_err(&adapter->pdev->dev,
                        "vNIC mode not operational, state check timed out.\n");
                return -EIO;
index a5f422f26cb4396a8dc25b65557c83793e956d94..daf05155b7329abdda58e63b1c19be9e06adc699 100644 (file)
@@ -772,8 +772,10 @@ int qlcnic_82xx_config_intrpt(struct qlcnic_adapter *adapter, u8 op_type)
        int i, err = 0;
 
        for (i = 0; i < ahw->num_msix; i++) {
-               qlcnic_alloc_mbx_args(&cmd, adapter,
-                                     QLCNIC_CMD_MQ_TX_CONFIG_INTR);
+               err = qlcnic_alloc_mbx_args(&cmd, adapter,
+                                           QLCNIC_CMD_MQ_TX_CONFIG_INTR);
+               if (err)
+                       return err;
                type = op_type ? QLCNIC_INTRPT_ADD : QLCNIC_INTRPT_DEL;
                val = type | (ahw->intr_tbl[i].type << 4);
                if (ahw->intr_tbl[i].type == QLCNIC_INTRPT_MSIX)
index 02b7115b6aaa64add8632094f6f0dfe354a89b7d..997976426799d90a328cef4ff958b92ce3ba491c 100644 (file)
@@ -4211,8 +4211,9 @@ static int ql_change_rx_buffers(struct ql_adapter *qdev)
 
        /* Wait for an outstanding reset to complete. */
        if (!test_bit(QL_ADAPTER_UP, &qdev->flags)) {
-               int i = 3;
-               while (i-- && !test_bit(QL_ADAPTER_UP, &qdev->flags)) {
+               int i = 4;
+
+               while (--i && !test_bit(QL_ADAPTER_UP, &qdev->flags)) {
                        netif_err(qdev, ifup, qdev->ndev,
                                  "Waiting for adapter UP...\n");
                        ssleep(1);
index ddb2c6c6ec94013efb5ada465d2c6446c34de5f0..689a4a5c8dcfc30fba2675e17293e98691648dd2 100644 (file)
@@ -736,9 +736,8 @@ qcaspi_netdev_tx_timeout(struct net_device *dev)
        netdev_info(qca->net_dev, "Transmit timeout at %ld, latency %ld\n",
                    jiffies, jiffies - dev->trans_start);
        qca->net_dev->stats.tx_errors++;
-       /* wake the queue if there is room */
-       if (qcaspi_tx_ring_has_space(&qca->txr))
-               netif_wake_queue(dev);
+       /* Trigger tx queue flush and QCA7000 reset */
+       qca->sync = QCASPI_SYNC_UNKNOWN;
 }
 
 static int
index ed5da4d476684d502a7d83469ee83566635d3d46..467d41698fd534e724d53ce03e35091bd01cdcdb 100644 (file)
@@ -905,6 +905,9 @@ static int ravb_phy_init(struct net_device *ndev)
                netdev_info(ndev, "limited PHY to 100Mbit/s\n");
        }
 
+       /* 10BASE is not supported */
+       phydev->supported &= ~PHY_10BT_FEATURES;
+
        netdev_info(ndev, "attached PHY %d (IRQ %d) to driver %s\n",
                    phydev->addr, phydev->irq, phydev->drv->name);
 
@@ -1037,7 +1040,7 @@ static const char ravb_gstrings_stats[][ETH_GSTRING_LEN] = {
        "rx_queue_1_mcast_packets",
        "rx_queue_1_errors",
        "rx_queue_1_crc_errors",
-       "rx_queue_1_frame_errors_",
+       "rx_queue_1_frame_errors",
        "rx_queue_1_length_errors",
        "rx_queue_1_missed_errors",
        "rx_queue_1_over_errors",
index e7bab7909ed9e1868dd5f8457b3cfc96c92788f1..6a8fc0f341ff2528fdda1cb97f8e2934d99c5f14 100644 (file)
@@ -52,6 +52,8 @@
                NETIF_MSG_RX_ERR| \
                NETIF_MSG_TX_ERR)
 
+#define SH_ETH_OFFSET_INVALID  ((u16)~0)
+
 #define SH_ETH_OFFSET_DEFAULTS                 \
        [0 ... SH_ETH_MAX_REGISTER_OFFSET - 1] = SH_ETH_OFFSET_INVALID
 
@@ -404,6 +406,28 @@ static const u16 sh_eth_offset_fast_sh3_sh2[SH_ETH_MAX_REGISTER_OFFSET] = {
 static void sh_eth_rcv_snd_disable(struct net_device *ndev);
 static struct net_device_stats *sh_eth_get_stats(struct net_device *ndev);
 
+static void sh_eth_write(struct net_device *ndev, u32 data, int enum_index)
+{
+       struct sh_eth_private *mdp = netdev_priv(ndev);
+       u16 offset = mdp->reg_offset[enum_index];
+
+       if (WARN_ON(offset == SH_ETH_OFFSET_INVALID))
+               return;
+
+       iowrite32(data, mdp->addr + offset);
+}
+
+static u32 sh_eth_read(struct net_device *ndev, int enum_index)
+{
+       struct sh_eth_private *mdp = netdev_priv(ndev);
+       u16 offset = mdp->reg_offset[enum_index];
+
+       if (WARN_ON(offset == SH_ETH_OFFSET_INVALID))
+               return ~0U;
+
+       return ioread32(mdp->addr + offset);
+}
+
 static bool sh_eth_is_gether(struct sh_eth_private *mdp)
 {
        return mdp->reg_offset == sh_eth_offset_gigabit;
@@ -1143,6 +1167,7 @@ static void sh_eth_ring_format(struct net_device *ndev)
        int tx_ringsize = sizeof(*txdesc) * mdp->num_tx_ring;
        int skbuff_size = mdp->rx_buf_sz + SH_ETH_RX_ALIGN + 32 - 1;
        dma_addr_t dma_addr;
+       u32 buf_len;
 
        mdp->cur_rx = 0;
        mdp->cur_tx = 0;
@@ -1163,16 +1188,16 @@ static void sh_eth_ring_format(struct net_device *ndev)
                /* RX descriptor */
                rxdesc = &mdp->rx_ring[i];
                /* The size of the buffer is a multiple of 32 bytes. */
-               rxdesc->buffer_length = ALIGN(mdp->rx_buf_sz, 32);
-               dma_addr = dma_map_single(&ndev->dev, skb->data,
-                                         rxdesc->buffer_length,
+               buf_len = ALIGN(mdp->rx_buf_sz, 32);
+               rxdesc->len = cpu_to_edmac(mdp, buf_len << 16);
+               dma_addr = dma_map_single(&ndev->dev, skb->data, buf_len,
                                          DMA_FROM_DEVICE);
                if (dma_mapping_error(&ndev->dev, dma_addr)) {
                        kfree_skb(skb);
                        break;
                }
                mdp->rx_skbuff[i] = skb;
-               rxdesc->addr = dma_addr;
+               rxdesc->addr = cpu_to_edmac(mdp, dma_addr);
                rxdesc->status = cpu_to_edmac(mdp, RD_RACT | RD_RFP);
 
                /* Rx descriptor address set */
@@ -1196,7 +1221,7 @@ static void sh_eth_ring_format(struct net_device *ndev)
                mdp->tx_skbuff[i] = NULL;
                txdesc = &mdp->tx_ring[i];
                txdesc->status = cpu_to_edmac(mdp, TD_TFP);
-               txdesc->buffer_length = 0;
+               txdesc->len = cpu_to_edmac(mdp, 0);
                if (i == 0) {
                        /* Tx descriptor address set */
                        sh_eth_write(ndev, mdp->tx_desc_dma, TDLAR);
@@ -1403,8 +1428,10 @@ static int sh_eth_txfree(struct net_device *ndev)
                           entry, edmac_to_cpu(mdp, txdesc->status));
                /* Free the original skb. */
                if (mdp->tx_skbuff[entry]) {
-                       dma_unmap_single(&ndev->dev, txdesc->addr,
-                                        txdesc->buffer_length, DMA_TO_DEVICE);
+                       dma_unmap_single(&ndev->dev,
+                                        edmac_to_cpu(mdp, txdesc->addr),
+                                        edmac_to_cpu(mdp, txdesc->len) >> 16,
+                                        DMA_TO_DEVICE);
                        dev_kfree_skb_irq(mdp->tx_skbuff[entry]);
                        mdp->tx_skbuff[entry] = NULL;
                        free_num++;
@@ -1414,7 +1441,7 @@ static int sh_eth_txfree(struct net_device *ndev)
                        txdesc->status |= cpu_to_edmac(mdp, TD_TDLE);
 
                ndev->stats.tx_packets++;
-               ndev->stats.tx_bytes += txdesc->buffer_length;
+               ndev->stats.tx_bytes += edmac_to_cpu(mdp, txdesc->len) >> 16;
        }
        return free_num;
 }
@@ -1433,6 +1460,7 @@ static int sh_eth_rx(struct net_device *ndev, u32 intr_status, int *quota)
        u32 desc_status;
        int skbuff_size = mdp->rx_buf_sz + SH_ETH_RX_ALIGN + 32 - 1;
        dma_addr_t dma_addr;
+       u32 buf_len;
 
        boguscnt = min(boguscnt, *quota);
        limit = boguscnt;
@@ -1441,7 +1469,7 @@ static int sh_eth_rx(struct net_device *ndev, u32 intr_status, int *quota)
                /* RACT bit must be checked before all the following reads */
                dma_rmb();
                desc_status = edmac_to_cpu(mdp, rxdesc->status);
-               pkt_len = rxdesc->frame_length;
+               pkt_len = edmac_to_cpu(mdp, rxdesc->len) & RD_RFL;
 
                if (--boguscnt < 0)
                        break;
@@ -1462,6 +1490,7 @@ static int sh_eth_rx(struct net_device *ndev, u32 intr_status, int *quota)
                if (mdp->cd->shift_rd0)
                        desc_status >>= 16;
 
+               skb = mdp->rx_skbuff[entry];
                if (desc_status & (RD_RFS1 | RD_RFS2 | RD_RFS3 | RD_RFS4 |
                                   RD_RFS5 | RD_RFS6 | RD_RFS10)) {
                        ndev->stats.rx_errors++;
@@ -1477,16 +1506,16 @@ static int sh_eth_rx(struct net_device *ndev, u32 intr_status, int *quota)
                                ndev->stats.rx_missed_errors++;
                        if (desc_status & RD_RFS10)
                                ndev->stats.rx_over_errors++;
-               } else {
+               } else  if (skb) {
+                       dma_addr = edmac_to_cpu(mdp, rxdesc->addr);
                        if (!mdp->cd->hw_swap)
                                sh_eth_soft_swap(
-                                       phys_to_virt(ALIGN(rxdesc->addr, 4)),
+                                       phys_to_virt(ALIGN(dma_addr, 4)),
                                        pkt_len + 2);
-                       skb = mdp->rx_skbuff[entry];
                        mdp->rx_skbuff[entry] = NULL;
                        if (mdp->cd->rpadir)
                                skb_reserve(skb, NET_IP_ALIGN);
-                       dma_unmap_single(&ndev->dev, rxdesc->addr,
+                       dma_unmap_single(&ndev->dev, dma_addr,
                                         ALIGN(mdp->rx_buf_sz, 32),
                                         DMA_FROM_DEVICE);
                        skb_put(skb, pkt_len);
@@ -1506,7 +1535,8 @@ static int sh_eth_rx(struct net_device *ndev, u32 intr_status, int *quota)
                entry = mdp->dirty_rx % mdp->num_rx_ring;
                rxdesc = &mdp->rx_ring[entry];
                /* The size of the buffer is 32 byte boundary. */
-               rxdesc->buffer_length = ALIGN(mdp->rx_buf_sz, 32);
+               buf_len = ALIGN(mdp->rx_buf_sz, 32);
+               rxdesc->len = cpu_to_edmac(mdp, buf_len << 16);
 
                if (mdp->rx_skbuff[entry] == NULL) {
                        skb = netdev_alloc_skb(ndev, skbuff_size);
@@ -1514,8 +1544,7 @@ static int sh_eth_rx(struct net_device *ndev, u32 intr_status, int *quota)
                                break;  /* Better luck next round. */
                        sh_eth_set_receive_align(skb);
                        dma_addr = dma_map_single(&ndev->dev, skb->data,
-                                                 rxdesc->buffer_length,
-                                                 DMA_FROM_DEVICE);
+                                                 buf_len, DMA_FROM_DEVICE);
                        if (dma_mapping_error(&ndev->dev, dma_addr)) {
                                kfree_skb(skb);
                                break;
@@ -1523,7 +1552,7 @@ static int sh_eth_rx(struct net_device *ndev, u32 intr_status, int *quota)
                        mdp->rx_skbuff[entry] = skb;
 
                        skb_checksum_none_assert(skb);
-                       rxdesc->addr = dma_addr;
+                       rxdesc->addr = cpu_to_edmac(mdp, dma_addr);
                }
                dma_wmb(); /* RACT bit must be set after all the above writes */
                if (entry >= mdp->num_rx_ring - 1)
@@ -2331,8 +2360,8 @@ static void sh_eth_tx_timeout(struct net_device *ndev)
        /* Free all the skbuffs in the Rx queue. */
        for (i = 0; i < mdp->num_rx_ring; i++) {
                rxdesc = &mdp->rx_ring[i];
-               rxdesc->status = 0;
-               rxdesc->addr = 0xBADF00D0;
+               rxdesc->status = cpu_to_edmac(mdp, 0);
+               rxdesc->addr = cpu_to_edmac(mdp, 0xBADF00D0);
                dev_kfree_skb(mdp->rx_skbuff[i]);
                mdp->rx_skbuff[i] = NULL;
        }
@@ -2350,6 +2379,7 @@ static int sh_eth_start_xmit(struct sk_buff *skb, struct net_device *ndev)
 {
        struct sh_eth_private *mdp = netdev_priv(ndev);
        struct sh_eth_txdesc *txdesc;
+       dma_addr_t dma_addr;
        u32 entry;
        unsigned long flags;
 
@@ -2372,15 +2402,15 @@ static int sh_eth_start_xmit(struct sk_buff *skb, struct net_device *ndev)
        txdesc = &mdp->tx_ring[entry];
        /* soft swap. */
        if (!mdp->cd->hw_swap)
-               sh_eth_soft_swap(phys_to_virt(ALIGN(txdesc->addr, 4)),
-                                skb->len + 2);
-       txdesc->addr = dma_map_single(&ndev->dev, skb->data, skb->len,
-                                     DMA_TO_DEVICE);
-       if (dma_mapping_error(&ndev->dev, txdesc->addr)) {
+               sh_eth_soft_swap(PTR_ALIGN(skb->data, 4), skb->len + 2);
+       dma_addr = dma_map_single(&ndev->dev, skb->data, skb->len,
+                                 DMA_TO_DEVICE);
+       if (dma_mapping_error(&ndev->dev, dma_addr)) {
                kfree_skb(skb);
                return NETDEV_TX_OK;
        }
-       txdesc->buffer_length = skb->len;
+       txdesc->addr = cpu_to_edmac(mdp, dma_addr);
+       txdesc->len  = cpu_to_edmac(mdp, skb->len << 16);
 
        dma_wmb(); /* TACT bit must be set after all the above writes */
        if (entry >= mdp->num_tx_ring - 1)
index 50382b1c9ddcf2e5b656c98236c0e7364ee3c1f2..72fcfc9245891e06bc4d37fd0e72a33880b48cd5 100644 (file)
@@ -283,7 +283,7 @@ enum DMAC_IM_BIT {
        DMAC_M_RINT1 = 0x00000001,
 };
 
-/* Receive descriptor bit */
+/* Receive descriptor 0 bits */
 enum RD_STS_BIT {
        RD_RACT = 0x80000000, RD_RDLE = 0x40000000,
        RD_RFP1 = 0x20000000, RD_RFP0 = 0x10000000,
@@ -298,6 +298,12 @@ enum RD_STS_BIT {
 #define RDFEND RD_RFP0
 #define RD_RFP (RD_RFP1|RD_RFP0)
 
+/* Receive descriptor 1 bits */
+enum RD_LEN_BIT {
+       RD_RFL  = 0x0000ffff,   /* receive frame  length */
+       RD_RBL  = 0xffff0000,   /* receive buffer length */
+};
+
 /* FCFTR */
 enum FCFTR_BIT {
        FCFTR_RFF2 = 0x00040000, FCFTR_RFF1 = 0x00020000,
@@ -307,7 +313,7 @@ enum FCFTR_BIT {
 #define DEFAULT_FIFO_F_D_RFF   (FCFTR_RFF2 | FCFTR_RFF1 | FCFTR_RFF0)
 #define DEFAULT_FIFO_F_D_RFD   (FCFTR_RFD2 | FCFTR_RFD1 | FCFTR_RFD0)
 
-/* Transmit descriptor bit */
+/* Transmit descriptor 0 bits */
 enum TD_STS_BIT {
        TD_TACT = 0x80000000, TD_TDLE = 0x40000000,
        TD_TFP1 = 0x20000000, TD_TFP0 = 0x10000000,
@@ -317,6 +323,11 @@ enum TD_STS_BIT {
 #define TDFEND TD_TFP0
 #define TD_TFP (TD_TFP1|TD_TFP0)
 
+/* Transmit descriptor 1 bits */
+enum TD_LEN_BIT {
+       TD_TBL  = 0xffff0000,   /* transmit buffer length */
+};
+
 /* RMCR */
 enum RMCR_BIT {
        RMCR_RNC = 0x00000001,
@@ -425,15 +436,9 @@ enum TSU_FWSLC_BIT {
  */
 struct sh_eth_txdesc {
        u32 status;             /* TD0 */
-#if defined(__LITTLE_ENDIAN)
-       u16 pad0;               /* TD1 */
-       u16 buffer_length;      /* TD1 */
-#else
-       u16 buffer_length;      /* TD1 */
-       u16 pad0;               /* TD1 */
-#endif
+       u32 len;                /* TD1 */
        u32 addr;               /* TD2 */
-       u32 pad1;               /* padding data */
+       u32 pad0;               /* padding data */
 } __aligned(2) __packed;
 
 /* The sh ether Rx buffer descriptors.
@@ -441,13 +446,7 @@ struct sh_eth_txdesc {
  */
 struct sh_eth_rxdesc {
        u32 status;             /* RD0 */
-#if defined(__LITTLE_ENDIAN)
-       u16 frame_length;       /* RD1 */
-       u16 buffer_length;      /* RD1 */
-#else
-       u16 buffer_length;      /* RD1 */
-       u16 frame_length;       /* RD1 */
-#endif
+       u32 len;                /* RD1 */
        u32 addr;               /* RD2 */
        u32 pad0;               /* padding data */
 } __aligned(2) __packed;
@@ -546,31 +545,6 @@ static inline void sh_eth_soft_swap(char *src, int len)
 #endif
 }
 
-#define SH_ETH_OFFSET_INVALID  ((u16) ~0)
-
-static inline void sh_eth_write(struct net_device *ndev, u32 data,
-                               int enum_index)
-{
-       struct sh_eth_private *mdp = netdev_priv(ndev);
-       u16 offset = mdp->reg_offset[enum_index];
-
-       if (WARN_ON(offset == SH_ETH_OFFSET_INVALID))
-               return;
-
-       iowrite32(data, mdp->addr + offset);
-}
-
-static inline u32 sh_eth_read(struct net_device *ndev, int enum_index)
-{
-       struct sh_eth_private *mdp = netdev_priv(ndev);
-       u16 offset = mdp->reg_offset[enum_index];
-
-       if (WARN_ON(offset == SH_ETH_OFFSET_INVALID))
-               return ~0U;
-
-       return ioread32(mdp->addr + offset);
-}
-
 static inline void *sh_eth_tsu_get_offset(struct sh_eth_private *mdp,
                                          int enum_index)
 {
index bc6d21b471be4f4ae2f0c4c1cb26430e92c24803..e6a084a6be12d0627da52a42e783839732c05c5e 100644 (file)
@@ -3299,7 +3299,8 @@ static int efx_ef10_filter_remove_internal(struct efx_nic *efx,
 
                new_spec.priority = EFX_FILTER_PRI_AUTO;
                new_spec.flags = (EFX_FILTER_FLAG_RX |
-                                 EFX_FILTER_FLAG_RX_RSS);
+                                 (efx_rss_enabled(efx) ?
+                                  EFX_FILTER_FLAG_RX_RSS : 0));
                new_spec.dmaq_id = 0;
                new_spec.rss_context = EFX_FILTER_RSS_CONTEXT_DEFAULT;
                rc = efx_ef10_filter_push(efx, &new_spec,
@@ -3921,6 +3922,7 @@ static int efx_ef10_filter_insert_addr_list(struct efx_nic *efx,
 {
        struct efx_ef10_filter_table *table = efx->filter_state;
        struct efx_ef10_dev_addr *addr_list;
+       enum efx_filter_flags filter_flags;
        struct efx_filter_spec spec;
        u8 baddr[ETH_ALEN];
        unsigned int i, j;
@@ -3935,11 +3937,11 @@ static int efx_ef10_filter_insert_addr_list(struct efx_nic *efx,
                addr_count = table->dev_uc_count;
        }
 
+       filter_flags = efx_rss_enabled(efx) ? EFX_FILTER_FLAG_RX_RSS : 0;
+
        /* Insert/renew filters */
        for (i = 0; i < addr_count; i++) {
-               efx_filter_init_rx(&spec, EFX_FILTER_PRI_AUTO,
-                                  EFX_FILTER_FLAG_RX_RSS,
-                                  0);
+               efx_filter_init_rx(&spec, EFX_FILTER_PRI_AUTO, filter_flags, 0);
                efx_filter_set_eth_local(&spec, EFX_FILTER_VID_UNSPEC,
                                         addr_list[i].addr);
                rc = efx_ef10_filter_insert(efx, &spec, true);
@@ -3968,9 +3970,7 @@ static int efx_ef10_filter_insert_addr_list(struct efx_nic *efx,
 
        if (multicast && rollback) {
                /* Also need an Ethernet broadcast filter */
-               efx_filter_init_rx(&spec, EFX_FILTER_PRI_AUTO,
-                                  EFX_FILTER_FLAG_RX_RSS,
-                                  0);
+               efx_filter_init_rx(&spec, EFX_FILTER_PRI_AUTO, filter_flags, 0);
                eth_broadcast_addr(baddr);
                efx_filter_set_eth_local(&spec, EFX_FILTER_VID_UNSPEC, baddr);
                rc = efx_ef10_filter_insert(efx, &spec, true);
@@ -4000,13 +4000,14 @@ static int efx_ef10_filter_insert_def(struct efx_nic *efx, bool multicast,
 {
        struct efx_ef10_filter_table *table = efx->filter_state;
        struct efx_ef10_nic_data *nic_data = efx->nic_data;
+       enum efx_filter_flags filter_flags;
        struct efx_filter_spec spec;
        u8 baddr[ETH_ALEN];
        int rc;
 
-       efx_filter_init_rx(&spec, EFX_FILTER_PRI_AUTO,
-                          EFX_FILTER_FLAG_RX_RSS,
-                          0);
+       filter_flags = efx_rss_enabled(efx) ? EFX_FILTER_FLAG_RX_RSS : 0;
+
+       efx_filter_init_rx(&spec, EFX_FILTER_PRI_AUTO, filter_flags, 0);
 
        if (multicast)
                efx_filter_set_mc_def(&spec);
@@ -4023,8 +4024,7 @@ static int efx_ef10_filter_insert_def(struct efx_nic *efx, bool multicast,
                if (!nic_data->workaround_26807) {
                        /* Also need an Ethernet broadcast filter */
                        efx_filter_init_rx(&spec, EFX_FILTER_PRI_AUTO,
-                                          EFX_FILTER_FLAG_RX_RSS,
-                                          0);
+                                          filter_flags, 0);
                        eth_broadcast_addr(baddr);
                        efx_filter_set_eth_local(&spec, EFX_FILTER_VID_UNSPEC,
                                                 baddr);
index 1aaf76c1ace866d7563afbd1eb19a87ec5ee2ff0..10827476bc0b38237b9b6999a31a907cd330cf9e 100644 (file)
@@ -76,6 +76,11 @@ void efx_schedule_slow_fill(struct efx_rx_queue *rx_queue);
 #define EFX_TXQ_MAX_ENT(efx)   (EFX_WORKAROUND_35388(efx) ? \
                                 EFX_MAX_DMAQ_SIZE / 2 : EFX_MAX_DMAQ_SIZE)
 
+static inline bool efx_rss_enabled(struct efx_nic *efx)
+{
+       return efx->rss_spread > 1;
+}
+
 /* Filters */
 
 void efx_mac_reconfigure(struct efx_nic *efx);
index 5a1c5a8f278ad1690e678b10cec82444ee45bb12..133e9e35be9e9212bf14531bffd1c0cf78fde742 100644 (file)
@@ -2242,7 +2242,7 @@ efx_farch_filter_init_rx_auto(struct efx_nic *efx,
         */
        spec->priority = EFX_FILTER_PRI_AUTO;
        spec->flags = (EFX_FILTER_FLAG_RX |
-                      (efx->n_rx_channels > 1 ? EFX_FILTER_FLAG_RX_RSS : 0) |
+                      (efx_rss_enabled(efx) ? EFX_FILTER_FLAG_RX_RSS : 0) |
                       (efx->rx_scatter ? EFX_FILTER_FLAG_RX_SCATTER : 0));
        spec->dmaq_id = 0;
 }
index 3d5ee3259885d9486933e5b821c3af2a94c910d2..194f67d9f3bfaa81bd99bf3ad64c6c1568476319 100644 (file)
@@ -418,7 +418,7 @@ static void txc_reset_logic_mmd(struct efx_nic *efx, int mmd)
 
        val |= (1 << TXC_GLCMD_LMTSWRST_LBN);
        efx_mdio_write(efx, mmd, TXC_GLRGS_GLCMD, val);
-       while (tries--) {
+       while (--tries) {
                val = efx_mdio_read(efx, mmd, TXC_GLRGS_GLCMD);
                if (!(val & (1 << TXC_GLCMD_LMTSWRST_LBN)))
                        break;
index 52b8ed9bd87c2e20707c41ab0eaac247de26afce..adff46375a32297ce01a7fdd519483ccc1226012 100644 (file)
@@ -153,7 +153,11 @@ static int sun7i_gmac_probe(struct platform_device *pdev)
        if (ret)
                return ret;
 
-       return stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
+       ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
+       if (ret)
+               sun7i_gmac_exit(pdev, plat_dat->bsp_priv);
+
+       return ret;
 }
 
 static const struct of_device_id sun7i_dwmac_match[] = {
index 3c6549aee11dee5cf13c92c90c5b4b7a8618f375..a5b869eb46783e338708f93c31f33524116e637f 100644 (file)
@@ -3046,8 +3046,6 @@ int stmmac_suspend(struct net_device *ndev)
        priv->hw->dma->stop_tx(priv->ioaddr);
        priv->hw->dma->stop_rx(priv->ioaddr);
 
-       stmmac_clear_descriptors(priv);
-
        /* Enable Power down mode by programming the PMT regs */
        if (device_may_wakeup(priv->device)) {
                priv->hw->mac->pmt(priv->hw, priv->wolopts);
@@ -3105,7 +3103,12 @@ int stmmac_resume(struct net_device *ndev)
 
        netif_device_attach(ndev);
 
-       init_dma_desc_rings(ndev, GFP_ATOMIC);
+       priv->cur_rx = 0;
+       priv->dirty_rx = 0;
+       priv->dirty_tx = 0;
+       priv->cur_tx = 0;
+       stmmac_clear_descriptors(priv);
+
        stmmac_hw_setup(ndev, false);
        stmmac_init_tx_coalesce(priv);
        stmmac_set_rx_mode(ndev);
index 48b92c9de12a5af4f75ab6b48b4ffd39a77d6ed5..fc958067d10a77d248115968ec0dc4625460aee2 100644 (file)
@@ -2026,45 +2026,54 @@ static int cpsw_probe_dt(struct cpsw_priv *priv,
        for_each_child_of_node(node, slave_node) {
                struct cpsw_slave_data *slave_data = data->slave_data + i;
                const void *mac_addr = NULL;
-               u32 phyid;
                int lenp;
                const __be32 *parp;
-               struct device_node *mdio_node;
-               struct platform_device *mdio;
 
                /* This is no slave child node, continue */
                if (strcmp(slave_node->name, "slave"))
                        continue;
 
                priv->phy_node = of_parse_phandle(slave_node, "phy-handle", 0);
+               parp = of_get_property(slave_node, "phy_id", &lenp);
                if (of_phy_is_fixed_link(slave_node)) {
-                       struct phy_device *pd;
+                       struct device_node *phy_node;
+                       struct phy_device *phy_dev;
 
+                       /* In the case of a fixed PHY, the DT node associated
+                        * to the PHY is the Ethernet MAC DT node.
+                        */
                        ret = of_phy_register_fixed_link(slave_node);
                        if (ret)
                                return ret;
-                       pd = of_phy_find_device(slave_node);
-                       if (!pd)
+                       phy_node = of_node_get(slave_node);
+                       phy_dev = of_phy_find_device(phy_node);
+                       if (!phy_dev)
                                return -ENODEV;
                        snprintf(slave_data->phy_id, sizeof(slave_data->phy_id),
-                                PHY_ID_FMT, pd->bus->id, pd->phy_id);
-                       goto no_phy_slave;
-               }
-               parp = of_get_property(slave_node, "phy_id", &lenp);
-               if ((parp == NULL) || (lenp != (sizeof(void *) * 2))) {
-                       dev_err(&pdev->dev, "Missing slave[%d] phy_id property\n", i);
+                                PHY_ID_FMT, phy_dev->bus->id, phy_dev->addr);
+               } else if (parp) {
+                       u32 phyid;
+                       struct device_node *mdio_node;
+                       struct platform_device *mdio;
+
+                       if (lenp != (sizeof(__be32) * 2)) {
+                               dev_err(&pdev->dev, "Invalid slave[%d] phy_id property\n", i);
+                               goto no_phy_slave;
+                       }
+                       mdio_node = of_find_node_by_phandle(be32_to_cpup(parp));
+                       phyid = be32_to_cpup(parp+1);
+                       mdio = of_find_device_by_node(mdio_node);
+                       of_node_put(mdio_node);
+                       if (!mdio) {
+                               dev_err(&pdev->dev, "Missing mdio platform device\n");
+                               return -EINVAL;
+                       }
+                       snprintf(slave_data->phy_id, sizeof(slave_data->phy_id),
+                                PHY_ID_FMT, mdio->name, phyid);
+               } else {
+                       dev_err(&pdev->dev, "No slave[%d] phy_id or fixed-link property\n", i);
                        goto no_phy_slave;
                }
-               mdio_node = of_find_node_by_phandle(be32_to_cpup(parp));
-               phyid = be32_to_cpup(parp+1);
-               mdio = of_find_device_by_node(mdio_node);
-               of_node_put(mdio_node);
-               if (!mdio) {
-                       dev_err(&pdev->dev, "Missing mdio platform device\n");
-                       return -EINVAL;
-               }
-               snprintf(slave_data->phy_id, sizeof(slave_data->phy_id),
-                        PHY_ID_FMT, mdio->name, phyid);
                slave_data->phy_if = of_get_phy_mode(slave_node);
                if (slave_data->phy_if < 0) {
                        dev_err(&pdev->dev, "Missing or malformed slave[%d] phy-mode property\n",
@@ -2418,7 +2427,7 @@ static int cpsw_probe(struct platform_device *pdev)
        ndev->irq = platform_get_irq(pdev, 1);
        if (ndev->irq < 0) {
                dev_err(priv->dev, "error getting irq resource\n");
-               ret = -ENOENT;
+               ret = ndev->irq;
                goto clean_ale_ret;
        }
 
@@ -2439,8 +2448,10 @@ static int cpsw_probe(struct platform_device *pdev)
 
        /* RX IRQ */
        irq = platform_get_irq(pdev, 1);
-       if (irq < 0)
+       if (irq < 0) {
+               ret = irq;
                goto clean_ale_ret;
+       }
 
        priv->irqs_table[0] = irq;
        ret = devm_request_irq(&pdev->dev, irq, cpsw_rx_interrupt,
@@ -2452,8 +2463,10 @@ static int cpsw_probe(struct platform_device *pdev)
 
        /* TX IRQ */
        irq = platform_get_irq(pdev, 2);
-       if (irq < 0)
+       if (irq < 0) {
+               ret = irq;
                goto clean_ale_ret;
+       }
 
        priv->irqs_table[1] = irq;
        ret = devm_request_irq(&pdev->dev, irq, cpsw_tx_interrupt,
index de5c30c9f059203040cc47e83cce76ae9e5bfde6..58efdec12f300dec69f6790c19f7cd56b10a4b22 100644 (file)
@@ -967,8 +967,6 @@ static netdev_tx_t geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev,
        err = udp_tunnel6_xmit_skb(dst, gs6->sock->sk, skb, dev,
                                   &fl6.saddr, &fl6.daddr, prio, ttl,
                                   sport, geneve->dst_port, !udp_csum);
-
-       iptunnel_xmit_stats(err, &dev->stats, dev->tstats);
        return NETDEV_TX_OK;
 
 tx_error:
@@ -1157,7 +1155,7 @@ static int geneve_configure(struct net *net, struct net_device *dev,
        struct geneve_net *gn = net_generic(net, geneve_net_id);
        struct geneve_dev *t, *geneve = netdev_priv(dev);
        bool tun_collect_md, tun_on_same_port;
-       int err;
+       int err, encap_len;
 
        if (!remote)
                return -EINVAL;
@@ -1189,6 +1187,14 @@ static int geneve_configure(struct net *net, struct net_device *dev,
        if (t)
                return -EBUSY;
 
+       /* make enough headroom for basic scenario */
+       encap_len = GENEVE_BASE_HLEN + ETH_HLEN;
+       if (remote->sa.sa_family == AF_INET)
+               encap_len += sizeof(struct iphdr);
+       else
+               encap_len += sizeof(struct ipv6hdr);
+       dev->needed_headroom = encap_len + ETH_HLEN;
+
        if (metadata) {
                if (tun_on_same_port)
                        return -EPERM;
index 7c4a4151ef0f23fca16b0fd957769c09dc5823d0..5a1e98547031953b1eae1db7ae59a3750d935f40 100644 (file)
@@ -683,14 +683,20 @@ static void sixpack_close(struct tty_struct *tty)
        if (!atomic_dec_and_test(&sp->refcnt))
                down(&sp->dead_sem);
 
-       unregister_netdev(sp->dev);
+       /* We must stop the queue to avoid potentially scribbling
+        * on the free buffers. The sp->dead_sem is not sufficient
+        * to protect us from sp->xbuff access.
+        */
+       netif_stop_queue(sp->dev);
 
-       del_timer(&sp->tx_t);
-       del_timer(&sp->resync_t);
+       del_timer_sync(&sp->tx_t);
+       del_timer_sync(&sp->resync_t);
 
        /* Free all 6pack frame buffers. */
        kfree(sp->rbuff);
        kfree(sp->xbuff);
+
+       unregister_netdev(sp->dev);
 }
 
 /* Perform I/O control on an active 6pack channel. */
index 216bfd350169a9da723035876d152e89b17c8432..85828f1534454dbfd4020e6407e6ad2a136af93c 100644 (file)
@@ -797,14 +797,19 @@ static void mkiss_close(struct tty_struct *tty)
         */
        if (!atomic_dec_and_test(&ax->refcnt))
                down(&ax->dead_sem);
-
-       unregister_netdev(ax->dev);
+       /*
+        * Halt the transmit queue so that a new transmit cannot scribble
+        * on our buffers
+        */
+       netif_stop_queue(ax->dev);
 
        /* Free all AX25 frame buffers. */
        kfree(ax->rbuff);
        kfree(ax->xbuff);
 
        ax->tty = NULL;
+
+       unregister_netdev(ax->dev);
 }
 
 /* Perform I/O control on an active ax25 channel. */
index 908e8d4863429fb6c11f4a625449500f3be36ce1..7f8e7662e28cbcb97891cb8af27d37c9fbb915c0 100644 (file)
@@ -149,9 +149,14 @@ int mdio_mux_init(struct device *dev,
                }
                cb->bus_number = v;
                cb->parent = pb;
+
                cb->mii_bus = mdiobus_alloc();
+               if (!cb->mii_bus) {
+                       ret_val = -ENOMEM;
+                       of_node_put(child_bus_node);
+                       break;
+               }
                cb->mii_bus->priv = cb;
-
                cb->mii_bus->irq = cb->phy_irq;
                cb->mii_bus->name = "mdio_mux";
                snprintf(cb->mii_bus->id, MII_BUS_ID_SIZE, "%x.%x",
index cf6312fafea545fbc3efb96e8ff6c63b35c7420e..e13ad6cdcc2216ca1d43b78bb41cac12933fe2b4 100644 (file)
@@ -339,9 +339,18 @@ static int ksz9021_config_init(struct phy_device *phydev)
 {
        const struct device *dev = &phydev->dev;
        const struct device_node *of_node = dev->of_node;
+       const struct device *dev_walker;
 
-       if (!of_node && dev->parent->of_node)
-               of_node = dev->parent->of_node;
+       /* The Micrel driver has a deprecated option to place phy OF
+        * properties in the MAC node. Walk up the tree of devices to
+        * find a device with an OF node.
+        */
+       dev_walker = &phydev->dev;
+       do {
+               of_node = dev_walker->of_node;
+               dev_walker = dev_walker->parent;
+
+       } while (!of_node && dev_walker);
 
        if (of_node) {
                ksz9021_load_values_from_of(phydev, of_node,
index 5e0b43283bce2c4f5251e5c5db982ca679526d07..0a37f840fcc52d17cee2d23dce50d27723735bad 100644 (file)
@@ -568,6 +568,9 @@ static int pppoe_create(struct net *net, struct socket *sock, int kern)
        sk->sk_family           = PF_PPPOX;
        sk->sk_protocol         = PX_PROTO_OE;
 
+       INIT_WORK(&pppox_sk(sk)->proto.pppoe.padt_work,
+                 pppoe_unbind_sock_work);
+
        return 0;
 }
 
@@ -632,8 +635,6 @@ static int pppoe_connect(struct socket *sock, struct sockaddr *uservaddr,
 
        lock_sock(sk);
 
-       INIT_WORK(&po->proto.pppoe.padt_work, pppoe_unbind_sock_work);
-
        error = -EINVAL;
        if (sp->sa_protocol != PX_PROTO_OE)
                goto end;
@@ -663,8 +664,13 @@ static int pppoe_connect(struct socket *sock, struct sockaddr *uservaddr,
                        po->pppoe_dev = NULL;
                }
 
-               memset(sk_pppox(po) + 1, 0,
-                      sizeof(struct pppox_sock) - sizeof(struct sock));
+               po->pppoe_ifindex = 0;
+               memset(&po->pppoe_pa, 0, sizeof(po->pppoe_pa));
+               memset(&po->pppoe_relay, 0, sizeof(po->pppoe_relay));
+               memset(&po->chan, 0, sizeof(po->chan));
+               po->next = NULL;
+               po->num = 0;
+
                sk->sk_state = PPPOX_NONE;
        }
 
index fc69e41d09506e96b38f067fa05175bd680fa36b..597c53e0a2ecce6a7fecaaf5032006f31795b307 100644 (file)
@@ -419,6 +419,9 @@ static int pptp_bind(struct socket *sock, struct sockaddr *uservaddr,
        struct pptp_opt *opt = &po->proto.pptp;
        int error = 0;
 
+       if (sockaddr_len < sizeof(struct sockaddr_pppox))
+               return -EINVAL;
+
        lock_sock(sk);
 
        opt->src_addr = sp->sa_addr.pptp;
@@ -440,6 +443,9 @@ static int pptp_connect(struct socket *sock, struct sockaddr *uservaddr,
        struct flowi4 fl4;
        int error = 0;
 
+       if (sockaddr_len < sizeof(struct sockaddr_pppox))
+               return -EINVAL;
+
        if (sp->sa_protocol != PX_PROTO_PPTP)
                return -EINVAL;
 
index bbde9884ab8ae7fb952cbf6583feff10c9ce1109..bdd83d95ec0aa677b8443476ef2ee66018aff701 100644 (file)
@@ -100,7 +100,7 @@ static const struct net_device_ops cdc_mbim_netdev_ops = {
        .ndo_stop             = usbnet_stop,
        .ndo_start_xmit       = usbnet_start_xmit,
        .ndo_tx_timeout       = usbnet_tx_timeout,
-       .ndo_change_mtu       = usbnet_change_mtu,
+       .ndo_change_mtu       = cdc_ncm_change_mtu,
        .ndo_set_mac_address  = eth_mac_addr,
        .ndo_validate_addr    = eth_validate_addr,
        .ndo_vlan_rx_add_vid  = cdc_mbim_rx_add_vid,
@@ -158,7 +158,7 @@ static int cdc_mbim_bind(struct usbnet *dev, struct usb_interface *intf)
        if (!cdc_ncm_comm_intf_is_mbim(intf->cur_altsetting))
                goto err;
 
-       ret = cdc_ncm_bind_common(dev, intf, data_altsetting, 0);
+       ret = cdc_ncm_bind_common(dev, intf, data_altsetting, dev->driver_info->data);
        if (ret)
                goto err;
 
@@ -582,6 +582,26 @@ static const struct driver_info cdc_mbim_info_zlp = {
        .tx_fixup = cdc_mbim_tx_fixup,
 };
 
+/* The spefication explicitly allows NDPs to be placed anywhere in the
+ * frame, but some devices fail unless the NDP is placed after the IP
+ * packets.  Using the CDC_NCM_FLAG_NDP_TO_END flags to force this
+ * behaviour.
+ *
+ * Note: The current implementation of this feature restricts each NTB
+ * to a single NDP, implying that multiplexed sessions cannot share an
+ * NTB. This might affect performace for multiplexed sessions.
+ */
+static const struct driver_info cdc_mbim_info_ndp_to_end = {
+       .description = "CDC MBIM",
+       .flags = FLAG_NO_SETINT | FLAG_MULTI_PACKET | FLAG_WWAN,
+       .bind = cdc_mbim_bind,
+       .unbind = cdc_mbim_unbind,
+       .manage_power = cdc_mbim_manage_power,
+       .rx_fixup = cdc_mbim_rx_fixup,
+       .tx_fixup = cdc_mbim_tx_fixup,
+       .data = CDC_NCM_FLAG_NDP_TO_END,
+};
+
 static const struct usb_device_id mbim_devs[] = {
        /* This duplicate NCM entry is intentional. MBIM devices can
         * be disguised as NCM by default, and this is necessary to
@@ -597,6 +617,10 @@ static const struct usb_device_id mbim_devs[] = {
        { USB_VENDOR_AND_INTERFACE_INFO(0x0bdb, USB_CLASS_COMM, USB_CDC_SUBCLASS_MBIM, USB_CDC_PROTO_NONE),
          .driver_info = (unsigned long)&cdc_mbim_info,
        },
+       /* Huawei E3372 fails unless NDP comes after the IP packets */
+       { USB_DEVICE_AND_INTERFACE_INFO(0x12d1, 0x157d, USB_CLASS_COMM, USB_CDC_SUBCLASS_MBIM, USB_CDC_PROTO_NONE),
+         .driver_info = (unsigned long)&cdc_mbim_info_ndp_to_end,
+       },
        /* default entry */
        { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_MBIM, USB_CDC_PROTO_NONE),
          .driver_info = (unsigned long)&cdc_mbim_info_zlp,
index 3b1ba823776842445b5d5b6a709c58208c357f2b..e8a1144c5a8bfa28c1ddca137c56c888b176ab32 100644 (file)
@@ -41,6 +41,7 @@
 #include <linux/module.h>
 #include <linux/netdevice.h>
 #include <linux/ctype.h>
+#include <linux/etherdevice.h>
 #include <linux/ethtool.h>
 #include <linux/workqueue.h>
 #include <linux/mii.h>
@@ -689,6 +690,33 @@ static void cdc_ncm_free(struct cdc_ncm_ctx *ctx)
        kfree(ctx);
 }
 
+/* we need to override the usbnet change_mtu ndo for two reasons:
+ *  - respect the negotiated maximum datagram size
+ *  - avoid unwanted changes to rx and tx buffers
+ */
+int cdc_ncm_change_mtu(struct net_device *net, int new_mtu)
+{
+       struct usbnet *dev = netdev_priv(net);
+       struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0];
+       int maxmtu = ctx->max_datagram_size - cdc_ncm_eth_hlen(dev);
+
+       if (new_mtu <= 0 || new_mtu > maxmtu)
+               return -EINVAL;
+       net->mtu = new_mtu;
+       return 0;
+}
+EXPORT_SYMBOL_GPL(cdc_ncm_change_mtu);
+
+static const struct net_device_ops cdc_ncm_netdev_ops = {
+       .ndo_open            = usbnet_open,
+       .ndo_stop            = usbnet_stop,
+       .ndo_start_xmit      = usbnet_start_xmit,
+       .ndo_tx_timeout      = usbnet_tx_timeout,
+       .ndo_change_mtu      = cdc_ncm_change_mtu,
+       .ndo_set_mac_address = eth_mac_addr,
+       .ndo_validate_addr   = eth_validate_addr,
+};
+
 int cdc_ncm_bind_common(struct usbnet *dev, struct usb_interface *intf, u8 data_altsetting, int drvflags)
 {
        struct cdc_ncm_ctx *ctx;
@@ -823,6 +851,9 @@ int cdc_ncm_bind_common(struct usbnet *dev, struct usb_interface *intf, u8 data_
        /* add our sysfs attrs */
        dev->net->sysfs_groups[0] = &cdc_ncm_sysfs_attr_group;
 
+       /* must handle MTU changes */
+       dev->net->netdev_ops = &cdc_ncm_netdev_ops;
+
        return 0;
 
 error2:
@@ -955,10 +986,18 @@ static struct usb_cdc_ncm_ndp16 *cdc_ncm_ndp(struct cdc_ncm_ctx *ctx, struct sk_
        * NTH16 header as we would normally do. NDP isn't written to the SKB yet, and
        * the wNdpIndex field in the header is actually not consistent with reality. It will be later.
        */
-       if (ctx->drvflags & CDC_NCM_FLAG_NDP_TO_END)
+       if (ctx->drvflags & CDC_NCM_FLAG_NDP_TO_END) {
                if (ctx->delayed_ndp16->dwSignature == sign)
                        return ctx->delayed_ndp16;
 
+               /* We can only push a single NDP to the end. Return
+                * NULL to send what we've already got and queue this
+                * skb for later.
+                */
+               else if (ctx->delayed_ndp16->dwSignature)
+                       return NULL;
+       }
+
        /* follow the chain of NDPs, looking for a match */
        while (ndpoffset) {
                ndp16 = (struct usb_cdc_ncm_ndp16 *)(skb->data + ndpoffset);
@@ -1550,6 +1589,24 @@ static const struct usb_device_id cdc_devs[] = {
          .driver_info = (unsigned long) &wwan_info,
        },
 
+       /* DW5812 LTE Verizon Mobile Broadband Card
+        * Unlike DW5550 this device requires FLAG_NOARP
+        */
+       { USB_DEVICE_AND_INTERFACE_INFO(0x413c, 0x81bb,
+               USB_CLASS_COMM,
+               USB_CDC_SUBCLASS_NCM, USB_CDC_PROTO_NONE),
+         .driver_info = (unsigned long)&wwan_noarp_info,
+       },
+
+       /* DW5813 LTE AT&T Mobile Broadband Card
+        * Unlike DW5550 this device requires FLAG_NOARP
+        */
+       { USB_DEVICE_AND_INTERFACE_INFO(0x413c, 0x81bc,
+               USB_CLASS_COMM,
+               USB_CDC_SUBCLASS_NCM, USB_CDC_PROTO_NONE),
+         .driver_info = (unsigned long)&wwan_noarp_info,
+       },
+
        /* Dell branded MBM devices like DW5550 */
        { .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
                | USB_DEVICE_ID_MATCH_VENDOR,
index 9a5be8b851867e53f7427ba31f7a089ad02562fd..5fccc5a8153f4d0f73f0fb212912302c19679c27 100644 (file)
@@ -742,6 +742,7 @@ static const struct usb_device_id products[] = {
        {QMI_FIXED_INTF(0x413c, 0x81a9, 8)},    /* Dell Wireless 5808e Gobi(TM) 4G LTE Mobile Broadband Card */
        {QMI_FIXED_INTF(0x413c, 0x81b1, 8)},    /* Dell Wireless 5809e Gobi(TM) 4G LTE Mobile Broadband Card */
        {QMI_FIXED_INTF(0x03f0, 0x4e1d, 8)},    /* HP lt4111 LTE/EV-DO/HSPA+ Gobi 4G Module */
+       {QMI_FIXED_INTF(0x22de, 0x9061, 3)},    /* WeTelecom WPD-600N */
 
        /* 4. Gobi 1000 devices */
        {QMI_GOBI1K_DEVICE(0x05c6, 0x9212)},    /* Acer Gobi Modem Device */
index d9427ca3dba79628f402867b83e735bee78fac3b..2fb637ad594a96fa35f30f686e25973ea70b578a 100644 (file)
@@ -3067,17 +3067,6 @@ static int rtl8152_open(struct net_device *netdev)
 
        mutex_lock(&tp->control);
 
-       /* The WORK_ENABLE may be set when autoresume occurs */
-       if (test_bit(WORK_ENABLE, &tp->flags)) {
-               clear_bit(WORK_ENABLE, &tp->flags);
-               usb_kill_urb(tp->intr_urb);
-               cancel_delayed_work_sync(&tp->schedule);
-
-               /* disable the tx/rx, if the workqueue has enabled them. */
-               if (netif_carrier_ok(netdev))
-                       tp->rtl_ops.disable(tp);
-       }
-
        tp->rtl_ops.up(tp);
 
        rtl8152_set_speed(tp, AUTONEG_ENABLE,
@@ -3124,12 +3113,6 @@ static int rtl8152_close(struct net_device *netdev)
        } else {
                mutex_lock(&tp->control);
 
-               /* The autosuspend may have been enabled and wouldn't
-                * be disable when autoresume occurs, because the
-                * netif_running() would be false.
-                */
-               rtl_runtime_suspend_enable(tp, false);
-
                tp->rtl_ops.down(tp);
 
                mutex_unlock(&tp->control);
@@ -3512,7 +3495,7 @@ static int rtl8152_resume(struct usb_interface *intf)
                netif_device_attach(tp->netdev);
        }
 
-       if (netif_running(tp->netdev)) {
+       if (netif_running(tp->netdev) && tp->netdev->flags & IFF_UP) {
                if (test_bit(SELECTIVE_SUSPEND, &tp->flags)) {
                        rtl_runtime_suspend_enable(tp, false);
                        clear_bit(SELECTIVE_SUSPEND, &tp->flags);
@@ -3532,6 +3515,8 @@ static int rtl8152_resume(struct usb_interface *intf)
                }
                usb_submit_urb(tp->intr_urb, GFP_KERNEL);
        } else if (test_bit(SELECTIVE_SUSPEND, &tp->flags)) {
+               if (tp->netdev->flags & IFF_UP)
+                       rtl_runtime_suspend_enable(tp, false);
                clear_bit(SELECTIVE_SUSPEND, &tp->flags);
        }
 
@@ -3540,6 +3525,14 @@ static int rtl8152_resume(struct usb_interface *intf)
        return 0;
 }
 
+static int rtl8152_reset_resume(struct usb_interface *intf)
+{
+       struct r8152 *tp = usb_get_intfdata(intf);
+
+       clear_bit(SELECTIVE_SUSPEND, &tp->flags);
+       return rtl8152_resume(intf);
+}
+
 static void rtl8152_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
 {
        struct r8152 *tp = netdev_priv(dev);
@@ -4291,7 +4284,7 @@ static struct usb_driver rtl8152_driver = {
        .disconnect =   rtl8152_disconnect,
        .suspend =      rtl8152_suspend,
        .resume =       rtl8152_resume,
-       .reset_resume = rtl8152_resume,
+       .reset_resume = rtl8152_reset_resume,
        .pre_reset =    rtl8152_pre_reset,
        .post_reset =   rtl8152_post_reset,
        .supports_autosuspend = 1,
index 0ef4a5ad555739870897bfbb96c7a95847deed20..ba21d072be31c95827833f9e5014f20cfa43bb8b 100644 (file)
@@ -117,12 +117,6 @@ static netdev_tx_t veth_xmit(struct sk_buff *skb, struct net_device *dev)
                kfree_skb(skb);
                goto drop;
        }
-       /* don't change ip_summed == CHECKSUM_PARTIAL, as that
-        * will cause bad checksum on forwarded packets
-        */
-       if (skb->ip_summed == CHECKSUM_NONE &&
-           rcv->features & NETIF_F_RXCSUM)
-               skb->ip_summed = CHECKSUM_UNNECESSARY;
 
        if (likely(dev_forward_skb(rcv, skb) == NET_RX_SUCCESS)) {
                struct pcpu_vstats *stats = this_cpu_ptr(dev->vstats);
index 417903715437ebda5b07a859effdca86a62d196b..0cbf520cea778fc703c9657ab2d085eee522634b 100644 (file)
@@ -1380,10 +1380,10 @@ vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq,
                                        skip_page_frags = true;
                                        goto rcd_done;
                                }
-                               new_dma_addr = dma_map_page(&adapter->pdev->dev
-                                                       , rbi->page,
-                                                       0, PAGE_SIZE,
-                                                       PCI_DMA_FROMDEVICE);
+                               new_dma_addr = dma_map_page(&adapter->pdev->dev,
+                                                           new_page,
+                                                           0, PAGE_SIZE,
+                                                           PCI_DMA_FROMDEVICE);
                                if (dma_mapping_error(&adapter->pdev->dev,
                                                      new_dma_addr)) {
                                        put_page(new_page);
index 4c58c83dc2253a43b7c6150866d67bcd0c02e250..bdb8a6c0f8aa2c62e22edc64d3900530477b6fa8 100644 (file)
 /*
  * Version numbers
  */
-#define VMXNET3_DRIVER_VERSION_STRING   "1.4.4.0-k"
+#define VMXNET3_DRIVER_VERSION_STRING   "1.4.5.0-k"
 
 /* a 32-bit int, each byte encode a verion number in VMXNET3_DRIVER_VERSION */
-#define VMXNET3_DRIVER_VERSION_NUM      0x01040400
+#define VMXNET3_DRIVER_VERSION_NUM      0x01040500
 
 #if defined(CONFIG_PCI_MSI)
        /* RSS only makes sense if MSI-X is supported. */
index 4f9748457f5a722658e5cfb01b6cbcc0f488d14f..0a242b200df4c9e8198a9a74764eb05f89f13cbd 100644 (file)
@@ -800,7 +800,7 @@ static struct rtable *vrf_get_rtable(const struct net_device *dev,
 }
 
 /* called under rcu_read_lock */
-static void vrf_get_saddr(struct net_device *dev, struct flowi4 *fl4)
+static int vrf_get_saddr(struct net_device *dev, struct flowi4 *fl4)
 {
        struct fib_result res = { .tclassid = 0 };
        struct net *net = dev_net(dev);
@@ -808,9 +808,10 @@ static void vrf_get_saddr(struct net_device *dev, struct flowi4 *fl4)
        u8 flags = fl4->flowi4_flags;
        u8 scope = fl4->flowi4_scope;
        u8 tos = RT_FL_TOS(fl4);
+       int rc;
 
        if (unlikely(!fl4->daddr))
-               return;
+               return 0;
 
        fl4->flowi4_flags |= FLOWI_FLAG_SKIP_NH_OIF;
        fl4->flowi4_iif = LOOPBACK_IFINDEX;
@@ -818,7 +819,8 @@ static void vrf_get_saddr(struct net_device *dev, struct flowi4 *fl4)
        fl4->flowi4_scope = ((tos & RTO_ONLINK) ?
                             RT_SCOPE_LINK : RT_SCOPE_UNIVERSE);
 
-       if (!fib_lookup(net, fl4, &res, 0)) {
+       rc = fib_lookup(net, fl4, &res, 0);
+       if (!rc) {
                if (res.type == RTN_LOCAL)
                        fl4->saddr = res.fi->fib_prefsrc ? : fl4->daddr;
                else
@@ -828,6 +830,8 @@ static void vrf_get_saddr(struct net_device *dev, struct flowi4 *fl4)
        fl4->flowi4_flags = flags;
        fl4->flowi4_tos = orig_tos;
        fl4->flowi4_scope = scope;
+
+       return rc;
 }
 
 #if IS_ENABLED(CONFIG_IPV6)
index 6369a5734d4c3e899e96ec74469b0af4b3bca865..ba363cedef80820feb11b5ce6f5f347f8a575d12 100644 (file)
@@ -1158,7 +1158,6 @@ static void vxlan_rcv(struct vxlan_sock *vs, struct sk_buff *skb,
        struct pcpu_sw_netstats *stats;
        union vxlan_addr saddr;
        int err = 0;
-       union vxlan_addr *remote_ip;
 
        /* For flow based devices, map all packets to VNI 0 */
        if (vs->flags & VXLAN_F_COLLECT_METADATA)
@@ -1169,7 +1168,6 @@ static void vxlan_rcv(struct vxlan_sock *vs, struct sk_buff *skb,
        if (!vxlan)
                goto drop;
 
-       remote_ip = &vxlan->default_dst.remote_ip;
        skb_reset_mac_header(skb);
        skb_scrub_packet(skb, !net_eq(vxlan->net, dev_net(vxlan->dev)));
        skb->protocol = eth_type_trans(skb, vxlan->dev);
@@ -1179,8 +1177,8 @@ static void vxlan_rcv(struct vxlan_sock *vs, struct sk_buff *skb,
        if (ether_addr_equal(eth_hdr(skb)->h_source, vxlan->dev->dev_addr))
                goto drop;
 
-       /* Re-examine inner Ethernet packet */
-       if (remote_ip->sa.sa_family == AF_INET) {
+       /* Get data from the outer IP header */
+       if (vxlan_get_sk_family(vs) == AF_INET) {
                oip = ip_hdr(skb);
                saddr.sin.sin_addr.s_addr = oip->saddr;
                saddr.sa.sa_family = AF_INET;
@@ -1848,6 +1846,34 @@ static int vxlan_xmit_skb(struct rtable *rt, struct sock *sk, struct sk_buff *sk
                                   !(vxflags & VXLAN_F_UDP_CSUM));
 }
 
+#if IS_ENABLED(CONFIG_IPV6)
+static struct dst_entry *vxlan6_get_route(struct vxlan_dev *vxlan,
+                                         struct sk_buff *skb, int oif,
+                                         const struct in6_addr *daddr,
+                                         struct in6_addr *saddr)
+{
+       struct dst_entry *ndst;
+       struct flowi6 fl6;
+       int err;
+
+       memset(&fl6, 0, sizeof(fl6));
+       fl6.flowi6_oif = oif;
+       fl6.daddr = *daddr;
+       fl6.saddr = vxlan->cfg.saddr.sin6.sin6_addr;
+       fl6.flowi6_mark = skb->mark;
+       fl6.flowi6_proto = IPPROTO_UDP;
+
+       err = ipv6_stub->ipv6_dst_lookup(vxlan->net,
+                                        vxlan->vn6_sock->sock->sk,
+                                        &ndst, &fl6);
+       if (err < 0)
+               return ERR_PTR(err);
+
+       *saddr = fl6.saddr;
+       return ndst;
+}
+#endif
+
 /* Bypass encapsulation if the destination is local */
 static void vxlan_encap_bypass(struct sk_buff *skb, struct vxlan_dev *src_vxlan,
                               struct vxlan_dev *dst_vxlan)
@@ -2035,21 +2061,17 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
 #if IS_ENABLED(CONFIG_IPV6)
        } else {
                struct dst_entry *ndst;
-               struct flowi6 fl6;
+               struct in6_addr saddr;
                u32 rt6i_flags;
 
                if (!vxlan->vn6_sock)
                        goto drop;
                sk = vxlan->vn6_sock->sock->sk;
 
-               memset(&fl6, 0, sizeof(fl6));
-               fl6.flowi6_oif = rdst ? rdst->remote_ifindex : 0;
-               fl6.daddr = dst->sin6.sin6_addr;
-               fl6.saddr = vxlan->cfg.saddr.sin6.sin6_addr;
-               fl6.flowi6_mark = skb->mark;
-               fl6.flowi6_proto = IPPROTO_UDP;
-
-               if (ipv6_stub->ipv6_dst_lookup(vxlan->net, sk, &ndst, &fl6)) {
+               ndst = vxlan6_get_route(vxlan, skb,
+                                       rdst ? rdst->remote_ifindex : 0,
+                                       &dst->sin6.sin6_addr, &saddr);
+               if (IS_ERR(ndst)) {
                        netdev_dbg(dev, "no route to %pI6\n",
                                   &dst->sin6.sin6_addr);
                        dev->stats.tx_carrier_errors++;
@@ -2081,7 +2103,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
                }
 
                ttl = ttl ? : ip6_dst_hoplimit(ndst);
-               err = vxlan6_xmit_skb(ndst, sk, skb, dev, &fl6.saddr, &fl6.daddr,
+               err = vxlan6_xmit_skb(ndst, sk, skb, dev, &saddr, &dst->sin6.sin6_addr,
                                      0, ttl, src_port, dst_port, htonl(vni << 8), md,
                                      !net_eq(vxlan->net, dev_net(vxlan->dev)),
                                      flags);
@@ -2395,9 +2417,30 @@ static int vxlan_fill_metadata_dst(struct net_device *dev, struct sk_buff *skb)
                                  vxlan->cfg.port_max, true);
        dport = info->key.tp_dst ? : vxlan->cfg.dst_port;
 
-       if (ip_tunnel_info_af(info) == AF_INET)
+       if (ip_tunnel_info_af(info) == AF_INET) {
+               if (!vxlan->vn4_sock)
+                       return -EINVAL;
                return egress_ipv4_tun_info(dev, skb, info, sport, dport);
-       return -EINVAL;
+       } else {
+#if IS_ENABLED(CONFIG_IPV6)
+               struct dst_entry *ndst;
+
+               if (!vxlan->vn6_sock)
+                       return -EINVAL;
+               ndst = vxlan6_get_route(vxlan, skb, 0,
+                                       &info->key.u.ipv6.dst,
+                                       &info->key.u.ipv6.src);
+               if (IS_ERR(ndst))
+                       return PTR_ERR(ndst);
+               dst_release(ndst);
+
+               info->key.tp_src = sport;
+               info->key.tp_dst = dport;
+#else /* !CONFIG_IPV6 */
+               return -EPFNOSUPPORT;
+#endif
+       }
+       return 0;
 }
 
 static const struct net_device_ops vxlan_netdev_ops = {
index bf88ec3a65fab3e04aab4398185236bdb955126b..d9a4aee246a6379c6a6aee7d6185ff680387c55e 100644 (file)
 #include "iwl-agn-hw.h"
 
 /* Highest firmware API version supported */
-#define IWL7260_UCODE_API_MAX  19
+#define IWL7260_UCODE_API_MAX  17
+#define IWL7265_UCODE_API_MAX  19
+#define IWL7265D_UCODE_API_MAX 19
 
 /* Oldest version we won't warn about */
 #define IWL7260_UCODE_API_OK   13
+#define IWL7265_UCODE_API_OK   13
+#define IWL7265D_UCODE_API_OK  13
 
 /* Lowest firmware API version supported */
 #define IWL7260_UCODE_API_MIN  13
+#define IWL7265_UCODE_API_MIN  13
+#define IWL7265D_UCODE_API_MIN 13
 
 /* NVM versions */
 #define IWL7260_NVM_VERSION            0x0a1d
@@ -149,10 +155,7 @@ static const struct iwl_ht_params iwl7000_ht_params = {
        .ht40_bands = BIT(IEEE80211_BAND_2GHZ) | BIT(IEEE80211_BAND_5GHZ),
 };
 
-#define IWL_DEVICE_7000                                                \
-       .ucode_api_max = IWL7260_UCODE_API_MAX,                 \
-       .ucode_api_ok = IWL7260_UCODE_API_OK,                   \
-       .ucode_api_min = IWL7260_UCODE_API_MIN,                 \
+#define IWL_DEVICE_7000_COMMON                                 \
        .device_family = IWL_DEVICE_FAMILY_7000,                \
        .max_inst_size = IWL60_RTC_INST_SIZE,                   \
        .max_data_size = IWL60_RTC_DATA_SIZE,                   \
@@ -163,6 +166,24 @@ static const struct iwl_ht_params iwl7000_ht_params = {
        .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,    \
        .dccm_offset = IWL7000_DCCM_OFFSET
 
+#define IWL_DEVICE_7000                                                \
+       IWL_DEVICE_7000_COMMON,                                 \
+       .ucode_api_max = IWL7260_UCODE_API_MAX,                 \
+       .ucode_api_ok = IWL7260_UCODE_API_OK,                   \
+       .ucode_api_min = IWL7260_UCODE_API_MIN
+
+#define IWL_DEVICE_7005                                                \
+       IWL_DEVICE_7000_COMMON,                                 \
+       .ucode_api_max = IWL7265_UCODE_API_MAX,                 \
+       .ucode_api_ok = IWL7265_UCODE_API_OK,                   \
+       .ucode_api_min = IWL7265_UCODE_API_MIN
+
+#define IWL_DEVICE_7005D                                       \
+       IWL_DEVICE_7000_COMMON,                                 \
+       .ucode_api_max = IWL7265D_UCODE_API_MAX,                \
+       .ucode_api_ok = IWL7265D_UCODE_API_OK,                  \
+       .ucode_api_min = IWL7265D_UCODE_API_MIN
+
 const struct iwl_cfg iwl7260_2ac_cfg = {
        .name = "Intel(R) Dual Band Wireless AC 7260",
        .fw_name_pre = IWL7260_FW_PRE,
@@ -266,7 +287,7 @@ 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 = IWL7265D_FW_PRE,
-       IWL_DEVICE_7000,
+       IWL_DEVICE_7005D,
        .ht_params = &iwl7000_ht_params,
        .nvm_ver = IWL3165_NVM_VERSION,
        .nvm_calib_ver = IWL3165_TX_POWER_VERSION,
@@ -277,7 +298,7 @@ const struct iwl_cfg iwl3165_2ac_cfg = {
 const struct iwl_cfg iwl7265_2ac_cfg = {
        .name = "Intel(R) Dual Band Wireless AC 7265",
        .fw_name_pre = IWL7265_FW_PRE,
-       IWL_DEVICE_7000,
+       IWL_DEVICE_7005,
        .ht_params = &iwl7265_ht_params,
        .nvm_ver = IWL7265_NVM_VERSION,
        .nvm_calib_ver = IWL7265_TX_POWER_VERSION,
@@ -288,7 +309,7 @@ const struct iwl_cfg iwl7265_2ac_cfg = {
 const struct iwl_cfg iwl7265_2n_cfg = {
        .name = "Intel(R) Dual Band Wireless N 7265",
        .fw_name_pre = IWL7265_FW_PRE,
-       IWL_DEVICE_7000,
+       IWL_DEVICE_7005,
        .ht_params = &iwl7265_ht_params,
        .nvm_ver = IWL7265_NVM_VERSION,
        .nvm_calib_ver = IWL7265_TX_POWER_VERSION,
@@ -299,7 +320,7 @@ const struct iwl_cfg iwl7265_2n_cfg = {
 const struct iwl_cfg iwl7265_n_cfg = {
        .name = "Intel(R) Wireless N 7265",
        .fw_name_pre = IWL7265_FW_PRE,
-       IWL_DEVICE_7000,
+       IWL_DEVICE_7005,
        .ht_params = &iwl7265_ht_params,
        .nvm_ver = IWL7265_NVM_VERSION,
        .nvm_calib_ver = IWL7265_TX_POWER_VERSION,
@@ -310,7 +331,7 @@ const struct iwl_cfg iwl7265_n_cfg = {
 const struct iwl_cfg iwl7265d_2ac_cfg = {
        .name = "Intel(R) Dual Band Wireless AC 7265",
        .fw_name_pre = IWL7265D_FW_PRE,
-       IWL_DEVICE_7000,
+       IWL_DEVICE_7005D,
        .ht_params = &iwl7265_ht_params,
        .nvm_ver = IWL7265D_NVM_VERSION,
        .nvm_calib_ver = IWL7265_TX_POWER_VERSION,
@@ -321,7 +342,7 @@ const struct iwl_cfg iwl7265d_2ac_cfg = {
 const struct iwl_cfg iwl7265d_2n_cfg = {
        .name = "Intel(R) Dual Band Wireless N 7265",
        .fw_name_pre = IWL7265D_FW_PRE,
-       IWL_DEVICE_7000,
+       IWL_DEVICE_7005D,
        .ht_params = &iwl7265_ht_params,
        .nvm_ver = IWL7265D_NVM_VERSION,
        .nvm_calib_ver = IWL7265_TX_POWER_VERSION,
@@ -332,7 +353,7 @@ const struct iwl_cfg iwl7265d_2n_cfg = {
 const struct iwl_cfg iwl7265d_n_cfg = {
        .name = "Intel(R) Wireless N 7265",
        .fw_name_pre = IWL7265D_FW_PRE,
-       IWL_DEVICE_7000,
+       IWL_DEVICE_7005D,
        .ht_params = &iwl7265_ht_params,
        .nvm_ver = IWL7265D_NVM_VERSION,
        .nvm_calib_ver = IWL7265_TX_POWER_VERSION,
@@ -342,5 +363,5 @@ const struct iwl_cfg iwl7265d_n_cfg = {
 
 MODULE_FIRMWARE(IWL7260_MODULE_FIRMWARE(IWL7260_UCODE_API_OK));
 MODULE_FIRMWARE(IWL3160_MODULE_FIRMWARE(IWL7260_UCODE_API_OK));
-MODULE_FIRMWARE(IWL7265_MODULE_FIRMWARE(IWL7260_UCODE_API_OK));
-MODULE_FIRMWARE(IWL7265D_MODULE_FIRMWARE(IWL7260_UCODE_API_OK));
+MODULE_FIRMWARE(IWL7265_MODULE_FIRMWARE(IWL7265_UCODE_API_OK));
+MODULE_FIRMWARE(IWL7265D_MODULE_FIRMWARE(IWL7265D_UCODE_API_OK));
index 354acbde088e9e6fad0927a9ef73787ab235558c..2b976b110207f87532162e6f8587c1fcd0063c83 100644 (file)
@@ -1222,8 +1222,8 @@ static u8 iwl_mvm_get_key_sta_id(struct iwl_mvm *mvm,
            mvmvif->ap_sta_id != IWL_MVM_STATION_COUNT) {
                u8 sta_id = mvmvif->ap_sta_id;
 
-               sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[sta_id],
-                                               lockdep_is_held(&mvm->mutex));
+               sta = rcu_dereference_check(mvm->fw_id_to_mac_id[sta_id],
+                                           lockdep_is_held(&mvm->mutex));
                /*
                 * It is possible that the 'sta' parameter is NULL,
                 * for example when a GTK is removed - the sta_id will then
@@ -1590,14 +1590,15 @@ void iwl_mvm_update_tkip_key(struct iwl_mvm *mvm,
                             u16 *phase1key)
 {
        struct iwl_mvm_sta *mvm_sta;
-       u8 sta_id = iwl_mvm_get_key_sta_id(mvm, vif, sta);
+       u8 sta_id;
        bool mcast = !(keyconf->flags & IEEE80211_KEY_FLAG_PAIRWISE);
 
-       if (WARN_ON_ONCE(sta_id == IWL_MVM_STATION_COUNT))
-               return;
-
        rcu_read_lock();
 
+       sta_id = iwl_mvm_get_key_sta_id(mvm, vif, sta);
+       if (WARN_ON_ONCE(sta_id == IWL_MVM_STATION_COUNT))
+               goto unlock;
+
        if (!sta) {
                sta = rcu_dereference(mvm->fw_id_to_mac_id[sta_id]);
                if (WARN_ON(IS_ERR_OR_NULL(sta))) {
@@ -1609,6 +1610,8 @@ void iwl_mvm_update_tkip_key(struct iwl_mvm *mvm,
        mvm_sta = iwl_mvm_sta_from_mac80211(sta);
        iwl_mvm_send_sta_key(mvm, mvm_sta, keyconf, mcast,
                             iv32, phase1key, CMD_ASYNC, keyconf->hw_key_idx);
+
+ unlock:
        rcu_read_unlock();
 }
 
index e481f3710bd38a330d00501c8bd4afadff9de8ff..1049c34e7d430fab13e8d36e54af1b049eb02a03 100644 (file)
@@ -258,18 +258,18 @@ static struct xenvif_rx_meta *get_next_rx_buffer(struct xenvif_queue *queue,
                                                 struct netrx_pending_operations *npo)
 {
        struct xenvif_rx_meta *meta;
-       struct xen_netif_rx_request *req;
+       struct xen_netif_rx_request req;
 
-       req = RING_GET_REQUEST(&queue->rx, queue->rx.req_cons++);
+       RING_COPY_REQUEST(&queue->rx, queue->rx.req_cons++, &req);
 
        meta = npo->meta + npo->meta_prod++;
        meta->gso_type = XEN_NETIF_GSO_TYPE_NONE;
        meta->gso_size = 0;
        meta->size = 0;
-       meta->id = req->id;
+       meta->id = req.id;
 
        npo->copy_off = 0;
-       npo->copy_gref = req->gref;
+       npo->copy_gref = req.gref;
 
        return meta;
 }
@@ -424,7 +424,7 @@ static int xenvif_gop_skb(struct sk_buff *skb,
        struct xenvif *vif = netdev_priv(skb->dev);
        int nr_frags = skb_shinfo(skb)->nr_frags;
        int i;
-       struct xen_netif_rx_request *req;
+       struct xen_netif_rx_request req;
        struct xenvif_rx_meta *meta;
        unsigned char *data;
        int head = 1;
@@ -443,15 +443,15 @@ static int xenvif_gop_skb(struct sk_buff *skb,
 
        /* Set up a GSO prefix descriptor, if necessary */
        if ((1 << gso_type) & vif->gso_prefix_mask) {
-               req = RING_GET_REQUEST(&queue->rx, queue->rx.req_cons++);
+               RING_COPY_REQUEST(&queue->rx, queue->rx.req_cons++, &req);
                meta = npo->meta + npo->meta_prod++;
                meta->gso_type = gso_type;
                meta->gso_size = skb_shinfo(skb)->gso_size;
                meta->size = 0;
-               meta->id = req->id;
+               meta->id = req.id;
        }
 
-       req = RING_GET_REQUEST(&queue->rx, queue->rx.req_cons++);
+       RING_COPY_REQUEST(&queue->rx, queue->rx.req_cons++, &req);
        meta = npo->meta + npo->meta_prod++;
 
        if ((1 << gso_type) & vif->gso_mask) {
@@ -463,9 +463,9 @@ static int xenvif_gop_skb(struct sk_buff *skb,
        }
 
        meta->size = 0;
-       meta->id = req->id;
+       meta->id = req.id;
        npo->copy_off = 0;
-       npo->copy_gref = req->gref;
+       npo->copy_gref = req.gref;
 
        data = skb->data;
        while (data < skb_tail_pointer(skb)) {
@@ -679,9 +679,7 @@ static void tx_add_credit(struct xenvif_queue *queue)
         * Allow a burst big enough to transmit a jumbo packet of up to 128kB.
         * Otherwise the interface can seize up due to insufficient credit.
         */
-       max_burst = RING_GET_REQUEST(&queue->tx, queue->tx.req_cons)->size;
-       max_burst = min(max_burst, 131072UL);
-       max_burst = max(max_burst, queue->credit_bytes);
+       max_burst = max(131072UL, queue->credit_bytes);
 
        /* Take care that adding a new chunk of credit doesn't wrap to zero. */
        max_credit = queue->remaining_credit + queue->credit_bytes;
@@ -711,7 +709,7 @@ static void xenvif_tx_err(struct xenvif_queue *queue,
                spin_unlock_irqrestore(&queue->response_lock, flags);
                if (cons == end)
                        break;
-               txp = RING_GET_REQUEST(&queue->tx, cons++);
+               RING_COPY_REQUEST(&queue->tx, cons++, txp);
        } while (1);
        queue->tx.req_cons = cons;
 }
@@ -778,8 +776,7 @@ static int xenvif_count_requests(struct xenvif_queue *queue,
                if (drop_err)
                        txp = &dropped_tx;
 
-               memcpy(txp, RING_GET_REQUEST(&queue->tx, cons + slots),
-                      sizeof(*txp));
+               RING_COPY_REQUEST(&queue->tx, cons + slots, txp);
 
                /* If the guest submitted a frame >= 64 KiB then
                 * first->size overflowed and following slots will
@@ -1112,8 +1109,7 @@ static int xenvif_get_extras(struct xenvif_queue *queue,
                        return -EBADR;
                }
 
-               memcpy(&extra, RING_GET_REQUEST(&queue->tx, cons),
-                      sizeof(extra));
+               RING_COPY_REQUEST(&queue->tx, cons, &extra);
                if (unlikely(!extra.type ||
                             extra.type >= XEN_NETIF_EXTRA_TYPE_MAX)) {
                        queue->tx.req_cons = ++cons;
@@ -1322,7 +1318,7 @@ static void xenvif_tx_build_gops(struct xenvif_queue *queue,
 
                idx = queue->tx.req_cons;
                rmb(); /* Ensure that we see the request before we copy it. */
-               memcpy(&txreq, RING_GET_REQUEST(&queue->tx, idx), sizeof(txreq));
+               RING_COPY_REQUEST(&queue->tx, idx, &txreq);
 
                /* Credit-based scheduling. */
                if (txreq.size > queue->remaining_credit &&
index 06c3364102350e7f90d3a357bfdfc54b728f724f..15f2acb4d5cd4937ee350e7daaf67f1b8ec56ad6 100644 (file)
@@ -271,9 +271,9 @@ static int init_grps(struct nvm_id *nvm_id, struct nvme_nvm_id *nvme_nvm_id)
        return 0;
 }
 
-static int nvme_nvm_identity(struct request_queue *q, struct nvm_id *nvm_id)
+static int nvme_nvm_identity(struct nvm_dev *nvmdev, struct nvm_id *nvm_id)
 {
-       struct nvme_ns *ns = q->queuedata;
+       struct nvme_ns *ns = nvmdev->q->queuedata;
        struct nvme_dev *dev = ns->dev;
        struct nvme_nvm_id *nvme_nvm_id;
        struct nvme_nvm_command c = {};
@@ -308,10 +308,10 @@ out:
        return ret;
 }
 
-static int nvme_nvm_get_l2p_tbl(struct request_queue *q, u64 slba, u32 nlb,
+static int nvme_nvm_get_l2p_tbl(struct nvm_dev *nvmdev, u64 slba, u32 nlb,
                                nvm_l2p_update_fn *update_l2p, void *priv)
 {
-       struct nvme_ns *ns = q->queuedata;
+       struct nvme_ns *ns = nvmdev->q->queuedata;
        struct nvme_dev *dev = ns->dev;
        struct nvme_nvm_command c = {};
        u32 len = queue_max_hw_sectors(dev->admin_q) << 9;
@@ -415,10 +415,10 @@ out:
        return ret;
 }
 
-static int nvme_nvm_set_bb_tbl(struct request_queue *q, struct nvm_rq *rqd,
+static int nvme_nvm_set_bb_tbl(struct nvm_dev *nvmdev, struct nvm_rq *rqd,
                                                                int type)
 {
-       struct nvme_ns *ns = q->queuedata;
+       struct nvme_ns *ns = nvmdev->q->queuedata;
        struct nvme_dev *dev = ns->dev;
        struct nvme_nvm_command c = {};
        int ret = 0;
@@ -455,7 +455,7 @@ static void nvme_nvm_end_io(struct request *rq, int error)
        struct nvm_rq *rqd = rq->end_io_data;
        struct nvm_dev *dev = rqd->dev;
 
-       if (dev->mt->end_io(rqd, error))
+       if (dev->mt && dev->mt->end_io(rqd, error))
                pr_err("nvme: err status: %x result: %lx\n",
                                rq->errors, (unsigned long)rq->special);
 
@@ -463,8 +463,9 @@ static void nvme_nvm_end_io(struct request *rq, int error)
        blk_mq_free_request(rq);
 }
 
-static int nvme_nvm_submit_io(struct request_queue *q, struct nvm_rq *rqd)
+static int nvme_nvm_submit_io(struct nvm_dev *dev, struct nvm_rq *rqd)
 {
+       struct request_queue *q = dev->q;
        struct nvme_ns *ns = q->queuedata;
        struct request *rq;
        struct bio *bio = rqd->bio;
@@ -502,8 +503,9 @@ static int nvme_nvm_submit_io(struct request_queue *q, struct nvm_rq *rqd)
        return 0;
 }
 
-static int nvme_nvm_erase_block(struct request_queue *q, struct nvm_rq *rqd)
+static int nvme_nvm_erase_block(struct nvm_dev *dev, struct nvm_rq *rqd)
 {
+       struct request_queue *q = dev->q;
        struct nvme_ns *ns = q->queuedata;
        struct nvme_nvm_command c = {};
 
@@ -515,9 +517,9 @@ static int nvme_nvm_erase_block(struct request_queue *q, struct nvm_rq *rqd)
        return nvme_submit_sync_cmd(q, (struct nvme_command *)&c, NULL, 0);
 }
 
-static void *nvme_nvm_create_dma_pool(struct request_queue *q, char *name)
+static void *nvme_nvm_create_dma_pool(struct nvm_dev *nvmdev, char *name)
 {
-       struct nvme_ns *ns = q->queuedata;
+       struct nvme_ns *ns = nvmdev->q->queuedata;
        struct nvme_dev *dev = ns->dev;
 
        return dma_pool_create(name, dev->dev, PAGE_SIZE, PAGE_SIZE, 0);
@@ -530,7 +532,7 @@ static void nvme_nvm_destroy_dma_pool(void *pool)
        dma_pool_destroy(dma_pool);
 }
 
-static void *nvme_nvm_dev_dma_alloc(struct request_queue *q, void *pool,
+static void *nvme_nvm_dev_dma_alloc(struct nvm_dev *dev, void *pool,
                                    gfp_t mem_flags, dma_addr_t *dma_handler)
 {
        return dma_pool_alloc(pool, mem_flags, dma_handler);
index 9e294ff4e652a2bb8daa9e3f4a94cc09e8bb8b88..0c67b57be83c4630a89c670acbbd150b65ec667f 100644 (file)
@@ -2540,8 +2540,17 @@ static void nvme_ns_remove(struct nvme_ns *ns)
 {
        bool kill = nvme_io_incapable(ns->dev) && !blk_queue_dying(ns->queue);
 
-       if (kill)
+       if (kill) {
                blk_set_queue_dying(ns->queue);
+
+               /*
+                * The controller was shutdown first if we got here through
+                * device removal. The shutdown may requeue outstanding
+                * requests. These need to be aborted immediately so
+                * del_gendisk doesn't block indefinitely for their completion.
+                */
+               blk_mq_abort_requeue_list(ns->queue);
+       }
        if (ns->disk->flags & GENHD_FL_UP)
                del_gendisk(ns->disk);
        if (kill || !blk_queue_dying(ns->queue)) {
@@ -2977,6 +2986,15 @@ static void nvme_dev_remove(struct nvme_dev *dev)
 {
        struct nvme_ns *ns, *next;
 
+       if (nvme_io_incapable(dev)) {
+               /*
+                * If the device is not capable of IO (surprise hot-removal,
+                * for example), we need to quiesce prior to deleting the
+                * namespaces. This will end outstanding requests and prevent
+                * attempts to sync dirty data.
+                */
+               nvme_dev_shutdown(dev);
+       }
        list_for_each_entry_safe(ns, next, &dev->namespaces, list)
                nvme_ns_remove(ns);
 }
index 761e77bfce5d2f43f251ebb74f82245d52c5f5f3..e56f1569f6c396f8c29448e9adb26214e26ba9fc 100644 (file)
@@ -104,7 +104,11 @@ iommu_coalesce_chunks(struct ioc *ioc, struct device *dev,
        struct scatterlist *contig_sg;     /* contig chunk head */
        unsigned long dma_offset, dma_len; /* start/len of DMA stream */
        unsigned int n_mappings = 0;
-       unsigned int max_seg_size = dma_get_max_seg_size(dev);
+       unsigned int max_seg_size = min(dma_get_max_seg_size(dev),
+                                       (unsigned)DMA_CHUNK_SIZE);
+       unsigned int max_seg_boundary = dma_get_seg_boundary(dev) + 1;
+       if (max_seg_boundary)   /* check if the addition above didn't overflow */
+               max_seg_size = min(max_seg_size, max_seg_boundary);
 
        while (nents > 0) {
 
@@ -138,14 +142,11 @@ iommu_coalesce_chunks(struct ioc *ioc, struct device *dev,
 
                        /*
                        ** First make sure current dma stream won't
-                       ** exceed DMA_CHUNK_SIZE if we coalesce the
+                       ** exceed max_seg_size if we coalesce the
                        ** next entry.
                        */   
-                       if(unlikely(ALIGN(dma_len + dma_offset + startsg->length,
-                                           IOVP_SIZE) > DMA_CHUNK_SIZE))
-                               break;
-
-                       if (startsg->length + dma_len > max_seg_size)
+                       if (unlikely(ALIGN(dma_len + dma_offset + startsg->length, IOVP_SIZE) >
+                                    max_seg_size))
                                break;
 
                        /*
index 163671a4f798dfc18bb24f3490ad7138753efac1..77f7c669a1b9bb497528874c10262430c868959d 100644 (file)
@@ -61,7 +61,9 @@ static int hisi_pcie_cfg_read(struct pcie_port *pp, int where, int size,
                *val = *(u8 __force *) walker;
        else if (size == 2)
                *val = *(u16 __force *) walker;
-       else if (size != 4)
+       else if (size == 4)
+               *val = reg_val;
+       else
                return PCIBIOS_BAD_REGISTER_NUMBER;
 
        return PCIBIOS_SUCCESSFUL;
index 7eb5859dd035fefabea842f40722580cfcdfe64a..03cb3ea2d2c035b32254022b1506fcf52d770655 100644 (file)
@@ -233,6 +233,7 @@ config PHY_SUN9I_USB
        tristate "Allwinner sun9i SoC USB PHY driver"
        depends on ARCH_SUNXI && HAS_IOMEM && OF
        depends on RESET_CONTROLLER
+       depends on USB_COMMON
        select GENERIC_PHY
        help
          Enable this to support the transceiver that is part of Allwinner
index 7ad72b7d2b981b6ff4ae59011fdd5e6c5538ef51..082c03f6438f796af868cb83127f1ce9ca56f83b 100644 (file)
@@ -128,6 +128,7 @@ static int cygnus_pcie_phy_probe(struct platform_device *pdev)
        struct phy_provider *provider;
        struct resource *res;
        unsigned cnt = 0;
+       int ret;
 
        if (of_get_child_count(node) == 0) {
                dev_err(dev, "PHY no child node\n");
@@ -154,24 +155,28 @@ static int cygnus_pcie_phy_probe(struct platform_device *pdev)
                if (of_property_read_u32(child, "reg", &id)) {
                        dev_err(dev, "missing reg property for %s\n",
                                child->name);
-                       return -EINVAL;
+                       ret = -EINVAL;
+                       goto put_child;
                }
 
                if (id >= MAX_NUM_PHYS) {
                        dev_err(dev, "invalid PHY id: %u\n", id);
-                       return -EINVAL;
+                       ret = -EINVAL;
+                       goto put_child;
                }
 
                if (core->phys[id].phy) {
                        dev_err(dev, "duplicated PHY id: %u\n", id);
-                       return -EINVAL;
+                       ret = -EINVAL;
+                       goto put_child;
                }
 
                p = &core->phys[id];
                p->phy = devm_phy_create(dev, child, &cygnus_pcie_phy_ops);
                if (IS_ERR(p->phy)) {
                        dev_err(dev, "failed to create PHY\n");
-                       return PTR_ERR(p->phy);
+                       ret = PTR_ERR(p->phy);
+                       goto put_child;
                }
 
                p->core = core;
@@ -191,6 +196,9 @@ static int cygnus_pcie_phy_probe(struct platform_device *pdev)
        dev_dbg(dev, "registered %u PCIe PHY(s)\n", cnt);
 
        return 0;
+put_child:
+       of_node_put(child);
+       return ret;
 }
 
 static const struct of_device_id cygnus_pcie_phy_match_table[] = {
index 77a2e054fdea0f46ccd3d2841f5f837f80a985e1..f84a33a1bdd935c5a6c171929d172b1a1a67840c 100644 (file)
@@ -195,7 +195,7 @@ static int phy_berlin_sata_probe(struct platform_device *pdev)
        struct phy_provider *phy_provider;
        struct phy_berlin_priv *priv;
        struct resource *res;
-       int i = 0;
+       int ret, i = 0;
        u32 phy_id;
 
        priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
@@ -237,22 +237,27 @@ static int phy_berlin_sata_probe(struct platform_device *pdev)
                if (of_property_read_u32(child, "reg", &phy_id)) {
                        dev_err(dev, "missing reg property in node %s\n",
                                child->name);
-                       return -EINVAL;
+                       ret = -EINVAL;
+                       goto put_child;
                }
 
                if (phy_id >= ARRAY_SIZE(phy_berlin_power_down_bits)) {
                        dev_err(dev, "invalid reg in node %s\n", child->name);
-                       return -EINVAL;
+                       ret = -EINVAL;
+                       goto put_child;
                }
 
                phy_desc = devm_kzalloc(dev, sizeof(*phy_desc), GFP_KERNEL);
-               if (!phy_desc)
-                       return -ENOMEM;
+               if (!phy_desc) {
+                       ret = -ENOMEM;
+                       goto put_child;
+               }
 
                phy = devm_phy_create(dev, NULL, &phy_berlin_sata_ops);
                if (IS_ERR(phy)) {
                        dev_err(dev, "failed to create PHY %d\n", phy_id);
-                       return PTR_ERR(phy);
+                       ret = PTR_ERR(phy);
+                       goto put_child;
                }
 
                phy_desc->phy = phy;
@@ -269,6 +274,9 @@ static int phy_berlin_sata_probe(struct platform_device *pdev)
        phy_provider =
                devm_of_phy_provider_register(dev, phy_berlin_sata_phy_xlate);
        return PTR_ERR_OR_ZERO(phy_provider);
+put_child:
+       of_node_put(child);
+       return ret;
 }
 
 static const struct of_device_id phy_berlin_sata_of_match[] = {
index 8a2cb16a1937d20e88b045868beec28db966be5c..cd9dba8205668d98665d938b13a5e254b74bdb17 100644 (file)
@@ -140,7 +140,7 @@ static int brcm_sata_phy_probe(struct platform_device *pdev)
        struct brcm_sata_phy *priv;
        struct resource *res;
        struct phy_provider *provider;
-       int count = 0;
+       int ret, count = 0;
 
        if (of_get_child_count(dn) == 0)
                return -ENODEV;
@@ -163,16 +163,19 @@ static int brcm_sata_phy_probe(struct platform_device *pdev)
                if (of_property_read_u32(child, "reg", &id)) {
                        dev_err(dev, "missing reg property in node %s\n",
                                        child->name);
-                       return -EINVAL;
+                       ret = -EINVAL;
+                       goto put_child;
                }
 
                if (id >= MAX_PORTS) {
                        dev_err(dev, "invalid reg: %u\n", id);
-                       return -EINVAL;
+                       ret = -EINVAL;
+                       goto put_child;
                }
                if (priv->phys[id].phy) {
                        dev_err(dev, "already registered port %u\n", id);
-                       return -EINVAL;
+                       ret = -EINVAL;
+                       goto put_child;
                }
 
                port = &priv->phys[id];
@@ -182,7 +185,8 @@ static int brcm_sata_phy_probe(struct platform_device *pdev)
                port->ssc_en = of_property_read_bool(child, "brcm,enable-ssc");
                if (IS_ERR(port->phy)) {
                        dev_err(dev, "failed to create PHY\n");
-                       return PTR_ERR(port->phy);
+                       ret = PTR_ERR(port->phy);
+                       goto put_child;
                }
 
                phy_set_drvdata(port->phy, port);
@@ -198,6 +202,9 @@ static int brcm_sata_phy_probe(struct platform_device *pdev)
        dev_info(dev, "registered %d port(s)\n", count);
 
        return 0;
+put_child:
+       of_node_put(child);
+       return ret;
 }
 
 static struct platform_driver brcm_sata_phy_driver = {
index fc48fac003a62ba124bd7c6820f24d5d040fcbf7..8c7f27db6ad352260f8ad8675758ed365b6390a6 100644 (file)
@@ -636,8 +636,9 @@ EXPORT_SYMBOL_GPL(devm_of_phy_get);
  * @np: node containing the phy
  * @index: index of the phy
  *
- * Gets the phy using _of_phy_get(), and associates a device with it using
- * devres. On driver detach, release function is invoked on the devres data,
+ * Gets the phy using _of_phy_get(), then gets a refcount to it,
+ * and associates a device with it using devres. On driver detach,
+ * release function is invoked on the devres data,
  * then, devres data is freed.
  *
  */
@@ -651,13 +652,21 @@ struct phy *devm_of_phy_get_by_index(struct device *dev, struct device_node *np,
                return ERR_PTR(-ENOMEM);
 
        phy = _of_phy_get(np, index);
-       if (!IS_ERR(phy)) {
-               *ptr = phy;
-               devres_add(dev, ptr);
-       } else {
+       if (IS_ERR(phy)) {
                devres_free(ptr);
+               return phy;
        }
 
+       if (!try_module_get(phy->ops->owner)) {
+               devres_free(ptr);
+               return ERR_PTR(-EPROBE_DEFER);
+       }
+
+       get_device(&phy->dev);
+
+       *ptr = phy;
+       devres_add(dev, ptr);
+
        return phy;
 }
 EXPORT_SYMBOL_GPL(devm_of_phy_get_by_index);
index c47b56b4a2b8892810f00179a53e9eceba7c612c..3acd2a1808dfbf9ccfa5d58467b6defdb793c2bb 100644 (file)
@@ -1226,15 +1226,18 @@ static int miphy28lp_probe(struct platform_device *pdev)
 
                miphy_phy = devm_kzalloc(&pdev->dev, sizeof(*miphy_phy),
                                         GFP_KERNEL);
-               if (!miphy_phy)
-                       return -ENOMEM;
+               if (!miphy_phy) {
+                       ret = -ENOMEM;
+                       goto put_child;
+               }
 
                miphy_dev->phys[port] = miphy_phy;
 
                phy = devm_phy_create(&pdev->dev, child, &miphy28lp_ops);
                if (IS_ERR(phy)) {
                        dev_err(&pdev->dev, "failed to create PHY\n");
-                       return PTR_ERR(phy);
+                       ret = PTR_ERR(phy);
+                       goto put_child;
                }
 
                miphy_dev->phys[port]->phy = phy;
@@ -1242,11 +1245,11 @@ static int miphy28lp_probe(struct platform_device *pdev)
 
                ret = miphy28lp_of_probe(child, miphy_phy);
                if (ret)
-                       return ret;
+                       goto put_child;
 
                ret = miphy28lp_probe_resets(child, miphy_dev->phys[port]);
                if (ret)
-                       return ret;
+                       goto put_child;
 
                phy_set_drvdata(phy, miphy_dev->phys[port]);
                port++;
@@ -1255,6 +1258,9 @@ static int miphy28lp_probe(struct platform_device *pdev)
 
        provider = devm_of_phy_provider_register(&pdev->dev, miphy28lp_xlate);
        return PTR_ERR_OR_ZERO(provider);
+put_child:
+       of_node_put(child);
+       return ret;
 }
 
 static const struct of_device_id miphy28lp_of_match[] = {
index 00a686a073ed6ee804ea96ebcdb0ef3813482a85..e661f3b36eaa0cdf992cde8f88d92644ff585c5e 100644 (file)
@@ -566,22 +566,25 @@ static int miphy365x_probe(struct platform_device *pdev)
 
                miphy_phy = devm_kzalloc(&pdev->dev, sizeof(*miphy_phy),
                                         GFP_KERNEL);
-               if (!miphy_phy)
-                       return -ENOMEM;
+               if (!miphy_phy) {
+                       ret = -ENOMEM;
+                       goto put_child;
+               }
 
                miphy_dev->phys[port] = miphy_phy;
 
                phy = devm_phy_create(&pdev->dev, child, &miphy365x_ops);
                if (IS_ERR(phy)) {
                        dev_err(&pdev->dev, "failed to create PHY\n");
-                       return PTR_ERR(phy);
+                       ret = PTR_ERR(phy);
+                       goto put_child;
                }
 
                miphy_dev->phys[port]->phy = phy;
 
                ret = miphy365x_of_probe(child, miphy_phy);
                if (ret)
-                       return ret;
+                       goto put_child;
 
                phy_set_drvdata(phy, miphy_dev->phys[port]);
 
@@ -591,12 +594,15 @@ static int miphy365x_probe(struct platform_device *pdev)
                                        &miphy_phy->ctrlreg);
                if (ret) {
                        dev_err(&pdev->dev, "No sysconfig offset found\n");
-                       return ret;
+                       goto put_child;
                }
        }
 
        provider = devm_of_phy_provider_register(&pdev->dev, miphy365x_xlate);
        return PTR_ERR_OR_ZERO(provider);
+put_child:
+       of_node_put(child);
+       return ret;
 }
 
 static const struct of_device_id miphy365x_of_match[] = {
index f30b28bd41fe7b11a8cce95e889ae894fef20518..e427c3b788ff35e23a49808116936f0d5f39ffa4 100644 (file)
@@ -415,7 +415,7 @@ static int mt65xx_u3phy_probe(struct platform_device *pdev)
        struct resource *sif_res;
        struct mt65xx_u3phy *u3phy;
        struct resource res;
-       int port;
+       int port, retval;
 
        u3phy = devm_kzalloc(dev, sizeof(*u3phy), GFP_KERNEL);
        if (!u3phy)
@@ -447,31 +447,34 @@ static int mt65xx_u3phy_probe(struct platform_device *pdev)
        for_each_child_of_node(np, child_np) {
                struct mt65xx_phy_instance *instance;
                struct phy *phy;
-               int retval;
 
                instance = devm_kzalloc(dev, sizeof(*instance), GFP_KERNEL);
-               if (!instance)
-                       return -ENOMEM;
+               if (!instance) {
+                       retval = -ENOMEM;
+                       goto put_child;
+               }
 
                u3phy->phys[port] = instance;
 
                phy = devm_phy_create(dev, child_np, &mt65xx_u3phy_ops);
                if (IS_ERR(phy)) {
                        dev_err(dev, "failed to create phy\n");
-                       return PTR_ERR(phy);
+                       retval = PTR_ERR(phy);
+                       goto put_child;
                }
 
                retval = of_address_to_resource(child_np, 0, &res);
                if (retval) {
                        dev_err(dev, "failed to get address resource(id-%d)\n",
                                port);
-                       return retval;
+                       goto put_child;
                }
 
                instance->port_base = devm_ioremap_resource(&phy->dev, &res);
                if (IS_ERR(instance->port_base)) {
                        dev_err(dev, "failed to remap phy regs\n");
-                       return PTR_ERR(instance->port_base);
+                       retval = PTR_ERR(instance->port_base);
+                       goto put_child;
                }
 
                instance->phy = phy;
@@ -483,6 +486,9 @@ static int mt65xx_u3phy_probe(struct platform_device *pdev)
        provider = devm_of_phy_provider_register(dev, mt65xx_phy_xlate);
 
        return PTR_ERR_OR_ZERO(provider);
+put_child:
+       of_node_put(child_np);
+       return retval;
 }
 
 static const struct of_device_id mt65xx_u3phy_id_table[] = {
index 91d6f342c56596fc2e3fcff18213dba004546c3e..62c43c435194313e7d5ea7049d568cb673857da9 100644 (file)
@@ -108,13 +108,16 @@ static int rockchip_usb_phy_probe(struct platform_device *pdev)
 
        for_each_available_child_of_node(dev->of_node, child) {
                rk_phy = devm_kzalloc(dev, sizeof(*rk_phy), GFP_KERNEL);
-               if (!rk_phy)
-                       return -ENOMEM;
+               if (!rk_phy) {
+                       err = -ENOMEM;
+                       goto put_child;
+               }
 
                if (of_property_read_u32(child, "reg", &reg_offset)) {
                        dev_err(dev, "missing reg property in node %s\n",
                                child->name);
-                       return -EINVAL;
+                       err = -EINVAL;
+                       goto put_child;
                }
 
                rk_phy->reg_offset = reg_offset;
@@ -127,18 +130,22 @@ static int rockchip_usb_phy_probe(struct platform_device *pdev)
                rk_phy->phy = devm_phy_create(dev, child, &ops);
                if (IS_ERR(rk_phy->phy)) {
                        dev_err(dev, "failed to create PHY\n");
-                       return PTR_ERR(rk_phy->phy);
+                       err = PTR_ERR(rk_phy->phy);
+                       goto put_child;
                }
                phy_set_drvdata(rk_phy->phy, rk_phy);
 
                /* only power up usb phy when it use, so disable it when init*/
                err = rockchip_usb_phy_power(rk_phy, 1);
                if (err)
-                       return err;
+                       goto put_child;
        }
 
        phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
        return PTR_ERR_OR_ZERO(phy_provider);
+put_child:
+       of_node_put(child);
+       return err;
 }
 
 static const struct of_device_id rockchip_usb_phy_dt_ids[] = {
index a1ea565fcd46490e58d48e4363318c2ce6970ebc..2e6ca69635aa001531d2b9aca128d001b97d9aca 100644 (file)
@@ -342,12 +342,6 @@ static int bcm2835_gpio_get(struct gpio_chip *chip, unsigned offset)
        return bcm2835_gpio_get_bit(pc, GPLEV0, offset);
 }
 
-static int bcm2835_gpio_direction_output(struct gpio_chip *chip,
-               unsigned offset, int value)
-{
-       return pinctrl_gpio_direction_output(chip->base + offset);
-}
-
 static void bcm2835_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
 {
        struct bcm2835_pinctrl *pc = dev_get_drvdata(chip->dev);
@@ -355,6 +349,13 @@ static void bcm2835_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
        bcm2835_gpio_set_bit(pc, value ? GPSET0 : GPCLR0, offset);
 }
 
+static int bcm2835_gpio_direction_output(struct gpio_chip *chip,
+               unsigned offset, int value)
+{
+       bcm2835_gpio_set(chip, offset, value);
+       return pinctrl_gpio_direction_output(chip->base + offset);
+}
+
 static int bcm2835_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
 {
        struct bcm2835_pinctrl *pc = dev_get_drvdata(chip->dev);
index 37a037543d299115a09e6a4106f1592acc9566a9..587d1ff6210efb62341b792d0318b412c0a4d046 100644 (file)
@@ -299,7 +299,7 @@ static const struct pinctrl_pin_desc vf610_pinctrl_pads[] = {
 static struct imx_pinctrl_soc_info vf610_pinctrl_info = {
        .pins = vf610_pinctrl_pads,
        .npins = ARRAY_SIZE(vf610_pinctrl_pads),
-       .flags = SHARE_MUX_CONF_REG,
+       .flags = SHARE_MUX_CONF_REG | ZERO_OFFSET_VALID,
 };
 
 static const struct of_device_id vf610_pinctrl_of_match[] = {
index e42d5d4183f57ff0dc0d942254f5925dabd3c07a..5979d38c46b254965e8a7782de9a6c902894ce9a 100644 (file)
@@ -28,6 +28,7 @@
                .padcfglock_offset = BXT_PADCFGLOCK,    \
                .hostown_offset = BXT_HOSTSW_OWN,       \
                .ie_offset = BXT_GPI_IE,                \
+               .gpp_size = 32,                         \
                .pin_base = (s),                        \
                .npins = ((e) - (s) + 1),               \
        }
index 392e28d3f48d0bee1a4087154e904c7dfdc0faa7..26f6b6ffea5b23fac04224d9772996db12bc6176 100644 (file)
@@ -25,9 +25,6 @@
 
 #include "pinctrl-intel.h"
 
-/* Maximum number of pads in each group */
-#define NPADS_IN_GPP                   24
-
 /* Offset from regs */
 #define PADBAR                         0x00c
 #define GPI_IS                         0x100
@@ -37,6 +34,7 @@
 #define PADOWN_BITS                    4
 #define PADOWN_SHIFT(p)                        ((p) % 8 * PADOWN_BITS)
 #define PADOWN_MASK(p)                 (0xf << PADOWN_SHIFT(p))
+#define PADOWN_GPP(p)                  ((p) / 8)
 
 /* Offset from pad_regs */
 #define PADCFG0                                0x000
@@ -142,7 +140,7 @@ static void __iomem *intel_get_padcfg(struct intel_pinctrl *pctrl, unsigned pin,
 static bool intel_pad_owned_by_host(struct intel_pinctrl *pctrl, unsigned pin)
 {
        const struct intel_community *community;
-       unsigned padno, gpp, gpp_offset, offset;
+       unsigned padno, gpp, offset, group;
        void __iomem *padown;
 
        community = intel_get_community(pctrl, pin);
@@ -152,9 +150,9 @@ static bool intel_pad_owned_by_host(struct intel_pinctrl *pctrl, unsigned pin)
                return true;
 
        padno = pin_to_padno(community, pin);
-       gpp = padno / NPADS_IN_GPP;
-       gpp_offset = padno % NPADS_IN_GPP;
-       offset = community->padown_offset + gpp * 16 + (gpp_offset / 8) * 4;
+       group = padno / community->gpp_size;
+       gpp = PADOWN_GPP(padno % community->gpp_size);
+       offset = community->padown_offset + 0x10 * group + gpp * 4;
        padown = community->regs + offset;
 
        return !(readl(padown) & PADOWN_MASK(padno));
@@ -173,11 +171,11 @@ static bool intel_pad_acpi_mode(struct intel_pinctrl *pctrl, unsigned pin)
                return false;
 
        padno = pin_to_padno(community, pin);
-       gpp = padno / NPADS_IN_GPP;
+       gpp = padno / community->gpp_size;
        offset = community->hostown_offset + gpp * 4;
        hostown = community->regs + offset;
 
-       return !(readl(hostown) & BIT(padno % NPADS_IN_GPP));
+       return !(readl(hostown) & BIT(padno % community->gpp_size));
 }
 
 static bool intel_pad_locked(struct intel_pinctrl *pctrl, unsigned pin)
@@ -193,7 +191,7 @@ static bool intel_pad_locked(struct intel_pinctrl *pctrl, unsigned pin)
                return false;
 
        padno = pin_to_padno(community, pin);
-       gpp = padno / NPADS_IN_GPP;
+       gpp = padno / community->gpp_size;
 
        /*
         * If PADCFGLOCK and PADCFGLOCKTX bits are both clear for this pad,
@@ -202,12 +200,12 @@ static bool intel_pad_locked(struct intel_pinctrl *pctrl, unsigned pin)
         */
        offset = community->padcfglock_offset + gpp * 8;
        value = readl(community->regs + offset);
-       if (value & BIT(pin % NPADS_IN_GPP))
+       if (value & BIT(pin % community->gpp_size))
                return true;
 
        offset = community->padcfglock_offset + 4 + gpp * 8;
        value = readl(community->regs + offset);
-       if (value & BIT(pin % NPADS_IN_GPP))
+       if (value & BIT(pin % community->gpp_size))
                return true;
 
        return false;
@@ -663,8 +661,8 @@ static void intel_gpio_irq_ack(struct irq_data *d)
        community = intel_get_community(pctrl, pin);
        if (community) {
                unsigned padno = pin_to_padno(community, pin);
-               unsigned gpp_offset = padno % NPADS_IN_GPP;
-               unsigned gpp = padno / NPADS_IN_GPP;
+               unsigned gpp_offset = padno % community->gpp_size;
+               unsigned gpp = padno / community->gpp_size;
 
                writel(BIT(gpp_offset), community->regs + GPI_IS + gpp * 4);
        }
@@ -685,8 +683,8 @@ static void intel_gpio_irq_mask_unmask(struct irq_data *d, bool mask)
        community = intel_get_community(pctrl, pin);
        if (community) {
                unsigned padno = pin_to_padno(community, pin);
-               unsigned gpp_offset = padno % NPADS_IN_GPP;
-               unsigned gpp = padno / NPADS_IN_GPP;
+               unsigned gpp_offset = padno % community->gpp_size;
+               unsigned gpp = padno / community->gpp_size;
                void __iomem *reg;
                u32 value;
 
@@ -780,8 +778,8 @@ static int intel_gpio_irq_wake(struct irq_data *d, unsigned int on)
                return -EINVAL;
 
        padno = pin_to_padno(community, pin);
-       gpp = padno / NPADS_IN_GPP;
-       gpp_offset = padno % NPADS_IN_GPP;
+       gpp = padno / community->gpp_size;
+       gpp_offset = padno % community->gpp_size;
 
        /* Clear the existing wake status */
        writel(BIT(gpp_offset), community->regs + GPI_GPE_STS + gpp * 4);
@@ -819,14 +817,14 @@ static irqreturn_t intel_gpio_community_irq_handler(struct intel_pinctrl *pctrl,
                /* Only interrupts that are enabled */
                pending &= enabled;
 
-               for_each_set_bit(gpp_offset, &pending, NPADS_IN_GPP) {
+               for_each_set_bit(gpp_offset, &pending, community->gpp_size) {
                        unsigned padno, irq;
 
                        /*
                         * The last group in community can have less pins
                         * than NPADS_IN_GPP.
                         */
-                       padno = gpp_offset + gpp * NPADS_IN_GPP;
+                       padno = gpp_offset + gpp * community->gpp_size;
                        if (padno >= community->npins)
                                break;
 
@@ -1002,7 +1000,8 @@ int intel_pinctrl_probe(struct platform_device *pdev,
 
                community->regs = regs;
                community->pad_regs = regs + padbar;
-               community->ngpps = DIV_ROUND_UP(community->npins, NPADS_IN_GPP);
+               community->ngpps = DIV_ROUND_UP(community->npins,
+                                               community->gpp_size);
        }
 
        irq = platform_get_irq(pdev, 0);
index 4ec8b572a288fbc337f5b40affdfbd012634a028..b60215793017bb95b42d39692020aa2f4c41ac0d 100644 (file)
@@ -55,6 +55,8 @@ struct intel_function {
  *                  ACPI).
  * @ie_offset: Register offset of GPI_IE from @regs.
  * @pin_base: Starting pin of pins in this community
+ * @gpp_size: Maximum number of pads in each group, such as PADCFGLOCK,
+ *            HOSTSW_OWN,  GPI_IS, GPI_IE, etc.
  * @npins: Number of pins in this community
  * @regs: Community specific common registers (reserved for core driver)
  * @pad_regs: Community specific pad registers (reserved for core driver)
@@ -68,6 +70,7 @@ struct intel_community {
        unsigned hostown_offset;
        unsigned ie_offset;
        unsigned pin_base;
+       unsigned gpp_size;
        size_t npins;
        void __iomem *regs;
        void __iomem *pad_regs;
index 1de9ae5010db285b53c01d7e67dec2bde7ce5233..c725a5313b4e692df92630535237e4b8374658a7 100644 (file)
@@ -30,6 +30,7 @@
                .padcfglock_offset = SPT_PADCFGLOCK,    \
                .hostown_offset = SPT_HOSTSW_OWN,       \
                .ie_offset = SPT_GPI_IE,                \
+               .gpp_size = 24,                         \
                .pin_base = (s),                        \
                .npins = ((e) - (s) + 1),               \
        }
index cc97f0869791d371c85f7e21c0ca04e1e595ac23..48747c28a43d4ac2fc1bed10f29cd1224ddd10f0 100644 (file)
@@ -1341,10 +1341,13 @@ static int rapl_detect_domains(struct rapl_package *rp, int cpu)
 
        for (rd = rp->domains; rd < rp->domains + rp->nr_domains; rd++) {
                /* check if the domain is locked by BIOS */
-               if (rapl_read_data_raw(rd, FW_LOCK, false, &locked)) {
+               ret = rapl_read_data_raw(rd, FW_LOCK, false, &locked);
+               if (ret)
+                       return ret;
+               if (locked) {
                        pr_info("RAPL package %d domain %s locked by BIOS\n",
                                rp->id, rd->name);
-                               rd->state |= DOMAIN_STATE_BIOS_LOCKED;
+                       rd->state |= DOMAIN_STATE_BIOS_LOCKED;
                }
        }
 
index 284b587da65c5fb20f6e96b8c843e52c0b420415..d6c853bbfa9fcbe0fee8968dda872041c6c8545a 100644 (file)
@@ -483,24 +483,23 @@ static int da9063_rtc_probe(struct platform_device *pdev)
 
        platform_set_drvdata(pdev, rtc);
 
+       rtc->rtc_dev = devm_rtc_device_register(&pdev->dev, DA9063_DRVNAME_RTC,
+                                          &da9063_rtc_ops, THIS_MODULE);
+       if (IS_ERR(rtc->rtc_dev))
+               return PTR_ERR(rtc->rtc_dev);
+
+       da9063_data_to_tm(data, &rtc->alarm_time, rtc);
+       rtc->rtc_sync = false;
+
        irq_alarm = platform_get_irq_byname(pdev, "ALARM");
        ret = devm_request_threaded_irq(&pdev->dev, irq_alarm, NULL,
                                        da9063_alarm_event,
                                        IRQF_TRIGGER_LOW | IRQF_ONESHOT,
                                        "ALARM", rtc);
-       if (ret) {
+       if (ret)
                dev_err(&pdev->dev, "Failed to request ALARM IRQ %d: %d\n",
                        irq_alarm, ret);
-               return ret;
-       }
-
-       rtc->rtc_dev = devm_rtc_device_register(&pdev->dev, DA9063_DRVNAME_RTC,
-                                          &da9063_rtc_ops, THIS_MODULE);
-       if (IS_ERR(rtc->rtc_dev))
-               return PTR_ERR(rtc->rtc_dev);
 
-       da9063_data_to_tm(data, &rtc->alarm_time, rtc);
-       rtc->rtc_sync = false;
        return ret;
 }
 
index 91ca0bc1b484b4af1120b3e1701a931a4e1ff6fc..35c9aada07c8ef3a19f44cf8d4a3e8811f484e3f 100644 (file)
@@ -56,6 +56,42 @@ struct rk808_rtc {
        int irq;
 };
 
+/*
+ * The Rockchip calendar used by the RK808 counts November with 31 days. We use
+ * these translation functions to convert its dates to/from the Gregorian
+ * calendar used by the rest of the world. We arbitrarily define Jan 1st, 2016
+ * as the day when both calendars were in sync, and treat all other dates
+ * relative to that.
+ * NOTE: Other system software (e.g. firmware) that reads the same hardware must
+ * implement this exact same conversion algorithm, with the same anchor date.
+ */
+static time64_t nov2dec_transitions(struct rtc_time *tm)
+{
+       return (tm->tm_year + 1900) - 2016 + (tm->tm_mon + 1 > 11 ? 1 : 0);
+}
+
+static void rockchip_to_gregorian(struct rtc_time *tm)
+{
+       /* If it's Nov 31st, rtc_tm_to_time64() will count that like Dec 1st */
+       time64_t time = rtc_tm_to_time64(tm);
+       rtc_time64_to_tm(time + nov2dec_transitions(tm) * 86400, tm);
+}
+
+static void gregorian_to_rockchip(struct rtc_time *tm)
+{
+       time64_t extra_days = nov2dec_transitions(tm);
+       time64_t time = rtc_tm_to_time64(tm);
+       rtc_time64_to_tm(time - extra_days * 86400, tm);
+
+       /* Compensate if we went back over Nov 31st (will work up to 2381) */
+       if (nov2dec_transitions(tm) < extra_days) {
+               if (tm->tm_mon + 1 == 11)
+                       tm->tm_mday++;  /* This may result in 31! */
+               else
+                       rtc_time64_to_tm(time - (extra_days - 1) * 86400, tm);
+       }
+}
+
 /* Read current time and date in RTC */
 static int rk808_rtc_readtime(struct device *dev, struct rtc_time *tm)
 {
@@ -101,9 +137,10 @@ static int rk808_rtc_readtime(struct device *dev, struct rtc_time *tm)
        tm->tm_mon = (bcd2bin(rtc_data[4] & MONTHS_REG_MSK)) - 1;
        tm->tm_year = (bcd2bin(rtc_data[5] & YEARS_REG_MSK)) + 100;
        tm->tm_wday = bcd2bin(rtc_data[6] & WEEKS_REG_MSK);
+       rockchip_to_gregorian(tm);
        dev_dbg(dev, "RTC date/time %4d-%02d-%02d(%d) %02d:%02d:%02d\n",
                1900 + tm->tm_year, tm->tm_mon + 1, tm->tm_mday,
-               tm->tm_wday, tm->tm_hour , tm->tm_min, tm->tm_sec);
+               tm->tm_wday, tm->tm_hour, tm->tm_min, tm->tm_sec);
 
        return ret;
 }
@@ -116,6 +153,10 @@ static int rk808_rtc_set_time(struct device *dev, struct rtc_time *tm)
        u8 rtc_data[NUM_TIME_REGS];
        int ret;
 
+       dev_dbg(dev, "set RTC date/time %4d-%02d-%02d(%d) %02d:%02d:%02d\n",
+               1900 + tm->tm_year, tm->tm_mon + 1, tm->tm_mday,
+               tm->tm_wday, tm->tm_hour, tm->tm_min, tm->tm_sec);
+       gregorian_to_rockchip(tm);
        rtc_data[0] = bin2bcd(tm->tm_sec);
        rtc_data[1] = bin2bcd(tm->tm_min);
        rtc_data[2] = bin2bcd(tm->tm_hour);
@@ -123,9 +164,6 @@ static int rk808_rtc_set_time(struct device *dev, struct rtc_time *tm)
        rtc_data[4] = bin2bcd(tm->tm_mon + 1);
        rtc_data[5] = bin2bcd(tm->tm_year - 100);
        rtc_data[6] = bin2bcd(tm->tm_wday);
-       dev_dbg(dev, "set RTC date/time %4d-%02d-%02d(%d) %02d:%02d:%02d\n",
-               1900 + tm->tm_year, tm->tm_mon + 1, tm->tm_mday,
-               tm->tm_wday, tm->tm_hour , tm->tm_min, tm->tm_sec);
 
        /* Stop RTC while updating the RTC registers */
        ret = regmap_update_bits(rk808->regmap, RK808_RTC_CTRL_REG,
@@ -170,6 +208,7 @@ static int rk808_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm)
        alrm->time.tm_mday = bcd2bin(alrm_data[3] & DAYS_REG_MSK);
        alrm->time.tm_mon = (bcd2bin(alrm_data[4] & MONTHS_REG_MSK)) - 1;
        alrm->time.tm_year = (bcd2bin(alrm_data[5] & YEARS_REG_MSK)) + 100;
+       rockchip_to_gregorian(&alrm->time);
 
        ret = regmap_read(rk808->regmap, RK808_RTC_INT_REG, &int_reg);
        if (ret) {
@@ -227,6 +266,7 @@ static int rk808_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
                alrm->time.tm_mday, alrm->time.tm_wday, alrm->time.tm_hour,
                alrm->time.tm_min, alrm->time.tm_sec);
 
+       gregorian_to_rockchip(&alrm->time);
        alrm_data[0] = bin2bcd(alrm->time.tm_sec);
        alrm_data[1] = bin2bcd(alrm->time.tm_min);
        alrm_data[2] = bin2bcd(alrm->time.tm_hour);
index 61f768518a34b0e963cd6b569610045a3f65188b..24ec282e15d8ae436e7dab130a4696708e34be9e 100644 (file)
@@ -599,8 +599,10 @@ static enum ap_wait ap_sm_read(struct ap_device *ap_dev)
        status = ap_sm_recv(ap_dev);
        switch (status.response_code) {
        case AP_RESPONSE_NORMAL:
-               if (ap_dev->queue_count > 0)
+               if (ap_dev->queue_count > 0) {
+                       ap_dev->state = AP_STATE_WORKING;
                        return AP_WAIT_AGAIN;
+               }
                ap_dev->state = AP_STATE_IDLE;
                return AP_WAIT_NONE;
        case AP_RESPONSE_NO_PENDING_REPLY:
index b2a1a81e6fc8f048c202b7eca54b2b0b6c22b368..1b831598df7c6544057f23ef69da5ea54bbafcdd 100644 (file)
@@ -984,6 +984,36 @@ static struct virtqueue *virtio_ccw_vq_by_ind(struct virtio_ccw_device *vcdev,
        return vq;
 }
 
+static void virtio_ccw_check_activity(struct virtio_ccw_device *vcdev,
+                                     __u32 activity)
+{
+       if (vcdev->curr_io & activity) {
+               switch (activity) {
+               case VIRTIO_CCW_DOING_READ_FEAT:
+               case VIRTIO_CCW_DOING_WRITE_FEAT:
+               case VIRTIO_CCW_DOING_READ_CONFIG:
+               case VIRTIO_CCW_DOING_WRITE_CONFIG:
+               case VIRTIO_CCW_DOING_WRITE_STATUS:
+               case VIRTIO_CCW_DOING_SET_VQ:
+               case VIRTIO_CCW_DOING_SET_IND:
+               case VIRTIO_CCW_DOING_SET_CONF_IND:
+               case VIRTIO_CCW_DOING_RESET:
+               case VIRTIO_CCW_DOING_READ_VQ_CONF:
+               case VIRTIO_CCW_DOING_SET_IND_ADAPTER:
+               case VIRTIO_CCW_DOING_SET_VIRTIO_REV:
+                       vcdev->curr_io &= ~activity;
+                       wake_up(&vcdev->wait_q);
+                       break;
+               default:
+                       /* don't know what to do... */
+                       dev_warn(&vcdev->cdev->dev,
+                                "Suspicious activity '%08x'\n", activity);
+                       WARN_ON(1);
+                       break;
+               }
+       }
+}
+
 static void virtio_ccw_int_handler(struct ccw_device *cdev,
                                   unsigned long intparm,
                                   struct irb *irb)
@@ -995,6 +1025,12 @@ static void virtio_ccw_int_handler(struct ccw_device *cdev,
 
        if (!vcdev)
                return;
+       if (IS_ERR(irb)) {
+               vcdev->err = PTR_ERR(irb);
+               virtio_ccw_check_activity(vcdev, activity);
+               /* Don't poke around indicators, something's wrong. */
+               return;
+       }
        /* Check if it's a notification from the host. */
        if ((intparm == 0) &&
            (scsw_stctl(&irb->scsw) ==
@@ -1010,31 +1046,7 @@ static void virtio_ccw_int_handler(struct ccw_device *cdev,
                        /* Map everything else to -EIO. */
                        vcdev->err = -EIO;
        }
-       if (vcdev->curr_io & activity) {
-               switch (activity) {
-               case VIRTIO_CCW_DOING_READ_FEAT:
-               case VIRTIO_CCW_DOING_WRITE_FEAT:
-               case VIRTIO_CCW_DOING_READ_CONFIG:
-               case VIRTIO_CCW_DOING_WRITE_CONFIG:
-               case VIRTIO_CCW_DOING_WRITE_STATUS:
-               case VIRTIO_CCW_DOING_SET_VQ:
-               case VIRTIO_CCW_DOING_SET_IND:
-               case VIRTIO_CCW_DOING_SET_CONF_IND:
-               case VIRTIO_CCW_DOING_RESET:
-               case VIRTIO_CCW_DOING_READ_VQ_CONF:
-               case VIRTIO_CCW_DOING_SET_IND_ADAPTER:
-               case VIRTIO_CCW_DOING_SET_VIRTIO_REV:
-                       vcdev->curr_io &= ~activity;
-                       wake_up(&vcdev->wait_q);
-                       break;
-               default:
-                       /* don't know what to do... */
-                       dev_warn(&cdev->dev, "Suspicious activity '%08x'\n",
-                                activity);
-                       WARN_ON(1);
-                       break;
-               }
-       }
+       virtio_ccw_check_activity(vcdev, activity);
        for_each_set_bit(i, &vcdev->indicators,
                         sizeof(vcdev->indicators) * BITS_PER_BYTE) {
                /* The bit clear must happen before the vring kick. */
index e4b7998379485454d26e39f6a5a91917a155ffbb..459abe1dcc87a6dfc1beca5672dc3d59d88bdbd2 100644 (file)
@@ -219,13 +219,13 @@ static int sdev_runtime_suspend(struct device *dev)
        struct scsi_device *sdev = to_scsi_device(dev);
        int err = 0;
 
-       if (pm && pm->runtime_suspend) {
-               err = blk_pre_runtime_suspend(sdev->request_queue);
-               if (err)
-                       return err;
+       err = blk_pre_runtime_suspend(sdev->request_queue);
+       if (err)
+               return err;
+       if (pm && pm->runtime_suspend)
                err = pm->runtime_suspend(dev);
-               blk_post_runtime_suspend(sdev->request_queue, err);
-       }
+       blk_post_runtime_suspend(sdev->request_queue, err);
+
        return err;
 }
 
@@ -248,11 +248,11 @@ static int sdev_runtime_resume(struct device *dev)
        const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
        int err = 0;
 
-       if (pm && pm->runtime_resume) {
-               blk_pre_runtime_resume(sdev->request_queue);
+       blk_pre_runtime_resume(sdev->request_queue);
+       if (pm && pm->runtime_resume)
                err = pm->runtime_resume(dev);
-               blk_post_runtime_resume(sdev->request_queue, err);
-       }
+       blk_post_runtime_resume(sdev->request_queue, err);
+
        return err;
 }
 
index dcb0d76d7312847d37809df1f5763206567d5daf..044d06410d4c86c0dc88071bb0de668dd91bb0e2 100644 (file)
@@ -84,6 +84,7 @@ static void init_device_slot_control(unsigned char *dest_desc,
 static int ses_recv_diag(struct scsi_device *sdev, int page_code,
                         void *buf, int bufflen)
 {
+       int ret;
        unsigned char cmd[] = {
                RECEIVE_DIAGNOSTIC,
                1,              /* Set PCV bit */
@@ -92,9 +93,26 @@ static int ses_recv_diag(struct scsi_device *sdev, int page_code,
                bufflen & 0xff,
                0
        };
+       unsigned char recv_page_code;
 
-       return scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buf, bufflen,
+       ret =  scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buf, bufflen,
                                NULL, SES_TIMEOUT, SES_RETRIES, NULL);
+       if (unlikely(!ret))
+               return ret;
+
+       recv_page_code = ((unsigned char *)buf)[0];
+
+       if (likely(recv_page_code == page_code))
+               return ret;
+
+       /* successful diagnostic but wrong page code.  This happens to some
+        * USB devices, just print a message and pretend there was an error */
+
+       sdev_printk(KERN_ERR, sdev,
+                   "Wrong diagnostic page; asked for %d got %u\n",
+                   page_code, recv_page_code);
+
+       return -EINVAL;
 }
 
 static int ses_send_diag(struct scsi_device *sdev, int page_code,
@@ -541,7 +559,15 @@ static void ses_enclosure_data_process(struct enclosure_device *edev,
                        if (desc_ptr)
                                desc_ptr += len;
 
-                       if (addl_desc_ptr)
+                       if (addl_desc_ptr &&
+                           /* only find additional descriptions for specific devices */
+                           (type_ptr[0] == ENCLOSURE_COMPONENT_DEVICE ||
+                            type_ptr[0] == ENCLOSURE_COMPONENT_ARRAY_DEVICE ||
+                            type_ptr[0] == ENCLOSURE_COMPONENT_SAS_EXPANDER ||
+                            /* these elements are optional */
+                            type_ptr[0] == ENCLOSURE_COMPONENT_SCSI_TARGET_PORT ||
+                            type_ptr[0] == ENCLOSURE_COMPONENT_SCSI_INITIATOR_PORT ||
+                            type_ptr[0] == ENCLOSURE_COMPONENT_CONTROLLER_ELECTRONICS))
                                addl_desc_ptr += addl_desc_ptr[1] + 2;
 
                }
index 59a11437db7090f9c8464f8ca0584c789be2e997..39412c9097c6a240466c51c941ec890a4612542e 100644 (file)
@@ -167,7 +167,7 @@ static inline int is_double_byte_mode(struct fsl_dspi *dspi)
 {
        unsigned int val;
 
-       regmap_read(dspi->regmap, SPI_CTAR(dspi->cs), &val);
+       regmap_read(dspi->regmap, SPI_CTAR(0), &val);
 
        return ((val & SPI_FRAME_BITS_MASK) == SPI_FRAME_BITS(8)) ? 0 : 1;
 }
@@ -257,7 +257,7 @@ static u32 dspi_data_to_pushr(struct fsl_dspi *dspi, int tx_word)
 
        return  SPI_PUSHR_TXDATA(d16) |
                SPI_PUSHR_PCS(dspi->cs) |
-               SPI_PUSHR_CTAS(dspi->cs) |
+               SPI_PUSHR_CTAS(0) |
                SPI_PUSHR_CONT;
 }
 
@@ -290,7 +290,7 @@ static int dspi_eoq_write(struct fsl_dspi *dspi)
                 */
                if (tx_word && (dspi->len == 1)) {
                        dspi->dataflags |= TRAN_STATE_WORD_ODD_NUM;
-                       regmap_update_bits(dspi->regmap, SPI_CTAR(dspi->cs),
+                       regmap_update_bits(dspi->regmap, SPI_CTAR(0),
                                        SPI_FRAME_BITS_MASK, SPI_FRAME_BITS(8));
                        tx_word = 0;
                }
@@ -339,7 +339,7 @@ static int dspi_tcfq_write(struct fsl_dspi *dspi)
 
        if (tx_word && (dspi->len == 1)) {
                dspi->dataflags |= TRAN_STATE_WORD_ODD_NUM;
-               regmap_update_bits(dspi->regmap, SPI_CTAR(dspi->cs),
+               regmap_update_bits(dspi->regmap, SPI_CTAR(0),
                                SPI_FRAME_BITS_MASK, SPI_FRAME_BITS(8));
                tx_word = 0;
        }
@@ -407,7 +407,7 @@ static int dspi_transfer_one_message(struct spi_master *master,
                regmap_update_bits(dspi->regmap, SPI_MCR,
                                SPI_MCR_CLR_TXF | SPI_MCR_CLR_RXF,
                                SPI_MCR_CLR_TXF | SPI_MCR_CLR_RXF);
-               regmap_write(dspi->regmap, SPI_CTAR(dspi->cs),
+               regmap_write(dspi->regmap, SPI_CTAR(0),
                                dspi->cur_chip->ctar_val);
 
                trans_mode = dspi->devtype_data->trans_mode;
@@ -566,7 +566,7 @@ static irqreturn_t dspi_interrupt(int irq, void *dev_id)
                if (!dspi->len) {
                        if (dspi->dataflags & TRAN_STATE_WORD_ODD_NUM) {
                                regmap_update_bits(dspi->regmap,
-                                                  SPI_CTAR(dspi->cs),
+                                                  SPI_CTAR(0),
                                                   SPI_FRAME_BITS_MASK,
                                                   SPI_FRAME_BITS(16));
                                dspi->dataflags &= ~TRAN_STATE_WORD_ODD_NUM;
index 2b0a8ec3affb87333f8bdb2e9a2d9ad95855d4c1..dee1cb87d24f4aaca1fd3d2e43b8101d3bf6e246 100644 (file)
@@ -1705,7 +1705,7 @@ struct spi_master *spi_alloc_master(struct device *dev, unsigned size)
        master->bus_num = -1;
        master->num_chipselect = 1;
        master->dev.class = &spi_master_class;
-       master->dev.parent = get_device(dev);
+       master->dev.parent = dev;
        spi_master_set_devdata(master, &master[1]);
 
        return master;
index 91a0fcd72423080900c6c733f6aeb7e800a85538..d0e7dfc647cf21a729696cbe499f7fc6dbf53b02 100644 (file)
@@ -651,11 +651,11 @@ static int spidev_release(struct inode *inode, struct file *filp)
                kfree(spidev->rx_buffer);
                spidev->rx_buffer = NULL;
 
+               spin_lock_irq(&spidev->spi_lock);
                if (spidev->spi)
                        spidev->speed_hz = spidev->spi->max_speed_hz;
 
                /* ... after we unbound from the underlying device? */
-               spin_lock_irq(&spidev->spi_lock);
                dofree = (spidev->spi == NULL);
                spin_unlock_irq(&spidev->spi_lock);
 
index 195c41d7bd53b3b6926507cdfea2a8de42d45578..0813163f962f09e328d6fc448238201f84cc55cd 100644 (file)
@@ -81,7 +81,7 @@ static int ion_chunk_heap_allocate(struct ion_heap *heap,
 err:
        sg = table->sgl;
        for (i -= 1; i >= 0; i--) {
-               gen_pool_free(chunk_heap->pool, sg_phys(sg) & PAGE_MASK,
+               gen_pool_free(chunk_heap->pool, page_to_phys(sg_page(sg)),
                              sg->length);
                sg = sg_next(sg);
        }
@@ -109,7 +109,7 @@ static void ion_chunk_heap_free(struct ion_buffer *buffer)
                                                        DMA_BIDIRECTIONAL);
 
        for_each_sg(table->sgl, sg, table->nents, i) {
-               gen_pool_free(chunk_heap->pool, sg_phys(sg) & PAGE_MASK,
+               gen_pool_free(chunk_heap->pool, page_to_phys(sg_page(sg)),
                              sg->length);
        }
        chunk_heap->allocated -= allocated_size;
index bfbf1c56bd22630e19ac739eadd514157071ab2b..6eb600ff70569ef6ceb902afcc49ddce08b09953 100644 (file)
@@ -159,7 +159,7 @@ static irqreturn_t iio_simple_dummy_get_timestamp(int irq, void *private)
        struct iio_dummy_state *st = iio_priv(indio_dev);
 
        st->event_timestamp = iio_get_time_ns();
-       return IRQ_HANDLED;
+       return IRQ_WAKE_THREAD;
 }
 
 /**
index f61ef669644cdadfc10c54539c5743c012082d09..a4a9a763ff023821644197fca610e7783d773129 100644 (file)
@@ -1270,6 +1270,7 @@ static int
 echo_copyout_lsm(struct lov_stripe_md *lsm, void *_ulsm, int ulsm_nob)
 {
        struct lov_stripe_md *ulsm = _ulsm;
+       struct lov_oinfo **p;
        int nob, i;
 
        nob = offsetof(struct lov_stripe_md, lsm_oinfo[lsm->lsm_stripe_count]);
@@ -1279,9 +1280,10 @@ echo_copyout_lsm(struct lov_stripe_md *lsm, void *_ulsm, int ulsm_nob)
        if (copy_to_user(ulsm, lsm, sizeof(*ulsm)))
                return -EFAULT;
 
-       for (i = 0; i < lsm->lsm_stripe_count; i++) {
-               if (copy_to_user(ulsm->lsm_oinfo[i], lsm->lsm_oinfo[i],
-                                     sizeof(lsm->lsm_oinfo[0])))
+       for (i = 0, p = lsm->lsm_oinfo; i < lsm->lsm_stripe_count; i++, p++) {
+               struct lov_oinfo __user *up;
+               if (get_user(up, ulsm->lsm_oinfo + i) ||
+                   copy_to_user(up, *p, sizeof(struct lov_oinfo)))
                        return -EFAULT;
        }
        return 0;
@@ -1289,9 +1291,10 @@ echo_copyout_lsm(struct lov_stripe_md *lsm, void *_ulsm, int ulsm_nob)
 
 static int
 echo_copyin_lsm(struct echo_device *ed, struct lov_stripe_md *lsm,
-                void *ulsm, int ulsm_nob)
+               struct lov_stripe_md __user *ulsm, int ulsm_nob)
 {
        struct echo_client_obd *ec = ed->ed_ec;
+       struct lov_oinfo **p;
        int                  i;
 
        if (ulsm_nob < sizeof(*lsm))
@@ -1306,11 +1309,10 @@ echo_copyin_lsm(struct echo_device *ed, struct lov_stripe_md *lsm,
            ((__u64)lsm->lsm_stripe_size * lsm->lsm_stripe_count > ~0UL))
                return -EINVAL;
 
-       for (i = 0; i < lsm->lsm_stripe_count; i++) {
-               if (copy_from_user(lsm->lsm_oinfo[i],
-                                      ((struct lov_stripe_md *)ulsm)-> \
-                                      lsm_oinfo[i],
-                                      sizeof(lsm->lsm_oinfo[0])))
+       for (i = 0, p = lsm->lsm_oinfo; i < lsm->lsm_stripe_count; i++, p++) {
+               struct lov_oinfo __user *up;
+               if (get_user(up, ulsm->lsm_oinfo + i) ||
+                   copy_from_user(*p, up, sizeof(struct lov_oinfo)))
                        return -EFAULT;
        }
        return 0;
index ed776149261ea1022fc0586ce3be200967ec4c0b..e49c2bce551d31db115b97f0a12807339258b69b 100644 (file)
@@ -2054,13 +2054,13 @@ static int canon_copy_from_read_buf(struct tty_struct *tty,
        size_t eol;
        size_t tail;
        int ret, found = 0;
-       bool eof_push = 0;
 
        /* N.B. avoid overrun if nr == 0 */
-       n = min(*nr, smp_load_acquire(&ldata->canon_head) - ldata->read_tail);
-       if (!n)
+       if (!*nr)
                return 0;
 
+       n = min(*nr + 1, smp_load_acquire(&ldata->canon_head) - ldata->read_tail);
+
        tail = ldata->read_tail & (N_TTY_BUF_SIZE - 1);
        size = min_t(size_t, tail + n, N_TTY_BUF_SIZE);
 
@@ -2081,12 +2081,11 @@ static int canon_copy_from_read_buf(struct tty_struct *tty,
        n = eol - tail;
        if (n > N_TTY_BUF_SIZE)
                n += N_TTY_BUF_SIZE;
-       n += found;
-       c = n;
+       c = n + found;
 
-       if (found && !ldata->push && read_buf(ldata, eol) == __DISABLED_CHAR) {
-               n--;
-               eof_push = !n && ldata->read_tail != ldata->line_start;
+       if (!found || read_buf(ldata, eol) != __DISABLED_CHAR) {
+               c = min(*nr, c);
+               n = c;
        }
 
        n_tty_trace("%s: eol:%zu found:%d n:%zu c:%zu size:%zu more:%zu\n",
@@ -2116,7 +2115,7 @@ static int canon_copy_from_read_buf(struct tty_struct *tty,
                        ldata->push = 0;
                tty_audit_push(tty);
        }
-       return eof_push ? -EAGAIN : 0;
+       return 0;
 }
 
 extern ssize_t redirected_tty_write(struct file *, const char __user *,
@@ -2273,10 +2272,7 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file,
 
                if (ldata->icanon && !L_EXTPROC(tty)) {
                        retval = canon_copy_from_read_buf(tty, &b, &nr);
-                       if (retval == -EAGAIN) {
-                               retval = 0;
-                               continue;
-                       } else if (retval)
+                       if (retval)
                                break;
                } else {
                        int uncopied;
index d11621e2cf1df083ca4c58309ef610df6c9c70fa..245edbb68d4ba5fe98e6e8fa915bf518cc4f28a5 100644 (file)
@@ -115,12 +115,16 @@ static void uniphier_serial_out(struct uart_port *p, int offset, int value)
  */
 static int uniphier_serial_dl_read(struct uart_8250_port *up)
 {
-       return readl(up->port.membase + UNIPHIER_UART_DLR);
+       int offset = UNIPHIER_UART_DLR << up->port.regshift;
+
+       return readl(up->port.membase + offset);
 }
 
 static void uniphier_serial_dl_write(struct uart_8250_port *up, int value)
 {
-       writel(value, up->port.membase + UNIPHIER_UART_DLR);
+       int offset = UNIPHIER_UART_DLR << up->port.regshift;
+
+       writel(value, up->port.membase + offset);
 }
 
 static int uniphier_of_serial_setup(struct device *dev, struct uart_port *port,
index f09636083426d5fc2fdb18a65a2a1af49a0093b7..b5b2f2be6be7c613b5c051c0d9730d3fa3b5e177 100644 (file)
@@ -115,6 +115,7 @@ static int __init register_earlycon(char *buf, const struct earlycon_id *match)
        if (buf && !parse_options(&early_console_dev, buf))
                buf = NULL;
 
+       spin_lock_init(&port->lock);
        port->uartclk = BASE_BAUD * 16;
        if (port->mapbase)
                port->membase = earlycon_map(port->mapbase, 64);
@@ -202,6 +203,7 @@ int __init of_setup_earlycon(unsigned long addr,
        int err;
        struct uart_port *port = &early_console_dev.port;
 
+       spin_lock_init(&port->lock);
        port->iotype = UPIO_MEM;
        port->mapbase = addr;
        port->uartclk = BASE_BAUD * 16;
index 960e50a97558cff52a1fb9eb8ed8879a5238991c..51c7507b0444957bcbc9c2c832bd6048a5f3b596 100644 (file)
@@ -1437,7 +1437,7 @@ static void sci_request_dma(struct uart_port *port)
                        sg_init_table(sg, 1);
                        s->rx_buf[i] = buf;
                        sg_dma_address(sg) = dma;
-                       sg->length = s->buf_len_rx;
+                       sg_dma_len(sg) = s->buf_len_rx;
 
                        buf += s->buf_len_rx;
                        dma += s->buf_len_rx;
index 064031870ba0d1b0bf09fd3bcb299d17dcaf76d5..ca0d3802f2af45fb8be9cad11d9763fb615e516a 100644 (file)
@@ -148,8 +148,10 @@ static int receive_chars_read(struct uart_port *port)
                        uart_handle_dcd_change(port, 1);
                }
 
-               for (i = 0; i < bytes_read; i++)
-                       uart_handle_sysrq_char(port, con_read_page[i]);
+               if (port->sysrq != 0 &&  *con_read_page) {
+                       for (i = 0; i < bytes_read; i++)
+                               uart_handle_sysrq_char(port, con_read_page[i]);
+               }
 
                if (port->state == NULL)
                        continue;
@@ -168,17 +170,17 @@ struct sunhv_ops {
        int (*receive_chars)(struct uart_port *port);
 };
 
-static struct sunhv_ops bychar_ops = {
+static const struct sunhv_ops bychar_ops = {
        .transmit_chars = transmit_chars_putchar,
        .receive_chars = receive_chars_getchar,
 };
 
-static struct sunhv_ops bywrite_ops = {
+static const struct sunhv_ops bywrite_ops = {
        .transmit_chars = transmit_chars_write,
        .receive_chars = receive_chars_read,
 };
 
-static struct sunhv_ops *sunhv_ops = &bychar_ops;
+static const struct sunhv_ops *sunhv_ops = &bychar_ops;
 
 static struct tty_port *receive_chars(struct uart_port *port)
 {
index 9a479e61791a2a80cd0ae3fd5c93c6d0873d6998..3cd31e0d4bd9545b5357cda0ffa14373d181e670 100644 (file)
@@ -450,7 +450,7 @@ receive_buf(struct tty_struct *tty, struct tty_buffer *head, int count)
                count = disc->ops->receive_buf2(tty, p, f, count);
        else {
                count = min_t(int, count, tty->receive_room);
-               if (count)
+               if (count && disc->ops->receive_buf)
                        disc->ops->receive_buf(tty, p, f, count);
        }
        return count;
index b30e7423549b04b0e7d442a128048b4221c68062..26ca4f910cb020aae539f29b260a98fe1eee92b0 100644 (file)
@@ -1838,6 +1838,11 @@ static const struct usb_device_id acm_ids[] = {
        },
 #endif
 
+       /* Exclude Infineon Flash Loader utility */
+       { USB_DEVICE(0x058b, 0x0041),
+       .driver_info = IGNORE_DEVICE,
+       },
+
        /* control interfaces without any protocol set */
        { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM,
                USB_CDC_PROTO_NONE) },
index 7caff020106e23f26f9c3bb9c34585885064848d..5050760f5e17cf3872952ae5fa6a40d01aab394b 100644 (file)
@@ -115,7 +115,8 @@ static void usb_parse_ss_endpoint_companion(struct device *ddev, int cfgno,
                   USB_SS_MULT(desc->bmAttributes) > 3) {
                dev_warn(ddev, "Isoc endpoint has Mult of %d in "
                                "config %d interface %d altsetting %d ep %d: "
-                               "setting to 3\n", desc->bmAttributes + 1,
+                               "setting to 3\n",
+                               USB_SS_MULT(desc->bmAttributes),
                                cfgno, inum, asnum, ep->desc.bEndpointAddress);
                ep->ss_ep_comp.bmAttributes = 2;
        }
index bdeadc112d29f9b4545bf3ab82645b52982f5cfd..ddbf32d599cba4e51aeb81eea8519500a8bbea01 100644 (file)
@@ -124,6 +124,10 @@ struct usb_hub *usb_hub_to_struct_hub(struct usb_device *hdev)
 
 int usb_device_supports_lpm(struct usb_device *udev)
 {
+       /* Some devices have trouble with LPM */
+       if (udev->quirks & USB_QUIRK_NO_LPM)
+               return 0;
+
        /* USB 2.1 (and greater) devices indicate LPM support through
         * their USB 2.0 Extended Capabilities BOS descriptor.
         */
@@ -1031,10 +1035,20 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
        unsigned delay;
 
        /* Continue a partial initialization */
-       if (type == HUB_INIT2)
-               goto init2;
-       if (type == HUB_INIT3)
+       if (type == HUB_INIT2 || type == HUB_INIT3) {
+               device_lock(hub->intfdev);
+
+               /* Was the hub disconnected while we were waiting? */
+               if (hub->disconnected) {
+                       device_unlock(hub->intfdev);
+                       kref_put(&hub->kref, hub_release);
+                       return;
+               }
+               if (type == HUB_INIT2)
+                       goto init2;
                goto init3;
+       }
+       kref_get(&hub->kref);
 
        /* The superspeed hub except for root hub has to use Hub Depth
         * value as an offset into the route string to locate the bits
@@ -1232,6 +1246,7 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
                        queue_delayed_work(system_power_efficient_wq,
                                        &hub->init_work,
                                        msecs_to_jiffies(delay));
+                       device_unlock(hub->intfdev);
                        return;         /* Continues at init3: below */
                } else {
                        msleep(delay);
@@ -1253,6 +1268,11 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
        /* Allow autosuspend if it was suppressed */
        if (type <= HUB_INIT3)
                usb_autopm_put_interface_async(to_usb_interface(hub->intfdev));
+
+       if (type == HUB_INIT2 || type == HUB_INIT3)
+               device_unlock(hub->intfdev);
+
+       kref_put(&hub->kref, hub_release);
 }
 
 /* Implement the continuations for the delays above */
@@ -4512,6 +4532,8 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1,
                goto fail;
        }
 
+       usb_detect_quirks(udev);
+
        if (udev->wusb == 0 && le16_to_cpu(udev->descriptor.bcdUSB) >= 0x0201) {
                retval = usb_get_bos_descriptor(udev);
                if (!retval) {
@@ -4710,7 +4732,6 @@ static void hub_port_connect(struct usb_hub *hub, int port1, u16 portstatus,
                if (status < 0)
                        goto loop;
 
-               usb_detect_quirks(udev);
                if (udev->quirks & USB_QUIRK_DELAY_INIT)
                        msleep(1000);
 
@@ -5326,9 +5347,6 @@ static int usb_reset_and_verify_device(struct usb_device *udev)
        if (udev->usb2_hw_lpm_enabled == 1)
                usb_set_usb2_hardware_lpm(udev, 0);
 
-       bos = udev->bos;
-       udev->bos = NULL;
-
        /* Disable LPM and LTM while we reset the device and reinstall the alt
         * settings.  Device-initiated LPM settings, and system exit latency
         * settings are cleared when the device is reset, so we have to set
@@ -5337,15 +5355,18 @@ static int usb_reset_and_verify_device(struct usb_device *udev)
        ret = usb_unlocked_disable_lpm(udev);
        if (ret) {
                dev_err(&udev->dev, "%s Failed to disable LPM\n.", __func__);
-               goto re_enumerate;
+               goto re_enumerate_no_bos;
        }
        ret = usb_disable_ltm(udev);
        if (ret) {
                dev_err(&udev->dev, "%s Failed to disable LTM\n.",
                                __func__);
-               goto re_enumerate;
+               goto re_enumerate_no_bos;
        }
 
+       bos = udev->bos;
+       udev->bos = NULL;
+
        for (i = 0; i < SET_CONFIG_TRIES; ++i) {
 
                /* ep0 maxpacket size may change; let the HCD know about it.
@@ -5442,10 +5463,11 @@ done:
        return 0;
 
 re_enumerate:
-       /* LPM state doesn't matter when we're about to destroy the device. */
-       hub_port_logical_disconnect(parent_hub, port1);
        usb_release_bos_descriptor(udev);
        udev->bos = bos;
+re_enumerate_no_bos:
+       /* LPM state doesn't matter when we're about to destroy the device. */
+       hub_port_logical_disconnect(parent_hub, port1);
        return -ENODEV;
 }
 
index 210618319f10a4110bc53191fc8a06a860992c3a..5487fe308f01b7be30bcecebc12726a295f9daa9 100644 (file)
@@ -206,7 +206,7 @@ static int link_peers(struct usb_port *left, struct usb_port *right)
                else
                        method = "default";
 
-               pr_warn("usb: failed to peer %s and %s by %s (%s:%s) (%s:%s)\n",
+               pr_debug("usb: failed to peer %s and %s by %s (%s:%s) (%s:%s)\n",
                        dev_name(&left->dev), dev_name(&right->dev), method,
                        dev_name(&left->dev),
                        lpeer ? dev_name(&lpeer->dev) : "none",
@@ -265,7 +265,7 @@ static void link_peers_report(struct usb_port *left, struct usb_port *right)
        if (rc == 0) {
                dev_dbg(&left->dev, "peered to %s\n", dev_name(&right->dev));
        } else {
-               dev_warn(&left->dev, "failed to peer to %s (%d)\n",
+               dev_dbg(&left->dev, "failed to peer to %s (%d)\n",
                                dev_name(&right->dev), rc);
                pr_warn_once("usb: port power management may be unreliable\n");
                usb_port_block_power_off = 1;
index f5a381945db2886a77e23a8fcf40ba9a34bb7fe7..6dc810bce295ab22dbb10b47755dddb421f96957 100644 (file)
@@ -125,6 +125,9 @@ static const struct usb_device_id usb_quirk_list[] = {
        { USB_DEVICE(0x04f3, 0x016f), .driver_info =
                        USB_QUIRK_DEVICE_QUALIFIER },
 
+       { USB_DEVICE(0x04f3, 0x21b8), .driver_info =
+                       USB_QUIRK_DEVICE_QUALIFIER },
+
        /* Roland SC-8820 */
        { USB_DEVICE(0x0582, 0x0007), .driver_info = USB_QUIRK_RESET_RESUME },
 
@@ -199,6 +202,12 @@ static const struct usb_device_id usb_quirk_list[] = {
        { USB_DEVICE(0x1a0a, 0x0200), .driver_info =
                        USB_QUIRK_LINEAR_UFRAME_INTR_BINTERVAL },
 
+       /* Blackmagic Design Intensity Shuttle */
+       { USB_DEVICE(0x1edb, 0xbd3b), .driver_info = USB_QUIRK_NO_LPM },
+
+       /* Blackmagic Design UltraStudio SDI */
+       { USB_DEVICE(0x1edb, 0xbd4f), .driver_info = USB_QUIRK_NO_LPM },
+
        { }  /* terminating entry must be last */
 };
 
index e61d773cf65e71e27a41f3c7d8e5306939d08908..39c1cbf0e75d9a5957b1567def5d23fb3631a015 100644 (file)
@@ -125,9 +125,11 @@ static int __dwc2_lowlevel_hw_enable(struct dwc2_hsotg *hsotg)
        if (ret)
                return ret;
 
-       ret = clk_prepare_enable(hsotg->clk);
-       if (ret)
-               return ret;
+       if (hsotg->clk) {
+               ret = clk_prepare_enable(hsotg->clk);
+               if (ret)
+                       return ret;
+       }
 
        if (hsotg->uphy)
                ret = usb_phy_init(hsotg->uphy);
@@ -175,7 +177,8 @@ static int __dwc2_lowlevel_hw_disable(struct dwc2_hsotg *hsotg)
        if (ret)
                return ret;
 
-       clk_disable_unprepare(hsotg->clk);
+       if (hsotg->clk)
+               clk_disable_unprepare(hsotg->clk);
 
        ret = regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies),
                                     hsotg->supplies);
@@ -212,14 +215,41 @@ static int dwc2_lowlevel_hw_init(struct dwc2_hsotg *hsotg)
         */
        hsotg->phy = devm_phy_get(hsotg->dev, "usb2-phy");
        if (IS_ERR(hsotg->phy)) {
-               hsotg->phy = NULL;
+               ret = PTR_ERR(hsotg->phy);
+               switch (ret) {
+               case -ENODEV:
+               case -ENOSYS:
+                       hsotg->phy = NULL;
+                       break;
+               case -EPROBE_DEFER:
+                       return ret;
+               default:
+                       dev_err(hsotg->dev, "error getting phy %d\n", ret);
+                       return ret;
+               }
+       }
+
+       if (!hsotg->phy) {
                hsotg->uphy = devm_usb_get_phy(hsotg->dev, USB_PHY_TYPE_USB2);
-               if (IS_ERR(hsotg->uphy))
-                       hsotg->uphy = NULL;
-               else
-                       hsotg->plat = dev_get_platdata(hsotg->dev);
+               if (IS_ERR(hsotg->uphy)) {
+                       ret = PTR_ERR(hsotg->uphy);
+                       switch (ret) {
+                       case -ENODEV:
+                       case -ENXIO:
+                               hsotg->uphy = NULL;
+                               break;
+                       case -EPROBE_DEFER:
+                               return ret;
+                       default:
+                               dev_err(hsotg->dev, "error getting usb phy %d\n",
+                                       ret);
+                               return ret;
+                       }
+               }
        }
 
+       hsotg->plat = dev_get_platdata(hsotg->dev);
+
        if (hsotg->phy) {
                /*
                 * If using the generic PHY framework, check if the PHY bus
@@ -229,11 +259,6 @@ static int dwc2_lowlevel_hw_init(struct dwc2_hsotg *hsotg)
                        hsotg->phyif = GUSBCFG_PHYIF8;
        }
 
-       if (!hsotg->phy && !hsotg->uphy && !hsotg->plat) {
-               dev_err(hsotg->dev, "no platform data or transceiver defined\n");
-               return -EPROBE_DEFER;
-       }
-
        /* Clock */
        hsotg->clk = devm_clk_get(hsotg->dev, "otg");
        if (IS_ERR(hsotg->clk)) {
@@ -342,20 +367,6 @@ static int dwc2_driver_probe(struct platform_device *dev)
        if (retval)
                return retval;
 
-       irq = platform_get_irq(dev, 0);
-       if (irq < 0) {
-               dev_err(&dev->dev, "missing IRQ resource\n");
-               return irq;
-       }
-
-       dev_dbg(hsotg->dev, "registering common handler for irq%d\n",
-               irq);
-       retval = devm_request_irq(hsotg->dev, irq,
-                                 dwc2_handle_common_intr, IRQF_SHARED,
-                                 dev_name(hsotg->dev), hsotg);
-       if (retval)
-               return retval;
-
        res = platform_get_resource(dev, IORESOURCE_MEM, 0);
        hsotg->regs = devm_ioremap_resource(&dev->dev, res);
        if (IS_ERR(hsotg->regs))
@@ -390,6 +401,20 @@ static int dwc2_driver_probe(struct platform_device *dev)
 
        dwc2_set_all_params(hsotg->core_params, -1);
 
+       irq = platform_get_irq(dev, 0);
+       if (irq < 0) {
+               dev_err(&dev->dev, "missing IRQ resource\n");
+               return irq;
+       }
+
+       dev_dbg(hsotg->dev, "registering common handler for irq%d\n",
+               irq);
+       retval = devm_request_irq(hsotg->dev, irq,
+                                 dwc2_handle_common_intr, IRQF_SHARED,
+                                 dev_name(hsotg->dev), hsotg);
+       if (retval)
+               return retval;
+
        retval = dwc2_lowlevel_hw_enable(hsotg);
        if (retval)
                return retval;
index e24a01cc98df4a43f2fd556e44b1557dce778d33..a58376fd65fe6d788fa817d5600696bfd431c791 100644 (file)
@@ -1078,6 +1078,7 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req)
         * little bit faster.
         */
        if (!usb_endpoint_xfer_isoc(dep->endpoint.desc) &&
+                       !usb_endpoint_xfer_int(dep->endpoint.desc) &&
                        !(dep->flags & DWC3_EP_BUSY)) {
                ret = __dwc3_gadget_kick_transfer(dep, 0, true);
                goto out;
index adc6d52efa4639387c30bcde2ae7cee95331b1bc..cf43e9e18368dcd84668b9378b1036b17276b593 100644 (file)
@@ -423,7 +423,7 @@ static ssize_t __ffs_ep0_read_events(struct ffs_data *ffs, char __user *buf,
        spin_unlock_irq(&ffs->ev.waitq.lock);
        mutex_unlock(&ffs->mutex);
 
-       return unlikely(__copy_to_user(buf, events, size)) ? -EFAULT : size;
+       return unlikely(copy_to_user(buf, events, size)) ? -EFAULT : size;
 }
 
 static ssize_t ffs_ep0_read(struct file *file, char __user *buf,
@@ -513,7 +513,7 @@ static ssize_t ffs_ep0_read(struct file *file, char __user *buf,
 
                /* unlocks spinlock */
                ret = __ffs_ep0_queue_wait(ffs, data, len);
-               if (likely(ret > 0) && unlikely(__copy_to_user(buf, data, len)))
+               if (likely(ret > 0) && unlikely(copy_to_user(buf, data, len)))
                        ret = -EFAULT;
                goto done_mutex;
 
@@ -3493,7 +3493,7 @@ static char *ffs_prepare_buffer(const char __user *buf, size_t len)
        if (unlikely(!data))
                return ERR_PTR(-ENOMEM);
 
-       if (unlikely(__copy_from_user(data, buf, len))) {
+       if (unlikely(copy_from_user(data, buf, len))) {
                kfree(data);
                return ERR_PTR(-EFAULT);
        }
index 42acb45e1ab42dd9436244bec16d4903603d6089..898a570319f17c3128b7a44878ebc09ea7242961 100644 (file)
@@ -370,6 +370,7 @@ static int f_midi_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
                if (err) {
                        ERROR(midi, "%s queue req: %d\n",
                                    midi->out_ep->name, err);
+                       free_ep_req(midi->out_ep, req);
                }
        }
 
@@ -545,7 +546,7 @@ static void f_midi_transmit(struct f_midi *midi, struct usb_request *req)
                }
        }
 
-       if (req->length > 0) {
+       if (req->length > 0 && ep->enabled) {
                int err;
 
                err = usb_ep_queue(ep, req, GFP_ATOMIC);
index 289ebca316d3f4ab0e136a14858bb7275eee53c0..ad8c9b05572d7421885ff161d32543f8942eb90d 100644 (file)
@@ -20,7 +20,7 @@
 #define UVC_ATTR(prefix, cname, aname) \
 static struct configfs_attribute prefix##attr_##cname = { \
        .ca_name        = __stringify(aname),                           \
-       .ca_mode        = S_IRUGO,                                      \
+       .ca_mode        = S_IRUGO | S_IWUGO,                            \
        .ca_owner       = THIS_MODULE,                                  \
        .show           = prefix##cname##_show,                         \
        .store          = prefix##cname##_store,                        \
index 670ac0b12f00842ad7a5b840c941f2e8a8a7f1cc..001a3b74a993ea677dd65650a4457f5f14376a7c 100644 (file)
@@ -2536,6 +2536,9 @@ static int pxa_udc_suspend(struct platform_device *_dev, pm_message_t state)
        udc->pullup_resume = udc->pullup_on;
        dplus_pullup(udc, 0);
 
+       if (udc->driver)
+               udc->driver->disconnect(&udc->gadget);
+
        return 0;
 }
 
index 342ffd1401222179589906ccc1d09ec102a1f03b..8c6e15bd6ff0b27ce2e8cb22c2fe03e9866f1768 100644 (file)
@@ -473,6 +473,8 @@ static int ohci_hcd_at91_drv_probe(struct platform_device *pdev)
        if (!pdata)
                return -ENOMEM;
 
+       pdev->dev.platform_data = pdata;
+
        if (!of_property_read_u32(np, "num-ports", &ports))
                pdata->ports = ports;
 
@@ -483,6 +485,7 @@ static int ohci_hcd_at91_drv_probe(struct platform_device *pdev)
                 */
                if (i >= pdata->ports) {
                        pdata->vbus_pin[i] = -EINVAL;
+                       pdata->overcurrent_pin[i] = -EINVAL;
                        continue;
                }
 
@@ -513,10 +516,8 @@ static int ohci_hcd_at91_drv_probe(struct platform_device *pdev)
        }
 
        at91_for_each_port(i) {
-               if (i >= pdata->ports) {
-                       pdata->overcurrent_pin[i] = -EINVAL;
-                       continue;
-               }
+               if (i >= pdata->ports)
+                       break;
 
                pdata->overcurrent_pin[i] =
                        of_get_named_gpio_flags(np, "atmel,oc-gpio", i, &flags);
@@ -552,8 +553,6 @@ static int ohci_hcd_at91_drv_probe(struct platform_device *pdev)
                }
        }
 
-       pdev->dev.platform_data = pdata;
-
        device_init_wakeup(&pdev->dev, 1);
        return usb_hcd_at91_probe(&ohci_at91_hc_driver, pdev);
 }
index dc31c425ce0179551b27e2d7a900f1bb7b411ad8..9f1c0538b211217d21184ef2527f764933aace0d 100644 (file)
@@ -377,6 +377,10 @@ static int qset_fill_page_list(struct whc *whc, struct whc_std *std, gfp_t mem_f
        if (std->pl_virt == NULL)
                return -ENOMEM;
        std->dma_addr = dma_map_single(whc->wusbhc.dev, std->pl_virt, pl_len, DMA_TO_DEVICE);
+       if (dma_mapping_error(whc->wusbhc.dev, std->dma_addr)) {
+               kfree(std->pl_virt);
+               return -EFAULT;
+       }
 
        for (p = 0; p < std->num_pointers; p++) {
                std->pl_virt[p].buf_ptr = cpu_to_le64(dma_addr);
index 0230965fb78cf3433702932625aee270dbf90535..f980c239eded9bd5e9615ebf96deefce5c7ec591 100644 (file)
@@ -733,8 +733,30 @@ static u32 xhci_get_port_status(struct usb_hcd *hcd,
                if ((raw_port_status & PORT_RESET) ||
                                !(raw_port_status & PORT_PE))
                        return 0xffffffff;
-               if (time_after_eq(jiffies,
-                                       bus_state->resume_done[wIndex])) {
+               /* did port event handler already start resume timing? */
+               if (!bus_state->resume_done[wIndex]) {
+                       /* If not, maybe we are in a host initated resume? */
+                       if (test_bit(wIndex, &bus_state->resuming_ports)) {
+                               /* Host initated resume doesn't time the resume
+                                * signalling using resume_done[].
+                                * It manually sets RESUME state, sleeps 20ms
+                                * and sets U0 state. This should probably be
+                                * changed, but not right now.
+                                */
+                       } else {
+                               /* port resume was discovered now and here,
+                                * start resume timing
+                                */
+                               unsigned long timeout = jiffies +
+                                       msecs_to_jiffies(USB_RESUME_TIMEOUT);
+
+                               set_bit(wIndex, &bus_state->resuming_ports);
+                               bus_state->resume_done[wIndex] = timeout;
+                               mod_timer(&hcd->rh_timer, timeout);
+                       }
+               /* Has resume been signalled for USB_RESUME_TIME yet? */
+               } else if (time_after_eq(jiffies,
+                                        bus_state->resume_done[wIndex])) {
                        int time_left;
 
                        xhci_dbg(xhci, "Resume USB2 port %d\n",
@@ -775,13 +797,26 @@ static u32 xhci_get_port_status(struct usb_hcd *hcd,
                } else {
                        /*
                         * The resume has been signaling for less than
-                        * 20ms. Report the port status as SUSPEND,
-                        * let the usbcore check port status again
-                        * and clear resume signaling later.
+                        * USB_RESUME_TIME. Report the port status as SUSPEND,
+                        * let the usbcore check port status again and clear
+                        * resume signaling later.
                         */
                        status |= USB_PORT_STAT_SUSPEND;
                }
        }
+       /*
+        * Clear stale usb2 resume signalling variables in case port changed
+        * state during resume signalling. For example on error
+        */
+       if ((bus_state->resume_done[wIndex] ||
+            test_bit(wIndex, &bus_state->resuming_ports)) &&
+           (raw_port_status & PORT_PLS_MASK) != XDEV_U3 &&
+           (raw_port_status & PORT_PLS_MASK) != XDEV_RESUME) {
+               bus_state->resume_done[wIndex] = 0;
+               clear_bit(wIndex, &bus_state->resuming_ports);
+       }
+
+
        if ((raw_port_status & PORT_PLS_MASK) == XDEV_U0 &&
            (raw_port_status & PORT_POWER)) {
                if (bus_state->suspended_ports & (1 << wIndex)) {
@@ -1115,6 +1150,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
                                if ((temp & PORT_PE) == 0)
                                        goto error;
 
+                               set_bit(wIndex, &bus_state->resuming_ports);
                                xhci_set_link_state(xhci, port_array, wIndex,
                                                        XDEV_RESUME);
                                spin_unlock_irqrestore(&xhci->lock, flags);
@@ -1122,6 +1158,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
                                spin_lock_irqsave(&xhci->lock, flags);
                                xhci_set_link_state(xhci, port_array, wIndex,
                                                        XDEV_U0);
+                               clear_bit(wIndex, &bus_state->resuming_ports);
                        }
                        bus_state->port_c_suspend |= 1 << wIndex;
 
index 17f6897acde2a5a7674ccff44ddc55f0db192166..c62109091d12855f7b5bb0e2b44a0b6b516cc88b 100644 (file)
@@ -188,10 +188,14 @@ static void xhci_pme_acpi_rtd3_enable(struct pci_dev *dev)
                0xb7, 0x0c, 0x34, 0xac, 0x01, 0xe9, 0xbf, 0x45,
                0xb7, 0xe6, 0x2b, 0x34, 0xec, 0x93, 0x1e, 0x23,
        };
-       acpi_evaluate_dsm(ACPI_HANDLE(&dev->dev), intel_dsm_uuid, 3, 1, NULL);
+       union acpi_object *obj;
+
+       obj = acpi_evaluate_dsm(ACPI_HANDLE(&dev->dev), intel_dsm_uuid, 3, 1,
+                               NULL);
+       ACPI_FREE(obj);
 }
 #else
-       static void xhci_pme_acpi_rtd3_enable(struct pci_dev *dev) { }
+static void xhci_pme_acpi_rtd3_enable(struct pci_dev *dev) { }
 #endif /* CONFIG_ACPI */
 
 /* called during probe() after chip reset completes */
index 6c5e8133cf87c4b203e2072de5b7275c4d944365..eeaa6c6bd540870f8065338a61ee37d838c6b07e 100644 (file)
@@ -1583,7 +1583,8 @@ static void handle_port_status(struct xhci_hcd *xhci,
                         */
                        bogus_port_status = true;
                        goto cleanup;
-               } else {
+               } else if (!test_bit(faked_port_index,
+                                    &bus_state->resuming_ports)) {
                        xhci_dbg(xhci, "resume HS port %d\n", port_id);
                        bus_state->resume_done[faked_port_index] = jiffies +
                                msecs_to_jiffies(USB_RESUME_TIMEOUT);
index dfa44d3e8eee469c9b8321fed57056ebe5813a2a..3f912705dcef93a5f27e6979f8aea9a6972b44eb 100644 (file)
@@ -4778,8 +4778,16 @@ int xhci_update_hub_device(struct usb_hcd *hcd, struct usb_device *hdev,
        ctrl_ctx->add_flags |= cpu_to_le32(SLOT_FLAG);
        slot_ctx = xhci_get_slot_ctx(xhci, config_cmd->in_ctx);
        slot_ctx->dev_info |= cpu_to_le32(DEV_HUB);
+       /*
+        * refer to section 6.2.2: MTT should be 0 for full speed hub,
+        * but it may be already set to 1 when setup an xHCI virtual
+        * device, so clear it anyway.
+        */
        if (tt->multi)
                slot_ctx->dev_info |= cpu_to_le32(DEV_MTT);
+       else if (hdev->speed == USB_SPEED_FULL)
+               slot_ctx->dev_info &= cpu_to_le32(~DEV_MTT);
+
        if (xhci->hci_version > 0x95) {
                xhci_dbg(xhci, "xHCI version %x needs hub "
                                "TT think time and number of ports\n",
index 1f2037bbeb0d1619572a2912bda7fa6e2c168ac0..45c83baf675dfb341089ca2f399ae636b45b0de5 100644 (file)
@@ -159,7 +159,7 @@ config USB_TI_CPPI_DMA
 
 config USB_TI_CPPI41_DMA
        bool 'TI CPPI 4.1 (AM335x)'
-       depends on ARCH_OMAP
+       depends on ARCH_OMAP && DMADEVICES
        select TI_CPPI41
 
 config USB_TUSB_OMAP_DMA
index 18cfc0a361cb340612bdf943d79a6302694afc43..ee9ff7028b926b1a7303afb261c3b261f91c9da4 100644 (file)
@@ -2017,7 +2017,6 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
        /* We need musb_read/write functions initialized for PM */
        pm_runtime_use_autosuspend(musb->controller);
        pm_runtime_set_autosuspend_delay(musb->controller, 200);
-       pm_runtime_irq_safe(musb->controller);
        pm_runtime_enable(musb->controller);
 
        /* The musb_platform_init() call:
@@ -2095,6 +2094,7 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
 #ifndef CONFIG_MUSB_PIO_ONLY
        if (!musb->ops->dma_init || !musb->ops->dma_exit) {
                dev_err(dev, "DMA controller not set\n");
+               status = -ENODEV;
                goto fail2;
        }
        musb_dma_controller_create = musb->ops->dma_init;
@@ -2218,6 +2218,12 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
 
        pm_runtime_put(musb->controller);
 
+       /*
+        * For why this is currently needed, see commit 3e43a0725637
+        * ("usb: musb: core: add pm_runtime_irq_safe()")
+        */
+       pm_runtime_irq_safe(musb->controller);
+
        return 0;
 
 fail5:
index 80eb991c2506c758315cc2e6e1f39b6ebbf319f4..0d19a6d61a71f7ccb7a55e1b90a7d5d5f27db535 100644 (file)
@@ -1506,7 +1506,6 @@ static int msm_otg_read_dt(struct platform_device *pdev, struct msm_otg *motg)
 {
        struct msm_otg_platform_data *pdata;
        struct extcon_dev *ext_id, *ext_vbus;
-       const struct of_device_id *id;
        struct device_node *node = pdev->dev.of_node;
        struct property *prop;
        int len, ret, words;
@@ -1518,8 +1517,9 @@ static int msm_otg_read_dt(struct platform_device *pdev, struct msm_otg *motg)
 
        motg->pdata = pdata;
 
-       id = of_match_device(msm_otg_dt_match, &pdev->dev);
-       pdata->phy_type = (enum msm_usb_phy_type) id->data;
+       pdata->phy_type = (enum msm_usb_phy_type)of_device_get_match_data(&pdev->dev);
+       if (!pdata->phy_type)
+               return 1;
 
        motg->link_rst = devm_reset_control_get(&pdev->dev, "link");
        if (IS_ERR(motg->link_rst))
index b7536af777ab9c4f083d7b88ff2bfe093fca9e21..c2936dc48ca7b45b0e5c186859d2879569719323 100644 (file)
@@ -143,12 +143,17 @@ static const struct mxs_phy_data imx6sx_phy_data = {
        .flags = MXS_PHY_DISCONNECT_LINE_WITHOUT_VBUS,
 };
 
+static const struct mxs_phy_data imx6ul_phy_data = {
+       .flags = MXS_PHY_DISCONNECT_LINE_WITHOUT_VBUS,
+};
+
 static const struct of_device_id mxs_phy_dt_ids[] = {
        { .compatible = "fsl,imx6sx-usbphy", .data = &imx6sx_phy_data, },
        { .compatible = "fsl,imx6sl-usbphy", .data = &imx6sl_phy_data, },
        { .compatible = "fsl,imx6q-usbphy", .data = &imx6q_phy_data, },
        { .compatible = "fsl,imx23-usbphy", .data = &imx23_phy_data, },
        { .compatible = "fsl,vf610-usbphy", .data = &vf610_phy_data, },
+       { .compatible = "fsl,imx6ul-usbphy", .data = &imx6ul_phy_data, },
        { /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, mxs_phy_dt_ids);
index de4f97d84a822ffd746b5550dcb68da08b581438..8f7a78e7097598a50e9d7ba3cc72831b41af25b8 100644 (file)
@@ -131,7 +131,8 @@ static void __usbhsg_queue_pop(struct usbhsg_uep *uep,
        struct device *dev = usbhsg_gpriv_to_dev(gpriv);
        struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv);
 
-       dev_dbg(dev, "pipe %d : queue pop\n", usbhs_pipe_number(pipe));
+       if (pipe)
+               dev_dbg(dev, "pipe %d : queue pop\n", usbhs_pipe_number(pipe));
 
        ureq->req.status = status;
        spin_unlock(usbhs_priv_to_lock(priv));
@@ -685,7 +686,13 @@ static int usbhsg_ep_dequeue(struct usb_ep *ep, struct usb_request *req)
        struct usbhsg_request *ureq = usbhsg_req_to_ureq(req);
        struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep);
 
-       usbhs_pkt_pop(pipe, usbhsg_ureq_to_pkt(ureq));
+       if (pipe)
+               usbhs_pkt_pop(pipe, usbhsg_ureq_to_pkt(ureq));
+
+       /*
+        * To dequeue a request, this driver should call the usbhsg_queue_pop()
+        * even if the pipe is NULL.
+        */
        usbhsg_queue_pop(uep, ureq, -ECONNRESET);
 
        return 0;
index eac7ccaa3c859cc3bae90e897fc071caa7168cfd..7d4f51a32e66fcb2b7568af975fcd5574edd7f88 100644 (file)
@@ -132,7 +132,6 @@ static const struct usb_device_id id_table[] = {
        { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */
        { USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */
        { USB_DEVICE(0x10C4, 0xEA70) }, /* Silicon Labs factory default */
-       { USB_DEVICE(0x10C4, 0xEA80) }, /* Silicon Labs factory default */
        { USB_DEVICE(0x10C4, 0xEA71) }, /* Infinity GPS-MIC-1 Radio Monophone */
        { USB_DEVICE(0x10C4, 0xF001) }, /* Elan Digital Systems USBscope50 */
        { USB_DEVICE(0x10C4, 0xF002) }, /* Elan Digital Systems USBwave12 */
index f51a5d52c0edab01b9c9fbd91b8c1d7389d00f78..ec1b8f2c11837fecd39468c1e053880d72da9f94 100644 (file)
@@ -531,7 +531,8 @@ static int ipaq_open(struct tty_struct *tty,
         * through. Since this has a reasonably high failure rate, we retry
         * several times.
         */
-       while (retries--) {
+       while (retries) {
+               retries--;
                result = usb_control_msg(serial->dev,
                                usb_sndctrlpipe(serial->dev, 0), 0x22, 0x21,
                                0x1, 0, NULL, 0, 100);
index 3658662898fcb170fcdca07a8a676383e4d70347..a204782ae530e1de8f7982f869a94f9b80ce9dad 100644 (file)
@@ -53,6 +53,7 @@ DEVICE(funsoft, FUNSOFT_IDS);
 
 /* Infineon Flashloader driver */
 #define FLASHLOADER_IDS()              \
+       { USB_DEVICE_INTERFACE_CLASS(0x058b, 0x0041, USB_CLASS_CDC_DATA) }, \
        { USB_DEVICE(0x8087, 0x0716) }
 DEVICE(flashloader, FLASHLOADER_IDS);
 
index e6915166443607283f8229eaca83fac38ed68377..5c66d3f7a6d070c54632751af97ef3c3d660744b 100644 (file)
@@ -796,6 +796,10 @@ static int uas_slave_configure(struct scsi_device *sdev)
        if (devinfo->flags & US_FL_NO_REPORT_OPCODES)
                sdev->no_report_opcodes = 1;
 
+       /* A few buggy USB-ATA bridges don't understand FUA */
+       if (devinfo->flags & US_FL_BROKEN_FUA)
+               sdev->broken_fua = 1;
+
        scsi_change_queue_depth(sdev, devinfo->qdepth - 2);
        return 0;
 }
index 6b2479123de7762f7145c93fdcd58efb11f51093..7ffe4209067bb35b62220660997b4d83344706ed 100644 (file)
@@ -1987,7 +1987,7 @@ UNUSUAL_DEV(  0x14cd, 0x6600, 0x0201, 0x0201,
                US_FL_IGNORE_RESIDUE ),
 
 /* Reported by Michael Büsch <m@bues.ch> */
-UNUSUAL_DEV(  0x152d, 0x0567, 0x0114, 0x0114,
+UNUSUAL_DEV(  0x152d, 0x0567, 0x0114, 0x0116,
                "JMicron",
                "USB to ATA/ATAPI Bridge",
                USB_SC_DEVICE, USB_PR_DEVICE, NULL,
index c85ea530085f12d86ca691d82122f04e9f2166ae..ccc113e83d88e2b1e69e207989a5d5b49d526ae2 100644 (file)
@@ -132,7 +132,7 @@ UNUSUAL_DEV(0x152d, 0x0567, 0x0000, 0x9999,
                "JMicron",
                "JMS567",
                USB_SC_DEVICE, USB_PR_DEVICE, NULL,
-               US_FL_NO_REPORT_OPCODES),
+               US_FL_BROKEN_FUA | US_FL_NO_REPORT_OPCODES),
 
 /* Reported-by: Hans de Goede <hdegoede@redhat.com> */
 UNUSUAL_DEV(0x2109, 0x0711, 0x0000, 0x9999,
index b335c1ae8625106efff818d696ebad532ade7f17..fe00a07c122e69f0735baf8832fdd112677b4dd6 100644 (file)
@@ -479,7 +479,10 @@ static enum fsl_diu_monitor_port fsl_diu_name_to_port(const char *s)
                        port = FSL_DIU_PORT_DLVDS;
        }
 
-       return diu_ops.valid_monitor_port(port);
+       if (diu_ops.valid_monitor_port)
+               port = diu_ops.valid_monitor_port(port);
+
+       return port;
 }
 
 /*
@@ -1915,6 +1918,14 @@ static int __init fsl_diu_init(void)
 #else
        monitor_port = fsl_diu_name_to_port(monitor_string);
 #endif
+
+       /*
+        * Must to verify set_pixel_clock. If not implement on platform,
+        * then that means that there is no platform support for the DIU.
+        */
+       if (!diu_ops.set_pixel_clock)
+               return -ENODEV;
+
        pr_info("Freescale Display Interface Unit (DIU) framebuffer driver\n");
 
 #ifdef CONFIG_NOT_COHERENT_CACHE
index 99ca268c1cddf24332308b58fbeb051d565b8dca..d05a54922ba6953bb686f07ba2ac4315f91aeace 100644 (file)
@@ -275,6 +275,12 @@ const struct omap_video_timings omap_dss_pal_timings = {
        .vbp            = 41,
 
        .interlace      = true,
+
+       .hsync_level = OMAPDSS_SIG_ACTIVE_LOW,
+       .vsync_level = OMAPDSS_SIG_ACTIVE_LOW,
+       .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE,
+       .de_level = OMAPDSS_SIG_ACTIVE_HIGH,
+       .sync_pclk_edge = OMAPDSS_DRIVE_SIG_FALLING_EDGE,
 };
 EXPORT_SYMBOL(omap_dss_pal_timings);
 
@@ -290,6 +296,12 @@ const struct omap_video_timings omap_dss_ntsc_timings = {
        .vbp            = 31,
 
        .interlace      = true,
+
+       .hsync_level = OMAPDSS_SIG_ACTIVE_LOW,
+       .vsync_level = OMAPDSS_SIG_ACTIVE_LOW,
+       .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE,
+       .de_level = OMAPDSS_SIG_ACTIVE_HIGH,
+       .sync_pclk_edge = OMAPDSS_DRIVE_SIG_FALLING_EDGE,
 };
 EXPORT_SYMBOL(omap_dss_ntsc_timings);
 
index e3e9e3d46d1bf55028cf4a7902fa72b494fb3ce6..96a1b8da53715e7501d09369ee9ef375f421e936 100644 (file)
@@ -281,7 +281,8 @@ static void handle_irq_for_port(unsigned port)
 
 static void consume_one_event(unsigned cpu,
                              struct evtchn_fifo_control_block *control_block,
-                             unsigned priority, unsigned long *ready)
+                             unsigned priority, unsigned long *ready,
+                             bool drop)
 {
        struct evtchn_fifo_queue *q = &per_cpu(cpu_queue, cpu);
        uint32_t head;
@@ -313,13 +314,17 @@ static void consume_one_event(unsigned cpu,
        if (head == 0)
                clear_bit(priority, ready);
 
-       if (evtchn_fifo_is_pending(port) && !evtchn_fifo_is_masked(port))
-               handle_irq_for_port(port);
+       if (evtchn_fifo_is_pending(port) && !evtchn_fifo_is_masked(port)) {
+               if (unlikely(drop))
+                       pr_warn("Dropping pending event for port %u\n", port);
+               else
+                       handle_irq_for_port(port);
+       }
 
        q->head[priority] = head;
 }
 
-static void evtchn_fifo_handle_events(unsigned cpu)
+static void __evtchn_fifo_handle_events(unsigned cpu, bool drop)
 {
        struct evtchn_fifo_control_block *control_block;
        unsigned long ready;
@@ -331,11 +336,16 @@ static void evtchn_fifo_handle_events(unsigned cpu)
 
        while (ready) {
                q = find_first_bit(&ready, EVTCHN_FIFO_MAX_QUEUES);
-               consume_one_event(cpu, control_block, q, &ready);
+               consume_one_event(cpu, control_block, q, &ready, drop);
                ready |= xchg(&control_block->ready, 0);
        }
 }
 
+static void evtchn_fifo_handle_events(unsigned cpu)
+{
+       __evtchn_fifo_handle_events(cpu, false);
+}
+
 static void evtchn_fifo_resume(void)
 {
        unsigned cpu;
@@ -420,6 +430,9 @@ static int evtchn_fifo_cpu_notification(struct notifier_block *self,
                if (!per_cpu(cpu_control_block, cpu))
                        ret = evtchn_fifo_alloc_control_block(cpu);
                break;
+       case CPU_DEAD:
+               __evtchn_fifo_handle_events(cpu, true);
+               break;
        default:
                break;
        }
index 58e38d586f524fd6b78b18594cbf2de593c1119e..4d529f3e40df93941c99f6fffee06da540f28ca2 100644 (file)
@@ -37,6 +37,7 @@ struct xen_pcibk_device {
        struct xen_pci_sharedinfo *sh_info;
        unsigned long flags;
        struct work_struct op_work;
+       struct xen_pci_op op;
 };
 
 struct xen_pcibk_dev_data {
index c4a0666de6f5e08a17edf4fcbcb001478d0e303b..73dafdc494aa8322e037f1d4a9ad4ec5530c5743 100644 (file)
@@ -70,6 +70,13 @@ static void xen_pcibk_control_isr(struct pci_dev *dev, int reset)
                enable ? "enable" : "disable");
 
        if (enable) {
+               /*
+                * The MSI or MSI-X should not have an IRQ handler. Otherwise
+                * if the guest terminates we BUG_ON in free_msi_irqs.
+                */
+               if (dev->msi_enabled || dev->msix_enabled)
+                       goto out;
+
                rc = request_irq(dev_data->irq,
                                xen_pcibk_guest_interrupt, IRQF_SHARED,
                                dev_data->irq_name, dev);
@@ -144,7 +151,12 @@ int xen_pcibk_enable_msi(struct xen_pcibk_device *pdev,
        if (unlikely(verbose_request))
                printk(KERN_DEBUG DRV_NAME ": %s: enable MSI\n", pci_name(dev));
 
-       status = pci_enable_msi(dev);
+       if (dev->msi_enabled)
+               status = -EALREADY;
+       else if (dev->msix_enabled)
+               status = -ENXIO;
+       else
+               status = pci_enable_msi(dev);
 
        if (status) {
                pr_warn_ratelimited("%s: error enabling MSI for guest %u: err %d\n",
@@ -173,20 +185,23 @@ static
 int xen_pcibk_disable_msi(struct xen_pcibk_device *pdev,
                          struct pci_dev *dev, struct xen_pci_op *op)
 {
-       struct xen_pcibk_dev_data *dev_data;
-
        if (unlikely(verbose_request))
                printk(KERN_DEBUG DRV_NAME ": %s: disable MSI\n",
                       pci_name(dev));
-       pci_disable_msi(dev);
 
+       if (dev->msi_enabled) {
+               struct xen_pcibk_dev_data *dev_data;
+
+               pci_disable_msi(dev);
+
+               dev_data = pci_get_drvdata(dev);
+               if (dev_data)
+                       dev_data->ack_intr = 1;
+       }
        op->value = dev->irq ? xen_pirq_from_irq(dev->irq) : 0;
        if (unlikely(verbose_request))
                printk(KERN_DEBUG DRV_NAME ": %s: MSI: %d\n", pci_name(dev),
                        op->value);
-       dev_data = pci_get_drvdata(dev);
-       if (dev_data)
-               dev_data->ack_intr = 1;
        return 0;
 }
 
@@ -197,13 +212,26 @@ int xen_pcibk_enable_msix(struct xen_pcibk_device *pdev,
        struct xen_pcibk_dev_data *dev_data;
        int i, result;
        struct msix_entry *entries;
+       u16 cmd;
 
        if (unlikely(verbose_request))
                printk(KERN_DEBUG DRV_NAME ": %s: enable MSI-X\n",
                       pci_name(dev));
+
        if (op->value > SH_INFO_MAX_VEC)
                return -EINVAL;
 
+       if (dev->msix_enabled)
+               return -EALREADY;
+
+       /*
+        * PCI_COMMAND_MEMORY must be enabled, otherwise we may not be able
+        * to access the BARs where the MSI-X entries reside.
+        */
+       pci_read_config_word(dev, PCI_COMMAND, &cmd);
+       if (dev->msi_enabled || !(cmd & PCI_COMMAND_MEMORY))
+               return -ENXIO;
+
        entries = kmalloc(op->value * sizeof(*entries), GFP_KERNEL);
        if (entries == NULL)
                return -ENOMEM;
@@ -245,23 +273,27 @@ static
 int xen_pcibk_disable_msix(struct xen_pcibk_device *pdev,
                           struct pci_dev *dev, struct xen_pci_op *op)
 {
-       struct xen_pcibk_dev_data *dev_data;
        if (unlikely(verbose_request))
                printk(KERN_DEBUG DRV_NAME ": %s: disable MSI-X\n",
                        pci_name(dev));
-       pci_disable_msix(dev);
 
+       if (dev->msix_enabled) {
+               struct xen_pcibk_dev_data *dev_data;
+
+               pci_disable_msix(dev);
+
+               dev_data = pci_get_drvdata(dev);
+               if (dev_data)
+                       dev_data->ack_intr = 1;
+       }
        /*
         * SR-IOV devices (which don't have any legacy IRQ) have
         * an undefined IRQ value of zero.
         */
        op->value = dev->irq ? xen_pirq_from_irq(dev->irq) : 0;
        if (unlikely(verbose_request))
-               printk(KERN_DEBUG DRV_NAME ": %s: MSI-X: %d\n", pci_name(dev),
-                       op->value);
-       dev_data = pci_get_drvdata(dev);
-       if (dev_data)
-               dev_data->ack_intr = 1;
+               printk(KERN_DEBUG DRV_NAME ": %s: MSI-X: %d\n",
+                      pci_name(dev), op->value);
        return 0;
 }
 #endif
@@ -298,9 +330,11 @@ void xen_pcibk_do_op(struct work_struct *data)
                container_of(data, struct xen_pcibk_device, op_work);
        struct pci_dev *dev;
        struct xen_pcibk_dev_data *dev_data = NULL;
-       struct xen_pci_op *op = &pdev->sh_info->op;
+       struct xen_pci_op *op = &pdev->op;
        int test_intx = 0;
 
+       *op = pdev->sh_info->op;
+       barrier();
        dev = xen_pcibk_get_pci_dev(pdev, op->domain, op->bus, op->devfn);
 
        if (dev == NULL)
@@ -342,6 +376,17 @@ void xen_pcibk_do_op(struct work_struct *data)
                if ((dev_data->enable_intx != test_intx))
                        xen_pcibk_control_isr(dev, 0 /* no reset */);
        }
+       pdev->sh_info->op.err = op->err;
+       pdev->sh_info->op.value = op->value;
+#ifdef CONFIG_PCI_MSI
+       if (op->cmd == XEN_PCI_OP_enable_msix && op->err == 0) {
+               unsigned int i;
+
+               for (i = 0; i < op->value; i++)
+                       pdev->sh_info->op.msix_entries[i].vector =
+                               op->msix_entries[i].vector;
+       }
+#endif
        /* Tell the driver domain that we're done. */
        wmb();
        clear_bit(_XEN_PCIF_active, (unsigned long *)&pdev->sh_info->flags);
index 98bc345f296ef866eaf0e3b1ffffad12ca35fb7e..4843741e703a336da72162af91165392f0560490 100644 (file)
@@ -44,7 +44,6 @@ static struct xen_pcibk_device *alloc_pdev(struct xenbus_device *xdev)
        dev_dbg(&xdev->dev, "allocated pdev @ 0x%p\n", pdev);
 
        pdev->xdev = xdev;
-       dev_set_drvdata(&xdev->dev, pdev);
 
        mutex_init(&pdev->dev_lock);
 
@@ -58,6 +57,9 @@ static struct xen_pcibk_device *alloc_pdev(struct xenbus_device *xdev)
                kfree(pdev);
                pdev = NULL;
        }
+
+       dev_set_drvdata(&xdev->dev, pdev);
+
 out:
        return pdev;
 }
index 43bcae852546ad2e5021b4a1d326dda375ae4023..ad4eb1024d1ffb7663db4e770fdd4c5c2663e821 100644 (file)
@@ -726,7 +726,7 @@ static int scsiback_do_cmd_fn(struct vscsibk_info *info)
                if (!pending_req)
                        return 1;
 
-               ring_req = *RING_GET_REQUEST(ring, rc);
+               RING_COPY_REQUEST(ring, rc, &ring_req);
                ring->req_cons = ++rc;
 
                err = prepare_pending_reqs(info, &ring_req, pending_req);
index c25639e907bd21a194aecedc6c60a93fb4994375..44d4a1e9244e74e923d7b26018d4b420aa2e1323 100644 (file)
@@ -1523,11 +1523,14 @@ static void __blkdev_put(struct block_device *bdev, fmode_t mode, int for_part)
                WARN_ON_ONCE(bdev->bd_holders);
                sync_blockdev(bdev);
                kill_bdev(bdev);
+
+               bdev_write_inode(bdev);
                /*
-                * ->release can cause the queue to disappear, so flush all
-                * dirty data before.
+                * Detaching bdev inode from its wb in __destroy_inode()
+                * is too late: the queue which embeds its bdi (along with
+                * root wb) can be gone as soon as we put_disk() below.
                 */
-               bdev_write_inode(bdev);
+               inode_detach_wb(bdev->bd_inode);
        }
        if (bdev->bd_contains == bdev) {
                if (disk->fops->release)
index 4b89680a192338c7a70a4c909e3c4374abe41284..c4661db2b72ae4c412adaaecb7cbc236fbe1e7cf 100644 (file)
@@ -10480,11 +10480,15 @@ void btrfs_delete_unused_bgs(struct btrfs_fs_info *fs_info)
                 * until transaction commit to do the actual discard.
                 */
                if (trimming) {
-                       WARN_ON(!list_empty(&block_group->bg_list));
-                       spin_lock(&trans->transaction->deleted_bgs_lock);
+                       spin_lock(&fs_info->unused_bgs_lock);
+                       /*
+                        * A concurrent scrub might have added us to the list
+                        * fs_info->unused_bgs, so use a list_move operation
+                        * to add the block group to the deleted_bgs list.
+                        */
                        list_move(&block_group->bg_list,
                                  &trans->transaction->deleted_bgs);
-                       spin_unlock(&trans->transaction->deleted_bgs_lock);
+                       spin_unlock(&fs_info->unused_bgs_lock);
                        btrfs_get_block_group(block_group);
                }
 end_trans:
index 72e73461c0643bbf128504c93a9c47dd377784aa..0f09526aa7d9d2017bb229eb4310f777c4b3b578 100644 (file)
@@ -1291,7 +1291,8 @@ out:
  * on error we return an unlocked page and the error value
  * on success we return a locked page and 0
  */
-static int prepare_uptodate_page(struct page *page, u64 pos,
+static int prepare_uptodate_page(struct inode *inode,
+                                struct page *page, u64 pos,
                                 bool force_uptodate)
 {
        int ret = 0;
@@ -1306,6 +1307,10 @@ static int prepare_uptodate_page(struct page *page, u64 pos,
                        unlock_page(page);
                        return -EIO;
                }
+               if (page->mapping != inode->i_mapping) {
+                       unlock_page(page);
+                       return -EAGAIN;
+               }
        }
        return 0;
 }
@@ -1324,6 +1329,7 @@ static noinline int prepare_pages(struct inode *inode, struct page **pages,
        int faili;
 
        for (i = 0; i < num_pages; i++) {
+again:
                pages[i] = find_or_create_page(inode->i_mapping, index + i,
                                               mask | __GFP_WRITE);
                if (!pages[i]) {
@@ -1333,13 +1339,17 @@ static noinline int prepare_pages(struct inode *inode, struct page **pages,
                }
 
                if (i == 0)
-                       err = prepare_uptodate_page(pages[i], pos,
+                       err = prepare_uptodate_page(inode, pages[i], pos,
                                                    force_uptodate);
-               if (i == num_pages - 1)
-                       err = prepare_uptodate_page(pages[i],
+               if (!err && i == num_pages - 1)
+                       err = prepare_uptodate_page(inode, pages[i],
                                                    pos + write_bytes, false);
                if (err) {
                        page_cache_release(pages[i]);
+                       if (err == -EAGAIN) {
+                               err = 0;
+                               goto again;
+                       }
                        faili = i - 1;
                        goto fail;
                }
index 85a1f8621b51f09f0893abae9ffab90382efdcfc..cfe99bec49dedd723e2a7fff04ace299be37ef87 100644 (file)
@@ -891,7 +891,7 @@ out:
                spin_unlock(&block_group->lock);
                ret = 0;
 
-               btrfs_warn(fs_info, "failed to load free space cache for block group %llu, rebuild it now",
+               btrfs_warn(fs_info, "failed to load free space cache for block group %llu, rebuilding it now",
                        block_group->key.objectid);
        }
 
@@ -2972,7 +2972,7 @@ setup_cluster_bitmap(struct btrfs_block_group_cache *block_group,
                     u64 cont1_bytes, u64 min_bytes)
 {
        struct btrfs_free_space_ctl *ctl = block_group->free_space_ctl;
-       struct btrfs_free_space *entry;
+       struct btrfs_free_space *entry = NULL;
        int ret = -ENOSPC;
        u64 bitmap_offset = offset_to_bitmap(ctl, offset);
 
@@ -2983,8 +2983,10 @@ setup_cluster_bitmap(struct btrfs_block_group_cache *block_group,
         * The bitmap that covers offset won't be in the list unless offset
         * is just its start offset.
         */
-       entry = list_first_entry(bitmaps, struct btrfs_free_space, list);
-       if (entry->offset != bitmap_offset) {
+       if (!list_empty(bitmaps))
+               entry = list_first_entry(bitmaps, struct btrfs_free_space, list);
+
+       if (!entry || entry->offset != bitmap_offset) {
                entry = tree_search_offset(ctl, bitmap_offset, 1, 0);
                if (entry && list_empty(&entry->list))
                        list_add(&entry->list, bitmaps);
index 3367a3c6f214f5ca248a79fff36c6404a49fbf4f..be8eae80ff6572608a478610f9c2b16f3bcb1871 100644 (file)
@@ -274,7 +274,6 @@ loop:
        cur_trans->num_dirty_bgs = 0;
        spin_lock_init(&cur_trans->dirty_bgs_lock);
        INIT_LIST_HEAD(&cur_trans->deleted_bgs);
-       spin_lock_init(&cur_trans->deleted_bgs_lock);
        spin_lock_init(&cur_trans->dropped_roots_lock);
        list_add_tail(&cur_trans->list, &fs_info->trans_list);
        extent_io_tree_init(&cur_trans->dirty_pages,
index 0da21ca9b3fb312a7ec77b4e8314a9e4b3410075..64c8221b6165bb7a6b786ac74e1833f2b93a197b 100644 (file)
@@ -77,8 +77,8 @@ struct btrfs_transaction {
         */
        struct mutex cache_write_mutex;
        spinlock_t dirty_bgs_lock;
+       /* Protected by spin lock fs_info->unused_bgs_lock. */
        struct list_head deleted_bgs;
-       spinlock_t deleted_bgs_lock;
        spinlock_t dropped_roots_lock;
        struct btrfs_delayed_ref_root delayed_refs;
        int aborted;
index 45645220660996773b1f76cd1d526d4aeae33dac..a23399e8e3aba2f63d4c0cee90932d073d3bd113 100644 (file)
@@ -3548,12 +3548,11 @@ again:
 
                        ret = btrfs_force_chunk_alloc(trans, chunk_root,
                                                      BTRFS_BLOCK_GROUP_DATA);
+                       btrfs_end_transaction(trans, chunk_root);
                        if (ret < 0) {
                                mutex_unlock(&fs_info->delete_unused_bgs_mutex);
                                goto error;
                        }
-
-                       btrfs_end_transaction(trans, chunk_root);
                        chunk_reserved = 1;
                }
 
index 6b66dd5d15408676ab6510f7ce415164fe5c0571..a329f5ba35aad8649ce3f644b9b11913c57cc5f8 100644 (file)
@@ -1831,11 +1831,11 @@ cifs_invalidate_mapping(struct inode *inode)
  * @word: long word containing the bit lock
  */
 static int
-cifs_wait_bit_killable(struct wait_bit_key *key)
+cifs_wait_bit_killable(struct wait_bit_key *key, int mode)
 {
-       if (fatal_signal_pending(current))
-               return -ERESTARTSYS;
        freezable_schedule_unsafe();
+       if (signal_pending_state(mode, current))
+               return -ERESTARTSYS;
        return 0;
 }
 
index 73c64daa0f5517b4ff8271bd17e25740bb83d506..60f03b78914e3012e50c90a9e9069aff615467be 100644 (file)
@@ -592,10 +592,7 @@ static struct page *__r4w_get_page(void *priv, u64 offset, bool *uptodate)
                        }
                        unlock_page(page);
                }
-               if (PageDirty(page) || PageWriteback(page))
-                       *uptodate = true;
-               else
-                       *uptodate = PageUptodate(page);
+               *uptodate = PageUptodate(page);
                EXOFS_DBGMSG2("index=0x%lx uptodate=%d\n", index, *uptodate);
                return page;
        } else {
index eae2c11268bcb484075cfd08482beeb172dd66bc..8e3ee1936c7e38ba381b33c26b2f1847422a613f 100644 (file)
@@ -549,6 +549,8 @@ static int cuse_channel_release(struct inode *inode, struct file *file)
                unregister_chrdev_region(cc->cdev->dev, 1);
                cdev_del(cc->cdev);
        }
+       /* Base reference is now owned by "fud" */
+       fuse_conn_put(&cc->fc);
 
        rc = fuse_dev_release(inode, file);     /* puts the base reference */
 
index e0faf8f2c868a26b80331ef78c89db85091715ea..570ca4053c805eb76acd76a44161f8349a9a6325 100644 (file)
@@ -1049,6 +1049,7 @@ static ssize_t fuse_fill_write_pages(struct fuse_req *req,
                tmp = iov_iter_copy_from_user_atomic(page, ii, offset, bytes);
                flush_dcache_page(page);
 
+               iov_iter_advance(ii, tmp);
                if (!tmp) {
                        unlock_page(page);
                        page_cache_release(page);
@@ -1061,7 +1062,6 @@ static ssize_t fuse_fill_write_pages(struct fuse_req *req,
                req->page_descs[req->num_pages].length = tmp;
                req->num_pages++;
 
-               iov_iter_advance(ii, tmp);
                count += tmp;
                pos += tmp;
                offset += tmp;
index beac58b0e09cbbb0a3cc74fbb55bfe6853c1d616..646cdac73488e96041f2bcad33b4220b096da684 100644 (file)
@@ -78,8 +78,7 @@ static __be32 *read_buf(struct xdr_stream *xdr, int nbytes)
 
        p = xdr_inline_decode(xdr, nbytes);
        if (unlikely(p == NULL))
-               printk(KERN_WARNING "NFS: NFSv4 callback reply buffer overflowed "
-                                                       "or truncated request.\n");
+               printk(KERN_WARNING "NFS: NFSv4 callback reply buffer overflowed!\n");
        return p;
 }
 
@@ -890,7 +889,6 @@ static __be32 nfs4_callback_compound(struct svc_rqst *rqstp, void *argp, void *r
        struct cb_compound_hdr_arg hdr_arg = { 0 };
        struct cb_compound_hdr_res hdr_res = { NULL };
        struct xdr_stream xdr_in, xdr_out;
-       struct xdr_buf *rq_arg = &rqstp->rq_arg;
        __be32 *p, status;
        struct cb_process_state cps = {
                .drc_status = 0,
@@ -902,8 +900,7 @@ static __be32 nfs4_callback_compound(struct svc_rqst *rqstp, void *argp, void *r
 
        dprintk("%s: start\n", __func__);
 
-       rq_arg->len = rq_arg->head[0].iov_len + rq_arg->page_len;
-       xdr_init_decode(&xdr_in, rq_arg, rq_arg->head[0].iov_base);
+       xdr_init_decode(&xdr_in, &rqstp->rq_arg, rqstp->rq_arg.head[0].iov_base);
 
        p = (__be32*)((char *)rqstp->rq_res.head[0].iov_base + rqstp->rq_res.head[0].iov_len);
        xdr_init_encode(&xdr_out, &rqstp->rq_res, p);
index 31b0a52223a73758c385d18bea4ec22ed63c2884..c7e8b87da5b24d13dff36f5d2510244c01b7abf4 100644 (file)
@@ -75,11 +75,11 @@ nfs_fattr_to_ino_t(struct nfs_fattr *fattr)
  * nfs_wait_bit_killable - helper for functions that are sleeping on bit locks
  * @word: long word containing the bit lock
  */
-int nfs_wait_bit_killable(struct wait_bit_key *key)
+int nfs_wait_bit_killable(struct wait_bit_key *key, int mode)
 {
-       if (fatal_signal_pending(current))
-               return -ERESTARTSYS;
        freezable_schedule_unsafe();
+       if (signal_pending_state(mode, current))
+               return -ERESTARTSYS;
        return 0;
 }
 EXPORT_SYMBOL_GPL(nfs_wait_bit_killable);
index 56cfde26fb9cea0100a99bb7c3fe8a2be813dc63..9dea85f7f918ec410c5281f959e6f546c1700bf2 100644 (file)
@@ -379,7 +379,7 @@ extern int nfs_drop_inode(struct inode *);
 extern void nfs_clear_inode(struct inode *);
 extern void nfs_evict_inode(struct inode *);
 void nfs_zap_acl_cache(struct inode *inode);
-extern int nfs_wait_bit_killable(struct wait_bit_key *key);
+extern int nfs_wait_bit_killable(struct wait_bit_key *key, int mode);
 
 /* super.c */
 extern const struct super_operations nfs_sops;
index 5c0c6b58157f906d6c35ce737a6d4a5623027bf1..9aebffb4050597e1daae74f28375d86335f73e0c 100644 (file)
@@ -476,10 +476,7 @@ static struct page *__r4w_get_page(void *priv, u64 offset, bool *uptodate)
                }
                unlock_page(page);
        }
-       if (PageDirty(page) || PageWriteback(page))
-               *uptodate = true;
-       else
-               *uptodate = PageUptodate(page);
+       *uptodate = PageUptodate(page);
        dprintk("%s: index=0x%lx uptodate=%d\n", __func__, index, *uptodate);
        return page;
 }
index fe3ddd20ff89095331ad854bafb4b26bc019e01e..452a011ba0d8a33e9e4b9afd858f82858185f57e 100644 (file)
@@ -129,7 +129,7 @@ __nfs_iocounter_wait(struct nfs_io_counter *c)
                set_bit(NFS_IO_INPROGRESS, &c->flags);
                if (atomic_read(&c->io_count) == 0)
                        break;
-               ret = nfs_wait_bit_killable(&q.key);
+               ret = nfs_wait_bit_killable(&q.key, TASK_KILLABLE);
        } while (atomic_read(&c->io_count) != 0 && !ret);
        finish_wait(wq, &q.wait);
        return ret;
index 5a8ae2125b50855d6f9f304ffd737fbbb57bb02a..bec0384499f76dd1acc8fb13bbf34c2ee17e6a9b 100644 (file)
@@ -1466,11 +1466,11 @@ static bool pnfs_within_mdsthreshold(struct nfs_open_context *ctx,
 }
 
 /* stop waiting if someone clears NFS_LAYOUT_RETRY_LAYOUTGET bit. */
-static int pnfs_layoutget_retry_bit_wait(struct wait_bit_key *key)
+static int pnfs_layoutget_retry_bit_wait(struct wait_bit_key *key, int mode)
 {
        if (!test_bit(NFS_LAYOUT_RETRY_LAYOUTGET, key->flags))
                return 1;
-       return nfs_wait_bit_killable(key);
+       return nfs_wait_bit_killable(key, mode);
 }
 
 static bool pnfs_prepare_to_retry_layoutget(struct pnfs_layout_hdr *lo)
index 9ffef06b30d51e2acb2ae1a6570f14c2c47eac59..c9d6c715c0fb7e3187ffd1f2105f9527aa32259b 100644 (file)
@@ -616,6 +616,7 @@ nfsd4_cb_layout_prepare(struct nfsd4_callback *cb)
 
        mutex_lock(&ls->ls_mutex);
        nfs4_inc_and_copy_stateid(&ls->ls_recall_sid, &ls->ls_stid);
+       mutex_unlock(&ls->ls_mutex);
 }
 
 static int
@@ -659,7 +660,6 @@ nfsd4_cb_layout_release(struct nfsd4_callback *cb)
 
        trace_layout_recall_release(&ls->ls_stid.sc_stateid);
 
-       mutex_unlock(&ls->ls_mutex);
        nfsd4_return_all_layouts(ls, &reaplist);
        nfsd4_free_layouts(&reaplist);
        nfs4_put_stid(&ls->ls_stid);
index ce38b4ccc9ab6c52c796a148b496bab0d8d46510..84f2f8079466a7fc07c8a4fda50d3513a02b68f9 100644 (file)
@@ -2843,6 +2843,8 @@ again:
        res->state &= ~DLM_LOCK_RES_BLOCK_DIRTY;
        if (!ret)
                BUG_ON(!(res->state & DLM_LOCK_RES_MIGRATING));
+       else
+               res->migration_pending = 0;
        spin_unlock(&res->spinlock);
 
        /*
index 652ece4a9d9e2e90a72a95b4be1d910ea46cfc9f..d56f0079b858081241357b26667bf7fba9de5e3e 100644 (file)
@@ -67,7 +67,10 @@ static int ocfs2_do_flock(struct file *file, struct inode *inode,
                 */
 
                locks_lock_file_wait(file,
-                                    &(struct file_lock){.fl_type = F_UNLCK});
+                               &(struct file_lock) {
+                                       .fl_type = F_UNLCK,
+                                       .fl_flags = FL_FLOCK
+                               });
 
                ocfs2_file_unlock(file);
        }
index a03f6f433075c02d3c87c192b362d2c7f2e96952..3123408da9352b365e8bb3ca5e619a8f188cdc5a 100644 (file)
@@ -367,13 +367,11 @@ static int ocfs2_mknod(struct inode *dir,
                goto leave;
        }
 
-       status = posix_acl_create(dir, &mode, &default_acl, &acl);
+       status = posix_acl_create(dir, &inode->i_mode, &default_acl, &acl);
        if (status) {
                mlog_errno(status);
                goto leave;
        }
-       /* update inode->i_mode after mask with "umask". */
-       inode->i_mode = mode;
 
        handle = ocfs2_start_trans(osb, ocfs2_mknod_credits(osb->sb,
                                                            S_ISDIR(mode),
index d5da6f624142812ab63e83f5ab1b90e05151fed3..79b8021302b3eed84b9c59637cddd0e4844eb78b 100644 (file)
 static u16 ocfs2_calc_new_backup_super(struct inode *inode,
                                       struct ocfs2_group_desc *gd,
                                       u16 cl_cpg,
+                                      u16 old_bg_clusters,
                                       int set)
 {
        int i;
        u16 backups = 0;
-       u32 cluster;
+       u32 cluster, lgd_cluster;
        u64 blkno, gd_blkno, lgd_blkno = le64_to_cpu(gd->bg_blkno);
 
        for (i = 0; i < OCFS2_MAX_BACKUP_SUPERBLOCKS; i++) {
@@ -71,6 +72,12 @@ static u16 ocfs2_calc_new_backup_super(struct inode *inode,
                else if (gd_blkno > lgd_blkno)
                        break;
 
+               /* check if already done backup super */
+               lgd_cluster = ocfs2_blocks_to_clusters(inode->i_sb, lgd_blkno);
+               lgd_cluster += old_bg_clusters;
+               if (lgd_cluster >= cluster)
+                       continue;
+
                if (set)
                        ocfs2_set_bit(cluster % cl_cpg,
                                      (unsigned long *)gd->bg_bitmap);
@@ -99,6 +106,7 @@ static int ocfs2_update_last_group_and_inode(handle_t *handle,
        u16 chain, num_bits, backups = 0;
        u16 cl_bpc = le16_to_cpu(cl->cl_bpc);
        u16 cl_cpg = le16_to_cpu(cl->cl_cpg);
+       u16 old_bg_clusters;
 
        trace_ocfs2_update_last_group_and_inode(new_clusters,
                                                first_new_cluster);
@@ -112,6 +120,7 @@ static int ocfs2_update_last_group_and_inode(handle_t *handle,
 
        group = (struct ocfs2_group_desc *)group_bh->b_data;
 
+       old_bg_clusters = le16_to_cpu(group->bg_bits) / cl_bpc;
        /* update the group first. */
        num_bits = new_clusters * cl_bpc;
        le16_add_cpu(&group->bg_bits, num_bits);
@@ -125,7 +134,7 @@ static int ocfs2_update_last_group_and_inode(handle_t *handle,
                                     OCFS2_FEATURE_COMPAT_BACKUP_SB)) {
                backups = ocfs2_calc_new_backup_super(bm_inode,
                                                     group,
-                                                    cl_cpg, 1);
+                                                    cl_cpg, old_bg_clusters, 1);
                le16_add_cpu(&group->bg_free_bits_count, -1 * backups);
        }
 
@@ -163,7 +172,7 @@ out_rollback:
        if (ret < 0) {
                ocfs2_calc_new_backup_super(bm_inode,
                                            group,
-                                           cl_cpg, 0);
+                                           cl_cpg, old_bg_clusters, 0);
                le16_add_cpu(&group->bg_free_bits_count, backups);
                le16_add_cpu(&group->bg_bits, -1 * num_bits);
                le16_add_cpu(&group->bg_free_bits_count, -1 * num_bits);
index bd3e9e68125b8933b2e32a4fea2e2282397dc1cd..4bd5d3118acd4b152d6e6f17b38b0a03b0f723d6 100644 (file)
@@ -2494,6 +2494,7 @@ static ssize_t proc_coredump_filter_write(struct file *file,
        mm = get_task_mm(task);
        if (!mm)
                goto out_no_mm;
+       ret = 0;
 
        for (i = 0, mask = 1; i < MMF_DUMP_FILTER_BITS; i++, mask <<= 1) {
                if (val & mask)
index 0169ba2e2e64b9c4bba07bf72b9c1194fe2db08a..c70e3588a48c723f4b7cd8536c0dabfc02871d5c 100644 (file)
@@ -797,6 +797,7 @@ extern int sg_scsi_ioctl(struct request_queue *, struct gendisk *, fmode_t,
 extern int blk_queue_enter(struct request_queue *q, gfp_t gfp);
 extern void blk_queue_exit(struct request_queue *q);
 extern void blk_start_queue(struct request_queue *q);
+extern void blk_start_queue_async(struct request_queue *q);
 extern void blk_stop_queue(struct request_queue *q);
 extern void blk_sync_queue(struct request_queue *q);
 extern void __blk_stop_queue(struct request_queue *q);
index 7be22da321f38eb1327bbbcaabddd6cbca131d44..a4cf57cd0f7512d66b15a036cb76114d5bf633e0 100644 (file)
 /* A few generic types ... taken from ses-2 */
 enum enclosure_component_type {
        ENCLOSURE_COMPONENT_DEVICE = 0x01,
+       ENCLOSURE_COMPONENT_CONTROLLER_ELECTRONICS = 0x07,
+       ENCLOSURE_COMPONENT_SCSI_TARGET_PORT = 0x14,
+       ENCLOSURE_COMPONENT_SCSI_INITIATOR_PORT = 0x15,
        ENCLOSURE_COMPONENT_ARRAY_DEVICE = 0x17,
+       ENCLOSURE_COMPONENT_SAS_EXPANDER = 0x18,
 };
 
 /* ses-2 common element status */
index 4165e9ac9e36aa82735f40a790e25e0b7218c95b..5972ffe5719a4e14012328035450759c12f43bec 100644 (file)
@@ -493,6 +493,25 @@ static inline void bpf_jit_free(struct bpf_prog *fp)
 
 #define BPF_ANC                BIT(15)
 
+static inline bool bpf_needs_clear_a(const struct sock_filter *first)
+{
+       switch (first->code) {
+       case BPF_RET | BPF_K:
+       case BPF_LD | BPF_W | BPF_LEN:
+               return false;
+
+       case BPF_LD | BPF_W | BPF_ABS:
+       case BPF_LD | BPF_H | BPF_ABS:
+       case BPF_LD | BPF_B | BPF_ABS:
+               if (first->k == SKF_AD_OFF + SKF_AD_ALU_XOR_X)
+                       return true;
+               return false;
+
+       default:
+               return true;
+       }
+}
+
 static inline u16 bpf_anc_helper(const struct sock_filter *ftest)
 {
        BUG_ON(ftest->code & BPF_ANC);
index eae6548efbf060d9a2ec21bd716b0c0e2b6f2be7..60048c50404ee612aae6535ef8abfcf8475086d6 100644 (file)
@@ -586,6 +586,7 @@ extern int ftrace_arch_read_dyn_info(char *buf, int size);
 
 extern int skip_trace(unsigned long ip);
 extern void ftrace_module_init(struct module *mod);
+extern void ftrace_release_mod(struct module *mod);
 
 extern void ftrace_disable_daemon(void);
 extern void ftrace_enable_daemon(void);
index c9ae0c6ec050569fc592b6f07b3ce1fa052bcc59..d5d798b35c1f6c105c81d0993bce6140bc4fc83b 100644 (file)
@@ -330,6 +330,7 @@ struct rdists {
 };
 
 struct irq_domain;
+struct device_node;
 int its_cpu_init(void);
 int its_init(struct device_node *node, struct rdists *rdists,
             struct irq_domain *domain);
index d0a1f99e24e3eb43219e9f8b8aad400c1cc867a9..4894c6888bc6cfb95e50d43366784769faf9b281 100644 (file)
@@ -25,7 +25,7 @@
 
 #ifdef CONFIG_DEBUG_KMEMLEAK
 
-extern void kmemleak_init(void) __ref;
+extern void kmemleak_init(void) __init;
 extern void kmemleak_alloc(const void *ptr, size_t size, int min_count,
                           gfp_t gfp) __ref;
 extern void kmemleak_alloc_percpu(const void __percpu *ptr, size_t size,
index c6916aec43b66200033b5a2a2a155d8b72a947bf..034117b3be5f7d91e5e869ea9e856f51964ebac6 100644 (file)
@@ -50,9 +50,16 @@ enum {
        NVM_IO_DUAL_ACCESS      = 0x1,
        NVM_IO_QUAD_ACCESS      = 0x2,
 
+       /* NAND Access Modes */
        NVM_IO_SUSPEND          = 0x80,
        NVM_IO_SLC_MODE         = 0x100,
        NVM_IO_SCRAMBLE_DISABLE = 0x200,
+
+       /* Block Types */
+       NVM_BLK_T_FREE          = 0x0,
+       NVM_BLK_T_BAD           = 0x1,
+       NVM_BLK_T_DEV           = 0x2,
+       NVM_BLK_T_HOST          = 0x4,
 };
 
 struct nvm_id_group {
@@ -176,17 +183,17 @@ struct nvm_block;
 
 typedef int (nvm_l2p_update_fn)(u64, u32, __le64 *, void *);
 typedef int (nvm_bb_update_fn)(struct ppa_addr, int, u8 *, void *);
-typedef int (nvm_id_fn)(struct request_queue *, struct nvm_id *);
-typedef int (nvm_get_l2p_tbl_fn)(struct request_queue *, u64, u32,
+typedef int (nvm_id_fn)(struct nvm_dev *, struct nvm_id *);
+typedef int (nvm_get_l2p_tbl_fn)(struct nvm_dev *, u64, u32,
                                nvm_l2p_update_fn *, void *);
 typedef int (nvm_op_bb_tbl_fn)(struct nvm_dev *, struct ppa_addr, int,
                                nvm_bb_update_fn *, void *);
-typedef int (nvm_op_set_bb_fn)(struct request_queue *, struct nvm_rq *, int);
-typedef int (nvm_submit_io_fn)(struct request_queue *, struct nvm_rq *);
-typedef int (nvm_erase_blk_fn)(struct request_queue *, struct nvm_rq *);
-typedef void *(nvm_create_dma_pool_fn)(struct request_queue *, char *);
+typedef int (nvm_op_set_bb_fn)(struct nvm_dev *, struct nvm_rq *, int);
+typedef int (nvm_submit_io_fn)(struct nvm_dev *, struct nvm_rq *);
+typedef int (nvm_erase_blk_fn)(struct nvm_dev *, struct nvm_rq *);
+typedef void *(nvm_create_dma_pool_fn)(struct nvm_dev *, char *);
 typedef void (nvm_destroy_dma_pool_fn)(void *);
-typedef void *(nvm_dev_dma_alloc_fn)(struct request_queue *, void *, gfp_t,
+typedef void *(nvm_dev_dma_alloc_fn)(struct nvm_dev *, void *, gfp_t,
                                                                dma_addr_t *);
 typedef void (nvm_dev_dma_free_fn)(void *, void*, dma_addr_t);
 
index 7501626ab5293414c29df692edb6fa7122871c84..d3133be12d922521e24528480edbdb31659a7007 100644 (file)
@@ -426,6 +426,17 @@ enum {
        MLX4_MAX_FAST_REG_PAGES = 511,
 };
 
+enum {
+       /*
+        * Max wqe size for rdma read is 512 bytes, so this
+        * limits our max_sge_rd as the wqe needs to fit:
+        * - ctrl segment (16 bytes)
+        * - rdma segment (16 bytes)
+        * - scatter elements (16 bytes each)
+        */
+       MLX4_MAX_SGE_RD = (512 - 16 - 16) / 16
+};
+
 enum {
        MLX4_DEV_PMC_SUBTYPE_GUID_INFO   = 0x14,
        MLX4_DEV_PMC_SUBTYPE_PORT_INFO   = 0x15,
index 877ef226f90fb3b945831c7e8f9edbabba1e9775..772362adf4713b77be041b6232097c97a7f5aad7 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef LINUX_MM_DEBUG_H
 #define LINUX_MM_DEBUG_H 1
 
+#include <linux/bug.h>
 #include <linux/stringify.h>
 
 struct page;
index c8723b62c4cd286aa7b6b382507dbb25cd975ab1..bc742dac7d3a10da925776e9fc4a0ca283a2eda6 100644 (file)
@@ -25,7 +25,7 @@
 #define SNOR_MFR_MACRONIX      CFI_MFR_MACRONIX
 #define SNOR_MFR_SPANSION      CFI_MFR_AMD
 #define SNOR_MFR_SST           CFI_MFR_SST
-#define SNOR_MFR_WINBOND       0xef
+#define SNOR_MFR_WINBOND       0xef /* Also used by some Spansion */
 
 /*
  * Note on opcode nomenclature: some opcodes have a format like
index 3b5d134e945a9b1a5dda9b636c04909318fe8a67..3143c847bddbca47bed1a324bf85e58283e966a5 100644 (file)
@@ -2084,7 +2084,7 @@ struct pcpu_sw_netstats {
 })
 
 #define netdev_alloc_pcpu_stats(type)                                  \
-       __netdev_alloc_pcpu_stats(type, GFP_KERNEL);
+       __netdev_alloc_pcpu_stats(type, GFP_KERNEL)
 
 #include <linux/notifier.h>
 
index 249d1bb01e03b0367f56f251c02269b24be0dac6..5646b24bfc64040d595b6fd4109e0caadc21494d 100644 (file)
@@ -14,7 +14,7 @@ struct nfnl_callback {
        int (*call_rcu)(struct sock *nl, struct sk_buff *skb, 
                    const struct nlmsghdr *nlh,
                    const struct nlattr * const cda[]);
-       int (*call_batch)(struct sock *nl, struct sk_buff *skb,
+       int (*call_batch)(struct net *net, struct sock *nl, struct sk_buff *skb,
                          const struct nlmsghdr *nlh,
                          const struct nlattr * const cda[]);
        const struct nla_policy *policy;        /* netlink attribute policy */
index e2878baeb90e8c804a27d90c37c7d79f14e95942..4299f4ba03bdde8a8eae4209f1cf537b63f0171f 100644 (file)
@@ -72,7 +72,7 @@ struct edma_soc_info {
        struct edma_rsv_info    *rsv;
 
        /* List of channels allocated for memcpy, terminated with -1 */
-       s16                     *memcpy_channels;
+       s32                     *memcpy_channels;
 
        s8      (*queue_priority_mapping)[2];
        const s16       (*xbar_chans)[2];
index 6a4347639c0329235a735d723a564acecf59f022..1d1ba2c5ee7a26f6a35b1835c016a6bd7755fcd8 100644 (file)
@@ -9,6 +9,8 @@
 #ifndef __COMMON_HSI__
 #define __COMMON_HSI__
 
+#define CORE_SPQE_PAGE_SIZE_BYTES                       4096
+
 #define FW_MAJOR_VERSION       8
 #define FW_MINOR_VERSION       4
 #define FW_REVISION_VERSION    2
index b920c3605c462ef0bdb9c8ba0c8cd9d8957addb7..41b9049b57e2475575d076b4f0728234618ce07e 100644 (file)
@@ -111,7 +111,8 @@ static inline u16 qed_chain_get_elem_left(struct qed_chain *p_chain)
        used = ((u32)0x10000u + (u32)(p_chain->prod_idx)) -
                (u32)p_chain->cons_idx;
        if (p_chain->mode == QED_CHAIN_MODE_NEXT_PTR)
-               used -= (used / p_chain->elem_per_page);
+               used -= p_chain->prod_idx / p_chain->elem_per_page -
+                       p_chain->cons_idx / p_chain->elem_per_page;
 
        return p_chain->capacity - used;
 }
index 843ceca9a21e5f1327fa5c82fa5f3089c5ebab23..e50b31d18462c02e5362e84bdeac4f0ab4e0f1ea 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <linux/atomic.h>
 #include <linux/compiler.h>
+#include <linux/err.h>
 #include <linux/errno.h>
 #include <linux/jhash.h>
 #include <linux/list_nulls.h>
@@ -339,10 +340,11 @@ static inline int lockdep_rht_bucket_is_held(const struct bucket_table *tbl,
 int rhashtable_init(struct rhashtable *ht,
                    const struct rhashtable_params *params);
 
-int rhashtable_insert_slow(struct rhashtable *ht, const void *key,
-                          struct rhash_head *obj,
-                          struct bucket_table *old_tbl);
-int rhashtable_insert_rehash(struct rhashtable *ht);
+struct bucket_table *rhashtable_insert_slow(struct rhashtable *ht,
+                                           const void *key,
+                                           struct rhash_head *obj,
+                                           struct bucket_table *old_tbl);
+int rhashtable_insert_rehash(struct rhashtable *ht, struct bucket_table *tbl);
 
 int rhashtable_walk_init(struct rhashtable *ht, struct rhashtable_iter *iter);
 void rhashtable_walk_exit(struct rhashtable_iter *iter);
@@ -598,9 +600,11 @@ restart:
 
        new_tbl = rht_dereference_rcu(tbl->future_tbl, ht);
        if (unlikely(new_tbl)) {
-               err = rhashtable_insert_slow(ht, key, obj, new_tbl);
-               if (err == -EAGAIN)
+               tbl = rhashtable_insert_slow(ht, key, obj, new_tbl);
+               if (!IS_ERR_OR_NULL(tbl))
                        goto slow_path;
+
+               err = PTR_ERR(tbl);
                goto out;
        }
 
@@ -611,7 +615,7 @@ restart:
        if (unlikely(rht_grow_above_100(ht, tbl))) {
 slow_path:
                spin_unlock_bh(lock);
-               err = rhashtable_insert_rehash(ht);
+               err = rhashtable_insert_rehash(ht, tbl);
                rcu_read_unlock();
                if (err)
                        return err;
index edad7a43edea141b3ada89f7f12edac2add7b68e..fa39434e3fdd1c74eaf18dd4a31dae0b69a9db1c 100644 (file)
@@ -1455,14 +1455,15 @@ struct task_struct {
        /* Used for emulating ABI behavior of previous Linux versions */
        unsigned int personality;
 
-       unsigned in_execve:1;   /* Tell the LSMs that the process is doing an
-                                * execve */
-       unsigned in_iowait:1;
-
-       /* Revert to default priority/policy when forking */
+       /* scheduler bits, serialized by scheduler locks */
        unsigned sched_reset_on_fork:1;
        unsigned sched_contributes_to_load:1;
        unsigned sched_migrated:1;
+       unsigned :0; /* force alignment to the next boundary */
+
+       /* unserialized, strictly 'current' */
+       unsigned in_execve:1; /* bit to tell LSMs we're in execve */
+       unsigned in_iowait:1;
 #ifdef CONFIG_MEMCG
        unsigned memcg_may_oom:1;
 #endif
@@ -2002,7 +2003,8 @@ static inline int pid_alive(const struct task_struct *p)
 }
 
 /**
- * is_global_init - check if a task structure is init
+ * is_global_init - check if a task structure is init. Since init
+ * is free to have sub-threads we need to check tgid.
  * @tsk: Task structure to be checked.
  *
  * Check if a task structure is the first user space task the kernel created.
@@ -2011,7 +2013,7 @@ static inline int pid_alive(const struct task_struct *p)
  */
 static inline int is_global_init(struct task_struct *tsk)
 {
-       return tsk->pid == 1;
+       return task_tgid_nr(tsk) == 1;
 }
 
 extern struct pid *cad_pid;
index 0adedca24c5bfbd4ca7a25b80641e76e0e638738..0e1b1540597a47253b6a2e5cc3ef1709d4a42992 100644 (file)
@@ -99,7 +99,7 @@ static inline int try_stop_cpus(const struct cpumask *cpumask,
  * grabbing every spinlock (and more).  So the "read" side to such a
  * lock is anything which disables preemption.
  */
-#if defined(CONFIG_STOP_MACHINE) && defined(CONFIG_SMP)
+#if defined(CONFIG_SMP) || defined(CONFIG_HOTPLUG_CPU)
 
 /**
  * stop_machine: freeze the machine on all CPUs and run this function
@@ -118,7 +118,7 @@ int stop_machine(cpu_stop_fn_t fn, void *data, const struct cpumask *cpus);
 
 int stop_machine_from_inactive_cpu(cpu_stop_fn_t fn, void *data,
                                   const struct cpumask *cpus);
-#else   /* CONFIG_STOP_MACHINE && CONFIG_SMP */
+#else  /* CONFIG_SMP || CONFIG_HOTPLUG_CPU */
 
 static inline int stop_machine(cpu_stop_fn_t fn, void *data,
                                 const struct cpumask *cpus)
@@ -137,5 +137,5 @@ static inline int stop_machine_from_inactive_cpu(cpu_stop_fn_t fn, void *data,
        return stop_machine(fn, data, cpus);
 }
 
-#endif /* CONFIG_STOP_MACHINE && CONFIG_SMP */
+#endif /* CONFIG_SMP || CONFIG_HOTPLUG_CPU */
 #endif /* _LINUX_STOP_MACHINE */
index 1f6526c76ee84f4068707bd0ecae16aaa25c0759..3a375d07d0dc0284441133228af266956ed94f89 100644 (file)
@@ -138,6 +138,7 @@ struct cdc_ncm_ctx {
 };
 
 u8 cdc_ncm_select_altsetting(struct usb_interface *intf);
+int cdc_ncm_change_mtu(struct net_device *net, int new_mtu);
 int cdc_ncm_bind_common(struct usbnet *dev, struct usb_interface *intf, u8 data_altsetting, int drvflags);
 void cdc_ncm_unbind(struct usbnet *dev, struct usb_interface *intf);
 struct sk_buff *cdc_ncm_fill_tx_frame(struct usbnet *dev, struct sk_buff *skb, __le32 sign);
index 9948c874e3f1e4e254ea666a3a7e623678edc26d..1d0043dc34e427403a1c82458249bed83e87d3a0 100644 (file)
@@ -47,4 +47,7 @@
 /* device generates spurious wakeup, ignore remote wakeup capability */
 #define USB_QUIRK_IGNORE_REMOTE_WAKEUP         BIT(9)
 
+/* device can't handle Link Power Management */
+#define USB_QUIRK_NO_LPM                       BIT(10)
+
 #endif /* __LINUX_USB_QUIRKS_H */
index 5dbc8b0ee567a751cf8c60872ae692fccb6a86ab..3e5d9075960f6c756ead3c60013f84f873206932 100644 (file)
@@ -176,11 +176,11 @@ extern void zone_statistics(struct zone *, struct zone *, gfp_t gfp);
 #define sub_zone_page_state(__z, __i, __d) mod_zone_page_state(__z, __i, -(__d))
 
 #ifdef CONFIG_SMP
-void __mod_zone_page_state(struct zone *, enum zone_stat_item item, int);
+void __mod_zone_page_state(struct zone *, enum zone_stat_item item, long);
 void __inc_zone_page_state(struct page *, enum zone_stat_item);
 void __dec_zone_page_state(struct page *, enum zone_stat_item);
 
-void mod_zone_page_state(struct zone *, enum zone_stat_item, int);
+void mod_zone_page_state(struct zone *, enum zone_stat_item, long);
 void inc_zone_page_state(struct page *, enum zone_stat_item);
 void dec_zone_page_state(struct page *, enum zone_stat_item);
 
@@ -205,7 +205,7 @@ void set_pgdat_percpu_threshold(pg_data_t *pgdat,
  * The functions directly modify the zone and global counters.
  */
 static inline void __mod_zone_page_state(struct zone *zone,
-                       enum zone_stat_item item, int delta)
+                       enum zone_stat_item item, long delta)
 {
        zone_page_state_add(delta, zone, item);
 }
index 1e1bf9f963a947fc686125d0a2809ad63b8a13ed..513b36f04dfd80bbe9cf40a272e8d2cd2eab452b 100644 (file)
@@ -145,7 +145,7 @@ __remove_wait_queue(wait_queue_head_t *head, wait_queue_t *old)
        list_del(&old->task_list);
 }
 
-typedef int wait_bit_action_f(struct wait_bit_key *);
+typedef int wait_bit_action_f(struct wait_bit_key *, int mode);
 void __wake_up(wait_queue_head_t *q, unsigned int mode, int nr, void *key);
 void __wake_up_locked_key(wait_queue_head_t *q, unsigned int mode, void *key);
 void __wake_up_sync_key(wait_queue_head_t *q, unsigned int mode, int nr, void *key);
@@ -960,10 +960,10 @@ int wake_bit_function(wait_queue_t *wait, unsigned mode, int sync, void *key);
        } while (0)
 
 
-extern int bit_wait(struct wait_bit_key *);
-extern int bit_wait_io(struct wait_bit_key *);
-extern int bit_wait_timeout(struct wait_bit_key *);
-extern int bit_wait_io_timeout(struct wait_bit_key *);
+extern int bit_wait(struct wait_bit_key *, int);
+extern int bit_wait_io(struct wait_bit_key *, int);
+extern int bit_wait_timeout(struct wait_bit_key *, int);
+extern int bit_wait_io_timeout(struct wait_bit_key *, int);
 
 /**
  * wait_on_bit - wait for a bit to be cleared
index 1279f9b09791ace6885b0dd67c2c28d578b6cd8e..c7329dcd90cc0637e16fe65eb78246a5d8d21521 100644 (file)
@@ -322,6 +322,39 @@ static inline void skb_dst_force(struct sk_buff *skb)
        }
 }
 
+/**
+ * dst_hold_safe - Take a reference on a dst if possible
+ * @dst: pointer to dst entry
+ *
+ * This helper returns false if it could not safely
+ * take a reference on a dst.
+ */
+static inline bool dst_hold_safe(struct dst_entry *dst)
+{
+       if (dst->flags & DST_NOCACHE)
+               return atomic_inc_not_zero(&dst->__refcnt);
+       dst_hold(dst);
+       return true;
+}
+
+/**
+ * skb_dst_force_safe - makes sure skb dst is refcounted
+ * @skb: buffer
+ *
+ * If dst is not yet refcounted and not destroyed, grab a ref on it.
+ */
+static inline void skb_dst_force_safe(struct sk_buff *skb)
+{
+       if (skb_dst_is_noref(skb)) {
+               struct dst_entry *dst = skb_dst(skb);
+
+               if (!dst_hold_safe(dst))
+                       dst = NULL;
+
+               skb->_skb_refdst = (unsigned long)dst;
+       }
+}
+
 
 /**
  *     __skb_tunnel_rx - prepare skb for rx reinsert
index 2134e6d815bcb0611a2f65cd7b4da44cb7762b8c..625bdf95d673d16eda11884e9adf1595c9926d0f 100644 (file)
@@ -210,18 +210,37 @@ struct inet_sock {
 #define IP_CMSG_ORIGDSTADDR    BIT(6)
 #define IP_CMSG_CHECKSUM       BIT(7)
 
-/* SYNACK messages might be attached to request sockets.
+/**
+ * sk_to_full_sk - Access to a full socket
+ * @sk: pointer to a socket
+ *
+ * SYNACK messages might be attached to request sockets.
  * Some places want to reach the listener in this case.
  */
-static inline struct sock *skb_to_full_sk(const struct sk_buff *skb)
+static inline struct sock *sk_to_full_sk(struct sock *sk)
 {
-       struct sock *sk = skb->sk;
-
+#ifdef CONFIG_INET
        if (sk && sk->sk_state == TCP_NEW_SYN_RECV)
                sk = inet_reqsk(sk)->rsk_listener;
+#endif
+       return sk;
+}
+
+/* sk_to_full_sk() variant with a const argument */
+static inline const struct sock *sk_const_to_full_sk(const struct sock *sk)
+{
+#ifdef CONFIG_INET
+       if (sk && sk->sk_state == TCP_NEW_SYN_RECV)
+               sk = ((const struct request_sock *)sk)->rsk_listener;
+#endif
        return sk;
 }
 
+static inline struct sock *skb_to_full_sk(const struct sk_buff *skb)
+{
+       return sk_to_full_sk(skb->sk);
+}
+
 static inline struct inet_sock *inet_sk(const struct sock *sk)
 {
        return (struct inet_sock *)sk;
index 4a6009d4486b9cfc914d583c5065a3be3d23fa7e..235c7811a86a1df748d838c6b4fd453cea0cbf40 100644 (file)
@@ -78,6 +78,7 @@ void inet_initpeers(void) __init;
 static inline void inetpeer_set_addr_v4(struct inetpeer_addr *iaddr, __be32 ip)
 {
        iaddr->a4.addr = ip;
+       iaddr->a4.vif = 0;
        iaddr->family = AF_INET;
 }
 
index 774d85b2d5d97734b79eadea20f090ebf684b057..5689a0c749f76cd7ce5810b6ac165e43ddb0b59d 100644 (file)
@@ -29,7 +29,7 @@ struct l3mdev_ops {
        /* IPv4 ops */
        struct rtable * (*l3mdev_get_rtable)(const struct net_device *dev,
                                             const struct flowi4 *fl4);
-       void            (*l3mdev_get_saddr)(struct net_device *dev,
+       int             (*l3mdev_get_saddr)(struct net_device *dev,
                                            struct flowi4 *fl4);
 
        /* IPv6 ops */
@@ -112,10 +112,11 @@ static inline bool netif_index_is_l3_master(struct net *net, int ifindex)
        return rc;
 }
 
-static inline void l3mdev_get_saddr(struct net *net, int ifindex,
-                                   struct flowi4 *fl4)
+static inline int l3mdev_get_saddr(struct net *net, int ifindex,
+                                  struct flowi4 *fl4)
 {
        struct net_device *dev;
+       int rc = 0;
 
        if (ifindex) {
 
@@ -124,11 +125,13 @@ static inline void l3mdev_get_saddr(struct net *net, int ifindex,
                dev = dev_get_by_index_rcu(net, ifindex);
                if (dev && netif_is_l3_master(dev) &&
                    dev->l3mdev_ops->l3mdev_get_saddr) {
-                       dev->l3mdev_ops->l3mdev_get_saddr(dev, fl4);
+                       rc = dev->l3mdev_ops->l3mdev_get_saddr(dev, fl4);
                }
 
                rcu_read_unlock();
        }
+
+       return rc;
 }
 
 static inline struct dst_entry *l3mdev_get_rt6_dst(const struct net_device *dev,
@@ -200,9 +203,10 @@ static inline bool netif_index_is_l3_master(struct net *net, int ifindex)
        return false;
 }
 
-static inline void l3mdev_get_saddr(struct net *net, int ifindex,
-                                   struct flowi4 *fl4)
+static inline int l3mdev_get_saddr(struct net *net, int ifindex,
+                                  struct flowi4 *fl4)
 {
+       return 0;
 }
 
 static inline
index ee81307863d56329c097bb3ec30d06b07828b2d0..a3b9ef74a3895dbce95b0eba9b4bb298f7be9d71 100644 (file)
@@ -283,7 +283,12 @@ static inline struct rtable *ip_route_connect(struct flowi4 *fl4,
                              sport, dport, sk);
 
        if (!src && oif) {
-               l3mdev_get_saddr(net, oif, fl4);
+               int rc;
+
+               rc = l3mdev_get_saddr(net, oif, fl4);
+               if (rc < 0)
+                       return ERR_PTR(rc);
+
                src = fl4->saddr;
        }
        if (!dst || !src) {
index 7bbb71081aeb6cfdc9cb049cf7a094dbcd4603bb..eea9bdeecba27f0ecff39e9d821fc029028f8e5b 100644 (file)
@@ -1493,7 +1493,8 @@ struct sctp_association {
                 *             : SACK's are not delayed (see Section 6).
                 */
                __u8    sack_needed:1,     /* Do we need to sack the peer? */
-                       sack_generation:1;
+                       sack_generation:1,
+                       zero_window_announced:1;
                __u32   sack_cnt;
 
                __u32   adaptation_ind;  /* Adaptation Code point. */
index 52d27ee924f47867026d8f65c65551a9137219d3..14d3c07340079b7a3e9de54ee635011589247ffd 100644 (file)
@@ -388,7 +388,7 @@ struct sock {
                struct socket_wq        *sk_wq_raw;
        };
 #ifdef CONFIG_XFRM
-       struct xfrm_policy      *sk_policy[2];
+       struct xfrm_policy __rcu *sk_policy[2];
 #endif
        struct dst_entry        *sk_rx_dst;
        struct dst_entry __rcu  *sk_dst_cache;
@@ -404,6 +404,7 @@ struct sock {
                                sk_userlocks : 4,
                                sk_protocol  : 8,
                                sk_type      : 16;
+#define SK_PROTOCOL_MAX U8_MAX
        kmemcheck_bitfield_end(flags);
        int                     sk_wmem_queued;
        gfp_t                   sk_allocation;
@@ -740,6 +741,8 @@ enum sock_flags {
        SOCK_SELECT_ERR_QUEUE, /* Wake select on error queue */
 };
 
+#define SK_FLAGS_TIMESTAMP ((1UL << SOCK_TIMESTAMP) | (1UL << SOCK_TIMESTAMPING_RX_SOFTWARE))
+
 static inline void sock_copy_flags(struct sock *nsk, struct sock *osk)
 {
        nsk->sk_flags = osk->sk_flags;
@@ -814,7 +817,7 @@ void sk_stream_write_space(struct sock *sk);
 static inline void __sk_add_backlog(struct sock *sk, struct sk_buff *skb)
 {
        /* dont let skb dst not refcounted, we are going to leave rcu lock */
-       skb_dst_force(skb);
+       skb_dst_force_safe(skb);
 
        if (!sk->sk_backlog.tail)
                sk->sk_backlog.head = skb;
index c1c899c3a51be42f680fff5ce0f5c5e997652daa..e289ada6adf6b0a7bd45debd46488a28b2642ee6 100644 (file)
@@ -79,7 +79,7 @@ struct vxlanhdr {
 };
 
 /* VXLAN header flags. */
-#define VXLAN_HF_RCO BIT(24)
+#define VXLAN_HF_RCO BIT(21)
 #define VXLAN_HF_VNI BIT(27)
 #define VXLAN_HF_GBP BIT(31)
 
index 4a9c21f9b4ea189075901a3f2c8c12ec6814f5fe..d6f6e5006ee9e3cb8dcd61e151fcc95ce165eab9 100644 (file)
@@ -548,6 +548,7 @@ struct xfrm_policy {
        u16                     family;
        struct xfrm_sec_ctx     *security;
        struct xfrm_tmpl        xfrm_vec[XFRM_MAX_DEPTH];
+       struct rcu_head         rcu;
 };
 
 static inline struct net *xp_net(const struct xfrm_policy *xp)
@@ -1141,12 +1142,14 @@ static inline int xfrm6_route_forward(struct sk_buff *skb)
        return xfrm_route_forward(skb, AF_INET6);
 }
 
-int __xfrm_sk_clone_policy(struct sock *sk);
+int __xfrm_sk_clone_policy(struct sock *sk, const struct sock *osk);
 
-static inline int xfrm_sk_clone_policy(struct sock *sk)
+static inline int xfrm_sk_clone_policy(struct sock *sk, const struct sock *osk)
 {
-       if (unlikely(sk->sk_policy[0] || sk->sk_policy[1]))
-               return __xfrm_sk_clone_policy(sk);
+       sk->sk_policy[0] = NULL;
+       sk->sk_policy[1] = NULL;
+       if (unlikely(osk->sk_policy[0] || osk->sk_policy[1]))
+               return __xfrm_sk_clone_policy(sk, osk);
        return 0;
 }
 
@@ -1154,12 +1157,16 @@ int xfrm_policy_delete(struct xfrm_policy *pol, int dir);
 
 static inline void xfrm_sk_free_policy(struct sock *sk)
 {
-       if (unlikely(sk->sk_policy[0] != NULL)) {
-               xfrm_policy_delete(sk->sk_policy[0], XFRM_POLICY_MAX);
+       struct xfrm_policy *pol;
+
+       pol = rcu_dereference_protected(sk->sk_policy[0], 1);
+       if (unlikely(pol != NULL)) {
+               xfrm_policy_delete(pol, XFRM_POLICY_MAX);
                sk->sk_policy[0] = NULL;
        }
-       if (unlikely(sk->sk_policy[1] != NULL)) {
-               xfrm_policy_delete(sk->sk_policy[1], XFRM_POLICY_MAX+1);
+       pol = rcu_dereference_protected(sk->sk_policy[1], 1);
+       if (unlikely(pol != NULL)) {
+               xfrm_policy_delete(pol, XFRM_POLICY_MAX+1);
                sk->sk_policy[1] = NULL;
        }
 }
@@ -1169,7 +1176,7 @@ void xfrm_garbage_collect(struct net *net);
 #else
 
 static inline void xfrm_sk_free_policy(struct sock *sk) {}
-static inline int xfrm_sk_clone_policy(struct sock *sk) { return 0; }
+static inline int xfrm_sk_clone_policy(struct sock *sk, const struct sock *osk) { return 0; }
 static inline int xfrm6_route_forward(struct sk_buff *skb) { return 1; }  
 static inline int xfrm4_route_forward(struct sk_buff *skb) { return 1; } 
 static inline int xfrm6_policy_check(struct sock *sk, int dir, struct sk_buff *skb)
index 188df91d58514a3248cab5b1b0d7ee09513295a6..ec9b44dd3d806b20d80920a0cb37487ea2d12c24 100644 (file)
@@ -237,6 +237,8 @@ struct ib_vendor_mad {
        u8                      data[IB_MGMT_VENDOR_DATA];
 };
 
+#define IB_MGMT_CLASSPORTINFO_ATTR_ID  cpu_to_be16(0x0001)
+
 struct ib_class_port_info {
        u8                      base_version;
        u8                      class_version;
index 9a68a19532ba57c27042cec499843f3cebfa273c..120da1d7f57eb578c327507ad2affa5b89488dbb 100644 (file)
@@ -1271,6 +1271,7 @@ struct ib_uobject {
        int                     id;             /* index into kernel idr */
        struct kref             ref;
        struct rw_semaphore     mutex;          /* protects .live */
+       struct rcu_head         rcu;            /* kfree_rcu() overhead */
        int                     live;
 };
 
index 2ae8812d7b1a37845789b7c0522c0ab1b4300c45..94dc6a9772e060ce31d97434b9972f6ff255a63b 100644 (file)
@@ -93,6 +93,9 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 };
 #define AZX_REG_HSW_EM4                        0x100c
 #define AZX_REG_HSW_EM5                        0x1010
 
+/* Skylake/Broxton display HD-A controller Extended Mode registers */
+#define AZX_REG_SKL_EM4L               0x1040
+
 /* PCI space */
 #define AZX_PCIREG_TCSEL               0x44
 
index a8b4b9c8b1d2415e7220913715fc2cd4bd95212c..fb955e69a78ea29f79bd4382b492bca009cd6fe7 100644 (file)
@@ -1655,7 +1655,7 @@ extern const struct dev_pm_ops snd_soc_pm_ops;
 /* Helper functions */
 static inline void snd_soc_dapm_mutex_lock(struct snd_soc_dapm_context *dapm)
 {
-       mutex_lock(&dapm->card->dapm_mutex);
+       mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
 }
 
 static inline void snd_soc_dapm_mutex_unlock(struct snd_soc_dapm_context *dapm)
index 628e6e64c2fb4ff2c858a57e0beeca3aa4fd49b6..c2e5d6cb34e36ba2e409985c7d66c70347dbebc7 100644 (file)
@@ -186,6 +186,7 @@ header-y += if_tunnel.h
 header-y += if_vlan.h
 header-y += if_x25.h
 header-y += igmp.h
+header-y += ila.h
 header-y += in6.h
 header-y += inet_diag.h
 header-y += in.h
index 28ccedd000f5720f6f41660ea6f049b9fd9f145c..a27222d5b413a85d4c773b5b43563bf9b57831d2 100644 (file)
@@ -628,7 +628,7 @@ struct ovs_action_hash {
  * @OVS_CT_ATTR_MARK: u32 value followed by u32 mask. For each bit set in the
  * mask, the corresponding bit in the value is copied to the connection
  * tracking mark field in the connection.
- * @OVS_CT_ATTR_LABEL: %OVS_CT_LABELS_LEN value followed by %OVS_CT_LABELS_LEN
+ * @OVS_CT_ATTR_LABELS: %OVS_CT_LABELS_LEN value followed by %OVS_CT_LABELS_LEN
  * mask. For each bit set in the mask, the corresponding bit in the value is
  * copied to the connection tracking label field in the connection.
  * @OVS_CT_ATTR_HELPER: variable length string defining conntrack ALG.
index 7d28aff605c7eb600c4c3bfe93b8b5f1edbaebfe..7dc685b4057d33ad227d861a2a3115a5ca55cd3e 100644 (file)
@@ -181,6 +181,20 @@ struct __name##_back_ring {                                                \
 #define RING_GET_REQUEST(_r, _idx)                                     \
     (&((_r)->sring->ring[((_idx) & (RING_SIZE(_r) - 1))].req))
 
+/*
+ * Get a local copy of a request.
+ *
+ * Use this in preference to RING_GET_REQUEST() so all processing is
+ * done on a local copy that cannot be modified by the other end.
+ *
+ * Note that https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58145 may cause this
+ * to be ineffective where _req is a struct which consists of only bitfields.
+ */
+#define RING_COPY_REQUEST(_r, _idx, _req) do {                         \
+       /* Use volatile to force the copy into _req. */                 \
+       *(_req) = *(volatile typeof(_req))RING_GET_REQUEST(_r, _idx);   \
+} while (0)
+
 #define RING_GET_RESPONSE(_r, _idx)                                    \
     (&((_r)->sring->ring[((_idx) & (RING_SIZE(_r) - 1))].rsp))
 
index c24b6f767bf0f2a4d8a873388a5fbd59ba01c562..235c7a2c0d2004f1121b7d98f4140683ab45ef53 100644 (file)
@@ -2030,13 +2030,6 @@ config INIT_ALL_POSSIBLE
          it was better to provide this option than to break all the archs
          and have several arch maintainers pursuing me down dark alleys.
 
-config STOP_MACHINE
-       bool
-       default y
-       depends on (SMP && MODULE_UNLOAD) || HOTPLUG_CPU
-       help
-         Need stop_machine() primitive.
-
 source "block/Kconfig"
 
 config PREEMPT_NOTIFIERS
index ef2d6ea10736e4805e758cae83524dc13c2f06e9..cfc227ccfcebc6e6843cf3e1c7edc5931d69e397 100644 (file)
@@ -3154,15 +3154,16 @@ static int event_enable_on_exec(struct perf_event *event,
  * Enable all of a task's events that have been marked enable-on-exec.
  * This expects task == current.
  */
-static void perf_event_enable_on_exec(struct perf_event_context *ctx)
+static void perf_event_enable_on_exec(int ctxn)
 {
-       struct perf_event_context *clone_ctx = NULL;
+       struct perf_event_context *ctx, *clone_ctx = NULL;
        struct perf_event *event;
        unsigned long flags;
        int enabled = 0;
        int ret;
 
        local_irq_save(flags);
+       ctx = current->perf_event_ctxp[ctxn];
        if (!ctx || !ctx->nr_events)
                goto out;
 
@@ -3205,17 +3206,11 @@ out:
 
 void perf_event_exec(void)
 {
-       struct perf_event_context *ctx;
        int ctxn;
 
        rcu_read_lock();
-       for_each_task_context_nr(ctxn) {
-               ctx = current->perf_event_ctxp[ctxn];
-               if (!ctx)
-                       continue;
-
-               perf_event_enable_on_exec(ctx);
-       }
+       for_each_task_context_nr(ctxn)
+               perf_event_enable_on_exec(ctxn);
        rcu_read_unlock();
 }
 
@@ -6493,9 +6488,6 @@ struct swevent_htable {
 
        /* Recursion avoidance in each contexts */
        int                             recursion[PERF_NR_CONTEXTS];
-
-       /* Keeps track of cpu being initialized/exited */
-       bool                            online;
 };
 
 static DEFINE_PER_CPU(struct swevent_htable, swevent_htable);
@@ -6753,14 +6745,8 @@ static int perf_swevent_add(struct perf_event *event, int flags)
        hwc->state = !(flags & PERF_EF_START);
 
        head = find_swevent_head(swhash, event);
-       if (!head) {
-               /*
-                * We can race with cpu hotplug code. Do not
-                * WARN if the cpu just got unplugged.
-                */
-               WARN_ON_ONCE(swhash->online);
+       if (WARN_ON_ONCE(!head))
                return -EINVAL;
-       }
 
        hlist_add_head_rcu(&event->hlist_entry, head);
        perf_event_update_userpage(event);
@@ -6828,7 +6814,6 @@ static int swevent_hlist_get_cpu(struct perf_event *event, int cpu)
        int err = 0;
 
        mutex_lock(&swhash->hlist_mutex);
-
        if (!swevent_hlist_deref(swhash) && cpu_online(cpu)) {
                struct swevent_hlist *hlist;
 
@@ -9291,7 +9276,6 @@ static void perf_event_init_cpu(int cpu)
        struct swevent_htable *swhash = &per_cpu(swevent_htable, cpu);
 
        mutex_lock(&swhash->hlist_mutex);
-       swhash->online = true;
        if (swhash->hlist_refcount > 0) {
                struct swevent_hlist *hlist;
 
@@ -9333,14 +9317,7 @@ static void perf_event_exit_cpu_context(int cpu)
 
 static void perf_event_exit_cpu(int cpu)
 {
-       struct swevent_htable *swhash = &per_cpu(swevent_htable, cpu);
-
        perf_event_exit_cpu_context(cpu);
-
-       mutex_lock(&swhash->hlist_mutex);
-       swhash->online = false;
-       swevent_hlist_release(swhash);
-       mutex_unlock(&swhash->hlist_mutex);
 }
 #else
 static inline void perf_event_exit_cpu(int cpu) { }
index fce002ee3ddffbab7613d0f9ec390683901f3c67..1155eac616878b5494ae94f2f1d0294812ddda72 100644 (file)
@@ -380,6 +380,7 @@ static struct task_struct *dup_task_struct(struct task_struct *orig)
 #endif
        tsk->splice_pipe = NULL;
        tsk->task_frag.page = NULL;
+       tsk->wake_q.next = NULL;
 
        account_kernel_stack(ti, 1);
 
index 0eebaeef317bc990e3ee1b1bd1719b9e89211685..6ead200370da0cfe15b9c6732ec5ec4e3a7523a9 100644 (file)
@@ -1434,6 +1434,7 @@ static struct irqaction *__free_irq(unsigned int irq, void *dev_id)
        if (!desc)
                return NULL;
 
+       chip_bus_lock(desc);
        raw_spin_lock_irqsave(&desc->lock, flags);
 
        /*
@@ -1447,7 +1448,7 @@ static struct irqaction *__free_irq(unsigned int irq, void *dev_id)
                if (!action) {
                        WARN(1, "Trying to free already-free IRQ %d\n", irq);
                        raw_spin_unlock_irqrestore(&desc->lock, flags);
-
+                       chip_bus_sync_unlock(desc);
                        return NULL;
                }
 
@@ -1475,6 +1476,7 @@ static struct irqaction *__free_irq(unsigned int irq, void *dev_id)
 #endif
 
        raw_spin_unlock_irqrestore(&desc->lock, flags);
+       chip_bus_sync_unlock(desc);
 
        unregister_handler_proc(irq, action);
 
@@ -1553,9 +1555,7 @@ void free_irq(unsigned int irq, void *dev_id)
                desc->affinity_notify = NULL;
 #endif
 
-       chip_bus_lock(desc);
        kfree(__free_irq(irq, dev_id));
-       chip_bus_sync_unlock(desc);
 }
 EXPORT_SYMBOL(free_irq);
 
index d092a0c9c2d4ed838004215cdf038691a14f4598..05a37857ab5516012949ca64b31cff3d133c61e7 100644 (file)
@@ -93,10 +93,12 @@ bool osq_lock(struct optimistic_spin_queue *lock)
        node->cpu = curr;
 
        /*
-        * ACQUIRE semantics, pairs with corresponding RELEASE
-        * in unlock() uncontended, or fastpath.
+        * We need both ACQUIRE (pairs with corresponding RELEASE in
+        * unlock() uncontended, or fastpath) and RELEASE (to publish
+        * the node fields we just initialised) semantics when updating
+        * the lock tail.
         */
-       old = atomic_xchg_acquire(&lock->tail, curr);
+       old = atomic_xchg(&lock->tail, curr);
        if (old == OSQ_UNLOCKED_VAL)
                return true;
 
index 8f051a106676fb8f2d5457a9104340cce81ce37a..38c7bd5583fff036c0f993ac2c15077882d61501 100644 (file)
@@ -3571,6 +3571,12 @@ static int load_module(struct load_info *info, const char __user *uargs,
        synchronize_sched();
        mutex_unlock(&module_mutex);
  free_module:
+       /*
+        * Ftrace needs to clean up what it initialized.
+        * This does nothing if ftrace_module_init() wasn't called,
+        * but it must be called outside of module_mutex.
+        */
+       ftrace_release_mod(mod);
        /* Free lock-classes; relies on the preceding sync_rcu() */
        lockdep_free_key_range(mod->module_core, mod->core_size);
 
index 90e26b11deaa1ab4b78302605850523a7852720b..cfdc0e61066c20b926e0d5ca7ed5d9732a1c903b 100644 (file)
@@ -2689,7 +2689,7 @@ static inline int update_cfs_rq_load_avg(u64 now, struct cfs_rq *cfs_rq)
        int decayed, removed = 0;
 
        if (atomic_long_read(&cfs_rq->removed_load_avg)) {
-               long r = atomic_long_xchg(&cfs_rq->removed_load_avg, 0);
+               s64 r = atomic_long_xchg(&cfs_rq->removed_load_avg, 0);
                sa->load_avg = max_t(long, sa->load_avg - r, 0);
                sa->load_sum = max_t(s64, sa->load_sum - r * LOAD_AVG_MAX, 0);
                removed = 1;
index f10bd873e6840441ed4750a5eb1c2d462ad0b436..f15d6b6a538a9d01c2d7c4045af0a661d34c3c4a 100644 (file)
@@ -392,7 +392,7 @@ __wait_on_bit(wait_queue_head_t *wq, struct wait_bit_queue *q,
        do {
                prepare_to_wait(wq, &q->wait, mode);
                if (test_bit(q->key.bit_nr, q->key.flags))
-                       ret = (*action)(&q->key);
+                       ret = (*action)(&q->key, mode);
        } while (test_bit(q->key.bit_nr, q->key.flags) && !ret);
        finish_wait(wq, &q->wait);
        return ret;
@@ -431,7 +431,7 @@ __wait_on_bit_lock(wait_queue_head_t *wq, struct wait_bit_queue *q,
                prepare_to_wait_exclusive(wq, &q->wait, mode);
                if (!test_bit(q->key.bit_nr, q->key.flags))
                        continue;
-               ret = action(&q->key);
+               ret = action(&q->key, mode);
                if (!ret)
                        continue;
                abort_exclusive_wait(wq, &q->wait, mode, &q->key);
@@ -581,43 +581,43 @@ void wake_up_atomic_t(atomic_t *p)
 }
 EXPORT_SYMBOL(wake_up_atomic_t);
 
-__sched int bit_wait(struct wait_bit_key *word)
+__sched int bit_wait(struct wait_bit_key *word, int mode)
 {
        schedule();
-       if (signal_pending(current))
+       if (signal_pending_state(mode, current))
                return -EINTR;
        return 0;
 }
 EXPORT_SYMBOL(bit_wait);
 
-__sched int bit_wait_io(struct wait_bit_key *word)
+__sched int bit_wait_io(struct wait_bit_key *word, int mode)
 {
        io_schedule();
-       if (signal_pending(current))
+       if (signal_pending_state(mode, current))
                return -EINTR;
        return 0;
 }
 EXPORT_SYMBOL(bit_wait_io);
 
-__sched int bit_wait_timeout(struct wait_bit_key *word)
+__sched int bit_wait_timeout(struct wait_bit_key *word, int mode)
 {
        unsigned long now = READ_ONCE(jiffies);
        if (time_after_eq(now, word->timeout))
                return -EAGAIN;
        schedule_timeout(word->timeout - now);
-       if (signal_pending(current))
+       if (signal_pending_state(mode, current))
                return -EINTR;
        return 0;
 }
 EXPORT_SYMBOL_GPL(bit_wait_timeout);
 
-__sched int bit_wait_io_timeout(struct wait_bit_key *word)
+__sched int bit_wait_io_timeout(struct wait_bit_key *word, int mode)
 {
        unsigned long now = READ_ONCE(jiffies);
        if (time_after_eq(now, word->timeout))
                return -EAGAIN;
        io_schedule_timeout(word->timeout - now);
-       if (signal_pending(current))
+       if (signal_pending_state(mode, current))
                return -EINTR;
        return 0;
 }
index 867bc20e1ef142a63349c345932af24b26a1adfc..a3bbaee77c586e9836567f900012aa5231e94dbd 100644 (file)
@@ -531,7 +531,7 @@ static int __init cpu_stop_init(void)
 }
 early_initcall(cpu_stop_init);
 
-#ifdef CONFIG_STOP_MACHINE
+#if defined(CONFIG_SMP) || defined(CONFIG_HOTPLUG_CPU)
 
 static int __stop_machine(cpu_stop_fn_t fn, void *data, const struct cpumask *cpus)
 {
@@ -631,4 +631,4 @@ int stop_machine_from_inactive_cpu(cpu_stop_fn_t fn, void *data,
        return ret ?: done.ret;
 }
 
-#endif /* CONFIG_STOP_MACHINE */
+#endif /* CONFIG_SMP || CONFIG_HOTPLUG_CPU */
index 1c2b28536feb8113a408b2335c38fb0a0c4272e1..060df67dbdd1d038dba8ec35909890f3e892b6d7 100644 (file)
@@ -273,6 +273,7 @@ static const char **find_next(void *v, loff_t *pos)
        if (*pos < last_index + start_index)
                return __start___tracepoint_str + (*pos - last_index);
 
+       start_index += last_index;
        return find_next_mod_format(start_index, v, fmt, pos);
 }
 
index 8855f019ebe8a61957795b0d5f5c3339fe180f5a..d34bd24c2c84779c38c300f470b22df52e76cb58 100644 (file)
@@ -1464,7 +1464,7 @@ void debug_dma_alloc_coherent(struct device *dev, size_t size,
        entry->type      = dma_debug_coherent;
        entry->dev       = dev;
        entry->pfn       = page_to_pfn(virt_to_page(virt));
-       entry->offset    = (size_t) virt & PAGE_MASK;
+       entry->offset    = (size_t) virt & ~PAGE_MASK;
        entry->size      = size;
        entry->dev_addr  = dma_addr;
        entry->direction = DMA_BIDIRECTIONAL;
@@ -1480,7 +1480,7 @@ void debug_dma_free_coherent(struct device *dev, size_t size,
                .type           = dma_debug_coherent,
                .dev            = dev,
                .pfn            = page_to_pfn(virt_to_page(virt)),
-               .offset         = (size_t) virt & PAGE_MASK,
+               .offset         = (size_t) virt & ~PAGE_MASK,
                .dev_addr       = addr,
                .size           = size,
                .direction      = DMA_BIDIRECTIONAL,
index a54ff8949f9116184631414086a9fa2d956c8031..51282f5797606545330a29e93b3728d843616ea9 100644 (file)
@@ -389,33 +389,31 @@ static bool rhashtable_check_elasticity(struct rhashtable *ht,
        return false;
 }
 
-int rhashtable_insert_rehash(struct rhashtable *ht)
+int rhashtable_insert_rehash(struct rhashtable *ht,
+                            struct bucket_table *tbl)
 {
        struct bucket_table *old_tbl;
        struct bucket_table *new_tbl;
-       struct bucket_table *tbl;
        unsigned int size;
        int err;
 
        old_tbl = rht_dereference_rcu(ht->tbl, ht);
-       tbl = rhashtable_last_table(ht, old_tbl);
 
        size = tbl->size;
 
+       err = -EBUSY;
+
        if (rht_grow_above_75(ht, tbl))
                size *= 2;
        /* Do not schedule more than one rehash */
        else if (old_tbl != tbl)
-               return -EBUSY;
+               goto fail;
+
+       err = -ENOMEM;
 
        new_tbl = bucket_table_alloc(ht, size, GFP_ATOMIC);
-       if (new_tbl == NULL) {
-               /* Schedule async resize/rehash to try allocation
-                * non-atomic context.
-                */
-               schedule_work(&ht->run_work);
-               return -ENOMEM;
-       }
+       if (new_tbl == NULL)
+               goto fail;
 
        err = rhashtable_rehash_attach(ht, tbl, new_tbl);
        if (err) {
@@ -426,12 +424,24 @@ int rhashtable_insert_rehash(struct rhashtable *ht)
                schedule_work(&ht->run_work);
 
        return err;
+
+fail:
+       /* Do not fail the insert if someone else did a rehash. */
+       if (likely(rcu_dereference_raw(tbl->future_tbl)))
+               return 0;
+
+       /* Schedule async rehash to retry allocation in process context. */
+       if (err == -ENOMEM)
+               schedule_work(&ht->run_work);
+
+       return err;
 }
 EXPORT_SYMBOL_GPL(rhashtable_insert_rehash);
 
-int rhashtable_insert_slow(struct rhashtable *ht, const void *key,
-                          struct rhash_head *obj,
-                          struct bucket_table *tbl)
+struct bucket_table *rhashtable_insert_slow(struct rhashtable *ht,
+                                           const void *key,
+                                           struct rhash_head *obj,
+                                           struct bucket_table *tbl)
 {
        struct rhash_head *head;
        unsigned int hash;
@@ -467,7 +477,12 @@ int rhashtable_insert_slow(struct rhashtable *ht, const void *key,
 exit:
        spin_unlock(rht_bucket_lock(tbl, hash));
 
-       return err;
+       if (err == 0)
+               return NULL;
+       else if (err == -EAGAIN)
+               return tbl;
+       else
+               return ERR_PTR(err);
 }
 EXPORT_SYMBOL_GPL(rhashtable_insert_slow);
 
@@ -503,10 +518,11 @@ int rhashtable_walk_init(struct rhashtable *ht, struct rhashtable_iter *iter)
        if (!iter->walker)
                return -ENOMEM;
 
-       mutex_lock(&ht->mutex);
-       iter->walker->tbl = rht_dereference(ht->tbl, ht);
+       spin_lock(&ht->lock);
+       iter->walker->tbl =
+               rcu_dereference_protected(ht->tbl, lockdep_is_held(&ht->lock));
        list_add(&iter->walker->list, &iter->walker->tbl->walkers);
-       mutex_unlock(&ht->mutex);
+       spin_unlock(&ht->lock);
 
        return 0;
 }
@@ -520,10 +536,10 @@ EXPORT_SYMBOL_GPL(rhashtable_walk_init);
  */
 void rhashtable_walk_exit(struct rhashtable_iter *iter)
 {
-       mutex_lock(&iter->ht->mutex);
+       spin_lock(&iter->ht->lock);
        if (iter->walker->tbl)
                list_del(&iter->walker->list);
-       mutex_unlock(&iter->ht->mutex);
+       spin_unlock(&iter->ht->lock);
        kfree(iter->walker);
 }
 EXPORT_SYMBOL_GPL(rhashtable_walk_exit);
@@ -547,14 +563,12 @@ int rhashtable_walk_start(struct rhashtable_iter *iter)
 {
        struct rhashtable *ht = iter->ht;
 
-       mutex_lock(&ht->mutex);
+       rcu_read_lock();
 
+       spin_lock(&ht->lock);
        if (iter->walker->tbl)
                list_del(&iter->walker->list);
-
-       rcu_read_lock();
-
-       mutex_unlock(&ht->mutex);
+       spin_unlock(&ht->lock);
 
        if (!iter->walker->tbl) {
                iter->walker->tbl = rht_dereference_rcu(ht->tbl, ht);
@@ -723,9 +737,6 @@ int rhashtable_init(struct rhashtable *ht,
        if (params->nulls_base && params->nulls_base < (1U << RHT_BASE_SHIFT))
                return -EINVAL;
 
-       if (params->nelem_hint)
-               size = rounded_hashtable_size(params);
-
        memset(ht, 0, sizeof(*ht));
        mutex_init(&ht->mutex);
        spin_lock_init(&ht->lock);
@@ -745,6 +756,9 @@ int rhashtable_init(struct rhashtable *ht,
 
        ht->p.min_size = max(ht->p.min_size, HASH_MIN_SIZE);
 
+       if (params->nelem_hint)
+               size = rounded_hashtable_size(&ht->p);
+
        /* The maximum (not average) chain length grows with the
         * size of the hash table, at a rate of (log N)/(log log N).
         * The value of 16 is selected so that even if the hash
index 8ed2ffd963c53b910f91e1b60b04c56385a3129f..7340353f8aea08ef428edcf7b287c45b312aeb1a 100644 (file)
@@ -957,8 +957,9 @@ EXPORT_SYMBOL(congestion_wait);
  * jiffies for either a BDI to exit congestion of the given @sync queue
  * or a write to complete.
  *
- * In the absence of zone congestion, cond_resched() is called to yield
- * the processor if necessary but otherwise does not sleep.
+ * In the absence of zone congestion, a short sleep or a cond_resched is
+ * performed to yield the processor and to allow other subsystems to make
+ * a forward progress.
  *
  * The return value is 0 if the sleep is for the full timeout. Otherwise,
  * it is the number of jiffies that were still remaining when the function
@@ -978,7 +979,19 @@ long wait_iff_congested(struct zone *zone, int sync, long timeout)
         */
        if (atomic_read(&nr_wb_congested[sync]) == 0 ||
            !test_bit(ZONE_CONGESTED, &zone->flags)) {
-               cond_resched();
+
+               /*
+                * Memory allocation/reclaim might be called from a WQ
+                * context and the current implementation of the WQ
+                * concurrency control doesn't recognize that a particular
+                * WQ is congested if the worker thread is looping without
+                * ever sleeping. Therefore we have to do a short sleep
+                * here rather than calling cond_resched().
+                */
+               if (current->flags & PF_WQ_WORKER)
+                       schedule_timeout(1);
+               else
+                       cond_resched();
 
                /* In case we scheduled, work out time remaining */
                ret = timeout - (jiffies - start);
index 827bb02a43a4e425393c296db89e7a49d6adf02b..ef6963b577fd2920c1a4857f7b74b50e91c98b7a 100644 (file)
@@ -372,8 +372,10 @@ retry_locked:
                spin_unlock(&resv->lock);
 
                trg = kmalloc(sizeof(*trg), GFP_KERNEL);
-               if (!trg)
+               if (!trg) {
+                       kfree(nrg);
                        return -ENOMEM;
+               }
 
                spin_lock(&resv->lock);
                list_add(&trg->link, &resv->region_cache);
@@ -483,8 +485,16 @@ static long region_del(struct resv_map *resv, long f, long t)
 retry:
        spin_lock(&resv->lock);
        list_for_each_entry_safe(rg, trg, head, link) {
-               if (rg->to <= f)
+               /*
+                * Skip regions before the range to be deleted.  file_region
+                * ranges are normally of the form [from, to).  However, there
+                * may be a "placeholder" entry in the map which is of the form
+                * (from, to) with from == to.  Check for placeholder entries
+                * at the beginning of the range to be deleted.
+                */
+               if (rg->to <= f && (rg->to != rg->from || rg->to != f))
                        continue;
+
                if (rg->from >= t)
                        break;
 
@@ -1886,7 +1896,10 @@ struct page *alloc_huge_page(struct vm_area_struct *vma,
                page = __alloc_buddy_huge_page_with_mpol(h, vma, addr);
                if (!page)
                        goto out_uncharge_cgroup;
-
+               if (!avoid_reserve && vma_has_reserves(vma, gbl_chg)) {
+                       SetPagePrivate(page);
+                       h->resv_huge_pages--;
+               }
                spin_lock(&hugetlb_lock);
                list_move(&page->lru, &h->hugepage_activelist);
                /* Fall through */
@@ -3693,12 +3706,12 @@ int hugetlb_fault(struct mm_struct *mm, struct vm_area_struct *vma,
                } else if (unlikely(is_hugetlb_entry_hwpoisoned(entry)))
                        return VM_FAULT_HWPOISON_LARGE |
                                VM_FAULT_SET_HINDEX(hstate_index(h));
+       } else {
+               ptep = huge_pte_alloc(mm, address, huge_page_size(h));
+               if (!ptep)
+                       return VM_FAULT_OOM;
        }
 
-       ptep = huge_pte_alloc(mm, address, huge_page_size(h));
-       if (!ptep)
-               return VM_FAULT_OOM;
-
        mapping = vma->vm_file->f_mapping;
        idx = vma_hugecache_offset(h, vma, address);
 
index c92a65b2b4ab4103454aa1f8bca828384b22e07b..fc10620967c79d7b8fbbcc0f82fd9804b1562f13 100644 (file)
@@ -903,14 +903,20 @@ struct mem_cgroup *mem_cgroup_iter(struct mem_cgroup *root,
                if (prev && reclaim->generation != iter->generation)
                        goto out_unlock;
 
-               do {
+               while (1) {
                        pos = READ_ONCE(iter->position);
+                       if (!pos || css_tryget(&pos->css))
+                               break;
                        /*
-                        * A racing update may change the position and
-                        * put the last reference, hence css_tryget(),
-                        * or retry to see the updated position.
+                        * css reference reached zero, so iter->position will
+                        * be cleared by ->css_released. However, we should not
+                        * rely on this happening soon, because ->css_released
+                        * is called from a work queue, and by busy-waiting we
+                        * might block it. So we clear iter->position right
+                        * away.
                         */
-               } while (pos && !css_tryget(&pos->css));
+                       (void)cmpxchg(&iter->position, pos, NULL);
+               }
        }
 
        if (pos)
@@ -956,17 +962,13 @@ struct mem_cgroup *mem_cgroup_iter(struct mem_cgroup *root,
        }
 
        if (reclaim) {
-               if (cmpxchg(&iter->position, pos, memcg) == pos) {
-                       if (memcg)
-                               css_get(&memcg->css);
-                       if (pos)
-                               css_put(&pos->css);
-               }
-
                /*
-                * pairs with css_tryget when dereferencing iter->position
-                * above.
+                * The position could have already been updated by a competing
+                * thread, so check that the value hasn't changed since we read
+                * it to avoid reclaiming from the same cgroup twice.
                 */
+               (void)cmpxchg(&iter->position, pos, memcg);
+
                if (pos)
                        css_put(&pos->css);
 
@@ -999,6 +1001,28 @@ void mem_cgroup_iter_break(struct mem_cgroup *root,
                css_put(&prev->css);
 }
 
+static void invalidate_reclaim_iterators(struct mem_cgroup *dead_memcg)
+{
+       struct mem_cgroup *memcg = dead_memcg;
+       struct mem_cgroup_reclaim_iter *iter;
+       struct mem_cgroup_per_zone *mz;
+       int nid, zid;
+       int i;
+
+       while ((memcg = parent_mem_cgroup(memcg))) {
+               for_each_node(nid) {
+                       for (zid = 0; zid < MAX_NR_ZONES; zid++) {
+                               mz = &memcg->nodeinfo[nid]->zoneinfo[zid];
+                               for (i = 0; i <= DEF_PRIORITY; i++) {
+                                       iter = &mz->iter[i];
+                                       cmpxchg(&iter->position,
+                                               dead_memcg, NULL);
+                               }
+                       }
+               }
+       }
+}
+
 /*
  * Iteration constructs for visiting all cgroups (under a tree).  If
  * loops are exited prematurely (break), mem_cgroup_iter_break() must
@@ -2128,7 +2152,7 @@ done_restock:
         */
        do {
                if (page_counter_read(&memcg->memory) > memcg->high) {
-                       current->memcg_nr_pages_over_high += nr_pages;
+                       current->memcg_nr_pages_over_high += batch;
                        set_notify_resume(current);
                        break;
                }
@@ -4324,6 +4348,13 @@ static void mem_cgroup_css_offline(struct cgroup_subsys_state *css)
        wb_memcg_offline(memcg);
 }
 
+static void mem_cgroup_css_released(struct cgroup_subsys_state *css)
+{
+       struct mem_cgroup *memcg = mem_cgroup_from_css(css);
+
+       invalidate_reclaim_iterators(memcg);
+}
+
 static void mem_cgroup_css_free(struct cgroup_subsys_state *css)
 {
        struct mem_cgroup *memcg = mem_cgroup_from_css(css);
@@ -5185,6 +5216,7 @@ struct cgroup_subsys memory_cgrp_subsys = {
        .css_alloc = mem_cgroup_css_alloc,
        .css_online = mem_cgroup_css_online,
        .css_offline = mem_cgroup_css_offline,
+       .css_released = mem_cgroup_css_released,
        .css_free = mem_cgroup_css_free,
        .css_reset = mem_cgroup_css_reset,
        .can_attach = mem_cgroup_can_attach,
@@ -5512,11 +5544,11 @@ void mem_cgroup_uncharge_list(struct list_head *page_list)
  * mem_cgroup_replace_page - migrate a charge to another page
  * @oldpage: currently charged page
  * @newpage: page to transfer the charge to
- * @lrucare: either or both pages might be on the LRU already
  *
  * Migrate the charge from @oldpage to @newpage.
  *
  * Both pages must be locked, @newpage->mapping must be set up.
+ * Either or both pages might be on the LRU already.
  */
 void mem_cgroup_replace_page(struct page *oldpage, struct page *newpage)
 {
index 67d488ab495e57b9018484932e135078c787903c..a042a9d537bb31984d6b2a8d3cc8ae1e54361e4f 100644 (file)
@@ -1375,23 +1375,30 @@ int is_mem_section_removable(unsigned long start_pfn, unsigned long nr_pages)
  */
 int test_pages_in_a_zone(unsigned long start_pfn, unsigned long end_pfn)
 {
-       unsigned long pfn;
+       unsigned long pfn, sec_end_pfn;
        struct zone *zone = NULL;
        struct page *page;
        int i;
-       for (pfn = start_pfn;
+       for (pfn = start_pfn, sec_end_pfn = SECTION_ALIGN_UP(start_pfn);
             pfn < end_pfn;
-            pfn += MAX_ORDER_NR_PAGES) {
-               i = 0;
-               /* This is just a CONFIG_HOLES_IN_ZONE check.*/
-               while ((i < MAX_ORDER_NR_PAGES) && !pfn_valid_within(pfn + i))
-                       i++;
-               if (i == MAX_ORDER_NR_PAGES)
+            pfn = sec_end_pfn + 1, sec_end_pfn += PAGES_PER_SECTION) {
+               /* Make sure the memory section is present first */
+               if (!present_section_nr(pfn_to_section_nr(pfn)))
                        continue;
-               page = pfn_to_page(pfn + i);
-               if (zone && page_zone(page) != zone)
-                       return 0;
-               zone = page_zone(page);
+               for (; pfn < sec_end_pfn && pfn < end_pfn;
+                    pfn += MAX_ORDER_NR_PAGES) {
+                       i = 0;
+                       /* This is just a CONFIG_HOLES_IN_ZONE check.*/
+                       while ((i < MAX_ORDER_NR_PAGES) &&
+                               !pfn_valid_within(pfn + i))
+                               i++;
+                       if (i == MAX_ORDER_NR_PAGES)
+                               continue;
+                       page = pfn_to_page(pfn + i);
+                       if (zone && page_zone(page) != zone)
+                               return 0;
+                       zone = page_zone(page);
+               }
        }
        return 1;
 }
index d13a33918fa23e685bc629bc23f58d97729beb62..c12680993ff334560dbfc84ffcee4e0bd0487650 100644 (file)
@@ -608,6 +608,8 @@ void oom_kill_process(struct oom_control *oc, struct task_struct *p,
                        continue;
                if (unlikely(p->flags & PF_KTHREAD))
                        continue;
+               if (is_global_init(p))
+                       continue;
                if (p->signal->oom_score_adj == OOM_SCORE_ADJ_MIN)
                        continue;
 
index 17a3c66639a9cd6625f333b4f64ab012e2cb56c4..9d666df5ef9502b70cf7ba0aedef5eb805fdd811 100644 (file)
@@ -3647,8 +3647,9 @@ static void show_migration_types(unsigned char type)
 {
        static const char types[MIGRATE_TYPES] = {
                [MIGRATE_UNMOVABLE]     = 'U',
-               [MIGRATE_RECLAIMABLE]   = 'E',
                [MIGRATE_MOVABLE]       = 'M',
+               [MIGRATE_RECLAIMABLE]   = 'E',
+               [MIGRATE_HIGHATOMIC]    = 'H',
 #ifdef CONFIG_CMA
                [MIGRATE_CMA]           = 'C',
 #endif
index 9187eee4128b45769583dae2a73720e3545ee933..2afcdbbdb68506096d5c6fad584a8425709d10aa 100644 (file)
@@ -843,14 +843,14 @@ static int shmem_writepage(struct page *page, struct writeback_control *wbc)
                list_add_tail(&info->swaplist, &shmem_swaplist);
 
        if (add_to_swap_cache(page, swap, GFP_ATOMIC) == 0) {
-               swap_shmem_alloc(swap);
-               shmem_delete_from_page_cache(page, swp_to_radix_entry(swap));
-
                spin_lock(&info->lock);
-               info->swapped++;
                shmem_recalc_inode(inode);
+               info->swapped++;
                spin_unlock(&info->lock);
 
+               swap_shmem_alloc(swap);
+               shmem_delete_from_page_cache(page, swp_to_radix_entry(swap));
+
                mutex_unlock(&shmem_swaplist_mutex);
                BUG_ON(page_mapped(page));
                swap_writepage(page, wbc);
@@ -1078,7 +1078,7 @@ repeat:
        if (sgp != SGP_WRITE && sgp != SGP_FALLOC &&
            ((loff_t)index << PAGE_CACHE_SHIFT) >= i_size_read(inode)) {
                error = -EINVAL;
-               goto failed;
+               goto unlock;
        }
 
        if (page && sgp == SGP_WRITE)
@@ -1246,11 +1246,15 @@ clear:
        /* Perhaps the file has been truncated since we checked */
        if (sgp != SGP_WRITE && sgp != SGP_FALLOC &&
            ((loff_t)index << PAGE_CACHE_SHIFT) >= i_size_read(inode)) {
+               if (alloced) {
+                       ClearPageDirty(page);
+                       delete_from_page_cache(page);
+                       spin_lock(&info->lock);
+                       shmem_recalc_inode(inode);
+                       spin_unlock(&info->lock);
+               }
                error = -EINVAL;
-               if (alloced)
-                       goto trunc;
-               else
-                       goto failed;
+               goto unlock;
        }
        *pagep = page;
        return 0;
@@ -1258,23 +1262,13 @@ clear:
        /*
         * Error recovery.
         */
-trunc:
-       info = SHMEM_I(inode);
-       ClearPageDirty(page);
-       delete_from_page_cache(page);
-       spin_lock(&info->lock);
-       info->alloced--;
-       inode->i_blocks -= BLOCKS_PER_PAGE;
-       spin_unlock(&info->lock);
 decused:
-       sbinfo = SHMEM_SB(inode->i_sb);
        if (sbinfo->max_blocks)
                percpu_counter_add(&sbinfo->used_blocks, -1);
 unacct:
        shmem_unacct_blocks(info->flags, 1);
 failed:
-       if (swap.val && error != -EINVAL &&
-           !shmem_confirm_swap(mapping, index, swap))
+       if (swap.val && !shmem_confirm_swap(mapping, index, swap))
                error = -EEXIST;
 unlock:
        if (page) {
index 879a2be23325ce73158e097eb381628a5fd5f548..4ebc17d948cb8414e3e2b0ea5b8f9342f71c77c2 100644 (file)
@@ -219,7 +219,7 @@ void set_pgdat_percpu_threshold(pg_data_t *pgdat,
  * particular counter cannot be updated from interrupt context.
  */
 void __mod_zone_page_state(struct zone *zone, enum zone_stat_item item,
-                               int delta)
+                          long delta)
 {
        struct per_cpu_pageset __percpu *pcp = zone->pageset;
        s8 __percpu *p = pcp->vm_stat_diff + item;
@@ -318,8 +318,8 @@ EXPORT_SYMBOL(__dec_zone_page_state);
  *     1       Overstepping half of threshold
  *     -1      Overstepping minus half of threshold
 */
-static inline void mod_state(struct zone *zone,
-       enum zone_stat_item item, int delta, int overstep_mode)
+static inline void mod_state(struct zone *zone, enum zone_stat_item item,
+                            long delta, int overstep_mode)
 {
        struct per_cpu_pageset __percpu *pcp = zone->pageset;
        s8 __percpu *p = pcp->vm_stat_diff + item;
@@ -357,7 +357,7 @@ static inline void mod_state(struct zone *zone,
 }
 
 void mod_zone_page_state(struct zone *zone, enum zone_stat_item item,
-                                       int delta)
+                        long delta)
 {
        mod_state(zone, item, delta, 0);
 }
@@ -384,7 +384,7 @@ EXPORT_SYMBOL(dec_zone_page_state);
  * Use interrupt disable to serialize counter updates
  */
 void mod_zone_page_state(struct zone *zone, enum zone_stat_item item,
-                                       int delta)
+                        long delta)
 {
        unsigned long flags;
 
@@ -921,8 +921,8 @@ static void walk_zones_in_node(struct seq_file *m, pg_data_t *pgdat,
 #ifdef CONFIG_PROC_FS
 static char * const migratetype_names[MIGRATE_TYPES] = {
        "Unmovable",
-       "Reclaimable",
        "Movable",
+       "Reclaimable",
        "HighAtomic",
 #ifdef CONFIG_CMA
        "CMA",
@@ -1379,6 +1379,7 @@ static const struct file_operations proc_vmstat_file_operations = {
 #endif /* CONFIG_PROC_FS */
 
 #ifdef CONFIG_SMP
+static struct workqueue_struct *vmstat_wq;
 static DEFINE_PER_CPU(struct delayed_work, vmstat_work);
 int sysctl_stat_interval __read_mostly = HZ;
 static cpumask_var_t cpu_stat_off;
@@ -1391,7 +1392,7 @@ static void vmstat_update(struct work_struct *w)
                 * to occur in the future. Keep on running the
                 * update worker thread.
                 */
-               schedule_delayed_work_on(smp_processor_id(),
+               queue_delayed_work_on(smp_processor_id(), vmstat_wq,
                        this_cpu_ptr(&vmstat_work),
                        round_jiffies_relative(sysctl_stat_interval));
        } else {
@@ -1460,7 +1461,7 @@ static void vmstat_shepherd(struct work_struct *w)
                if (need_update(cpu) &&
                        cpumask_test_and_clear_cpu(cpu, cpu_stat_off))
 
-                       schedule_delayed_work_on(cpu,
+                       queue_delayed_work_on(cpu, vmstat_wq,
                                &per_cpu(vmstat_work, cpu), 0);
 
        put_online_cpus();
@@ -1549,6 +1550,7 @@ static int __init setup_vmstat(void)
 
        start_shepherd_timer();
        cpu_notifier_register_done();
+       vmstat_wq = alloc_workqueue("vmstat", WQ_FREEZABLE|WQ_MEM_RECLAIM, 0);
 #endif
 #ifdef CONFIG_PROC_FS
        proc_create("buddyinfo", S_IRUGO, NULL, &fragmentation_file_operations);
index 025f8dc723dedf60da7d2d9d580ac208e75cd8f6..bf14508afd64573d8310a5a3e12b99b629fc8c02 100644 (file)
@@ -541,6 +541,7 @@ static struct zswap_pool *zswap_pool_last_get(void)
        return last;
 }
 
+/* type and compressor must be null-terminated */
 static struct zswap_pool *zswap_pool_find_get(char *type, char *compressor)
 {
        struct zswap_pool *pool;
@@ -548,10 +549,9 @@ static struct zswap_pool *zswap_pool_find_get(char *type, char *compressor)
        assert_spin_locked(&zswap_pools_lock);
 
        list_for_each_entry_rcu(pool, &zswap_pools, list) {
-               if (strncmp(pool->tfm_name, compressor, sizeof(pool->tfm_name)))
+               if (strcmp(pool->tfm_name, compressor))
                        continue;
-               if (strncmp(zpool_get_type(pool->zpool), type,
-                           sizeof(zswap_zpool_type)))
+               if (strcmp(zpool_get_type(pool->zpool), type))
                        continue;
                /* if we can't get it, it's about to be destroyed */
                if (!zswap_pool_get(pool))
index ae3a47f9d1d5298406ca33900624fe49c9c85719..fbd0acf80b13236bd8c768bc8bf5d69d6a7e7125 100644 (file)
@@ -805,6 +805,9 @@ static int ax25_create(struct net *net, struct socket *sock, int protocol,
        struct sock *sk;
        ax25_cb *ax25;
 
+       if (protocol < 0 || protocol > SK_PROTOCOL_MAX)
+               return -EINVAL;
+
        if (!net_eq(net, &init_net))
                return -EAFNOSUPPORT;
 
index 83bc1aaf5800cbc68aa8a33f967a2ae5533af801..a49c705fb86b861f5595c8c0cfb7b8b1e1010589 100644 (file)
@@ -566,6 +566,7 @@ batadv_dat_select_candidates(struct batadv_priv *bat_priv, __be32 ip_dst)
        int select;
        batadv_dat_addr_t last_max = BATADV_DAT_ADDR_MAX, ip_key;
        struct batadv_dat_candidate *res;
+       struct batadv_dat_entry dat;
 
        if (!bat_priv->orig_hash)
                return NULL;
@@ -575,7 +576,9 @@ batadv_dat_select_candidates(struct batadv_priv *bat_priv, __be32 ip_dst)
        if (!res)
                return NULL;
 
-       ip_key = (batadv_dat_addr_t)batadv_hash_dat(&ip_dst,
+       dat.ip = ip_dst;
+       dat.vid = 0;
+       ip_key = (batadv_dat_addr_t)batadv_hash_dat(&dat,
                                                    BATADV_DAT_ADDR_MAX);
 
        batadv_dbg(BATADV_DBG_DAT, bat_priv,
index 8d990b070a2e87db6a6e71f9e3eaad93dbf4a59e..3207667e69de30e92499c705f39319c55f36732f 100644 (file)
@@ -836,6 +836,7 @@ int batadv_recv_unicast_packet(struct sk_buff *skb,
        u8 *orig_addr;
        struct batadv_orig_node *orig_node = NULL;
        int check, hdr_size = sizeof(*unicast_packet);
+       enum batadv_subtype subtype;
        bool is4addr;
 
        unicast_packet = (struct batadv_unicast_packet *)skb->data;
@@ -863,10 +864,20 @@ int batadv_recv_unicast_packet(struct sk_buff *skb,
        /* packet for me */
        if (batadv_is_my_mac(bat_priv, unicast_packet->dest)) {
                if (is4addr) {
-                       batadv_dat_inc_counter(bat_priv,
-                                              unicast_4addr_packet->subtype);
-                       orig_addr = unicast_4addr_packet->src;
-                       orig_node = batadv_orig_hash_find(bat_priv, orig_addr);
+                       subtype = unicast_4addr_packet->subtype;
+                       batadv_dat_inc_counter(bat_priv, subtype);
+
+                       /* Only payload data should be considered for speedy
+                        * join. For example, DAT also uses unicast 4addr
+                        * types, but those packets should not be considered
+                        * for speedy join, since the clients do not actually
+                        * reside at the sending originator.
+                        */
+                       if (subtype == BATADV_P_DATA) {
+                               orig_addr = unicast_4addr_packet->src;
+                               orig_node = batadv_orig_hash_find(bat_priv,
+                                                                 orig_addr);
+                       }
                }
 
                if (batadv_dat_snoop_incoming_arp_request(bat_priv, skb,
index 4228b10c47ead06db9284997afc1899e181d6505..76f19ba62462bf03fadba72171d3ae01a565ba57 100644 (file)
@@ -68,13 +68,15 @@ static void batadv_tt_global_del(struct batadv_priv *bat_priv,
                                 unsigned short vid, const char *message,
                                 bool roaming);
 
-/* returns 1 if they are the same mac addr */
+/* returns 1 if they are the same mac addr and vid */
 static int batadv_compare_tt(const struct hlist_node *node, const void *data2)
 {
        const void *data1 = container_of(node, struct batadv_tt_common_entry,
                                         hash_entry);
+       const struct batadv_tt_common_entry *tt1 = data1;
+       const struct batadv_tt_common_entry *tt2 = data2;
 
-       return batadv_compare_eth(data1, data2);
+       return (tt1->vid == tt2->vid) && batadv_compare_eth(data1, data2);
 }
 
 /**
@@ -1427,9 +1429,15 @@ static bool batadv_tt_global_add(struct batadv_priv *bat_priv,
                }
 
                /* if the client was temporary added before receiving the first
-                * OGM announcing it, we have to clear the TEMP flag
+                * OGM announcing it, we have to clear the TEMP flag. Also,
+                * remove the previous temporary orig node and re-add it
+                * if required. If the orig entry changed, the new one which
+                * is a non-temporary entry is preferred.
                 */
-               common->flags &= ~BATADV_TT_CLIENT_TEMP;
+               if (common->flags & BATADV_TT_CLIENT_TEMP) {
+                       batadv_tt_global_del_orig_list(tt_global_entry);
+                       common->flags &= ~BATADV_TT_CLIENT_TEMP;
+               }
 
                /* the change can carry possible "attribute" flags like the
                 * TT_CLIENT_WIFI, therefore they have to be copied in the
index fe129663bd3f7faeb39f20d02a8425d525da071d..f52bcbf2e58cd8b8ded4c3d65c8dd9b87034b002 100644 (file)
@@ -526,6 +526,9 @@ static int sco_sock_bind(struct socket *sock, struct sockaddr *addr,
        if (!addr || addr->sa_family != AF_BLUETOOTH)
                return -EINVAL;
 
+       if (addr_len < sizeof(struct sockaddr_sco))
+               return -EINVAL;
+
        lock_sock(sk);
 
        if (sk->sk_state != BT_OPEN) {
index 5396ff08af3215d1a532b853c8859fb64dfc6a1f..8a7ada8bb947f5129375e549c22af5a5b32c5a99 100644 (file)
@@ -39,7 +39,7 @@ void br_init_port(struct net_bridge_port *p)
        struct switchdev_attr attr = {
                .id = SWITCHDEV_ATTR_ID_BRIDGE_AGEING_TIME,
                .flags = SWITCHDEV_F_SKIP_EOPNOTSUPP | SWITCHDEV_F_DEFER,
-               .u.ageing_time = p->br->ageing_time,
+               .u.ageing_time = jiffies_to_clock_t(p->br->ageing_time),
        };
        int err;
 
@@ -142,7 +142,10 @@ static void br_stp_start(struct net_bridge *br)
        char *envp[] = { NULL };
        struct net_bridge_port *p;
 
-       r = call_usermodehelper(BR_STP_PROG, argv, envp, UMH_WAIT_PROC);
+       if (net_eq(dev_net(br->dev), &init_net))
+               r = call_usermodehelper(BR_STP_PROG, argv, envp, UMH_WAIT_PROC);
+       else
+               r = -ENOENT;
 
        spin_lock_bh(&br->lock);
 
index e6dc77252fe9fa3e401529426079f094c9f6f999..a1656e3b8d72a66ff56656284205129ecfd30b3e 100644 (file)
@@ -301,12 +301,13 @@ void dst_release(struct dst_entry *dst)
 {
        if (dst) {
                int newrefcnt;
+               unsigned short nocache = dst->flags & DST_NOCACHE;
 
                newrefcnt = atomic_dec_return(&dst->__refcnt);
                if (unlikely(newrefcnt < 0))
                        net_warn_ratelimited("%s: dst:%p refcnt:%d\n",
                                             __func__, dst, newrefcnt);
-               if (!newrefcnt && unlikely(dst->flags & DST_NOCACHE))
+               if (!newrefcnt && unlikely(nocache))
                        call_rcu(&dst->rcu_head, dst_destroy_rcu);
        }
 }
index 152b9c70e25255f1c104c00db3867fd6b21bfa99..b2df375ec9c2173a8132b8efa1c3062f0510284b 100644 (file)
@@ -3643,7 +3643,8 @@ static void __skb_complete_tx_timestamp(struct sk_buff *skb,
        serr->ee.ee_info = tstype;
        if (sk->sk_tsflags & SOF_TIMESTAMPING_OPT_ID) {
                serr->ee.ee_data = skb_shinfo(skb)->tskey;
-               if (sk->sk_protocol == IPPROTO_TCP)
+               if (sk->sk_protocol == IPPROTO_TCP &&
+                   sk->sk_type == SOCK_STREAM)
                        serr->ee.ee_data -= sk->sk_tskey;
        }
 
@@ -4268,7 +4269,7 @@ static struct sk_buff *skb_reorder_vlan_header(struct sk_buff *skb)
                return NULL;
        }
 
-       memmove(skb->data - ETH_HLEN, skb->data - skb->mac_len,
+       memmove(skb->data - ETH_HLEN, skb->data - skb->mac_len - VLAN_HLEN,
                2 * ETH_ALEN);
        skb->mac_header += VLAN_HLEN;
        return skb;
index e31dfcee1729aa23bdd2ed692fda1b90bd75afb8..0d91f7dca751efc3e32348ba217c29e8ed55e80b 100644 (file)
@@ -433,8 +433,6 @@ static bool sock_needs_netstamp(const struct sock *sk)
        }
 }
 
-#define SK_FLAGS_TIMESTAMP ((1UL << SOCK_TIMESTAMP) | (1UL << SOCK_TIMESTAMPING_RX_SOFTWARE))
-
 static void sock_disable_timestamp(struct sock *sk, unsigned long flags)
 {
        if (sk->sk_flags & flags) {
@@ -874,7 +872,8 @@ set_rcvbuf:
 
                if (val & SOF_TIMESTAMPING_OPT_ID &&
                    !(sk->sk_tsflags & SOF_TIMESTAMPING_OPT_ID)) {
-                       if (sk->sk_protocol == IPPROTO_TCP) {
+                       if (sk->sk_protocol == IPPROTO_TCP &&
+                           sk->sk_type == SOCK_STREAM) {
                                if (sk->sk_state != TCP_ESTABLISHED) {
                                        ret = -EINVAL;
                                        break;
@@ -1552,7 +1551,7 @@ struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority)
                         */
                        is_charged = sk_filter_charge(newsk, filter);
 
-               if (unlikely(!is_charged || xfrm_sk_clone_policy(newsk))) {
+               if (unlikely(!is_charged || xfrm_sk_clone_policy(newsk, sk))) {
                        /* It is still raw copy of parent, so invalidate
                         * destructor and make plain sk_free() */
                        newsk->sk_destruct = NULL;
index eebf5ac8ce18abdb7ac094a1e6de081fcbfa79aa..13d6b1a6e0fc2b0730827d93d154d6464a3e58ec 100644 (file)
@@ -678,6 +678,9 @@ static int dn_create(struct net *net, struct socket *sock, int protocol,
 {
        struct sock *sk;
 
+       if (protocol < 0 || protocol > SK_PROTOCOL_MAX)
+               return -EINVAL;
+
        if (!net_eq(net, &init_net))
                return -EAFNOSUPPORT;
 
index 11c4ca13ec3b0434090b3d5cbdd7a0aae784952f..5c5db6636704daa0c49fc13e84b2c5b282a44ed3 100644 (file)
@@ -257,6 +257,9 @@ static int inet_create(struct net *net, struct socket *sock, int protocol,
        int try_loading_module = 0;
        int err;
 
+       if (protocol < 0 || protocol >= IPPROTO_MAX)
+               return -EINVAL;
+
        sock->state = SS_UNCONNECTED;
 
        /* Look for the requested type/protocol pair. */
index cc8f3e506cded3fbcc9a64bbd369577c5f7cb52d..47344759306011b5bb940e9cab9237b9e9f624b4 100644 (file)
@@ -1155,6 +1155,7 @@ static int fib_inetaddr_event(struct notifier_block *this, unsigned long event,
 static int fib_netdev_event(struct notifier_block *this, unsigned long event, void *ptr)
 {
        struct net_device *dev = netdev_notifier_info_to_dev(ptr);
+       struct netdev_notifier_changeupper_info *info;
        struct in_device *in_dev;
        struct net *net = dev_net(dev);
        unsigned int flags;
@@ -1193,6 +1194,14 @@ static int fib_netdev_event(struct notifier_block *this, unsigned long event, vo
        case NETDEV_CHANGEMTU:
                rt_cache_flush(net);
                break;
+       case NETDEV_CHANGEUPPER:
+               info = ptr;
+               /* flush all routes if dev is linked to or unlinked from
+                * an L3 master device (e.g., VRF)
+                */
+               if (info->upper_dev && netif_is_l3_master(info->upper_dev))
+                       fib_disable_ip(dev, NETDEV_DOWN, true);
+               break;
        }
        return NOTIFY_DONE;
 }
index e0fcbbbcfe54d0b35b46597b5f217075ffbc745c..bd903fe0f7508d9d7a94c4ce1e0a825f3e35c398 100644 (file)
@@ -24,6 +24,7 @@ struct fou {
        u16 type;
        struct udp_offload udp_offloads;
        struct list_head list;
+       struct rcu_head rcu;
 };
 
 #define FOU_F_REMCSUM_NOPARTIAL BIT(0)
@@ -417,7 +418,7 @@ static void fou_release(struct fou *fou)
        list_del(&fou->list);
        udp_tunnel_sock_release(sock);
 
-       kfree(fou);
+       kfree_rcu(fou, rcu);
 }
 
 static int fou_encap_init(struct sock *sk, struct fou *fou, struct fou_cfg *cfg)
index f34c31defafe083fcc9146affff5c39745150d04..a09fb0dec725a8827ba5d1e928597c103d1f9322 100644 (file)
@@ -253,9 +253,6 @@ ipip_tunnel_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 
        p.i_key = p.o_key = 0;
        p.i_flags = p.o_flags = 0;
-       if (p.iph.ttl)
-               p.iph.frag_off |= htons(IP_DF);
-
        err = ip_tunnel_ioctl(dev, &p, cmd);
        if (err)
                return err;
index a3558417653567ffe3a83d06515fb1b68ec36dcf..c187c60e3e0c75e0f9c298eaa831c2f19d9a73fc 100644 (file)
@@ -60,6 +60,7 @@ config NFT_REJECT_IPV4
 
 config NFT_DUP_IPV4
        tristate "IPv4 nf_tables packet duplication support"
+       depends on !NF_CONNTRACK || NF_CONNTRACK
        select NF_DUP_IPV4
        help
          This module enables IPv4 packet duplication support for nf_tables.
index 63e5be0abd86ddab6476221161c48aacef34d8c4..bc35f1842512bef8e4d87e76542d7bf11f8946fa 100644 (file)
@@ -601,8 +601,11 @@ static int raw_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
                            (inet->hdrincl ? FLOWI_FLAG_KNOWN_NH : 0),
                           daddr, saddr, 0, 0);
 
-       if (!saddr && ipc.oif)
-               l3mdev_get_saddr(net, ipc.oif, &fl4);
+       if (!saddr && ipc.oif) {
+               err = l3mdev_get_saddr(net, ipc.oif, &fl4);
+               if (err < 0)
+                       goto done;
+       }
 
        if (!inet->hdrincl) {
                rfv.msg = msg;
index 2d656eef7f8e16458127ba591e0a4154365f6a83..d4c51158470f5afb7cee8a5c875b5f9ed5b04e14 100644 (file)
@@ -2478,6 +2478,9 @@ static void tcp_cwnd_reduction(struct sock *sk, const int prior_unsacked,
        int newly_acked_sacked = prior_unsacked -
                                 (tp->packets_out - tp->sacked_out);
 
+       if (newly_acked_sacked <= 0 || WARN_ON_ONCE(!tp->prior_cwnd))
+               return;
+
        tp->prr_delivered += newly_acked_sacked;
        if (delta < 0) {
                u64 dividend = (u64)tp->snd_ssthresh * tp->prr_delivered +
index db003438aaf5f6a2b27319c4669be1b1f62c7ae3..d8841a2f15691fd80c46fbaa62e2431e9ca16003 100644 (file)
@@ -1493,7 +1493,7 @@ bool tcp_prequeue(struct sock *sk, struct sk_buff *skb)
        if (likely(sk->sk_rx_dst))
                skb_dst_drop(skb);
        else
-               skb_dst_force(skb);
+               skb_dst_force_safe(skb);
 
        __skb_queue_tail(&tp->ucopy.prequeue, skb);
        tp->ucopy.memory += skb->truesize;
@@ -1721,8 +1721,7 @@ void inet_sk_rx_dst_set(struct sock *sk, const struct sk_buff *skb)
 {
        struct dst_entry *dst = skb_dst(skb);
 
-       if (dst) {
-               dst_hold(dst);
+       if (dst && dst_hold_safe(dst)) {
                sk->sk_rx_dst = dst;
                inet_sk(sk)->rx_dst_ifindex = skb->skb_iif;
        }
index cb7ca569052c5b69f78418e9c966cb285eff1d50..9bfc39ff2285aecaab86f519a017b84282cb6597 100644 (file)
@@ -3150,7 +3150,7 @@ static int tcp_send_syn_data(struct sock *sk, struct sk_buff *syn)
 {
        struct tcp_sock *tp = tcp_sk(sk);
        struct tcp_fastopen_request *fo = tp->fastopen_req;
-       int syn_loss = 0, space, err = 0, copied;
+       int syn_loss = 0, space, err = 0;
        unsigned long last_syn_loss = 0;
        struct sk_buff *syn_data;
 
@@ -3188,17 +3188,18 @@ static int tcp_send_syn_data(struct sock *sk, struct sk_buff *syn)
                goto fallback;
        syn_data->ip_summed = CHECKSUM_PARTIAL;
        memcpy(syn_data->cb, syn->cb, sizeof(syn->cb));
-       copied = copy_from_iter(skb_put(syn_data, space), space,
-                               &fo->data->msg_iter);
-       if (unlikely(!copied)) {
-               kfree_skb(syn_data);
-               goto fallback;
-       }
-       if (copied != space) {
-               skb_trim(syn_data, copied);
-               space = copied;
+       if (space) {
+               int copied = copy_from_iter(skb_put(syn_data, space), space,
+                                           &fo->data->msg_iter);
+               if (unlikely(!copied)) {
+                       kfree_skb(syn_data);
+                       goto fallback;
+               }
+               if (copied != space) {
+                       skb_trim(syn_data, copied);
+                       space = copied;
+               }
        }
-
        /* No more data pending in inet_wait_for_connect() */
        if (space == fo->size)
                fo->data = NULL;
index 0c7b0e61b917158af7e431f9e7781f7bce313c83..c43890848641948b1e9c55244614ac9a48756753 100644 (file)
@@ -1025,8 +1025,11 @@ int udp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
                                   flow_flags,
                                   faddr, saddr, dport, inet->inet_sport);
 
-               if (!saddr && ipc.oif)
-                       l3mdev_get_saddr(net, ipc.oif, fl4);
+               if (!saddr && ipc.oif) {
+                       err = l3mdev_get_saddr(net, ipc.oif, fl4);
+                       if (err < 0)
+                               goto out;
+               }
 
                security_sk_classify_flow(sk, flowi4_to_flowi(fl4));
                rt = ip_route_output_flow(net, fl4, sk);
index 1e0c3c835a6349eedca54e2dff191ed56b437613..7b0edb37a1150427ef3b0d9a7f2be11421ef67b0 100644 (file)
@@ -259,7 +259,7 @@ static void xfrm4_dst_ifdown(struct dst_entry *dst, struct net_device *dev,
        xfrm_dst_ifdown(dst, dev);
 }
 
-static struct dst_ops xfrm4_dst_ops = {
+static struct dst_ops xfrm4_dst_ops_template = {
        .family =               AF_INET,
        .gc =                   xfrm4_garbage_collect,
        .update_pmtu =          xfrm4_update_pmtu,
@@ -273,7 +273,7 @@ static struct dst_ops xfrm4_dst_ops = {
 
 static struct xfrm_policy_afinfo xfrm4_policy_afinfo = {
        .family =               AF_INET,
-       .dst_ops =              &xfrm4_dst_ops,
+       .dst_ops =              &xfrm4_dst_ops_template,
        .dst_lookup =           xfrm4_dst_lookup,
        .get_saddr =            xfrm4_get_saddr,
        .decode_session =       _decode_session4,
@@ -295,7 +295,7 @@ static struct ctl_table xfrm4_policy_table[] = {
        { }
 };
 
-static int __net_init xfrm4_net_init(struct net *net)
+static int __net_init xfrm4_net_sysctl_init(struct net *net)
 {
        struct ctl_table *table;
        struct ctl_table_header *hdr;
@@ -323,7 +323,7 @@ err_alloc:
        return -ENOMEM;
 }
 
-static void __net_exit xfrm4_net_exit(struct net *net)
+static void __net_exit xfrm4_net_sysctl_exit(struct net *net)
 {
        struct ctl_table *table;
 
@@ -335,12 +335,44 @@ static void __net_exit xfrm4_net_exit(struct net *net)
        if (!net_eq(net, &init_net))
                kfree(table);
 }
+#else /* CONFIG_SYSCTL */
+static int inline xfrm4_net_sysctl_init(struct net *net)
+{
+       return 0;
+}
+
+static void inline xfrm4_net_sysctl_exit(struct net *net)
+{
+}
+#endif
+
+static int __net_init xfrm4_net_init(struct net *net)
+{
+       int ret;
+
+       memcpy(&net->xfrm.xfrm4_dst_ops, &xfrm4_dst_ops_template,
+              sizeof(xfrm4_dst_ops_template));
+       ret = dst_entries_init(&net->xfrm.xfrm4_dst_ops);
+       if (ret)
+               return ret;
+
+       ret = xfrm4_net_sysctl_init(net);
+       if (ret)
+               dst_entries_destroy(&net->xfrm.xfrm4_dst_ops);
+
+       return ret;
+}
+
+static void __net_exit xfrm4_net_exit(struct net *net)
+{
+       xfrm4_net_sysctl_exit(net);
+       dst_entries_destroy(&net->xfrm.xfrm4_dst_ops);
+}
 
 static struct pernet_operations __net_initdata xfrm4_net_ops = {
        .init   = xfrm4_net_init,
        .exit   = xfrm4_net_exit,
 };
-#endif
 
 static void __init xfrm4_policy_init(void)
 {
@@ -349,13 +381,9 @@ static void __init xfrm4_policy_init(void)
 
 void __init xfrm4_init(void)
 {
-       dst_entries_init(&xfrm4_dst_ops);
-
        xfrm4_state_init();
        xfrm4_policy_init();
        xfrm4_protocol_init();
-#ifdef CONFIG_SYSCTL
        register_pernet_subsys(&xfrm4_net_ops);
-#endif
 }
 
index 61f26851655ccd23200278d34ceda44351da1c17..1f21087accab258e5be6cc104f8b8ced13fedd6d 100644 (file)
@@ -350,6 +350,12 @@ static struct inet6_dev *ipv6_add_dev(struct net_device *dev)
        setup_timer(&ndev->rs_timer, addrconf_rs_timer,
                    (unsigned long)ndev);
        memcpy(&ndev->cnf, dev_net(dev)->ipv6.devconf_dflt, sizeof(ndev->cnf));
+
+       if (ndev->cnf.stable_secret.initialized)
+               ndev->addr_gen_mode = IN6_ADDR_GEN_MODE_STABLE_PRIVACY;
+       else
+               ndev->addr_gen_mode = IN6_ADDR_GEN_MODE_EUI64;
+
        ndev->cnf.mtu6 = dev->mtu;
        ndev->cnf.sysctl = NULL;
        ndev->nd_parms = neigh_parms_alloc(dev, &nd_tbl);
@@ -2455,7 +2461,7 @@ ok:
 #ifdef CONFIG_IPV6_OPTIMISTIC_DAD
                        if (in6_dev->cnf.optimistic_dad &&
                            !net->ipv6.devconf_all->forwarding && sllao)
-                               addr_flags = IFA_F_OPTIMISTIC;
+                               addr_flags |= IFA_F_OPTIMISTIC;
 #endif
 
                        /* Do not allow to create too much of autoconfigured
@@ -5363,13 +5369,10 @@ static int addrconf_sysctl_stable_secret(struct ctl_table *ctl, int write,
                goto out;
        }
 
-       if (!write) {
-               err = snprintf(str, sizeof(str), "%pI6",
-                              &secret->secret);
-               if (err >= sizeof(str)) {
-                       err = -EIO;
-                       goto out;
-               }
+       err = snprintf(str, sizeof(str), "%pI6", &secret->secret);
+       if (err >= sizeof(str)) {
+               err = -EIO;
+               goto out;
        }
 
        err = proc_dostring(&lctl, write, buffer, lenp, ppos);
index 882124ebb438bd033765c4284ddf7ada9834d39d..a8f6986dcbe5ea5a36a3cc6fcf51becebb50c33b 100644 (file)
@@ -552,7 +552,7 @@ static int ip6addrlbl_get(struct sk_buff *in_skb, struct nlmsghdr *nlh)
 
        rcu_read_lock();
        p = __ipv6_addr_label(net, addr, ipv6_addr_type(addr), ifal->ifal_index);
-       if (p && ip6addrlbl_hold(p))
+       if (p && !ip6addrlbl_hold(p))
                p = NULL;
        lseq = ip6addrlbl_table.seq;
        rcu_read_unlock();
index 8ec0df75f1c4f81bea71cb466c4da802c39099d8..9f5137cd604e51316c6c3a85ca5423b30ed7ce30 100644 (file)
@@ -109,6 +109,9 @@ static int inet6_create(struct net *net, struct socket *sock, int protocol,
        int try_loading_module = 0;
        int err;
 
+       if (protocol < 0 || protocol >= IPPROTO_MAX)
+               return -EINVAL;
+
        /* Look for the requested type/protocol pair. */
 lookup_protocol:
        err = -ESOCKTNOSUPPORT;
index 3c7b9310b33fdb052e2b97d4cd502482524b4dd8..e5ea177d34c6492713d5271032394a69874a300c 100644 (file)
@@ -1571,13 +1571,11 @@ static int ip6gre_changelink(struct net_device *dev, struct nlattr *tb[],
                        return -EEXIST;
        } else {
                t = nt;
-
-               ip6gre_tunnel_unlink(ign, t);
-               ip6gre_tnl_change(t, &p, !tb[IFLA_MTU]);
-               ip6gre_tunnel_link(ign, t);
-               netdev_state_change(dev);
        }
 
+       ip6gre_tunnel_unlink(ign, t);
+       ip6gre_tnl_change(t, &p, !tb[IFLA_MTU]);
+       ip6gre_tunnel_link(ign, t);
        return 0;
 }
 
index d6161e1c48c86f4a5dfa5cedc89d4b93f8e3d24a..84afb9a7727848038b51ee7a60eebb28d555f693 100644 (file)
@@ -1183,7 +1183,7 @@ static void ndisc_router_discovery(struct sk_buff *skb)
         */
        if (!in6_dev->cnf.accept_ra_from_local &&
            ipv6_chk_addr(dev_net(in6_dev->dev), &ipv6_hdr(skb)->saddr,
-                         NULL, 0)) {
+                         in6_dev->dev, 0)) {
                ND_PRINTK(2, info,
                          "RA from local address detected on dev: %s: default router ignored\n",
                          skb->dev->name);
@@ -1337,7 +1337,7 @@ skip_linkparms:
 #ifdef CONFIG_IPV6_ROUTE_INFO
        if (!in6_dev->cnf.accept_ra_from_local &&
            ipv6_chk_addr(dev_net(in6_dev->dev), &ipv6_hdr(skb)->saddr,
-                         NULL, 0)) {
+                         in6_dev->dev, 0)) {
                ND_PRINTK(2, info,
                          "RA from local address detected on dev: %s: router info ignored.\n",
                          skb->dev->name);
index f6a024e141e595541009cb24c172e0c52a8a879f..e10a04c9cdc7be6bd8fc18f960e7bf51f43cbd81 100644 (file)
@@ -49,6 +49,7 @@ config NFT_REJECT_IPV6
 
 config NFT_DUP_IPV6
        tristate "IPv6 nf_tables packet duplication support"
+       depends on !NF_CONNTRACK || NF_CONNTRACK
        select NF_DUP_IPV6
        help
          This module enables IPv6 packet duplication support for nf_tables.
index e7aab561b7b463d4bfbdd7e7a89302403e252560..6b8a8a9091fa113ee28906c570e78811e6f29815 100644 (file)
@@ -93,10 +93,9 @@ static void inet6_sk_rx_dst_set(struct sock *sk, const struct sk_buff *skb)
 {
        struct dst_entry *dst = skb_dst(skb);
 
-       if (dst) {
+       if (dst && dst_hold_safe(dst)) {
                const struct rt6_info *rt = (const struct rt6_info *)dst;
 
-               dst_hold(dst);
                sk->sk_rx_dst = dst;
                inet_sk(sk)->rx_dst_ifindex = skb->skb_iif;
                inet6_sk(sk)->rx_dst_cookie = rt6_get_cookie(rt);
index 5643423fe67a238c05aee5398ac4064a77bafc16..c074771a10f761253f99611de8294172bdb0e142 100644 (file)
@@ -279,7 +279,7 @@ static void xfrm6_dst_ifdown(struct dst_entry *dst, struct net_device *dev,
        xfrm_dst_ifdown(dst, dev);
 }
 
-static struct dst_ops xfrm6_dst_ops = {
+static struct dst_ops xfrm6_dst_ops_template = {
        .family =               AF_INET6,
        .gc =                   xfrm6_garbage_collect,
        .update_pmtu =          xfrm6_update_pmtu,
@@ -293,7 +293,7 @@ static struct dst_ops xfrm6_dst_ops = {
 
 static struct xfrm_policy_afinfo xfrm6_policy_afinfo = {
        .family =               AF_INET6,
-       .dst_ops =              &xfrm6_dst_ops,
+       .dst_ops =              &xfrm6_dst_ops_template,
        .dst_lookup =           xfrm6_dst_lookup,
        .get_saddr =            xfrm6_get_saddr,
        .decode_session =       _decode_session6,
@@ -325,7 +325,7 @@ static struct ctl_table xfrm6_policy_table[] = {
        { }
 };
 
-static int __net_init xfrm6_net_init(struct net *net)
+static int __net_init xfrm6_net_sysctl_init(struct net *net)
 {
        struct ctl_table *table;
        struct ctl_table_header *hdr;
@@ -353,7 +353,7 @@ err_alloc:
        return -ENOMEM;
 }
 
-static void __net_exit xfrm6_net_exit(struct net *net)
+static void __net_exit xfrm6_net_sysctl_exit(struct net *net)
 {
        struct ctl_table *table;
 
@@ -365,24 +365,52 @@ static void __net_exit xfrm6_net_exit(struct net *net)
        if (!net_eq(net, &init_net))
                kfree(table);
 }
+#else /* CONFIG_SYSCTL */
+static int inline xfrm6_net_sysctl_init(struct net *net)
+{
+       return 0;
+}
+
+static void inline xfrm6_net_sysctl_exit(struct net *net)
+{
+}
+#endif
+
+static int __net_init xfrm6_net_init(struct net *net)
+{
+       int ret;
+
+       memcpy(&net->xfrm.xfrm6_dst_ops, &xfrm6_dst_ops_template,
+              sizeof(xfrm6_dst_ops_template));
+       ret = dst_entries_init(&net->xfrm.xfrm6_dst_ops);
+       if (ret)
+               return ret;
+
+       ret = xfrm6_net_sysctl_init(net);
+       if (ret)
+               dst_entries_destroy(&net->xfrm.xfrm6_dst_ops);
+
+       return ret;
+}
+
+static void __net_exit xfrm6_net_exit(struct net *net)
+{
+       xfrm6_net_sysctl_exit(net);
+       dst_entries_destroy(&net->xfrm.xfrm6_dst_ops);
+}
 
 static struct pernet_operations xfrm6_net_ops = {
        .init   = xfrm6_net_init,
        .exit   = xfrm6_net_exit,
 };
-#endif
 
 int __init xfrm6_init(void)
 {
        int ret;
 
-       dst_entries_init(&xfrm6_dst_ops);
-
        ret = xfrm6_policy_init();
-       if (ret) {
-               dst_entries_destroy(&xfrm6_dst_ops);
+       if (ret)
                goto out;
-       }
        ret = xfrm6_state_init();
        if (ret)
                goto out_policy;
@@ -391,9 +419,7 @@ int __init xfrm6_init(void)
        if (ret)
                goto out_state;
 
-#ifdef CONFIG_SYSCTL
        register_pernet_subsys(&xfrm6_net_ops);
-#endif
 out:
        return ret;
 out_state:
@@ -405,11 +431,8 @@ out_policy:
 
 void xfrm6_fini(void)
 {
-#ifdef CONFIG_SYSCTL
        unregister_pernet_subsys(&xfrm6_net_ops);
-#endif
        xfrm6_protocol_fini();
        xfrm6_policy_fini();
        xfrm6_state_fini();
-       dst_entries_destroy(&xfrm6_dst_ops);
 }
index e6aa48b5395c67e2600eed9482c97b9a626d01bd..923abd6b3064074f39f84644b2d3d1f068403f51 100644 (file)
@@ -1086,6 +1086,9 @@ static int irda_create(struct net *net, struct socket *sock, int protocol,
        struct sock *sk;
        struct irda_sock *self;
 
+       if (protocol < 0 || protocol > SK_PROTOCOL_MAX)
+               return -EINVAL;
+
        if (net != &init_net)
                return -EAFNOSUPPORT;
 
index da471eef07bb1a6ba6e42d3e5b570dbdff6c21e3..c12f348138acf7075297e5854b6e17391646d52b 100644 (file)
@@ -1169,8 +1169,7 @@ static int sta_apply_parameters(struct ieee80211_local *local,
                 * rc isn't initialized here yet, so ignore it
                 */
                __ieee80211_vht_handle_opmode(sdata, sta,
-                                             params->opmode_notif,
-                                             band, false);
+                                             params->opmode_notif, band);
        }
 
        if (ieee80211_vif_is_mesh(&sdata->vif))
index d832bd59236be15c5a6bb86dbb1efc4547025f51..5322b4c716307f90710153bdb91e5425221b1742 100644 (file)
@@ -1709,10 +1709,10 @@ enum ieee80211_sta_rx_bandwidth ieee80211_sta_cur_vht_bw(struct sta_info *sta);
 void ieee80211_sta_set_rx_nss(struct sta_info *sta);
 u32 __ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata,
                                   struct sta_info *sta, u8 opmode,
-                                  enum ieee80211_band band, bool nss_only);
+                                 enum ieee80211_band band);
 void ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata,
                                 struct sta_info *sta, u8 opmode,
-                                enum ieee80211_band band, bool nss_only);
+                                enum ieee80211_band band);
 void ieee80211_apply_vhtcap_overrides(struct ieee80211_sub_if_data *sdata,
                                      struct ieee80211_sta_vht_cap *vht_cap);
 void ieee80211_get_vht_mask_from_cap(__le16 vht_cap,
index b140cc6651f4a7a650380965c0901b60c800746c..3aa04344942bfc06c75341abf841646745c58c7f 100644 (file)
@@ -1379,21 +1379,26 @@ static u32 ieee80211_handle_pwr_constr(struct ieee80211_sub_if_data *sdata,
         */
        if (has_80211h_pwr &&
            (!has_cisco_pwr || pwr_level_80211h <= pwr_level_cisco)) {
+               new_ap_level = pwr_level_80211h;
+
+               if (sdata->ap_power_level == new_ap_level)
+                       return 0;
+
                sdata_dbg(sdata,
                          "Limiting TX power to %d (%d - %d) dBm as advertised by %pM\n",
                          pwr_level_80211h, chan_pwr, pwr_reduction_80211h,
                          sdata->u.mgd.bssid);
-               new_ap_level = pwr_level_80211h;
        } else {  /* has_cisco_pwr is always true here. */
+               new_ap_level = pwr_level_cisco;
+
+               if (sdata->ap_power_level == new_ap_level)
+                       return 0;
+
                sdata_dbg(sdata,
                          "Limiting TX power to %d dBm as advertised by %pM\n",
                          pwr_level_cisco, sdata->u.mgd.bssid);
-               new_ap_level = pwr_level_cisco;
        }
 
-       if (sdata->ap_power_level == new_ap_level)
-               return 0;
-
        sdata->ap_power_level = new_ap_level;
        if (__ieee80211_recalc_txpower(sdata))
                return BSS_CHANGED_TXPOWER;
@@ -3575,7 +3580,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
 
        if (sta && elems.opmode_notif)
                ieee80211_vht_handle_opmode(sdata, sta, *elems.opmode_notif,
-                                           rx_status->band, true);
+                                           rx_status->band);
        mutex_unlock(&local->sta_mtx);
 
        changed |= ieee80211_handle_pwr_constr(sdata, chan, mgmt,
index 8bae5de0dc44299146993df3581a951078eed733..82af407fea7a094db5f08e6426ae670a4cab3729 100644 (file)
@@ -2736,8 +2736,7 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
                        opmode = mgmt->u.action.u.vht_opmode_notif.operating_mode;
 
                        ieee80211_vht_handle_opmode(rx->sdata, rx->sta,
-                                                   opmode, status->band,
-                                                   false);
+                                                   opmode, status->band);
                        goto handled;
                }
                default:
index 74058020b7d6154c1ea1613e9a8a9775789736fa..33344f5a66a85e8a4c0842807249aee3e9d3d02e 100644 (file)
@@ -1641,6 +1641,29 @@ void ieee80211_stop_device(struct ieee80211_local *local)
        drv_stop(local);
 }
 
+static void ieee80211_flush_completed_scan(struct ieee80211_local *local,
+                                          bool aborted)
+{
+       /* It's possible that we don't handle the scan completion in
+        * time during suspend, so if it's still marked as completed
+        * here, queue the work and flush it to clean things up.
+        * Instead of calling the worker function directly here, we
+        * really queue it to avoid potential races with other flows
+        * scheduling the same work.
+        */
+       if (test_bit(SCAN_COMPLETED, &local->scanning)) {
+               /* If coming from reconfiguration failure, abort the scan so
+                * we don't attempt to continue a partial HW scan - which is
+                * possible otherwise if (e.g.) the 2.4 GHz portion was the
+                * completed scan, and a 5 GHz portion is still pending.
+                */
+               if (aborted)
+                       set_bit(SCAN_ABORTED, &local->scanning);
+               ieee80211_queue_delayed_work(&local->hw, &local->scan_work, 0);
+               flush_delayed_work(&local->scan_work);
+       }
+}
+
 static void ieee80211_handle_reconfig_failure(struct ieee80211_local *local)
 {
        struct ieee80211_sub_if_data *sdata;
@@ -1660,6 +1683,8 @@ static void ieee80211_handle_reconfig_failure(struct ieee80211_local *local)
        local->suspended = false;
        local->in_reconfig = false;
 
+       ieee80211_flush_completed_scan(local, true);
+
        /* scheduled scan clearly can't be running any more, but tell
         * cfg80211 and clear local state
         */
@@ -1698,6 +1723,27 @@ static void ieee80211_assign_chanctx(struct ieee80211_local *local,
        mutex_unlock(&local->chanctx_mtx);
 }
 
+static void ieee80211_reconfig_stations(struct ieee80211_sub_if_data *sdata)
+{
+       struct ieee80211_local *local = sdata->local;
+       struct sta_info *sta;
+
+       /* add STAs back */
+       mutex_lock(&local->sta_mtx);
+       list_for_each_entry(sta, &local->sta_list, list) {
+               enum ieee80211_sta_state state;
+
+               if (!sta->uploaded || sta->sdata != sdata)
+                       continue;
+
+               for (state = IEEE80211_STA_NOTEXIST;
+                    state < sta->sta_state; state++)
+                       WARN_ON(drv_sta_state(local, sta->sdata, sta, state,
+                                             state + 1));
+       }
+       mutex_unlock(&local->sta_mtx);
+}
+
 int ieee80211_reconfig(struct ieee80211_local *local)
 {
        struct ieee80211_hw *hw = &local->hw;
@@ -1833,50 +1879,11 @@ int ieee80211_reconfig(struct ieee80211_local *local)
                                WARN_ON(drv_add_chanctx(local, ctx));
                mutex_unlock(&local->chanctx_mtx);
 
-               list_for_each_entry(sdata, &local->interfaces, list) {
-                       if (!ieee80211_sdata_running(sdata))
-                               continue;
-                       ieee80211_assign_chanctx(local, sdata);
-               }
-
                sdata = rtnl_dereference(local->monitor_sdata);
                if (sdata && ieee80211_sdata_running(sdata))
                        ieee80211_assign_chanctx(local, sdata);
        }
 
-       /* add STAs back */
-       mutex_lock(&local->sta_mtx);
-       list_for_each_entry(sta, &local->sta_list, list) {
-               enum ieee80211_sta_state state;
-
-               if (!sta->uploaded)
-                       continue;
-
-               /* AP-mode stations will be added later */
-               if (sta->sdata->vif.type == NL80211_IFTYPE_AP)
-                       continue;
-
-               for (state = IEEE80211_STA_NOTEXIST;
-                    state < sta->sta_state; state++)
-                       WARN_ON(drv_sta_state(local, sta->sdata, sta, state,
-                                             state + 1));
-       }
-       mutex_unlock(&local->sta_mtx);
-
-       /* reconfigure tx conf */
-       if (hw->queues >= IEEE80211_NUM_ACS) {
-               list_for_each_entry(sdata, &local->interfaces, list) {
-                       if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
-                           sdata->vif.type == NL80211_IFTYPE_MONITOR ||
-                           !ieee80211_sdata_running(sdata))
-                               continue;
-
-                       for (i = 0; i < IEEE80211_NUM_ACS; i++)
-                               drv_conf_tx(local, sdata, i,
-                                           &sdata->tx_conf[i]);
-               }
-       }
-
        /* reconfigure hardware */
        ieee80211_hw_config(local, ~0);
 
@@ -1889,6 +1896,22 @@ int ieee80211_reconfig(struct ieee80211_local *local)
                if (!ieee80211_sdata_running(sdata))
                        continue;
 
+               ieee80211_assign_chanctx(local, sdata);
+
+               switch (sdata->vif.type) {
+               case NL80211_IFTYPE_AP_VLAN:
+               case NL80211_IFTYPE_MONITOR:
+                       break;
+               default:
+                       ieee80211_reconfig_stations(sdata);
+                       /* fall through */
+               case NL80211_IFTYPE_AP: /* AP stations are handled later */
+                       for (i = 0; i < IEEE80211_NUM_ACS; i++)
+                               drv_conf_tx(local, sdata, i,
+                                           &sdata->tx_conf[i]);
+                       break;
+               }
+
                /* common change flags for all interface types */
                changed = BSS_CHANGED_ERP_CTS_PROT |
                          BSS_CHANGED_ERP_PREAMBLE |
@@ -2074,17 +2097,7 @@ int ieee80211_reconfig(struct ieee80211_local *local)
        mb();
        local->resuming = false;
 
-       /* It's possible that we don't handle the scan completion in
-        * time during suspend, so if it's still marked as completed
-        * here, queue the work and flush it to clean things up.
-        * Instead of calling the worker function directly here, we
-        * really queue it to avoid potential races with other flows
-        * scheduling the same work.
-        */
-       if (test_bit(SCAN_COMPLETED, &local->scanning)) {
-               ieee80211_queue_delayed_work(&local->hw, &local->scan_work, 0);
-               flush_delayed_work(&local->scan_work);
-       }
+       ieee80211_flush_completed_scan(local, false);
 
        if (local->open_count && !reconfig_due_to_wowlan)
                drv_reconfig_complete(local, IEEE80211_RECONFIG_TYPE_SUSPEND);
index ff1c798921a6acc90181923456cf92bed0973f61..c38b2f07a919e20dc22363fe80911f5f5a0b004f 100644 (file)
@@ -378,7 +378,7 @@ void ieee80211_sta_set_rx_nss(struct sta_info *sta)
 
 u32 __ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata,
                                  struct sta_info *sta, u8 opmode,
-                                 enum ieee80211_band band, bool nss_only)
+                                 enum ieee80211_band band)
 {
        struct ieee80211_local *local = sdata->local;
        struct ieee80211_supported_band *sband;
@@ -401,9 +401,6 @@ u32 __ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata,
                changed |= IEEE80211_RC_NSS_CHANGED;
        }
 
-       if (nss_only)
-               return changed;
-
        switch (opmode & IEEE80211_OPMODE_NOTIF_CHANWIDTH_MASK) {
        case IEEE80211_OPMODE_NOTIF_CHANWIDTH_20MHZ:
                sta->cur_max_bandwidth = IEEE80211_STA_RX_BW_20;
@@ -430,13 +427,12 @@ u32 __ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata,
 
 void ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata,
                                 struct sta_info *sta, u8 opmode,
-                                enum ieee80211_band band, bool nss_only)
+                                enum ieee80211_band band)
 {
        struct ieee80211_local *local = sdata->local;
        struct ieee80211_supported_band *sband = local->hw.wiphy->bands[band];
 
-       u32 changed = __ieee80211_vht_handle_opmode(sdata, sta, opmode,
-                                                   band, nss_only);
+       u32 changed = __ieee80211_vht_handle_opmode(sdata, sta, opmode, band);
 
        if (changed > 0)
                rate_control_rate_update(local, sband, sta, changed);
index c70d750148b66759ce47525c6f6b348c2e69efaa..c32fc411a911a414db2d0c1e141cb76093079d33 100644 (file)
@@ -27,6 +27,8 @@
  */
 #define MAX_MP_SELECT_LABELS 4
 
+#define MPLS_NEIGH_TABLE_UNSPEC (NEIGH_LINK_TABLE + 1)
+
 static int zero = 0;
 static int label_limit = (1 << 20) - 1;
 
@@ -317,7 +319,13 @@ static int mpls_forward(struct sk_buff *skb, struct net_device *dev,
                }
        }
 
-       err = neigh_xmit(nh->nh_via_table, out_dev, mpls_nh_via(rt, nh), skb);
+       /* If via wasn't specified then send out using device address */
+       if (nh->nh_via_table == MPLS_NEIGH_TABLE_UNSPEC)
+               err = neigh_xmit(NEIGH_LINK_TABLE, out_dev,
+                                out_dev->dev_addr, skb);
+       else
+               err = neigh_xmit(nh->nh_via_table, out_dev,
+                                mpls_nh_via(rt, nh), skb);
        if (err)
                net_dbg_ratelimited("%s: packet transmission failed: %d\n",
                                    __func__, err);
@@ -534,6 +542,10 @@ static int mpls_nh_assign_dev(struct net *net, struct mpls_route *rt,
        if (!mpls_dev_get(dev))
                goto errout;
 
+       if ((nh->nh_via_table == NEIGH_LINK_TABLE) &&
+           (dev->addr_len != nh->nh_via_alen))
+               goto errout;
+
        RCU_INIT_POINTER(nh->nh_dev, dev);
 
        return 0;
@@ -592,10 +604,14 @@ static int mpls_nh_build(struct net *net, struct mpls_route *rt,
                        goto errout;
        }
 
-       err = nla_get_via(via, &nh->nh_via_alen, &nh->nh_via_table,
-                         __mpls_nh_via(rt, nh));
-       if (err)
-               goto errout;
+       if (via) {
+               err = nla_get_via(via, &nh->nh_via_alen, &nh->nh_via_table,
+                                 __mpls_nh_via(rt, nh));
+               if (err)
+                       goto errout;
+       } else {
+               nh->nh_via_table = MPLS_NEIGH_TABLE_UNSPEC;
+       }
 
        err = mpls_nh_assign_dev(net, rt, nh, oif);
        if (err)
@@ -677,9 +693,6 @@ static int mpls_nh_build_multi(struct mpls_route_config *cfg,
                        nla_newdst = nla_find(attrs, attrlen, RTA_NEWDST);
                }
 
-               if (!nla_via)
-                       goto errout;
-
                err = mpls_nh_build(cfg->rc_nlinfo.nl_net, rt, nh,
                                    rtnh->rtnh_ifindex, nla_via,
                                    nla_newdst);
@@ -1118,6 +1131,7 @@ static int rtm_to_route_config(struct sk_buff *skb,  struct nlmsghdr *nlh,
 
        cfg->rc_label           = LABEL_NOT_SPECIFIED;
        cfg->rc_protocol        = rtm->rtm_protocol;
+       cfg->rc_via_table       = MPLS_NEIGH_TABLE_UNSPEC;
        cfg->rc_nlflags         = nlh->nlmsg_flags;
        cfg->rc_nlinfo.portid   = NETLINK_CB(skb).portid;
        cfg->rc_nlinfo.nlh      = nlh;
@@ -1231,7 +1245,8 @@ static int mpls_dump_route(struct sk_buff *skb, u32 portid, u32 seq, int event,
                    nla_put_labels(skb, RTA_NEWDST, nh->nh_labels,
                                   nh->nh_label))
                        goto nla_put_failure;
-               if (nla_put_via(skb, nh->nh_via_table, mpls_nh_via(rt, nh),
+               if (nh->nh_via_table != MPLS_NEIGH_TABLE_UNSPEC &&
+                   nla_put_via(skb, nh->nh_via_table, mpls_nh_via(rt, nh),
                                nh->nh_via_alen))
                        goto nla_put_failure;
                dev = rtnl_dereference(nh->nh_dev);
@@ -1257,7 +1272,8 @@ static int mpls_dump_route(struct sk_buff *skb, u32 portid, u32 seq, int event,
                                                            nh->nh_labels,
                                                            nh->nh_label))
                                goto nla_put_failure;
-                       if (nla_put_via(skb, nh->nh_via_table,
+                       if (nh->nh_via_table != MPLS_NEIGH_TABLE_UNSPEC &&
+                           nla_put_via(skb, nh->nh_via_table,
                                        mpls_nh_via(rt, nh),
                                        nh->nh_via_alen))
                                goto nla_put_failure;
@@ -1319,7 +1335,8 @@ static inline size_t lfib_nlmsg_size(struct mpls_route *rt)
 
                if (nh->nh_dev)
                        payload += nla_total_size(4); /* RTA_OIF */
-               payload += nla_total_size(2 + nh->nh_via_alen); /* RTA_VIA */
+               if (nh->nh_via_table != MPLS_NEIGH_TABLE_UNSPEC) /* RTA_VIA */
+                       payload += nla_total_size(2 + nh->nh_via_alen);
                if (nh->nh_labels) /* RTA_NEWDST */
                        payload += nla_total_size(nh->nh_labels * 4);
        } else {
@@ -1328,7 +1345,9 @@ static inline size_t lfib_nlmsg_size(struct mpls_route *rt)
 
                for_nexthops(rt) {
                        nhsize += nla_total_size(sizeof(struct rtnexthop));
-                       nhsize += nla_total_size(2 + nh->nh_via_alen);
+                       /* RTA_VIA */
+                       if (nh->nh_via_table != MPLS_NEIGH_TABLE_UNSPEC)
+                               nhsize += nla_total_size(2 + nh->nh_via_alen);
                        if (nh->nh_labels)
                                nhsize += nla_total_size(nh->nh_labels * 4);
                } endfor_nexthops(rt);
index 67591aef9cae6fb203ef802272baad6e5b191000..64afd3d0b14407c252a766ab2280a30452a684c5 100644 (file)
@@ -54,10 +54,10 @@ int mpls_output(struct net *net, struct sock *sk, struct sk_buff *skb)
        unsigned int ttl;
 
        /* Obtain the ttl */
-       if (skb->protocol == htons(ETH_P_IP)) {
+       if (dst->ops->family == AF_INET) {
                ttl = ip_hdr(skb)->ttl;
                rt = (struct rtable *)dst;
-       } else if (skb->protocol == htons(ETH_P_IPV6)) {
+       } else if (dst->ops->family == AF_INET6) {
                ttl = ipv6_hdr(skb)->hop_limit;
                rt6 = (struct rt6_info *)dst;
        } else {
index 93cc4737018fdf3d13a2896c19a9c65891355f9e..2cb429d34c03c99e2e030becede22b05db604a76 100644 (file)
@@ -89,6 +89,7 @@ nf_tables_afinfo_lookup(struct net *net, int family, bool autoload)
 }
 
 static void nft_ctx_init(struct nft_ctx *ctx,
+                        struct net *net,
                         const struct sk_buff *skb,
                         const struct nlmsghdr *nlh,
                         struct nft_af_info *afi,
@@ -96,7 +97,7 @@ static void nft_ctx_init(struct nft_ctx *ctx,
                         struct nft_chain *chain,
                         const struct nlattr * const *nla)
 {
-       ctx->net        = sock_net(skb->sk);
+       ctx->net        = net;
        ctx->afi        = afi;
        ctx->table      = table;
        ctx->chain      = chain;
@@ -672,15 +673,14 @@ err:
        return ret;
 }
 
-static int nf_tables_newtable(struct sock *nlsk, struct sk_buff *skb,
-                             const struct nlmsghdr *nlh,
+static int nf_tables_newtable(struct net *net, struct sock *nlsk,
+                             struct sk_buff *skb, const struct nlmsghdr *nlh,
                              const struct nlattr * const nla[])
 {
        const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
        const struct nlattr *name;
        struct nft_af_info *afi;
        struct nft_table *table;
-       struct net *net = sock_net(skb->sk);
        int family = nfmsg->nfgen_family;
        u32 flags = 0;
        struct nft_ctx ctx;
@@ -706,7 +706,7 @@ static int nf_tables_newtable(struct sock *nlsk, struct sk_buff *skb,
                if (nlh->nlmsg_flags & NLM_F_REPLACE)
                        return -EOPNOTSUPP;
 
-               nft_ctx_init(&ctx, skb, nlh, afi, table, NULL, nla);
+               nft_ctx_init(&ctx, net, skb, nlh, afi, table, NULL, nla);
                return nf_tables_updtable(&ctx);
        }
 
@@ -730,7 +730,7 @@ static int nf_tables_newtable(struct sock *nlsk, struct sk_buff *skb,
        INIT_LIST_HEAD(&table->sets);
        table->flags = flags;
 
-       nft_ctx_init(&ctx, skb, nlh, afi, table, NULL, nla);
+       nft_ctx_init(&ctx, net, skb, nlh, afi, table, NULL, nla);
        err = nft_trans_table_add(&ctx, NFT_MSG_NEWTABLE);
        if (err < 0)
                goto err3;
@@ -810,18 +810,17 @@ out:
        return err;
 }
 
-static int nf_tables_deltable(struct sock *nlsk, struct sk_buff *skb,
-                             const struct nlmsghdr *nlh,
+static int nf_tables_deltable(struct net *net, struct sock *nlsk,
+                             struct sk_buff *skb, const struct nlmsghdr *nlh,
                              const struct nlattr * const nla[])
 {
        const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
        struct nft_af_info *afi;
        struct nft_table *table;
-       struct net *net = sock_net(skb->sk);
        int family = nfmsg->nfgen_family;
        struct nft_ctx ctx;
 
-       nft_ctx_init(&ctx, skb, nlh, NULL, NULL, NULL, nla);
+       nft_ctx_init(&ctx, net, skb, nlh, NULL, NULL, NULL, nla);
        if (family == AF_UNSPEC || nla[NFTA_TABLE_NAME] == NULL)
                return nft_flush(&ctx, family);
 
@@ -1221,8 +1220,8 @@ static void nf_tables_chain_destroy(struct nft_chain *chain)
        }
 }
 
-static int nf_tables_newchain(struct sock *nlsk, struct sk_buff *skb,
-                             const struct nlmsghdr *nlh,
+static int nf_tables_newchain(struct net *net, struct sock *nlsk,
+                             struct sk_buff *skb, const struct nlmsghdr *nlh,
                              const struct nlattr * const nla[])
 {
        const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
@@ -1232,7 +1231,6 @@ static int nf_tables_newchain(struct sock *nlsk, struct sk_buff *skb,
        struct nft_chain *chain;
        struct nft_base_chain *basechain = NULL;
        struct nlattr *ha[NFTA_HOOK_MAX + 1];
-       struct net *net = sock_net(skb->sk);
        int family = nfmsg->nfgen_family;
        struct net_device *dev = NULL;
        u8 policy = NF_ACCEPT;
@@ -1313,7 +1311,7 @@ static int nf_tables_newchain(struct sock *nlsk, struct sk_buff *skb,
                                return PTR_ERR(stats);
                }
 
-               nft_ctx_init(&ctx, skb, nlh, afi, table, chain, nla);
+               nft_ctx_init(&ctx, net, skb, nlh, afi, table, chain, nla);
                trans = nft_trans_alloc(&ctx, NFT_MSG_NEWCHAIN,
                                        sizeof(struct nft_trans_chain));
                if (trans == NULL) {
@@ -1461,7 +1459,7 @@ static int nf_tables_newchain(struct sock *nlsk, struct sk_buff *skb,
        if (err < 0)
                goto err1;
 
-       nft_ctx_init(&ctx, skb, nlh, afi, table, chain, nla);
+       nft_ctx_init(&ctx, net, skb, nlh, afi, table, chain, nla);
        err = nft_trans_chain_add(&ctx, NFT_MSG_NEWCHAIN);
        if (err < 0)
                goto err2;
@@ -1476,15 +1474,14 @@ err1:
        return err;
 }
 
-static int nf_tables_delchain(struct sock *nlsk, struct sk_buff *skb,
-                             const struct nlmsghdr *nlh,
+static int nf_tables_delchain(struct net *net, struct sock *nlsk,
+                             struct sk_buff *skb, const struct nlmsghdr *nlh,
                              const struct nlattr * const nla[])
 {
        const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
        struct nft_af_info *afi;
        struct nft_table *table;
        struct nft_chain *chain;
-       struct net *net = sock_net(skb->sk);
        int family = nfmsg->nfgen_family;
        struct nft_ctx ctx;
 
@@ -1506,7 +1503,7 @@ static int nf_tables_delchain(struct sock *nlsk, struct sk_buff *skb,
        if (chain->use > 0)
                return -EBUSY;
 
-       nft_ctx_init(&ctx, skb, nlh, afi, table, chain, nla);
+       nft_ctx_init(&ctx, net, skb, nlh, afi, table, chain, nla);
 
        return nft_delchain(&ctx);
 }
@@ -2010,13 +2007,12 @@ static void nf_tables_rule_destroy(const struct nft_ctx *ctx,
 
 static struct nft_expr_info *info;
 
-static int nf_tables_newrule(struct sock *nlsk, struct sk_buff *skb,
-                            const struct nlmsghdr *nlh,
+static int nf_tables_newrule(struct net *net, struct sock *nlsk,
+                            struct sk_buff *skb, const struct nlmsghdr *nlh,
                             const struct nlattr * const nla[])
 {
        const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
        struct nft_af_info *afi;
-       struct net *net = sock_net(skb->sk);
        struct nft_table *table;
        struct nft_chain *chain;
        struct nft_rule *rule, *old_rule = NULL;
@@ -2075,7 +2071,7 @@ static int nf_tables_newrule(struct sock *nlsk, struct sk_buff *skb,
                        return PTR_ERR(old_rule);
        }
 
-       nft_ctx_init(&ctx, skb, nlh, afi, table, chain, nla);
+       nft_ctx_init(&ctx, net, skb, nlh, afi, table, chain, nla);
 
        n = 0;
        size = 0;
@@ -2176,13 +2172,12 @@ err1:
        return err;
 }
 
-static int nf_tables_delrule(struct sock *nlsk, struct sk_buff *skb,
-                            const struct nlmsghdr *nlh,
+static int nf_tables_delrule(struct net *net, struct sock *nlsk,
+                            struct sk_buff *skb, const struct nlmsghdr *nlh,
                             const struct nlattr * const nla[])
 {
        const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
        struct nft_af_info *afi;
-       struct net *net = sock_net(skb->sk);
        struct nft_table *table;
        struct nft_chain *chain = NULL;
        struct nft_rule *rule;
@@ -2205,7 +2200,7 @@ static int nf_tables_delrule(struct sock *nlsk, struct sk_buff *skb,
                        return PTR_ERR(chain);
        }
 
-       nft_ctx_init(&ctx, skb, nlh, afi, table, chain, nla);
+       nft_ctx_init(&ctx, net, skb, nlh, afi, table, chain, nla);
 
        if (chain) {
                if (nla[NFTA_RULE_HANDLE]) {
@@ -2344,12 +2339,11 @@ static const struct nla_policy nft_set_desc_policy[NFTA_SET_DESC_MAX + 1] = {
        [NFTA_SET_DESC_SIZE]            = { .type = NLA_U32 },
 };
 
-static int nft_ctx_init_from_setattr(struct nft_ctx *ctx,
+static int nft_ctx_init_from_setattr(struct nft_ctx *ctx, struct net *net,
                                     const struct sk_buff *skb,
                                     const struct nlmsghdr *nlh,
                                     const struct nlattr * const nla[])
 {
-       struct net *net = sock_net(skb->sk);
        const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
        struct nft_af_info *afi = NULL;
        struct nft_table *table = NULL;
@@ -2371,7 +2365,7 @@ static int nft_ctx_init_from_setattr(struct nft_ctx *ctx,
                        return -ENOENT;
        }
 
-       nft_ctx_init(ctx, skb, nlh, afi, table, NULL, nla);
+       nft_ctx_init(ctx, net, skb, nlh, afi, table, NULL, nla);
        return 0;
 }
 
@@ -2623,6 +2617,7 @@ static int nf_tables_getset(struct sock *nlsk, struct sk_buff *skb,
                            const struct nlmsghdr *nlh,
                            const struct nlattr * const nla[])
 {
+       struct net *net = sock_net(skb->sk);
        const struct nft_set *set;
        struct nft_ctx ctx;
        struct sk_buff *skb2;
@@ -2630,7 +2625,7 @@ static int nf_tables_getset(struct sock *nlsk, struct sk_buff *skb,
        int err;
 
        /* Verify existence before starting dump */
-       err = nft_ctx_init_from_setattr(&ctx, skb, nlh, nla);
+       err = nft_ctx_init_from_setattr(&ctx, net, skb, nlh, nla);
        if (err < 0)
                return err;
 
@@ -2693,14 +2688,13 @@ static int nf_tables_set_desc_parse(const struct nft_ctx *ctx,
        return 0;
 }
 
-static int nf_tables_newset(struct sock *nlsk, struct sk_buff *skb,
-                           const struct nlmsghdr *nlh,
+static int nf_tables_newset(struct net *net, struct sock *nlsk,
+                           struct sk_buff *skb, const struct nlmsghdr *nlh,
                            const struct nlattr * const nla[])
 {
        const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
        const struct nft_set_ops *ops;
        struct nft_af_info *afi;
-       struct net *net = sock_net(skb->sk);
        struct nft_table *table;
        struct nft_set *set;
        struct nft_ctx ctx;
@@ -2798,7 +2792,7 @@ static int nf_tables_newset(struct sock *nlsk, struct sk_buff *skb,
        if (IS_ERR(table))
                return PTR_ERR(table);
 
-       nft_ctx_init(&ctx, skb, nlh, afi, table, NULL, nla);
+       nft_ctx_init(&ctx, net, skb, nlh, afi, table, NULL, nla);
 
        set = nf_tables_set_lookup(table, nla[NFTA_SET_NAME]);
        if (IS_ERR(set)) {
@@ -2882,8 +2876,8 @@ static void nf_tables_set_destroy(const struct nft_ctx *ctx, struct nft_set *set
        nft_set_destroy(set);
 }
 
-static int nf_tables_delset(struct sock *nlsk, struct sk_buff *skb,
-                           const struct nlmsghdr *nlh,
+static int nf_tables_delset(struct net *net, struct sock *nlsk,
+                           struct sk_buff *skb, const struct nlmsghdr *nlh,
                            const struct nlattr * const nla[])
 {
        const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
@@ -2896,7 +2890,7 @@ static int nf_tables_delset(struct sock *nlsk, struct sk_buff *skb,
        if (nla[NFTA_SET_TABLE] == NULL)
                return -EINVAL;
 
-       err = nft_ctx_init_from_setattr(&ctx, skb, nlh, nla);
+       err = nft_ctx_init_from_setattr(&ctx, net, skb, nlh, nla);
        if (err < 0)
                return err;
 
@@ -3024,7 +3018,7 @@ static const struct nla_policy nft_set_elem_list_policy[NFTA_SET_ELEM_LIST_MAX +
        [NFTA_SET_ELEM_LIST_SET_ID]     = { .type = NLA_U32 },
 };
 
-static int nft_ctx_init_from_elemattr(struct nft_ctx *ctx,
+static int nft_ctx_init_from_elemattr(struct nft_ctx *ctx, struct net *net,
                                      const struct sk_buff *skb,
                                      const struct nlmsghdr *nlh,
                                      const struct nlattr * const nla[],
@@ -3033,7 +3027,6 @@ static int nft_ctx_init_from_elemattr(struct nft_ctx *ctx,
        const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
        struct nft_af_info *afi;
        struct nft_table *table;
-       struct net *net = sock_net(skb->sk);
 
        afi = nf_tables_afinfo_lookup(net, nfmsg->nfgen_family, false);
        if (IS_ERR(afi))
@@ -3045,7 +3038,7 @@ static int nft_ctx_init_from_elemattr(struct nft_ctx *ctx,
        if (!trans && (table->flags & NFT_TABLE_INACTIVE))
                return -ENOENT;
 
-       nft_ctx_init(ctx, skb, nlh, afi, table, NULL, nla);
+       nft_ctx_init(ctx, net, skb, nlh, afi, table, NULL, nla);
        return 0;
 }
 
@@ -3135,6 +3128,7 @@ static int nf_tables_dump_setelem(const struct nft_ctx *ctx,
 
 static int nf_tables_dump_set(struct sk_buff *skb, struct netlink_callback *cb)
 {
+       struct net *net = sock_net(skb->sk);
        const struct nft_set *set;
        struct nft_set_dump_args args;
        struct nft_ctx ctx;
@@ -3150,8 +3144,8 @@ static int nf_tables_dump_set(struct sk_buff *skb, struct netlink_callback *cb)
        if (err < 0)
                return err;
 
-       err = nft_ctx_init_from_elemattr(&ctx, cb->skb, cb->nlh, (void *)nla,
-                                        false);
+       err = nft_ctx_init_from_elemattr(&ctx, net, cb->skb, cb->nlh,
+                                        (void *)nla, false);
        if (err < 0)
                return err;
 
@@ -3212,11 +3206,12 @@ static int nf_tables_getsetelem(struct sock *nlsk, struct sk_buff *skb,
                                const struct nlmsghdr *nlh,
                                const struct nlattr * const nla[])
 {
+       struct net *net = sock_net(skb->sk);
        const struct nft_set *set;
        struct nft_ctx ctx;
        int err;
 
-       err = nft_ctx_init_from_elemattr(&ctx, skb, nlh, nla, false);
+       err = nft_ctx_init_from_elemattr(&ctx, net, skb, nlh, nla, false);
        if (err < 0)
                return err;
 
@@ -3528,11 +3523,10 @@ err1:
        return err;
 }
 
-static int nf_tables_newsetelem(struct sock *nlsk, struct sk_buff *skb,
-                               const struct nlmsghdr *nlh,
+static int nf_tables_newsetelem(struct net *net, struct sock *nlsk,
+                               struct sk_buff *skb, const struct nlmsghdr *nlh,
                                const struct nlattr * const nla[])
 {
-       struct net *net = sock_net(skb->sk);
        const struct nlattr *attr;
        struct nft_set *set;
        struct nft_ctx ctx;
@@ -3541,7 +3535,7 @@ static int nf_tables_newsetelem(struct sock *nlsk, struct sk_buff *skb,
        if (nla[NFTA_SET_ELEM_LIST_ELEMENTS] == NULL)
                return -EINVAL;
 
-       err = nft_ctx_init_from_elemattr(&ctx, skb, nlh, nla, true);
+       err = nft_ctx_init_from_elemattr(&ctx, net, skb, nlh, nla, true);
        if (err < 0)
                return err;
 
@@ -3623,8 +3617,8 @@ err1:
        return err;
 }
 
-static int nf_tables_delsetelem(struct sock *nlsk, struct sk_buff *skb,
-                               const struct nlmsghdr *nlh,
+static int nf_tables_delsetelem(struct net *net, struct sock *nlsk,
+                               struct sk_buff *skb, const struct nlmsghdr *nlh,
                                const struct nlattr * const nla[])
 {
        const struct nlattr *attr;
@@ -3635,7 +3629,7 @@ static int nf_tables_delsetelem(struct sock *nlsk, struct sk_buff *skb,
        if (nla[NFTA_SET_ELEM_LIST_ELEMENTS] == NULL)
                return -EINVAL;
 
-       err = nft_ctx_init_from_elemattr(&ctx, skb, nlh, nla, false);
+       err = nft_ctx_init_from_elemattr(&ctx, net, skb, nlh, nla, false);
        if (err < 0)
                return err;
 
@@ -4030,7 +4024,8 @@ static int nf_tables_abort(struct sk_buff *skb)
        struct nft_trans *trans, *next;
        struct nft_trans_elem *te;
 
-       list_for_each_entry_safe(trans, next, &net->nft.commit_list, list) {
+       list_for_each_entry_safe_reverse(trans, next, &net->nft.commit_list,
+                                        list) {
                switch (trans->msg_type) {
                case NFT_MSG_NEWTABLE:
                        if (nft_trans_table_update(trans)) {
index 7b9c053ba75072276ee9227ea8d1e67ce3307715..edb3502f20161cf53d44e3fe84d9f0c63072be6a 100644 (file)
@@ -94,7 +94,7 @@ nft_do_chain_netdev(void *priv, struct sk_buff *skb,
 {
        struct nft_pktinfo pkt;
 
-       switch (eth_hdr(skb)->h_proto) {
+       switch (skb->protocol) {
        case htons(ETH_P_IP):
                nft_netdev_set_pktinfo_ipv4(&pkt, skb, state);
                break;
index 46453ab318db0bf2a4bc957dcad6742ccbcacc92..77afe913d03db73c65631fba8c42732cb3f33f32 100644 (file)
@@ -295,8 +295,6 @@ replay:
        if (!skb)
                return netlink_ack(oskb, nlh, -ENOMEM);
 
-       skb->sk = oskb->sk;
-
        nfnl_lock(subsys_id);
        ss = rcu_dereference_protected(table[subsys_id].subsys,
                                       lockdep_is_held(&table[subsys_id].mutex));
@@ -381,7 +379,7 @@ replay:
                                goto ack;
 
                        if (nc->call_batch) {
-                               err = nc->call_batch(net->nfnl, skb, nlh,
+                               err = nc->call_batch(net, net->nfnl, skb, nlh,
                                                     (const struct nlattr **)cda);
                        }
 
index 7d81d280cb4ff3e8878af96bd644930f68a4340c..861c6615253bfe3b45e648d9c98a7715d873cbf9 100644 (file)
@@ -365,8 +365,9 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue,
                break;
        }
 
+       nfnl_ct = rcu_dereference(nfnl_ct_hook);
+
        if (queue->flags & NFQA_CFG_F_CONNTRACK) {
-               nfnl_ct = rcu_dereference(nfnl_ct_hook);
                if (nfnl_ct != NULL) {
                        ct = nfnl_ct->get_ct(entskb, &ctinfo);
                        if (ct != NULL)
@@ -1064,9 +1065,10 @@ nfqnl_recv_verdict(struct sock *ctnl, struct sk_buff *skb,
        if (entry == NULL)
                return -ENOENT;
 
+       /* rcu lock already held from nfnl->call_rcu. */
+       nfnl_ct = rcu_dereference(nfnl_ct_hook);
+
        if (nfqa[NFQA_CT]) {
-               /* rcu lock already held from nfnl->call_rcu. */
-               nfnl_ct = rcu_dereference(nfnl_ct_hook);
                if (nfnl_ct != NULL)
                        ct = nfqnl_ct_parse(nfnl_ct, nlh, nfqa, entry, &ctinfo);
        }
@@ -1417,6 +1419,7 @@ static int __init nfnetlink_queue_init(void)
 
 cleanup_netlink_notifier:
        netlink_unregister_notifier(&nfqnl_rtnl_notifier);
+       unregister_pernet_subsys(&nfnl_queue_net_ops);
 out:
        return status;
 }
index 8cbca3432f90324f8a28df2bd67da88cdaf72b12..939921532764acdd61a4d33c352abd2b8e1d4756 100644 (file)
@@ -366,6 +366,7 @@ static int nft_ct_get_dump(struct sk_buff *skb, const struct nft_expr *expr)
                goto nla_put_failure;
 
        switch (priv->key) {
+       case NFT_CT_L3PROTOCOL:
        case NFT_CT_PROTOCOL:
        case NFT_CT_SRC:
        case NFT_CT_DST:
index c2cc11168fd5e164fa122da5dd44f7aa47279a1e..e004067ec24ac448467c0bd5a552eea019975e56 100644 (file)
@@ -53,6 +53,8 @@ struct ovs_conntrack_info {
        struct md_labels labels;
 };
 
+static void __ovs_ct_free_action(struct ovs_conntrack_info *ct_info);
+
 static u16 key_to_nfproto(const struct sw_flow_key *key)
 {
        switch (ntohs(key->eth.type)) {
@@ -141,6 +143,7 @@ static void __ovs_ct_update_key(struct sw_flow_key *key, u8 state,
  * previously sent the packet to conntrack via the ct action.
  */
 static void ovs_ct_update_key(const struct sk_buff *skb,
+                             const struct ovs_conntrack_info *info,
                              struct sw_flow_key *key, bool post_ct)
 {
        const struct nf_conntrack_zone *zone = &nf_ct_zone_dflt;
@@ -158,13 +161,15 @@ static void ovs_ct_update_key(const struct sk_buff *skb,
                zone = nf_ct_zone(ct);
        } else if (post_ct) {
                state = OVS_CS_F_TRACKED | OVS_CS_F_INVALID;
+               if (info)
+                       zone = &info->zone;
        }
        __ovs_ct_update_key(key, state, zone, ct);
 }
 
 void ovs_ct_fill_key(const struct sk_buff *skb, struct sw_flow_key *key)
 {
-       ovs_ct_update_key(skb, key, false);
+       ovs_ct_update_key(skb, NULL, key, false);
 }
 
 int ovs_ct_put_key(const struct sw_flow_key *key, struct sk_buff *skb)
@@ -418,7 +423,7 @@ static int __ovs_ct_lookup(struct net *net, struct sw_flow_key *key,
                }
        }
 
-       ovs_ct_update_key(skb, key, true);
+       ovs_ct_update_key(skb, info, key, true);
 
        return 0;
 }
@@ -693,6 +698,10 @@ int ovs_ct_copy_action(struct net *net, const struct nlattr *attr,
                OVS_NLERR(log, "Failed to allocate conntrack template");
                return -ENOMEM;
        }
+
+       __set_bit(IPS_CONFIRMED_BIT, &ct_info.ct->status);
+       nf_conntrack_get(&ct_info.ct->ct_general);
+
        if (helper) {
                err = ovs_ct_add_helper(&ct_info, helper, key, log);
                if (err)
@@ -704,11 +713,9 @@ int ovs_ct_copy_action(struct net *net, const struct nlattr *attr,
        if (err)
                goto err_free_ct;
 
-       __set_bit(IPS_CONFIRMED_BIT, &ct_info.ct->status);
-       nf_conntrack_get(&ct_info.ct->ct_general);
        return 0;
 err_free_ct:
-       nf_conntrack_free(ct_info.ct);
+       __ovs_ct_free_action(&ct_info);
        return err;
 }
 
@@ -750,6 +757,11 @@ void ovs_ct_free_action(const struct nlattr *a)
 {
        struct ovs_conntrack_info *ct_info = nla_data(a);
 
+       __ovs_ct_free_action(ct_info);
+}
+
+static void __ovs_ct_free_action(struct ovs_conntrack_info *ct_info)
+{
        if (ct_info->helper)
                module_put(ct_info->helper->me);
        if (ct_info->ct)
index 907d6fd28ede695cc1b876570c101883ed0b4b0e..d1bd4a45ca2d64eca6439335d967aa21feff2b8b 100644 (file)
@@ -2434,7 +2434,10 @@ static int set_action_to_attr(const struct nlattr *a, struct sk_buff *skb)
                if (!start)
                        return -EMSGSIZE;
 
-               err = ovs_nla_put_tunnel_info(skb, tun_info);
+               err =  ip_tun_to_nlattr(skb, &tun_info->key,
+                                       ip_tunnel_info_opts(tun_info),
+                                       tun_info->options_len,
+                                       ip_tunnel_info_af(tun_info));
                if (err)
                        return err;
                nla_nest_end(skb, start);
index b41e9ea2ffff461847465d621a3284480f433cc5..f53bf3b6558b094b6e1b379568620157b4ffae17 100644 (file)
@@ -49,7 +49,6 @@
 struct rfkill {
        spinlock_t              lock;
 
-       const char              *name;
        enum rfkill_type        type;
 
        unsigned long           state;
@@ -73,6 +72,7 @@ struct rfkill {
        struct delayed_work     poll_work;
        struct work_struct      uevent_work;
        struct work_struct      sync_work;
+       char                    name[];
 };
 #define to_rfkill(d)   container_of(d, struct rfkill, dev)
 
@@ -876,14 +876,14 @@ struct rfkill * __must_check rfkill_alloc(const char *name,
        if (WARN_ON(type == RFKILL_TYPE_ALL || type >= NUM_RFKILL_TYPES))
                return NULL;
 
-       rfkill = kzalloc(sizeof(*rfkill), GFP_KERNEL);
+       rfkill = kzalloc(sizeof(*rfkill) + strlen(name) + 1, GFP_KERNEL);
        if (!rfkill)
                return NULL;
 
        spin_lock_init(&rfkill->lock);
        INIT_LIST_HEAD(&rfkill->node);
        rfkill->type = type;
-       rfkill->name = name;
+       strcpy(rfkill->name, name);
        rfkill->ops = ops;
        rfkill->data = ops_data;
 
index 7ec667dd4ce1d01deef3698af8c291da0722a657..b5c2cf2aa6d4bc00e5c4bac2b3326db3d785c8be 100644 (file)
@@ -950,7 +950,7 @@ qdisc_create(struct net_device *dev, struct netdev_queue *dev_queue,
                }
                lockdep_set_class(qdisc_lock(sch), &qdisc_tx_lock);
                if (!netif_is_multiqueue(dev))
-                       sch->flags |= TCQ_F_ONETXQUEUE | TCQ_F_NOPARENT;
+                       sch->flags |= TCQ_F_ONETXQUEUE;
        }
 
        sch->handle = handle;
index e82a1ad80aa521291fba4e704bb3828e88a009db..16bc83b2842a74616cd58dd923a5981942321f3e 100644 (file)
@@ -658,8 +658,10 @@ static void qdisc_rcu_free(struct rcu_head *head)
 {
        struct Qdisc *qdisc = container_of(head, struct Qdisc, rcu_head);
 
-       if (qdisc_is_percpu_stats(qdisc))
+       if (qdisc_is_percpu_stats(qdisc)) {
                free_percpu(qdisc->cpu_bstats);
+               free_percpu(qdisc->cpu_qstats);
+       }
 
        kfree((char *) qdisc - qdisc->padded);
 }
index acb45b8c2a9d6ce902af7a2ffb9cbd53309a1bdc..ec529121f38a03c4b3e2317249cd0694fd619d3f 100644 (file)
@@ -323,14 +323,13 @@ static void sctp_v6_get_dst(struct sctp_transport *t, union sctp_addr *saddr,
                        }
                }
        }
-       rcu_read_unlock();
-
        if (baddr) {
                fl6->saddr = baddr->v6.sin6_addr;
                fl6->fl6_sport = baddr->v6.sin6_port;
                final_p = fl6_update_dst(fl6, rcu_dereference(np->opt), &final);
                dst = ip6_dst_lookup_flow(sk, fl6, final_p);
        }
+       rcu_read_unlock();
 
 out:
        if (!IS_ERR_OR_NULL(dst)) {
@@ -642,6 +641,7 @@ static struct sock *sctp_v6_create_accept_sk(struct sock *sk,
        struct sock *newsk;
        struct ipv6_pinfo *newnp, *np = inet6_sk(sk);
        struct sctp6_sock *newsctp6sk;
+       struct ipv6_txoptions *opt;
 
        newsk = sk_alloc(sock_net(sk), PF_INET6, GFP_KERNEL, sk->sk_prot, 0);
        if (!newsk)
@@ -661,6 +661,13 @@ static struct sock *sctp_v6_create_accept_sk(struct sock *sk,
 
        memcpy(newnp, np, sizeof(struct ipv6_pinfo));
 
+       rcu_read_lock();
+       opt = rcu_dereference(np->opt);
+       if (opt)
+               opt = ipv6_dup_options(newsk, opt);
+       RCU_INIT_POINTER(newnp->opt, opt);
+       rcu_read_unlock();
+
        /* Initialize sk's sport, dport, rcv_saddr and daddr for getsockname()
         * and getpeername().
         */
index 7e8f0a117106cabbf043e24e33f56b307cf4fc88..c0380cfb16ae4eb77bdab457e8310c0cb15a1c4a 100644 (file)
@@ -324,6 +324,7 @@ int sctp_outq_tail(struct sctp_outq *q, struct sctp_chunk *chunk)
                                 sctp_cname(SCTP_ST_CHUNK(chunk->chunk_hdr->type)) :
                                 "illegal chunk");
 
+                       sctp_chunk_hold(chunk);
                        sctp_outq_tail_data(q, chunk);
                        if (chunk->chunk_hdr->flags & SCTP_DATA_UNORDERED)
                                SCTP_INC_STATS(net, SCTP_MIB_OUTUNORDERCHUNKS);
@@ -1251,6 +1252,7 @@ int sctp_outq_sack(struct sctp_outq *q, struct sctp_chunk *chunk)
         */
 
        sack_a_rwnd = ntohl(sack->a_rwnd);
+       asoc->peer.zero_window_announced = !sack_a_rwnd;
        outstanding = q->outstanding_bytes;
 
        if (outstanding < sack_a_rwnd)
index 763e06a55155b2a9e0a9d918ecc1fe2dd6d9e0c0..5d6a03fad3789a12290f5f14c5a7efa69c98f41a 100644 (file)
@@ -1652,7 +1652,7 @@ static sctp_cookie_param_t *sctp_pack_cookie(const struct sctp_endpoint *ep,
 
        /* Set an expiration time for the cookie.  */
        cookie->c.expiration = ktime_add(asoc->cookie_life,
-                                        ktime_get());
+                                        ktime_get_real());
 
        /* Copy the peer's init packet.  */
        memcpy(&cookie->c.peer_init[0], init_chunk->chunk_hdr,
@@ -1780,7 +1780,7 @@ no_hmac:
        if (sock_flag(ep->base.sk, SOCK_TIMESTAMP))
                kt = skb_get_ktime(skb);
        else
-               kt = ktime_get();
+               kt = ktime_get_real();
 
        if (!asoc && ktime_before(bear_cookie->expiration, kt)) {
                /*
index 6f46aa16cb76963de27cb87e5e8cedf617a259a9..22c2bf367d7e8c7025065f33eabfd7e93a7f4021 100644 (file)
@@ -4829,7 +4829,8 @@ sctp_disposition_t sctp_sf_do_9_1_prm_abort(
 
        retval = SCTP_DISPOSITION_CONSUME;
 
-       sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(abort));
+       if (abort)
+               sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(abort));
 
        /* Even if we can't send the ABORT due to low memory delete the
         * TCB.  This is a departure from our typical NOMEM handling.
@@ -4966,7 +4967,8 @@ sctp_disposition_t sctp_sf_cookie_wait_prm_abort(
                        SCTP_TO(SCTP_EVENT_TIMEOUT_T1_INIT));
        retval = SCTP_DISPOSITION_CONSUME;
 
-       sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(abort));
+       if (abort)
+               sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(abort));
 
        sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
                        SCTP_STATE(SCTP_STATE_CLOSED));
@@ -5412,7 +5414,8 @@ sctp_disposition_t sctp_sf_do_6_3_3_rtx(struct net *net,
        SCTP_INC_STATS(net, SCTP_MIB_T3_RTX_EXPIREDS);
 
        if (asoc->overall_error_count >= asoc->max_retrans) {
-               if (asoc->state == SCTP_STATE_SHUTDOWN_PENDING) {
+               if (asoc->peer.zero_window_announced &&
+                   asoc->state == SCTP_STATE_SHUTDOWN_PENDING) {
                        /*
                         * We are here likely because the receiver had its rwnd
                         * closed for a while and we have not been able to
index 03c8256063ec6355fcce034366aa5d005d75b5f7..ef1d90fdc773d2ca4104c9dabc96d1058e99629a 100644 (file)
@@ -1301,8 +1301,9 @@ static int __sctp_setsockopt_connectx(struct sock *sk,
                                      int addrs_size,
                                      sctp_assoc_t *assoc_id)
 {
-       int err = 0;
        struct sockaddr *kaddrs;
+       gfp_t gfp = GFP_KERNEL;
+       int err = 0;
 
        pr_debug("%s: sk:%p addrs:%p addrs_size:%d\n",
                 __func__, sk, addrs, addrs_size);
@@ -1315,7 +1316,9 @@ static int __sctp_setsockopt_connectx(struct sock *sk,
                return -EFAULT;
 
        /* Alloc space for the address array in kernel memory.  */
-       kaddrs = kmalloc(addrs_size, GFP_KERNEL);
+       if (sk->sk_socket->file)
+               gfp = GFP_USER | __GFP_NOWARN;
+       kaddrs = kmalloc(addrs_size, gfp);
        if (unlikely(!kaddrs))
                return -ENOMEM;
 
@@ -1513,8 +1516,7 @@ static void sctp_close(struct sock *sk, long timeout)
                        struct sctp_chunk *chunk;
 
                        chunk = sctp_make_abort_user(asoc, NULL, 0);
-                       if (chunk)
-                               sctp_primitive_ABORT(net, asoc, chunk);
+                       sctp_primitive_ABORT(net, asoc, chunk);
                } else
                        sctp_primitive_SHUTDOWN(net, asoc, NULL);
        }
@@ -1952,8 +1954,6 @@ static int sctp_sendmsg(struct sock *sk, struct msghdr *msg, size_t msg_len)
 
        /* Now send the (possibly) fragmented message. */
        list_for_each_entry(chunk, &datamsg->chunks, frag_list) {
-               sctp_chunk_hold(chunk);
-
                /* Do accounting for the write space.  */
                sctp_set_owner_w(chunk);
 
@@ -1966,15 +1966,13 @@ static int sctp_sendmsg(struct sock *sk, struct msghdr *msg, size_t msg_len)
         * breaks.
         */
        err = sctp_primitive_SEND(net, asoc, datamsg);
+       sctp_datamsg_put(datamsg);
        /* Did the lower layer accept the chunk? */
-       if (err) {
-               sctp_datamsg_free(datamsg);
+       if (err)
                goto out_free;
-       }
 
        pr_debug("%s: we sent primitively\n", __func__);
 
-       sctp_datamsg_put(datamsg);
        err = msg_len;
 
        if (unlikely(wait_connect)) {
@@ -5777,7 +5775,7 @@ static int sctp_getsockopt_assoc_ids(struct sock *sk, int len,
 
        len = sizeof(struct sctp_assoc_ids) + sizeof(sctp_assoc_t) * num;
 
-       ids = kmalloc(len, GFP_KERNEL);
+       ids = kmalloc(len, GFP_USER | __GFP_NOWARN);
        if (unlikely(!ids))
                return -ENOMEM;
 
@@ -7167,6 +7165,7 @@ void sctp_copy_sock(struct sock *newsk, struct sock *sk,
        newsk->sk_type = sk->sk_type;
        newsk->sk_bound_dev_if = sk->sk_bound_dev_if;
        newsk->sk_flags = sk->sk_flags;
+       newsk->sk_tsflags = sk->sk_tsflags;
        newsk->sk_no_check_tx = sk->sk_no_check_tx;
        newsk->sk_no_check_rx = sk->sk_no_check_rx;
        newsk->sk_reuse = sk->sk_reuse;
@@ -7199,6 +7198,11 @@ void sctp_copy_sock(struct sock *newsk, struct sock *sk,
        newinet->mc_ttl = 1;
        newinet->mc_index = 0;
        newinet->mc_list = NULL;
+
+       if (newsk->sk_flags & SK_FLAGS_TIMESTAMP)
+               net_enable_timestamp();
+
+       security_sk_clone(sk, newsk);
 }
 
 static inline void sctp_copy_descendant(struct sock *sk_to,
index 456fadb3d8193a2238bf30881506cd66dbe11957..d730ef9dfbf02aba150d5229a0d2875ddc23aa4d 100644 (file)
@@ -257,6 +257,7 @@ static struct inode *sock_alloc_inode(struct super_block *sb)
        }
        init_waitqueue_head(&wq->wait);
        wq->fasync_list = NULL;
+       wq->flags = 0;
        RCU_INIT_POINTER(ei->socket.wq, wq);
 
        ei->socket.state = SS_UNCONNECTED;
@@ -1695,6 +1696,7 @@ SYSCALL_DEFINE6(recvfrom, int, fd, void __user *, ubuf, size_t, size,
        msg.msg_name = addr ? (struct sockaddr *)&address : NULL;
        /* We assume all kernel code knows the size of sockaddr_storage */
        msg.msg_namelen = 0;
+       msg.msg_iocb = NULL;
        if (sock->file->f_flags & O_NONBLOCK)
                flags |= MSG_DONTWAIT;
        err = sock_recvmsg(sock, &msg, iov_iter_count(&msg.msg_iter), flags);
index 95f82d8d488871e5cc8337acc9073e2aa569b4e6..229956bf84577f81d380536b76d1e57d16de53ae 100644 (file)
@@ -353,20 +353,12 @@ void xprt_complete_bc_request(struct rpc_rqst *req, uint32_t copied)
 {
        struct rpc_xprt *xprt = req->rq_xprt;
        struct svc_serv *bc_serv = xprt->bc_serv;
-       struct xdr_buf *rq_rcv_buf = &req->rq_rcv_buf;
 
        spin_lock(&xprt->bc_pa_lock);
        list_del(&req->rq_bc_pa_list);
        xprt_dec_alloc_count(xprt, 1);
        spin_unlock(&xprt->bc_pa_lock);
 
-       if (copied <= rq_rcv_buf->head[0].iov_len) {
-               rq_rcv_buf->head[0].iov_len = copied;
-               rq_rcv_buf->page_len = 0;
-       } else {
-               rq_rcv_buf->page_len = copied - rq_rcv_buf->head[0].iov_len;
-       }
-
        req->rq_private_buf.len = copied;
        set_bit(RPC_BC_PA_IN_USE, &req->rq_bc_pa_state);
 
index f14f24ee998344f5c356ef49e3b3fc52d581a39c..73ad57a59989cb9234d06c1d399e02408e50c7d3 100644 (file)
@@ -250,11 +250,11 @@ void rpc_destroy_wait_queue(struct rpc_wait_queue *queue)
 }
 EXPORT_SYMBOL_GPL(rpc_destroy_wait_queue);
 
-static int rpc_wait_bit_killable(struct wait_bit_key *key)
+static int rpc_wait_bit_killable(struct wait_bit_key *key, int mode)
 {
-       if (fatal_signal_pending(current))
-               return -ERESTARTSYS;
        freezable_schedule_unsafe();
+       if (signal_pending_state(mode, current))
+               return -ERESTARTSYS;
        return 0;
 }
 
index 7fccf9675df8c238e4cc1d1f437540e48a3df9d2..cc9852897395c6f6db42653c773788446a9c5d3e 100644 (file)
@@ -1363,7 +1363,19 @@ bc_svc_process(struct svc_serv *serv, struct rpc_rqst *req,
        memcpy(&rqstp->rq_addr, &req->rq_xprt->addr, rqstp->rq_addrlen);
        memcpy(&rqstp->rq_arg, &req->rq_rcv_buf, sizeof(rqstp->rq_arg));
        memcpy(&rqstp->rq_res, &req->rq_snd_buf, sizeof(rqstp->rq_res));
+
+       /* Adjust the argument buffer length */
        rqstp->rq_arg.len = req->rq_private_buf.len;
+       if (rqstp->rq_arg.len <= rqstp->rq_arg.head[0].iov_len) {
+               rqstp->rq_arg.head[0].iov_len = rqstp->rq_arg.len;
+               rqstp->rq_arg.page_len = 0;
+       } else if (rqstp->rq_arg.len <= rqstp->rq_arg.head[0].iov_len +
+                       rqstp->rq_arg.page_len)
+               rqstp->rq_arg.page_len = rqstp->rq_arg.len -
+                       rqstp->rq_arg.head[0].iov_len;
+       else
+               rqstp->rq_arg.len = rqstp->rq_arg.head[0].iov_len +
+                       rqstp->rq_arg.page_len;
 
        /* reset result send buffer "put" position */
        resv->iov_len = 0;
index 45aebd966978bdc6abb886487d029957036bdda4..ef05cd9403d4bb2c2ad0a3faddc71de611d892df 100644 (file)
@@ -953,32 +953,20 @@ fail:
        return NULL;
 }
 
-static int unix_mknod(const char *sun_path, umode_t mode, struct path *res)
+static int unix_mknod(struct dentry *dentry, struct path *path, umode_t mode,
+                     struct path *res)
 {
-       struct dentry *dentry;
-       struct path path;
-       int err = 0;
-       /*
-        * Get the parent directory, calculate the hash for last
-        * component.
-        */
-       dentry = kern_path_create(AT_FDCWD, sun_path, &path, 0);
-       err = PTR_ERR(dentry);
-       if (IS_ERR(dentry))
-               return err;
+       int err;
 
-       /*
-        * All right, let's create it.
-        */
-       err = security_path_mknod(&path, dentry, mode, 0);
+       err = security_path_mknod(path, dentry, mode, 0);
        if (!err) {
-               err = vfs_mknod(d_inode(path.dentry), dentry, mode, 0);
+               err = vfs_mknod(d_inode(path->dentry), dentry, mode, 0);
                if (!err) {
-                       res->mnt = mntget(path.mnt);
+                       res->mnt = mntget(path->mnt);
                        res->dentry = dget(dentry);
                }
        }
-       done_path_create(&path, dentry);
+
        return err;
 }
 
@@ -989,10 +977,12 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
        struct unix_sock *u = unix_sk(sk);
        struct sockaddr_un *sunaddr = (struct sockaddr_un *)uaddr;
        char *sun_path = sunaddr->sun_path;
-       int err;
+       int err, name_err;
        unsigned int hash;
        struct unix_address *addr;
        struct hlist_head *list;
+       struct path path;
+       struct dentry *dentry;
 
        err = -EINVAL;
        if (sunaddr->sun_family != AF_UNIX)
@@ -1008,14 +998,34 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
                goto out;
        addr_len = err;
 
+       name_err = 0;
+       dentry = NULL;
+       if (sun_path[0]) {
+               /* Get the parent directory, calculate the hash for last
+                * component.
+                */
+               dentry = kern_path_create(AT_FDCWD, sun_path, &path, 0);
+
+               if (IS_ERR(dentry)) {
+                       /* delay report until after 'already bound' check */
+                       name_err = PTR_ERR(dentry);
+                       dentry = NULL;
+               }
+       }
+
        err = mutex_lock_interruptible(&u->readlock);
        if (err)
-               goto out;
+               goto out_path;
 
        err = -EINVAL;
        if (u->addr)
                goto out_up;
 
+       if (name_err) {
+               err = name_err == -EEXIST ? -EADDRINUSE : name_err;
+               goto out_up;
+       }
+
        err = -ENOMEM;
        addr = kmalloc(sizeof(*addr)+addr_len, GFP_KERNEL);
        if (!addr)
@@ -1026,11 +1036,11 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
        addr->hash = hash ^ sk->sk_type;
        atomic_set(&addr->refcnt, 1);
 
-       if (sun_path[0]) {
-               struct path path;
+       if (dentry) {
+               struct path u_path;
                umode_t mode = S_IFSOCK |
                       (SOCK_INODE(sock)->i_mode & ~current_umask());
-               err = unix_mknod(sun_path, mode, &path);
+               err = unix_mknod(dentry, &path, mode, &u_path);
                if (err) {
                        if (err == -EEXIST)
                                err = -EADDRINUSE;
@@ -1038,9 +1048,9 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
                        goto out_up;
                }
                addr->hash = UNIX_HASH_SIZE;
-               hash = d_backing_inode(path.dentry)->i_ino & (UNIX_HASH_SIZE-1);
+               hash = d_backing_inode(dentry)->i_ino & (UNIX_HASH_SIZE - 1);
                spin_lock(&unix_table_lock);
-               u->path = path;
+               u->path = u_path;
                list = &unix_socket_table[hash];
        } else {
                spin_lock(&unix_table_lock);
@@ -1063,6 +1073,10 @@ out_unlock:
        spin_unlock(&unix_table_lock);
 out_up:
        mutex_unlock(&u->readlock);
+out_path:
+       if (dentry)
+               done_path_create(&path, dentry);
+
 out:
        return err;
 }
@@ -2256,14 +2270,7 @@ static int unix_stream_read_generic(struct unix_stream_read_state *state)
        /* Lock the socket to prevent queue disordering
         * while sleeps in memcpy_tomsg
         */
-       err = mutex_lock_interruptible(&u->readlock);
-       if (unlikely(err)) {
-               /* recvmsg() in non blocking mode is supposed to return -EAGAIN
-                * sk_rcvtimeo is not honored by mutex_lock_interruptible()
-                */
-               err = noblock ? -EAGAIN : -ERESTARTSYS;
-               goto out;
-       }
+       mutex_lock(&u->readlock);
 
        if (flags & MSG_PEEK)
                skip = sk_peek_offset(sk, flags);
@@ -2307,12 +2314,12 @@ again:
                        timeo = unix_stream_data_wait(sk, timeo, last,
                                                      last_len);
 
-                       if (signal_pending(current) ||
-                           mutex_lock_interruptible(&u->readlock)) {
+                       if (signal_pending(current)) {
                                err = sock_intr_errno(timeo);
                                goto out;
                        }
 
+                       mutex_lock(&u->readlock);
                        continue;
 unlock:
                        unix_state_unlock(sk);
index c71e274c810ac6610df652ec029838000ee7c69d..75b0d23ee882293a07fb9e236757931780def482 100644 (file)
@@ -7941,8 +7941,10 @@ static int nl80211_connect(struct sk_buff *skb, struct genl_info *info)
        if (nla_get_flag(info->attrs[NL80211_ATTR_USE_RRM])) {
                if (!(rdev->wiphy.features &
                      NL80211_FEATURE_DS_PARAM_SET_IE_IN_PROBES) ||
-                   !(rdev->wiphy.features & NL80211_FEATURE_QUIET))
+                   !(rdev->wiphy.features & NL80211_FEATURE_QUIET)) {
+                       kzfree(connkeys);
                        return -EINVAL;
+               }
                connect.flags |= ASSOC_REQ_USE_RRM;
        }
 
@@ -9503,6 +9505,7 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info)
        if (new_triggers.tcp && new_triggers.tcp->sock)
                sock_release(new_triggers.tcp->sock);
        kfree(new_triggers.tcp);
+       kfree(new_triggers.nd_config);
        return err;
 }
 #endif
index 2e8d6f39ed564ac7111be036a1f735da1d87d68b..06d050da0d94720cb40d3ad28425b06da22b3e89 100644 (file)
@@ -3029,6 +3029,7 @@ int set_regdom(const struct ieee80211_regdomain *rd,
                break;
        default:
                WARN(1, "invalid initiator %d\n", lr->initiator);
+               kfree(rd);
                return -EINVAL;
        }
 
@@ -3221,8 +3222,10 @@ int __init regulatory_init(void)
        /* We always try to get an update for the static regdomain */
        err = regulatory_hint_core(cfg80211_world_regdom->alpha2);
        if (err) {
-               if (err == -ENOMEM)
+               if (err == -ENOMEM) {
+                       platform_device_unregister(reg_pdev);
                        return err;
+               }
                /*
                 * N.B. kobject_uevent_env() can fail mainly for when we're out
                 * memory which is handled and propagated appropriately above
index 09bfcbac63bb3f75d909aecd840b63d36b169eec..b5e665b3cfb05f4d08970387802fee8aec8243dd 100644 (file)
@@ -303,6 +303,14 @@ struct xfrm_policy *xfrm_policy_alloc(struct net *net, gfp_t gfp)
 }
 EXPORT_SYMBOL(xfrm_policy_alloc);
 
+static void xfrm_policy_destroy_rcu(struct rcu_head *head)
+{
+       struct xfrm_policy *policy = container_of(head, struct xfrm_policy, rcu);
+
+       security_xfrm_policy_free(policy->security);
+       kfree(policy);
+}
+
 /* Destroy xfrm_policy: descendant resources must be released to this moment. */
 
 void xfrm_policy_destroy(struct xfrm_policy *policy)
@@ -312,8 +320,7 @@ void xfrm_policy_destroy(struct xfrm_policy *policy)
        if (del_timer(&policy->timer) || del_timer(&policy->polq.hold_timer))
                BUG();
 
-       security_xfrm_policy_free(policy->security);
-       kfree(policy);
+       call_rcu(&policy->rcu, xfrm_policy_destroy_rcu);
 }
 EXPORT_SYMBOL(xfrm_policy_destroy);
 
@@ -1214,8 +1221,10 @@ static struct xfrm_policy *xfrm_sk_policy_lookup(const struct sock *sk, int dir,
        struct xfrm_policy *pol;
        struct net *net = sock_net(sk);
 
+       rcu_read_lock();
        read_lock_bh(&net->xfrm.xfrm_policy_lock);
-       if ((pol = sk->sk_policy[dir]) != NULL) {
+       pol = rcu_dereference(sk->sk_policy[dir]);
+       if (pol != NULL) {
                bool match = xfrm_selector_match(&pol->selector, fl,
                                                 sk->sk_family);
                int err = 0;
@@ -1239,6 +1248,7 @@ static struct xfrm_policy *xfrm_sk_policy_lookup(const struct sock *sk, int dir,
        }
 out:
        read_unlock_bh(&net->xfrm.xfrm_policy_lock);
+       rcu_read_unlock();
        return pol;
 }
 
@@ -1307,13 +1317,14 @@ int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol)
 #endif
 
        write_lock_bh(&net->xfrm.xfrm_policy_lock);
-       old_pol = sk->sk_policy[dir];
-       sk->sk_policy[dir] = pol;
+       old_pol = rcu_dereference_protected(sk->sk_policy[dir],
+                               lockdep_is_held(&net->xfrm.xfrm_policy_lock));
        if (pol) {
                pol->curlft.add_time = get_seconds();
                pol->index = xfrm_gen_index(net, XFRM_POLICY_MAX+dir, 0);
                xfrm_sk_policy_link(pol, dir);
        }
+       rcu_assign_pointer(sk->sk_policy[dir], pol);
        if (old_pol) {
                if (pol)
                        xfrm_policy_requeue(old_pol, pol);
@@ -1361,17 +1372,26 @@ static struct xfrm_policy *clone_policy(const struct xfrm_policy *old, int dir)
        return newp;
 }
 
-int __xfrm_sk_clone_policy(struct sock *sk)
+int __xfrm_sk_clone_policy(struct sock *sk, const struct sock *osk)
 {
-       struct xfrm_policy *p0 = sk->sk_policy[0],
-                          *p1 = sk->sk_policy[1];
+       const struct xfrm_policy *p;
+       struct xfrm_policy *np;
+       int i, ret = 0;
 
-       sk->sk_policy[0] = sk->sk_policy[1] = NULL;
-       if (p0 && (sk->sk_policy[0] = clone_policy(p0, 0)) == NULL)
-               return -ENOMEM;
-       if (p1 && (sk->sk_policy[1] = clone_policy(p1, 1)) == NULL)
-               return -ENOMEM;
-       return 0;
+       rcu_read_lock();
+       for (i = 0; i < 2; i++) {
+               p = rcu_dereference(osk->sk_policy[i]);
+               if (p) {
+                       np = clone_policy(p, i);
+                       if (unlikely(!np)) {
+                               ret = -ENOMEM;
+                               break;
+                       }
+                       rcu_assign_pointer(sk->sk_policy[i], np);
+               }
+       }
+       rcu_read_unlock();
+       return ret;
 }
 
 static int
@@ -2198,6 +2218,7 @@ struct dst_entry *xfrm_lookup(struct net *net, struct dst_entry *dst_orig,
        xdst = NULL;
        route = NULL;
 
+       sk = sk_const_to_full_sk(sk);
        if (sk && sk->sk_policy[XFRM_POLICY_OUT]) {
                num_pols = 1;
                pols[0] = xfrm_sk_policy_lookup(sk, XFRM_POLICY_OUT, fl);
@@ -2477,6 +2498,7 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb,
        }
 
        pol = NULL;
+       sk = sk_to_full_sk(sk);
        if (sk && sk->sk_policy[dir]) {
                pol = xfrm_sk_policy_lookup(sk, dir, &fl);
                if (IS_ERR(pol)) {
@@ -2804,7 +2826,6 @@ static struct neighbour *xfrm_neigh_lookup(const struct dst_entry *dst,
 
 int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo)
 {
-       struct net *net;
        int err = 0;
        if (unlikely(afinfo == NULL))
                return -EINVAL;
@@ -2835,26 +2856,6 @@ int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo)
        }
        spin_unlock(&xfrm_policy_afinfo_lock);
 
-       rtnl_lock();
-       for_each_net(net) {
-               struct dst_ops *xfrm_dst_ops;
-
-               switch (afinfo->family) {
-               case AF_INET:
-                       xfrm_dst_ops = &net->xfrm.xfrm4_dst_ops;
-                       break;
-#if IS_ENABLED(CONFIG_IPV6)
-               case AF_INET6:
-                       xfrm_dst_ops = &net->xfrm.xfrm6_dst_ops;
-                       break;
-#endif
-               default:
-                       BUG();
-               }
-               *xfrm_dst_ops = *afinfo->dst_ops;
-       }
-       rtnl_unlock();
-
        return err;
 }
 EXPORT_SYMBOL(xfrm_policy_register_afinfo);
@@ -2890,22 +2891,6 @@ int xfrm_policy_unregister_afinfo(struct xfrm_policy_afinfo *afinfo)
 }
 EXPORT_SYMBOL(xfrm_policy_unregister_afinfo);
 
-static void __net_init xfrm_dst_ops_init(struct net *net)
-{
-       struct xfrm_policy_afinfo *afinfo;
-
-       rcu_read_lock();
-       afinfo = rcu_dereference(xfrm_policy_afinfo[AF_INET]);
-       if (afinfo)
-               net->xfrm.xfrm4_dst_ops = *afinfo->dst_ops;
-#if IS_ENABLED(CONFIG_IPV6)
-       afinfo = rcu_dereference(xfrm_policy_afinfo[AF_INET6]);
-       if (afinfo)
-               net->xfrm.xfrm6_dst_ops = *afinfo->dst_ops;
-#endif
-       rcu_read_unlock();
-}
-
 static int xfrm_dev_event(struct notifier_block *this, unsigned long event, void *ptr)
 {
        struct net_device *dev = netdev_notifier_info_to_dev(ptr);
@@ -3054,7 +3039,6 @@ static int __net_init xfrm_net_init(struct net *net)
        rv = xfrm_policy_init(net);
        if (rv < 0)
                goto out_policy;
-       xfrm_dst_ops_init(net);
        rv = xfrm_sysctl_init(net);
        if (rv < 0)
                goto out_sysctl;
index 698768bdc5815021b61814ddabc408d4310c3c0e..e167592793a70e8a1bac057d58ca7456e064db8e 100644 (file)
 
 static int fd_map;     /* File descriptor for file being modified. */
 static int mmap_failed; /* Boolean flag. */
-static void *ehdr_curr; /* current ElfXX_Ehdr *  for resource cleanup */
 static char gpfx;      /* prefix for global symbol name (sometimes '_') */
 static struct stat sb; /* Remember .st_size, etc. */
 static jmp_buf jmpenv; /* setjmp/longjmp per-file error escape */
 static const char *altmcount;  /* alternate mcount symbol name */
 static int warn_on_notrace_sect; /* warn when section has mcount not being recorded */
+static void *file_map; /* pointer of the mapped file */
+static void *file_end; /* pointer to the end of the mapped file */
+static int file_updated; /* flag to state file was changed */
+static void *file_ptr; /* current file pointer location */
+static void *file_append; /* added to the end of the file */
+static size_t file_append_size; /* how much is added to end of file */
 
 /* setjmp() return values */
 enum {
@@ -67,10 +72,14 @@ static void
 cleanup(void)
 {
        if (!mmap_failed)
-               munmap(ehdr_curr, sb.st_size);
+               munmap(file_map, sb.st_size);
        else
-               free(ehdr_curr);
-       close(fd_map);
+               free(file_map);
+       file_map = NULL;
+       free(file_append);
+       file_append = NULL;
+       file_append_size = 0;
+       file_updated = 0;
 }
 
 static void __attribute__((noreturn))
@@ -92,12 +101,22 @@ succeed_file(void)
 static off_t
 ulseek(int const fd, off_t const offset, int const whence)
 {
-       off_t const w = lseek(fd, offset, whence);
-       if (w == (off_t)-1) {
-               perror("lseek");
+       switch (whence) {
+       case SEEK_SET:
+               file_ptr = file_map + offset;
+               break;
+       case SEEK_CUR:
+               file_ptr += offset;
+               break;
+       case SEEK_END:
+               file_ptr = file_map + (sb.st_size - offset);
+               break;
+       }
+       if (file_ptr < file_map) {
+               fprintf(stderr, "lseek: seek before file\n");
                fail_file();
        }
-       return w;
+       return file_ptr - file_map;
 }
 
 static size_t
@@ -114,12 +133,38 @@ uread(int const fd, void *const buf, size_t const count)
 static size_t
 uwrite(int const fd, void const *const buf, size_t const count)
 {
-       size_t const n = write(fd, buf, count);
-       if (n != count) {
-               perror("write");
-               fail_file();
+       size_t cnt = count;
+       off_t idx = 0;
+
+       file_updated = 1;
+
+       if (file_ptr + count >= file_end) {
+               off_t aoffset = (file_ptr + count) - file_end;
+
+               if (aoffset > file_append_size) {
+                       file_append = realloc(file_append, aoffset);
+                       file_append_size = aoffset;
+               }
+               if (!file_append) {
+                       perror("write");
+                       fail_file();
+               }
+               if (file_ptr < file_end) {
+                       cnt = file_end - file_ptr;
+               } else {
+                       cnt = 0;
+                       idx = aoffset - count;
+               }
        }
-       return n;
+
+       if (cnt)
+               memcpy(file_ptr, buf, cnt);
+
+       if (cnt < count)
+               memcpy(file_append + idx, buf + cnt, count - cnt);
+
+       file_ptr += count;
+       return count;
 }
 
 static void *
@@ -192,9 +237,7 @@ static int make_nop_arm64(void *map, size_t const offset)
  */
 static void *mmap_file(char const *fname)
 {
-       void *addr;
-
-       fd_map = open(fname, O_RDWR);
+       fd_map = open(fname, O_RDONLY);
        if (fd_map < 0 || fstat(fd_map, &sb) < 0) {
                perror(fname);
                fail_file();
@@ -203,15 +246,58 @@ static void *mmap_file(char const *fname)
                fprintf(stderr, "not a regular file: %s\n", fname);
                fail_file();
        }
-       addr = mmap(0, sb.st_size, PROT_READ|PROT_WRITE, MAP_PRIVATE,
-                   fd_map, 0);
+       file_map = mmap(0, sb.st_size, PROT_READ|PROT_WRITE, MAP_PRIVATE,
+                       fd_map, 0);
        mmap_failed = 0;
-       if (addr == MAP_FAILED) {
+       if (file_map == MAP_FAILED) {
                mmap_failed = 1;
-               addr = umalloc(sb.st_size);
-               uread(fd_map, addr, sb.st_size);
+               file_map = umalloc(sb.st_size);
+               uread(fd_map, file_map, sb.st_size);
+       }
+       close(fd_map);
+
+       file_end = file_map + sb.st_size;
+
+       return file_map;
+}
+
+static void write_file(const char *fname)
+{
+       char tmp_file[strlen(fname) + 4];
+       size_t n;
+
+       if (!file_updated)
+               return;
+
+       sprintf(tmp_file, "%s.rc", fname);
+
+       /*
+        * After reading the entire file into memory, delete it
+        * and write it back, to prevent weird side effects of modifying
+        * an object file in place.
+        */
+       fd_map = open(tmp_file, O_WRONLY | O_TRUNC | O_CREAT, sb.st_mode);
+       if (fd_map < 0) {
+               perror(fname);
+               fail_file();
+       }
+       n = write(fd_map, file_map, sb.st_size);
+       if (n != sb.st_size) {
+               perror("write");
+               fail_file();
+       }
+       if (file_append_size) {
+               n = write(fd_map, file_append, file_append_size);
+               if (n != file_append_size) {
+                       perror("write");
+                       fail_file();
+               }
+       }
+       close(fd_map);
+       if (rename(tmp_file, fname) < 0) {
+               perror(fname);
+               fail_file();
        }
-       return addr;
 }
 
 /* w8rev, w8nat, ...: Handle endianness. */
@@ -318,7 +404,6 @@ do_file(char const *const fname)
        Elf32_Ehdr *const ehdr = mmap_file(fname);
        unsigned int reltype = 0;
 
-       ehdr_curr = ehdr;
        w = w4nat;
        w2 = w2nat;
        w8 = w8nat;
@@ -441,6 +526,7 @@ do_file(char const *const fname)
        }
        }  /* end switch */
 
+       write_file(fname);
        cleanup();
 }
 
@@ -493,11 +579,14 @@ main(int argc, char *argv[])
                case SJ_SETJMP:    /* normal sequence */
                        /* Avoid problems if early cleanup() */
                        fd_map = -1;
-                       ehdr_curr = NULL;
                        mmap_failed = 1;
+                       file_map = NULL;
+                       file_ptr = NULL;
+                       file_updated = 0;
                        do_file(file);
                        break;
                case SJ_FAIL:    /* error in do_file or below */
+                       fprintf(stderr, "%s: failed\n", file);
                        ++n_error;
                        break;
                case SJ_SUCCEED:    /* premature success */
index fb111eafcb893e4f5146c74a84f8499d4e1553c4..1c3872aeed14ace421a9d43fc396c43afdd5b93c 100644 (file)
@@ -751,16 +751,16 @@ long keyctl_read_key(key_serial_t keyid, char __user *buffer, size_t buflen)
 
        /* the key is probably readable - now try to read it */
 can_read_key:
-       ret = key_validate(key);
-       if (ret == 0) {
-               ret = -EOPNOTSUPP;
-               if (key->type->read) {
-                       /* read the data with the semaphore held (since we
-                        * might sleep) */
-                       down_read(&key->sem);
+       ret = -EOPNOTSUPP;
+       if (key->type->read) {
+               /* Read the data with the semaphore held (since we might sleep)
+                * to protect against the key being updated or revoked.
+                */
+               down_read(&key->sem);
+               ret = key_validate(key);
+               if (ret == 0)
                        ret = key->type->read(key, buffer, buflen);
-                       up_read(&key->sem);
-               }
+               up_read(&key->sem);
        }
 
 error2:
index 963f82430938a976826074bfe41f33f286e3fbe1..3b36582970702219f0e1b28f16093b4de6425b48 100644 (file)
@@ -355,6 +355,8 @@ enum {
                                        ((pci)->device == 0x0d0c) || \
                                        ((pci)->device == 0x160c))
 
+#define IS_BROXTON(pci)        ((pci)->device == 0x5a98)
+
 static char *driver_short_names[] = {
        [AZX_DRIVER_ICH] = "HDA Intel",
        [AZX_DRIVER_PCH] = "HDA Intel PCH",
@@ -506,15 +508,36 @@ static void azx_init_pci(struct azx *chip)
         }
 }
 
+/*
+ * In BXT-P A0, HD-Audio DMA requests is later than expected,
+ * and makes an audio stream sensitive to system latencies when
+ * 24/32 bits are playing.
+ * Adjusting threshold of DMA fifo to force the DMA request
+ * sooner to improve latency tolerance at the expense of power.
+ */
+static void bxt_reduce_dma_latency(struct azx *chip)
+{
+       u32 val;
+
+       val = azx_readl(chip, SKL_EM4L);
+       val &= (0x3 << 20);
+       azx_writel(chip, SKL_EM4L, val);
+}
+
 static void hda_intel_init_chip(struct azx *chip, bool full_reset)
 {
        struct hdac_bus *bus = azx_bus(chip);
+       struct pci_dev *pci = chip->pci;
 
        if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL)
                snd_hdac_set_codec_wakeup(bus, true);
        azx_init_chip(chip, full_reset);
        if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL)
                snd_hdac_set_codec_wakeup(bus, false);
+
+       /* reduce dma latency to avoid noise */
+       if (IS_BROXTON(pci))
+               bxt_reduce_dma_latency(chip);
 }
 
 /* calculate runtime delay from LPIB */
@@ -931,6 +954,36 @@ static int azx_resume(struct device *dev)
 }
 #endif /* CONFIG_PM_SLEEP || SUPPORT_VGA_SWITCHEROO */
 
+#ifdef CONFIG_PM_SLEEP
+/* put codec down to D3 at hibernation for Intel SKL+;
+ * otherwise BIOS may still access the codec and screw up the driver
+ */
+#define IS_SKL(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0xa170)
+#define IS_SKL_LP(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x9d70)
+#define IS_BXT(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x5a98)
+#define IS_SKL_PLUS(pci) (IS_SKL(pci) || IS_SKL_LP(pci) || IS_BXT(pci))
+
+static int azx_freeze_noirq(struct device *dev)
+{
+       struct pci_dev *pci = to_pci_dev(dev);
+
+       if (IS_SKL_PLUS(pci))
+               pci_set_power_state(pci, PCI_D3hot);
+
+       return 0;
+}
+
+static int azx_thaw_noirq(struct device *dev)
+{
+       struct pci_dev *pci = to_pci_dev(dev);
+
+       if (IS_SKL_PLUS(pci))
+               pci_set_power_state(pci, PCI_D0);
+
+       return 0;
+}
+#endif /* CONFIG_PM_SLEEP */
+
 #ifdef CONFIG_PM
 static int azx_runtime_suspend(struct device *dev)
 {
@@ -1040,6 +1093,10 @@ static int azx_runtime_idle(struct device *dev)
 
 static const struct dev_pm_ops azx_pm = {
        SET_SYSTEM_SLEEP_PM_OPS(azx_suspend, azx_resume)
+#ifdef CONFIG_PM_SLEEP
+       .freeze_noirq = azx_freeze_noirq,
+       .thaw_noirq = azx_thaw_noirq,
+#endif
        SET_RUNTIME_PM_OPS(azx_runtime_suspend, azx_runtime_resume, azx_runtime_idle)
 };
 
index f8a12ca477f1ab775a101c8bb41876a11707477e..4ef2259f88cae3b1cf328880447dbf528ad42a95 100644 (file)
@@ -778,7 +778,8 @@ static const struct hda_pintbl alienware_pincfgs[] = {
 };
 
 static const struct snd_pci_quirk ca0132_quirks[] = {
-       SND_PCI_QUIRK(0x1028, 0x0685, "Alienware 15", QUIRK_ALIENWARE),
+       SND_PCI_QUIRK(0x1028, 0x0685, "Alienware 15 2015", QUIRK_ALIENWARE),
+       SND_PCI_QUIRK(0x1028, 0x0688, "Alienware 17 2015", QUIRK_ALIENWARE),
        {}
 };
 
index 9bedf7c85e295d6dab65c04093abf7a58cab1a5a..3a89d82f805759f5c4016c47df40d1a3b5522f49 100644 (file)
@@ -67,6 +67,10 @@ enum {
        ALC_HEADSET_TYPE_OMTP,
 };
 
+enum {
+       ALC_KEY_MICMUTE_INDEX,
+};
+
 struct alc_customize_define {
        unsigned int  sku_cfg;
        unsigned char port_connectivity;
@@ -111,6 +115,7 @@ struct alc_spec {
        void (*power_hook)(struct hda_codec *codec);
 #endif
        void (*shutup)(struct hda_codec *codec);
+       void (*reboot_notify)(struct hda_codec *codec);
 
        int init_amp;
        int codec_variant;      /* flag for other variants */
@@ -122,6 +127,7 @@ struct alc_spec {
        unsigned int pll_coef_idx, pll_coef_bit;
        unsigned int coef0;
        struct input_dev *kb_dev;
+       u8 alc_mute_keycode_map[1];
 };
 
 /*
@@ -773,6 +779,25 @@ static inline void alc_shutup(struct hda_codec *codec)
                snd_hda_shutup_pins(codec);
 }
 
+static void alc_reboot_notify(struct hda_codec *codec)
+{
+       struct alc_spec *spec = codec->spec;
+
+       if (spec && spec->reboot_notify)
+               spec->reboot_notify(codec);
+       else
+               alc_shutup(codec);
+}
+
+/* power down codec to D3 at reboot/shutdown; set as reboot_notify ops */
+static void alc_d3_at_reboot(struct hda_codec *codec)
+{
+       snd_hda_codec_set_power_to_all(codec, codec->core.afg, AC_PWRST_D3);
+       snd_hda_codec_write(codec, codec->core.afg, 0,
+                           AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
+       msleep(10);
+}
+
 #define alc_free       snd_hda_gen_free
 
 #ifdef CONFIG_PM
@@ -818,7 +843,7 @@ static const struct hda_codec_ops alc_patch_ops = {
        .suspend = alc_suspend,
        .check_power_status = snd_hda_gen_check_power_status,
 #endif
-       .reboot_notify = alc_shutup,
+       .reboot_notify = alc_reboot_notify,
 };
 
 
@@ -1755,6 +1780,7 @@ enum {
        ALC889_FIXUP_MBA11_VREF,
        ALC889_FIXUP_MBA21_VREF,
        ALC889_FIXUP_MP11_VREF,
+       ALC889_FIXUP_MP41_VREF,
        ALC882_FIXUP_INV_DMIC,
        ALC882_FIXUP_NO_PRIMARY_HP,
        ALC887_FIXUP_ASUS_BASS,
@@ -1843,7 +1869,7 @@ static void alc889_fixup_mbp_vref(struct hda_codec *codec,
                                  const struct hda_fixup *fix, int action)
 {
        struct alc_spec *spec = codec->spec;
-       static hda_nid_t nids[2] = { 0x14, 0x15 };
+       static hda_nid_t nids[3] = { 0x14, 0x15, 0x19 };
        int i;
 
        if (action != HDA_FIXUP_ACT_INIT)
@@ -2133,6 +2159,12 @@ static const struct hda_fixup alc882_fixups[] = {
                .chained = true,
                .chain_id = ALC885_FIXUP_MACPRO_GPIO,
        },
+       [ALC889_FIXUP_MP41_VREF] = {
+               .type = HDA_FIXUP_FUNC,
+               .v.func = alc889_fixup_mbp_vref,
+               .chained = true,
+               .chain_id = ALC885_FIXUP_MACPRO_GPIO,
+       },
        [ALC882_FIXUP_INV_DMIC] = {
                .type = HDA_FIXUP_FUNC,
                .v.func = alc_fixup_inv_dmic,
@@ -2215,7 +2247,7 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = {
        SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC889_FIXUP_IMAC91_VREF),
        SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC889_FIXUP_IMAC91_VREF),
        SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC889_FIXUP_IMAC91_VREF),
-       SND_PCI_QUIRK(0x106b, 0x4200, "Mac Pro 5,1", ALC885_FIXUP_MACPRO_GPIO),
+       SND_PCI_QUIRK(0x106b, 0x4200, "Mac Pro 4,1/5,1", ALC889_FIXUP_MP41_VREF),
        SND_PCI_QUIRK(0x106b, 0x4300, "iMac 9,1", ALC889_FIXUP_IMAC91_VREF),
        SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC889_FIXUP_IMAC91_VREF),
        SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC889_FIXUP_IMAC91_VREF),
@@ -3435,12 +3467,43 @@ static void gpio2_mic_hotkey_event(struct hda_codec *codec,
 
        /* GPIO2 just toggles on a keypress/keyrelease cycle. Therefore
           send both key on and key off event for every interrupt. */
-       input_report_key(spec->kb_dev, KEY_MICMUTE, 1);
+       input_report_key(spec->kb_dev, spec->alc_mute_keycode_map[ALC_KEY_MICMUTE_INDEX], 1);
        input_sync(spec->kb_dev);
-       input_report_key(spec->kb_dev, KEY_MICMUTE, 0);
+       input_report_key(spec->kb_dev, spec->alc_mute_keycode_map[ALC_KEY_MICMUTE_INDEX], 0);
        input_sync(spec->kb_dev);
 }
 
+static int alc_register_micmute_input_device(struct hda_codec *codec)
+{
+       struct alc_spec *spec = codec->spec;
+       int i;
+
+       spec->kb_dev = input_allocate_device();
+       if (!spec->kb_dev) {
+               codec_err(codec, "Out of memory (input_allocate_device)\n");
+               return -ENOMEM;
+       }
+
+       spec->alc_mute_keycode_map[ALC_KEY_MICMUTE_INDEX] = KEY_MICMUTE;
+
+       spec->kb_dev->name = "Microphone Mute Button";
+       spec->kb_dev->evbit[0] = BIT_MASK(EV_KEY);
+       spec->kb_dev->keycodesize = sizeof(spec->alc_mute_keycode_map[0]);
+       spec->kb_dev->keycodemax = ARRAY_SIZE(spec->alc_mute_keycode_map);
+       spec->kb_dev->keycode = spec->alc_mute_keycode_map;
+       for (i = 0; i < ARRAY_SIZE(spec->alc_mute_keycode_map); i++)
+               set_bit(spec->alc_mute_keycode_map[i], spec->kb_dev->keybit);
+
+       if (input_register_device(spec->kb_dev)) {
+               codec_err(codec, "input_register_device failed\n");
+               input_free_device(spec->kb_dev);
+               spec->kb_dev = NULL;
+               return -ENOMEM;
+       }
+
+       return 0;
+}
+
 static void alc280_fixup_hp_gpio2_mic_hotkey(struct hda_codec *codec,
                                             const struct hda_fixup *fix, int action)
 {
@@ -3458,20 +3521,8 @@ static void alc280_fixup_hp_gpio2_mic_hotkey(struct hda_codec *codec,
        struct alc_spec *spec = codec->spec;
 
        if (action == HDA_FIXUP_ACT_PRE_PROBE) {
-               spec->kb_dev = input_allocate_device();
-               if (!spec->kb_dev) {
-                       codec_err(codec, "Out of memory (input_allocate_device)\n");
-                       return;
-               }
-               spec->kb_dev->name = "Microphone Mute Button";
-               spec->kb_dev->evbit[0] = BIT_MASK(EV_KEY);
-               spec->kb_dev->keybit[BIT_WORD(KEY_MICMUTE)] = BIT_MASK(KEY_MICMUTE);
-               if (input_register_device(spec->kb_dev)) {
-                       codec_err(codec, "input_register_device failed\n");
-                       input_free_device(spec->kb_dev);
-                       spec->kb_dev = NULL;
+               if (alc_register_micmute_input_device(codec) != 0)
                        return;
-               }
 
                snd_hda_add_verbs(codec, gpio_init);
                snd_hda_codec_write_cache(codec, codec->core.afg, 0,
@@ -3501,6 +3552,47 @@ static void alc280_fixup_hp_gpio2_mic_hotkey(struct hda_codec *codec,
        }
 }
 
+static void alc233_fixup_lenovo_line2_mic_hotkey(struct hda_codec *codec,
+                                            const struct hda_fixup *fix, int action)
+{
+       /* Line2 = mic mute hotkey
+          GPIO2 = mic mute LED */
+       static const struct hda_verb gpio_init[] = {
+               { 0x01, AC_VERB_SET_GPIO_MASK, 0x04 },
+               { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04 },
+               {}
+       };
+
+       struct alc_spec *spec = codec->spec;
+
+       if (action == HDA_FIXUP_ACT_PRE_PROBE) {
+               if (alc_register_micmute_input_device(codec) != 0)
+                       return;
+
+               snd_hda_add_verbs(codec, gpio_init);
+               snd_hda_jack_detect_enable_callback(codec, 0x1b,
+                                                   gpio2_mic_hotkey_event);
+
+               spec->gen.cap_sync_hook = alc_fixup_gpio_mic_mute_hook;
+               spec->gpio_led = 0;
+               spec->mute_led_polarity = 0;
+               spec->gpio_mic_led_mask = 0x04;
+               return;
+       }
+
+       if (!spec->kb_dev)
+               return;
+
+       switch (action) {
+       case HDA_FIXUP_ACT_PROBE:
+               spec->init_amp = ALC_INIT_DEFAULT;
+               break;
+       case HDA_FIXUP_ACT_FREE:
+               input_unregister_device(spec->kb_dev);
+               spec->kb_dev = NULL;
+       }
+}
+
 static void alc269_fixup_hp_line1_mic1_led(struct hda_codec *codec,
                                const struct hda_fixup *fix, int action)
 {
@@ -4198,6 +4290,8 @@ static void alc_fixup_tpt440_dock(struct hda_codec *codec,
        struct alc_spec *spec = codec->spec;
 
        if (action == HDA_FIXUP_ACT_PRE_PROBE) {
+               spec->shutup = alc_no_shutup; /* reduce click noise */
+               spec->reboot_notify = alc_d3_at_reboot; /* reduce noise */
                spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
                codec->power_save_node = 0; /* avoid click noises */
                snd_hda_apply_pincfgs(codec, pincfgs);
@@ -4578,6 +4672,7 @@ enum {
        ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC,
        ALC293_FIXUP_DELL1_MIC_NO_PRESENCE,
        ALC292_FIXUP_TPT440_DOCK,
+       ALC292_FIXUP_TPT440,
        ALC283_FIXUP_BXBT2807_MIC,
        ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED,
        ALC282_FIXUP_ASPIRE_V5_PINS,
@@ -4593,9 +4688,12 @@ enum {
        ALC288_FIXUP_DISABLE_AAMIX,
        ALC292_FIXUP_DELL_E7X,
        ALC292_FIXUP_DISABLE_AAMIX,
+       ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK,
        ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
        ALC275_FIXUP_DELL_XPS,
        ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE,
+       ALC293_FIXUP_LENOVO_SPK_NOISE,
+       ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY,
 };
 
 static const struct hda_fixup alc269_fixups[] = {
@@ -5050,6 +5148,12 @@ static const struct hda_fixup alc269_fixups[] = {
                .chained = true,
                .chain_id = ALC269_FIXUP_LIMIT_INT_MIC_BOOST
        },
+       [ALC292_FIXUP_TPT440] = {
+               .type = HDA_FIXUP_FUNC,
+               .v.func = alc_fixup_disable_aamix,
+               .chained = true,
+               .chain_id = ALC292_FIXUP_TPT440_DOCK,
+       },
        [ALC283_FIXUP_BXBT2807_MIC] = {
                .type = HDA_FIXUP_PINS,
                .v.pins = (const struct hda_pintbl[]) {
@@ -5149,6 +5253,12 @@ static const struct hda_fixup alc269_fixups[] = {
                .chained = true,
                .chain_id = ALC269_FIXUP_DELL2_MIC_NO_PRESENCE
        },
+       [ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK] = {
+               .type = HDA_FIXUP_FUNC,
+               .v.func = alc_fixup_disable_aamix,
+               .chained = true,
+               .chain_id = ALC293_FIXUP_DELL1_MIC_NO_PRESENCE
+       },
        [ALC292_FIXUP_DELL_E7X] = {
                .type = HDA_FIXUP_FUNC,
                .v.func = alc_fixup_dell_xps13,
@@ -5187,6 +5297,16 @@ static const struct hda_fixup alc269_fixups[] = {
                .chained = true,
                .chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE
        },
+       [ALC293_FIXUP_LENOVO_SPK_NOISE] = {
+               .type = HDA_FIXUP_FUNC,
+               .v.func = alc_fixup_disable_aamix,
+               .chained = true,
+               .chain_id = ALC269_FIXUP_THINKPAD_ACPI
+       },
+       [ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY] = {
+               .type = HDA_FIXUP_FUNC,
+               .v.func = alc233_fixup_lenovo_line2_mic_hotkey,
+       },
 };
 
 static const struct snd_pci_quirk alc269_fixup_tbl[] = {
@@ -5221,11 +5341,11 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x1028, 0x06c7, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1028, 0x06d9, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1028, 0x06da, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
-       SND_PCI_QUIRK(0x1028, 0x06db, "Dell", ALC292_FIXUP_DISABLE_AAMIX),
-       SND_PCI_QUIRK(0x1028, 0x06dd, "Dell", ALC292_FIXUP_DISABLE_AAMIX),
-       SND_PCI_QUIRK(0x1028, 0x06de, "Dell", ALC292_FIXUP_DISABLE_AAMIX),
-       SND_PCI_QUIRK(0x1028, 0x06df, "Dell", ALC292_FIXUP_DISABLE_AAMIX),
-       SND_PCI_QUIRK(0x1028, 0x06e0, "Dell", ALC292_FIXUP_DISABLE_AAMIX),
+       SND_PCI_QUIRK(0x1028, 0x06db, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
+       SND_PCI_QUIRK(0x1028, 0x06dd, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
+       SND_PCI_QUIRK(0x1028, 0x06de, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
+       SND_PCI_QUIRK(0x1028, 0x06df, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
+       SND_PCI_QUIRK(0x1028, 0x06e0, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
        SND_PCI_QUIRK(0x1028, 0x0704, "Dell XPS 13", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE),
        SND_PCI_QUIRK(0x1028, 0x164a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1028, 0x164b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
@@ -5325,15 +5445,18 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x17aa, 0x21fb, "Thinkpad T430s", ALC269_FIXUP_LENOVO_DOCK),
        SND_PCI_QUIRK(0x17aa, 0x2203, "Thinkpad X230 Tablet", ALC269_FIXUP_LENOVO_DOCK),
        SND_PCI_QUIRK(0x17aa, 0x2208, "Thinkpad T431s", ALC269_FIXUP_LENOVO_DOCK),
-       SND_PCI_QUIRK(0x17aa, 0x220c, "Thinkpad T440s", ALC292_FIXUP_TPT440_DOCK),
+       SND_PCI_QUIRK(0x17aa, 0x220c, "Thinkpad T440s", ALC292_FIXUP_TPT440),
        SND_PCI_QUIRK(0x17aa, 0x220e, "Thinkpad T440p", ALC292_FIXUP_TPT440_DOCK),
        SND_PCI_QUIRK(0x17aa, 0x2210, "Thinkpad T540p", ALC292_FIXUP_TPT440_DOCK),
        SND_PCI_QUIRK(0x17aa, 0x2211, "Thinkpad W541", ALC292_FIXUP_TPT440_DOCK),
        SND_PCI_QUIRK(0x17aa, 0x2212, "Thinkpad T440", ALC292_FIXUP_TPT440_DOCK),
        SND_PCI_QUIRK(0x17aa, 0x2214, "Thinkpad X240", ALC292_FIXUP_TPT440_DOCK),
        SND_PCI_QUIRK(0x17aa, 0x2215, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
+       SND_PCI_QUIRK(0x17aa, 0x2218, "Thinkpad X1 Carbon 2nd", ALC292_FIXUP_TPT440_DOCK),
        SND_PCI_QUIRK(0x17aa, 0x2223, "ThinkPad T550", ALC292_FIXUP_TPT440_DOCK),
        SND_PCI_QUIRK(0x17aa, 0x2226, "ThinkPad X250", ALC292_FIXUP_TPT440_DOCK),
+       SND_PCI_QUIRK(0x17aa, 0x2233, "Thinkpad", ALC293_FIXUP_LENOVO_SPK_NOISE),
+       SND_PCI_QUIRK(0x17aa, 0x30bb, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),
        SND_PCI_QUIRK(0x17aa, 0x3977, "IdeaPad S210", ALC283_FIXUP_INT_MIC),
        SND_PCI_QUIRK(0x17aa, 0x3978, "IdeaPad Y410P", ALC269_FIXUP_NO_SHUTUP),
        SND_PCI_QUIRK(0x17aa, 0x5013, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
@@ -5343,6 +5466,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x17aa, 0x5034, "Thinkpad T450", ALC292_FIXUP_TPT440_DOCK),
        SND_PCI_QUIRK(0x17aa, 0x5036, "Thinkpad T450s", ALC292_FIXUP_TPT440_DOCK),
        SND_PCI_QUIRK(0x17aa, 0x503c, "Thinkpad L450", ALC292_FIXUP_TPT440_DOCK),
+       SND_PCI_QUIRK(0x17aa, 0x504b, "Thinkpad", ALC293_FIXUP_LENOVO_SPK_NOISE),
        SND_PCI_QUIRK(0x17aa, 0x5109, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
        SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_PCM_44K),
        SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
@@ -5423,6 +5547,7 @@ static const struct hda_model_fixup alc269_fixup_models[] = {
        {.id = ALC283_FIXUP_CHROME_BOOK, .name = "alc283-dac-wcaps"},
        {.id = ALC283_FIXUP_SENSE_COMBO_JACK, .name = "alc283-sense-combo"},
        {.id = ALC292_FIXUP_TPT440_DOCK, .name = "tpt440-dock"},
+       {.id = ALC292_FIXUP_TPT440, .name = "tpt440"},
        {}
 };
 
@@ -6409,6 +6534,7 @@ static const struct hda_fixup alc662_fixups[] = {
 static const struct snd_pci_quirk alc662_fixup_tbl[] = {
        SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_FIXUP_ASUS_MODE2),
        SND_PCI_QUIRK(0x1025, 0x022f, "Acer Aspire One", ALC662_FIXUP_INV_DMIC),
+       SND_PCI_QUIRK(0x1025, 0x0241, "Packard Bell DOTS", ALC662_FIXUP_INV_DMIC),
        SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE),
        SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE),
        SND_PCI_QUIRK(0x1025, 0x0349, "eMachines eM250", ALC662_FIXUP_INV_DMIC),
index 714df906249eab42c54816fed4630cc4890d7603..41c31db650390c651617530ce08b44e11a889e2f 100644 (file)
@@ -741,10 +741,11 @@ snd_rme96_playback_setrate(struct rme96 *rme96,
        {
                /* change to/from double-speed: reset the DAC (if available) */
                snd_rme96_reset_dac(rme96);
+               return 1; /* need to restore volume */
        } else {
                writel(rme96->wcreg, rme96->iobase + RME96_IO_CONTROL_REGISTER);
+               return 0;
        }
-       return 0;
 }
 
 static int
@@ -980,6 +981,7 @@ snd_rme96_playback_hw_params(struct snd_pcm_substream *substream,
        struct rme96 *rme96 = snd_pcm_substream_chip(substream);
        struct snd_pcm_runtime *runtime = substream->runtime;
        int err, rate, dummy;
+       bool apply_dac_volume = false;
 
        runtime->dma_area = (void __force *)(rme96->iobase +
                                             RME96_IO_PLAY_BUFFER);
@@ -993,24 +995,26 @@ snd_rme96_playback_hw_params(struct snd_pcm_substream *substream,
        {
                 /* slave clock */
                 if ((int)params_rate(params) != rate) {
-                       spin_unlock_irq(&rme96->lock);
-                       return -EIO;                    
-                }
-       } else if ((err = snd_rme96_playback_setrate(rme96, params_rate(params))) < 0) {
-               spin_unlock_irq(&rme96->lock);
-               return err;
-       }
-       if ((err = snd_rme96_playback_setformat(rme96, params_format(params))) < 0) {
-               spin_unlock_irq(&rme96->lock);
-               return err;
+                       err = -EIO;
+                       goto error;
+               }
+       } else {
+               err = snd_rme96_playback_setrate(rme96, params_rate(params));
+               if (err < 0)
+                       goto error;
+               apply_dac_volume = err > 0; /* need to restore volume later? */
        }
+
+       err = snd_rme96_playback_setformat(rme96, params_format(params));
+       if (err < 0)
+               goto error;
        snd_rme96_setframelog(rme96, params_channels(params), 1);
        if (rme96->capture_periodsize != 0) {
                if (params_period_size(params) << rme96->playback_frlog !=
                    rme96->capture_periodsize)
                {
-                       spin_unlock_irq(&rme96->lock);
-                       return -EBUSY;
+                       err = -EBUSY;
+                       goto error;
                }
        }
        rme96->playback_periodsize =
@@ -1021,9 +1025,16 @@ snd_rme96_playback_hw_params(struct snd_pcm_substream *substream,
                rme96->wcreg &= ~(RME96_WCR_PRO | RME96_WCR_DOLBY | RME96_WCR_EMP);
                writel(rme96->wcreg |= rme96->wcreg_spdif_stream, rme96->iobase + RME96_IO_CONTROL_REGISTER);
        }
+
+       err = 0;
+ error:
        spin_unlock_irq(&rme96->lock);
-               
-       return 0;
+       if (apply_dac_volume) {
+               usleep_range(3000, 10000);
+               snd_rme96_apply_dac_volume(rme96);
+       }
+
+       return err;
 }
 
 static int
index b3ea24d64c5009cf4cc77e1877c894e3f21f4ee7..93b400800905d2fee18b066f11761cca524d9369 100644 (file)
@@ -1537,7 +1537,7 @@ static int arizona_hw_params(struct snd_pcm_substream *substream,
        bool reconfig;
        unsigned int aif_tx_state, aif_rx_state;
 
-       if (params_rate(params) % 8000)
+       if (params_rate(params) % 4000)
                rates = &arizona_44k1_bclk_rates[0];
        else
                rates = &arizona_48k_bclk_rates[0];
index 84f5eb07a91b1d27274f595cf595d97f36663484..afa6c5db9dccc9b00f049f8421b04e3091a1bcfc 100644 (file)
@@ -85,7 +85,15 @@ static const DECLARE_TLV_DB_SCALE(pga_tlv, 0, 300, 0);
 static const DECLARE_TLV_DB_SCALE(bypass_tlv, -1500, 300, 0);
 static const DECLARE_TLV_DB_SCALE(mic_tlv, 0, 300, 0);
 
-static const int deemph_settings[] = { 0, 32000, 44100, 48000 };
+static const struct {
+       int rate;
+       unsigned int val;
+} deemph_settings[] = {
+       { 0,     ES8328_DACCONTROL6_DEEMPH_OFF },
+       { 32000, ES8328_DACCONTROL6_DEEMPH_32k },
+       { 44100, ES8328_DACCONTROL6_DEEMPH_44_1k },
+       { 48000, ES8328_DACCONTROL6_DEEMPH_48k },
+};
 
 static int es8328_set_deemph(struct snd_soc_codec *codec)
 {
@@ -97,21 +105,22 @@ static int es8328_set_deemph(struct snd_soc_codec *codec)
         * rate.
         */
        if (es8328->deemph) {
-               best = 1;
-               for (i = 2; i < ARRAY_SIZE(deemph_settings); i++) {
-                       if (abs(deemph_settings[i] - es8328->playback_fs) <
-                           abs(deemph_settings[best] - es8328->playback_fs))
+               best = 0;
+               for (i = 1; i < ARRAY_SIZE(deemph_settings); i++) {
+                       if (abs(deemph_settings[i].rate - es8328->playback_fs) <
+                           abs(deemph_settings[best].rate - es8328->playback_fs))
                                best = i;
                }
 
-               val = best << 1;
+               val = deemph_settings[best].val;
        } else {
-               val = 0;
+               val = ES8328_DACCONTROL6_DEEMPH_OFF;
        }
 
        dev_dbg(codec->dev, "Set deemphasis %d\n", val);
 
-       return snd_soc_update_bits(codec, ES8328_DACCONTROL6, 0x6, val);
+       return snd_soc_update_bits(codec, ES8328_DACCONTROL6,
+                       ES8328_DACCONTROL6_DEEMPH_MASK, val);
 }
 
 static int es8328_get_deemph(struct snd_kcontrol *kcontrol,
index cb36afe10c0ecdf0b51183bea6eb8446e01271d3..156c748c89c7e55d86421b27522b22f9b16d6f76 100644 (file)
@@ -153,6 +153,7 @@ int es8328_probe(struct device *dev, struct regmap *regmap);
 #define ES8328_DACCONTROL6_CLICKFREE (1 << 3)
 #define ES8328_DACCONTROL6_DAC_INVR (1 << 4)
 #define ES8328_DACCONTROL6_DAC_INVL (1 << 5)
+#define ES8328_DACCONTROL6_DEEMPH_MASK (3 << 6)
 #define ES8328_DACCONTROL6_DEEMPH_OFF (0 << 6)
 #define ES8328_DACCONTROL6_DEEMPH_32k (1 << 6)
 #define ES8328_DACCONTROL6_DEEMPH_44_1k (2 << 6)
index ef76940f9dcb63196b10798f80d54528adc6109d..3e3c7f6be29d9a463f3b07bdefa78e0f2f29ace2 100644 (file)
@@ -1667,9 +1667,13 @@ static int rt5645_spk_event(struct snd_soc_dapm_widget *w,
                        RT5645_PWR_CLS_D_L,
                        RT5645_PWR_CLS_D | RT5645_PWR_CLS_D_R |
                        RT5645_PWR_CLS_D_L);
+               snd_soc_update_bits(codec, RT5645_GEN_CTRL3,
+                       RT5645_DET_CLK_MASK, RT5645_DET_CLK_MODE1);
                break;
 
        case SND_SOC_DAPM_PRE_PMD:
+               snd_soc_update_bits(codec, RT5645_GEN_CTRL3,
+                       RT5645_DET_CLK_MASK, RT5645_DET_CLK_DIS);
                snd_soc_write(codec, RT5645_EQ_CTRL2, 0);
                snd_soc_update_bits(codec, RT5645_PWR_DIG1,
                        RT5645_PWR_CLS_D | RT5645_PWR_CLS_D_R |
index 093e46d559fbab24aa05efc5c74a2e8488fa49d0..205e0715c99abad45e771c0504b92a512f5b6adf 100644 (file)
@@ -2122,6 +2122,10 @@ enum {
 /* General Control3 (0xfc) */
 #define RT5645_JD_PSV_MODE                     (0x1 << 12)
 #define RT5645_IRQ_CLK_GATE_CTRL               (0x1 << 11)
+#define RT5645_DET_CLK_MASK                    (0x3 << 9)
+#define RT5645_DET_CLK_DIS                     (0x0 << 9)
+#define RT5645_DET_CLK_MODE1                   (0x1 << 9)
+#define RT5645_DET_CLK_MODE2                   (0x2 << 9)
 #define RT5645_MICINDET_MANU                   (0x1 << 7)
 #define RT5645_RING2_SLEEVE_GND                        (0x1 << 5)
 
index f540f82b1f271ec4833d9ea43aa7f4567c0df712..08b40460663c2f28bd450261889cd365116f0bf9 100644 (file)
@@ -189,6 +189,7 @@ static int power_vag_event(struct snd_soc_dapm_widget *w,
        case SND_SOC_DAPM_POST_PMU:
                snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER,
                        SGTL5000_VAG_POWERUP, SGTL5000_VAG_POWERUP);
+               msleep(400);
                break;
 
        case SND_SOC_DAPM_PRE_PMD:
index 0a60677397b3dedb0b9652e112137e9b3c03f3d4..4c29bd2ae75cf987b34e28e28298ab026bb8c40e 100644 (file)
@@ -574,6 +574,7 @@ static const struct regmap_config wm8974_regmap = {
        .max_register = WM8974_MONOMIX,
        .reg_defaults = wm8974_reg_defaults,
        .num_reg_defaults = ARRAY_SIZE(wm8974_reg_defaults),
+       .cache_type = REGCACHE_FLAT,
 };
 
 static int wm8974_probe(struct snd_soc_codec *codec)
index c1c9c2e3525bf88f8cf6de409fcc9370320dd3b2..2ccb8bccc9d4cc4a79c6a94abe4dfb1566872737 100644 (file)
@@ -223,8 +223,8 @@ static void mcasp_start_tx(struct davinci_mcasp *mcasp)
 
        /* wait for XDATA to be cleared */
        cnt = 0;
-       while (!(mcasp_get_reg(mcasp, DAVINCI_MCASP_TXSTAT_REG) &
-                ~XRDATA) && (cnt < 100000))
+       while ((mcasp_get_reg(mcasp, DAVINCI_MCASP_TXSTAT_REG) & XRDATA) &&
+              (cnt < 100000))
                cnt++;
 
        /* Release TX state machine */
index ffd5f9acc849ffb3d8152bdfa1e5c13a26342668..08b460ba06efc28906fe1094e9e68b7c4e1e66cf 100644 (file)
@@ -505,6 +505,24 @@ static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd,
                                           FSL_SAI_CSR_FR, FSL_SAI_CSR_FR);
                        regmap_update_bits(sai->regmap, FSL_SAI_RCSR,
                                           FSL_SAI_CSR_FR, FSL_SAI_CSR_FR);
+
+                       /*
+                        * For sai master mode, after several open/close sai,
+                        * there will be no frame clock, and can't recover
+                        * anymore. Add software reset to fix this issue.
+                        * This is a hardware bug, and will be fix in the
+                        * next sai version.
+                        */
+                       if (!sai->is_slave_mode) {
+                               /* Software Reset for both Tx and Rx */
+                               regmap_write(sai->regmap,
+                                            FSL_SAI_TCSR, FSL_SAI_CSR_SR);
+                               regmap_write(sai->regmap,
+                                            FSL_SAI_RCSR, FSL_SAI_CSR_SR);
+                               /* Clear SR bit to finish the reset */
+                               regmap_write(sai->regmap, FSL_SAI_TCSR, 0);
+                               regmap_write(sai->regmap, FSL_SAI_RCSR, 0);
+                       }
                }
                break;
        default:
index ffea427aeca8eab29809f049c53ba27f71b54393..ad4d0f82603e7f65292a6c02530d66413a80ca91 100644 (file)
@@ -1240,7 +1240,6 @@ int skl_tplg_init(struct snd_soc_platform *platform, struct hdac_ext_bus *ebus)
         */
        ret = snd_soc_tplg_component_load(&platform->component,
                                        &skl_tplg_ops, fw, 0);
-       release_firmware(fw);
        if (ret < 0) {
                dev_err(bus->dev, "tplg component load failed%d\n", ret);
                return -EINVAL;
@@ -1249,5 +1248,7 @@ int skl_tplg_init(struct snd_soc_platform *platform, struct hdac_ext_bus *ebus)
        skl->resource.max_mcps = SKL_MAX_MCPS;
        skl->resource.max_mem = SKL_FW_MAX_MEM;
 
+       skl->tplg = fw;
+
        return 0;
 }
index 5319529aedf7ae5030dbf47ce9b6056512f05c2d..caa69c4598a6f14eb27c91575b49aae9fd7d3e8a 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/pci.h>
 #include <linux/pm_runtime.h>
 #include <linux/platform_device.h>
+#include <linux/firmware.h>
 #include <sound/pcm.h>
 #include "skl.h"
 
@@ -520,6 +521,9 @@ static void skl_remove(struct pci_dev *pci)
        struct hdac_ext_bus *ebus = pci_get_drvdata(pci);
        struct skl *skl = ebus_to_skl(ebus);
 
+       if (skl->tplg)
+               release_firmware(skl->tplg);
+
        if (pci_dev_run_wake(pci))
                pm_runtime_get_noresume(&pci->dev);
        pci_dev_put(pci);
index dd2e79ae45a8e6294c2766ef5eff7f4fac37befe..a0709e344d4419f4a37d28636cc3c79f368acd36 100644 (file)
@@ -68,6 +68,8 @@ struct skl {
        struct skl_dsp_resource resource;
        struct list_head ppl_list;
        struct list_head dapm_path_list;
+
+       const struct firmware *tplg;
 };
 
 #define skl_to_ebus(s) (&(s)->ebus)
index ac72ff5055bbce626550c4fd277a96c351321b25..5a806da89f42b49967ea52d15eac0f3348b7b873 100644 (file)
@@ -152,8 +152,10 @@ static int rk_spdif_trigger(struct snd_pcm_substream *substream,
        case SNDRV_PCM_TRIGGER_RESUME:
        case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
                ret = regmap_update_bits(spdif->regmap, SPDIF_DMACR,
-                                  SPDIF_DMACR_TDE_ENABLE,
-                                  SPDIF_DMACR_TDE_ENABLE);
+                                  SPDIF_DMACR_TDE_ENABLE |
+                                  SPDIF_DMACR_TDL_MASK,
+                                  SPDIF_DMACR_TDE_ENABLE |
+                                  SPDIF_DMACR_TDL(16));
 
                if (ret != 0)
                        return ret;
index 921b4095fb92c98d7b09fb8d7ec8bbea7f9139bb..3ef12770ae124d705d59b1916e5c400210aa0bf5 100644 (file)
@@ -42,7 +42,7 @@
 
 #define SPDIF_DMACR_TDL_SHIFT  0
 #define SPDIF_DMACR_TDL(x)     ((x) << SPDIF_DMACR_TDL_SHIFT)
-#define SPDIF_DMACR_TDL_MASK   (0x1f << SDPIF_DMACR_TDL_SHIFT)
+#define SPDIF_DMACR_TDL_MASK   (0x1f << SPDIF_DMACR_TDL_SHIFT)
 
 /*
  * XFER
index f494dced3c11e3a662b93d95df9ea53ff2767dfc..4f85757009b3e44e2246cc21f4387d0948056da3 100644 (file)
@@ -1354,6 +1354,8 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc,
                }
        }
 
+       snd_usb_mixer_fu_apply_quirk(state->mixer, cval, unitid, kctl);
+
        range = (cval->max - cval->min) / cval->res;
        /*
         * Are there devices with volume range more than 255? I use a bit more
index 6a803eff87f71110049d9c39cb07025d2c64d828..ddca6547399b0103b37abbdf73cfa5c9e710a7fd 100644 (file)
@@ -348,13 +348,6 @@ static struct usbmix_name_map bose_companion5_map[] = {
        { 0 }   /* terminator */
 };
 
-/* Dragonfly DAC 1.2, the dB conversion factor is 1 instead of 256 */
-static struct usbmix_dB_map dragonfly_1_2_dB = {0, 5000};
-static struct usbmix_name_map dragonfly_1_2_map[] = {
-       { 7, NULL, .dB = &dragonfly_1_2_dB },
-       { 0 }   /* terminator */
-};
-
 /*
  * Control map entries
  */
@@ -470,11 +463,6 @@ static struct usbmix_ctl_map usbmix_ctl_maps[] = {
                .id = USB_ID(0x05a7, 0x1020),
                .map = bose_companion5_map,
        },
-       {
-               /* Dragonfly DAC 1.2 */
-               .id = USB_ID(0x21b4, 0x0081),
-               .map = dragonfly_1_2_map,
-       },
        { 0 } /* terminator */
 };
 
index fe91184ce83247d8b0360bab09e94c8f7cb720d8..0ce888dceed0ea24db7b677eeb93b05c728ab40a 100644 (file)
@@ -37,6 +37,7 @@
 #include <sound/control.h>
 #include <sound/hwdep.h>
 #include <sound/info.h>
+#include <sound/tlv.h>
 
 #include "usbaudio.h"
 #include "mixer.h"
@@ -1825,3 +1826,39 @@ void snd_usb_mixer_rc_memory_change(struct usb_mixer_interface *mixer,
        }
 }
 
+static void snd_dragonfly_quirk_db_scale(struct usb_mixer_interface *mixer,
+                                        struct snd_kcontrol *kctl)
+{
+       /* Approximation using 10 ranges based on output measurement on hw v1.2.
+        * This seems close to the cubic mapping e.g. alsamixer uses. */
+       static const DECLARE_TLV_DB_RANGE(scale,
+                0,  1, TLV_DB_MINMAX_ITEM(-5300, -4970),
+                2,  5, TLV_DB_MINMAX_ITEM(-4710, -4160),
+                6,  7, TLV_DB_MINMAX_ITEM(-3884, -3710),
+                8, 14, TLV_DB_MINMAX_ITEM(-3443, -2560),
+               15, 16, TLV_DB_MINMAX_ITEM(-2475, -2324),
+               17, 19, TLV_DB_MINMAX_ITEM(-2228, -2031),
+               20, 26, TLV_DB_MINMAX_ITEM(-1910, -1393),
+               27, 31, TLV_DB_MINMAX_ITEM(-1322, -1032),
+               32, 40, TLV_DB_MINMAX_ITEM(-968, -490),
+               41, 50, TLV_DB_MINMAX_ITEM(-441, 0),
+       );
+
+       usb_audio_info(mixer->chip, "applying DragonFly dB scale quirk\n");
+       kctl->tlv.p = scale;
+       kctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ;
+       kctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK;
+}
+
+void snd_usb_mixer_fu_apply_quirk(struct usb_mixer_interface *mixer,
+                                 struct usb_mixer_elem_info *cval, int unitid,
+                                 struct snd_kcontrol *kctl)
+{
+       switch (mixer->chip->usb_id) {
+       case USB_ID(0x21b4, 0x0081): /* AudioQuest DragonFly */
+               if (unitid == 7 && cval->min == 0 && cval->max == 50)
+                       snd_dragonfly_quirk_db_scale(mixer, kctl);
+               break;
+       }
+}
+
index bdbfab093816a59772353635fd38eae79ddb3b38..177c329cd4ddb792e144f4ecd945976e6ab9b1a4 100644 (file)
@@ -9,5 +9,9 @@ void snd_emuusb_set_samplerate(struct snd_usb_audio *chip,
 void snd_usb_mixer_rc_memory_change(struct usb_mixer_interface *mixer,
                                    int unitid);
 
+void snd_usb_mixer_fu_apply_quirk(struct usb_mixer_interface *mixer,
+                                 struct usb_mixer_elem_info *cval, int unitid,
+                                 struct snd_kcontrol *kctl);
+
 #endif /* SND_USB_MIXER_QUIRKS_H */
 
index 7016ad8981873ca046000d631ac112c12ed62dc1..b6c0c8e3b450c5f0dd41ea308f61efe15b3446b8 100644 (file)
@@ -1125,6 +1125,7 @@ bool snd_usb_get_sample_rate_quirk(struct snd_usb_audio *chip)
        case USB_ID(0x045E, 0x0779): /* MS Lifecam HD-3000 */
        case USB_ID(0x04D8, 0xFEEA): /* Benchmark DAC1 Pre */
        case USB_ID(0x074D, 0x3553): /* Outlaw RR2150 (Micronas UAC3553B) */
+       case USB_ID(0x21B4, 0x0081): /* AudioQuest DragonFly */
                return true;
        }
        return false;
index 918b4de29de4ea86fc27cd40db49861618869d34..6419f57b08507ccea527f98bd050e41ead204b9b 100644 (file)
@@ -110,7 +110,7 @@ int cmd_buildid_list(int argc, const char **argv,
        setup_pager();
 
        if (show_kernel)
-               return sysfs__fprintf_build_id(stdout);
+               return !(sysfs__fprintf_build_id(stdout) > 0);
 
        return perf_session__list_build_ids(force, with_hits);
 }
index fa9eb92c9e24a477e45623c1017a2791fc68dd07..81def6c3f24bf16397c8e15d26178cd4957bd86f 100644 (file)
@@ -298,6 +298,9 @@ static bool hist_browser__toggle_fold(struct hist_browser *browser)
        struct callchain_list *cl = container_of(ms, struct callchain_list, ms);
        bool has_children;
 
+       if (!he || !ms)
+               return false;
+
        if (ms == &he->ms)
                has_children = hist_entry__toggle_fold(he);
        else
@@ -928,6 +931,8 @@ static unsigned int hist_browser__refresh(struct ui_browser *browser)
        }
 
        ui_browser__hists_init_top(browser);
+       hb->he_selection = NULL;
+       hb->selection = NULL;
 
        for (nd = browser->top; nd; nd = rb_next(nd)) {
                struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
@@ -1033,6 +1038,9 @@ static void ui_browser__hists_seek(struct ui_browser *browser,
         * and stop when we printed enough lines to fill the screen.
         */
 do_offset:
+       if (!nd)
+               return;
+
        if (offset > 0) {
                do {
                        h = rb_entry(nd, struct hist_entry, rb_node);
index 217b5a60e2ab0e000fbd4ff75445665d08833ba6..6a7e273a514a642b30a477c3119696dc7fa09975 100644 (file)
@@ -91,7 +91,7 @@ int build_id__sprintf(const u8 *build_id, int len, char *bf)
                bid += 2;
        }
 
-       return raw - build_id;
+       return (bid - bf) + 1;
 }
 
 int sysfs__sprintf_build_id(const char *root_dir, char *sbuild_id)
index e48d9da757078f0c35afae590ce87ac7892dafab..6fc8cd753e1a7dc791e1e165c0808d8fd509e3de 100644 (file)
@@ -124,6 +124,10 @@ struct event_symbol event_symbols_sw[PERF_COUNT_SW_MAX] = {
                .symbol = "dummy",
                .alias  = "",
        },
+       [PERF_COUNT_SW_BPF_OUTPUT] = {
+               .symbol = "bpf-output",
+               .alias  = "",
+       },
 };
 
 #define __PERF_EVENT_FIELD(config, name) \
@@ -1879,7 +1883,7 @@ restart:
 
        for (i = 0; i < max; i++, syms++) {
 
-               if (event_glob != NULL &&
+               if (event_glob != NULL && syms->symbol != NULL &&
                    !(strglobmatch(syms->symbol, event_glob) ||
                      (syms->alias && strglobmatch(syms->alias, event_glob))))
                        continue;
index 65461f821a75a7ffd3d0bdab471052e7061c8824..7a2f449bd85d02d7f6571fa4f5b3091df81a04d9 100644 (file)
@@ -1114,7 +1114,7 @@ bool kvm_vgic_map_is_active(struct kvm_vcpu *vcpu, struct irq_phys_map *map)
                        return true;
        }
 
-       return dist_active_irq(vcpu);
+       return vgic_irq_is_active(vcpu, map->virt_irq);
 }
 
 /*