Merge remote-tracking branch 'stable/linux-4.19.y' into rpi-4.19.y
authorpopcornmix <popcornmix@gmail.com>
Mon, 6 Jan 2020 12:44:50 +0000 (12:44 +0000)
committerpopcornmix <popcornmix@gmail.com>
Mon, 6 Jan 2020 12:44:50 +0000 (12:44 +0000)
553 files changed:
Documentation/admin-guide/kernel-parameters.txt
Documentation/filesystems/proc.txt
Makefile
arch/arm/boot/compressed/libfdt_env.h
arch/arm/boot/dts/omap3-pandora-common.dtsi
arch/arm/boot/dts/omap3-tao3530.dtsi
arch/arm/boot/dts/s3c6410-mini6410.dts
arch/arm/boot/dts/s3c6410-smdk6410.dts
arch/arm/mach-omap2/pdata-quirks.c
arch/arm/mach-tegra/reset-handler.S
arch/arm/mm/proc-v7-bugs.c
arch/arm64/include/asm/assembler.h
arch/arm64/kernel/entry.S
arch/arm64/kernel/psci.c
arch/arm64/kvm/sys_regs.c
arch/mips/include/asm/pgtable-64.h
arch/powerpc/Makefile
arch/powerpc/boot/libfdt_env.h
arch/powerpc/include/asm/vdso_datapage.h
arch/powerpc/kernel/Makefile
arch/powerpc/kernel/asm-offsets.c
arch/powerpc/kernel/irq.c
arch/powerpc/kernel/misc_64.S
arch/powerpc/kernel/security.c
arch/powerpc/kernel/time.c
arch/powerpc/kernel/vdso32/gettimeofday.S
arch/powerpc/kernel/vdso64/cacheflush.S
arch/powerpc/kernel/vdso64/gettimeofday.S
arch/powerpc/mm/hash_utils_64.c
arch/powerpc/platforms/pseries/cmm.c
arch/powerpc/sysdev/xive/common.c
arch/powerpc/sysdev/xive/spapr.c
arch/powerpc/tools/relocs_check.sh
arch/powerpc/tools/unrel_branch_check.sh
arch/powerpc/xmon/Makefile
arch/s390/include/asm/pgalloc.h
arch/s390/include/asm/pgtable.h
arch/s390/include/asm/timex.h
arch/s390/kernel/dis.c
arch/s390/kernel/perf_cpum_sf.c
arch/s390/kernel/smp.c
arch/sh/include/cpu-sh4/cpu/sh7734.h
arch/x86/include/asm/crash.h
arch/x86/include/asm/fixmap.h
arch/x86/include/asm/syscall_wrapper.h
arch/x86/kernel/apic/io_apic.c
arch/x86/kernel/cpu/mcheck/mce.c
arch/x86/kernel/cpu/mcheck/mce_amd.c
arch/x86/kernel/cpu/mcheck/therm_throt.c
arch/x86/lib/x86-opcode-map.txt
arch/x86/mm/pgtable.c
arch/xtensa/mm/tlb.c
block/blk-merge.c
block/blk-mq-sysfs.c
drivers/acpi/bus.c
drivers/acpi/button.c
drivers/acpi/device_pm.c
drivers/acpi/osl.c
drivers/ata/libata-core.c
drivers/block/drbd/drbd_state.c
drivers/block/drbd/drbd_state.h
drivers/block/loop.c
drivers/block/nbd.c
drivers/cdrom/cdrom.c
drivers/char/hw_random/omap-rng.c
drivers/char/hw_random/omap3-rom-rng.c
drivers/char/ipmi/ipmi_msghandler.c
drivers/char/ppdev.c
drivers/char/tpm/tpm2-cmd.c
drivers/clk/clk-gpio.c
drivers/clk/pxa/clk-pxa27x.c
drivers/clk/qcom/clk-rcg2.c
drivers/clk/qcom/common.c
drivers/clocksource/asm9260_timer.c
drivers/clocksource/timer-of.c
drivers/cpufreq/cpufreq.c
drivers/cpufreq/powernv-cpufreq.c
drivers/cpuidle/driver.c
drivers/crypto/atmel-aes.c
drivers/crypto/atmel-authenc.h
drivers/crypto/atmel-sha.c
drivers/crypto/sunxi-ss/sun4i-ss-cipher.c
drivers/crypto/sunxi-ss/sun4i-ss-hash.c
drivers/crypto/virtio/virtio_crypto_algs.c
drivers/crypto/vmx/Makefile
drivers/devfreq/devfreq.c
drivers/dma-buf/sync_file.c
drivers/dma/xilinx/xilinx_dma.c
drivers/edac/ghes_edac.c
drivers/extcon/extcon-sm5502.c
drivers/extcon/extcon-sm5502.h
drivers/firmware/arm_scmi/bus.c
drivers/firmware/qcom_scm-64.c
drivers/fsi/fsi-core.c
drivers/gpio/gpio-mpc8xxx.c
drivers/gpio/gpiolib-acpi.c
drivers/gpu/drm/amd/amdgpu/amdgpu_test.c
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
drivers/gpu/drm/amd/amdgpu/si_ih.c
drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c
drivers/gpu/drm/amd/display/dc/core/dc_link.c
drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
drivers/gpu/drm/bridge/analogix-anx78xx.c
drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
drivers/gpu/drm/drm_vblank.c
drivers/gpu/drm/gma500/oaktrail_crtc.c
drivers/gpu/drm/meson/meson_venc_cvbs.c
drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c
drivers/gpu/drm/panel/panel-sitronix-st7789v.c
drivers/gpu/drm/radeon/r100.c
drivers/gpu/drm/radeon/r200.c
drivers/gpu/drm/tegra/sor.c
drivers/gpu/host1x/job.c
drivers/hid/hid-core.c
drivers/hid/hid-ids.h
drivers/hid/hid-logitech-hidpp.c
drivers/hid/hid-quirks.c
drivers/hid/hid-rmi.c
drivers/hwtracing/intel_th/core.c
drivers/hwtracing/intel_th/pci.c
drivers/iio/adc/dln2-adc.c
drivers/iio/adc/max1027.c
drivers/iio/dac/Kconfig
drivers/iio/dac/ad5446.c
drivers/iio/humidity/hdc100x.c
drivers/iio/imu/adis16480.c
drivers/iio/imu/inv_mpu6050/inv_mpu_core.c
drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h
drivers/iio/light/bh1750.c
drivers/infiniband/hw/qedr/verbs.c
drivers/infiniband/ulp/iser/iscsi_iser.c
drivers/input/touchscreen/atmel_mxt_ts.c
drivers/iommu/rockchip-iommu.c
drivers/iommu/tegra-smmu.c
drivers/irqchip/irq-bcm7038-l1.c
drivers/irqchip/irq-ingenic.c
drivers/isdn/gigaset/usb-gigaset.c
drivers/leds/leds-lm3692x.c
drivers/leds/trigger/ledtrig-netdev.c
drivers/mailbox/imx-mailbox.c
drivers/md/bcache/alloc.c
drivers/md/bcache/bcache.h
drivers/md/bcache/btree.c
drivers/md/bcache/super.c
drivers/md/dm-mpath.c
drivers/md/dm-writecache.c
drivers/md/dm-zoned-metadata.c
drivers/md/dm-zoned-reclaim.c
drivers/md/dm-zoned-target.c
drivers/md/dm-zoned.h
drivers/md/md-bitmap.c
drivers/md/md-linear.c
drivers/md/md-multipath.c
drivers/md/md.c
drivers/md/md.h
drivers/md/persistent-data/dm-btree-remove.c
drivers/md/raid0.c
drivers/md/raid1.c
drivers/md/raid10.c
drivers/md/raid5.c
drivers/media/i2c/ov2659.c
drivers/media/i2c/ov6650.c
drivers/media/i2c/smiapp/smiapp-core.c
drivers/media/pci/cx88/cx88-video.c
drivers/media/platform/am437x/am437x-vpfe.c
drivers/media/platform/qcom/venus/core.c
drivers/media/platform/qcom/venus/hfi_venus.c
drivers/media/platform/qcom/venus/vdec.c
drivers/media/platform/qcom/venus/venc.c
drivers/media/platform/rcar_drif.c
drivers/media/platform/sti/bdisp/bdisp-v4l2.c
drivers/media/platform/ti-vpe/vpdma.h
drivers/media/platform/ti-vpe/vpe.c
drivers/media/platform/vimc/vimc-core.c
drivers/media/radio/radio-wl1273.c
drivers/media/radio/si470x/radio-si470x-i2c.c
drivers/media/usb/b2c2/flexcop-usb.c
drivers/media/usb/pvrusb2/pvrusb2-v4l2.c
drivers/media/v4l2-core/v4l2-ioctl.c
drivers/mmc/core/block.c
drivers/mmc/host/mtk-sd.c
drivers/mmc/host/omap_hsmmc.c
drivers/mmc/host/sdhci-msm.c
drivers/mmc/host/sdhci-of-esdhc.c
drivers/mmc/host/sdhci-pci-core.c
drivers/mmc/host/sdhci.c
drivers/mmc/host/sdhci.h
drivers/mmc/host/tmio_mmc_core.c
drivers/mtd/devices/spear_smi.c
drivers/net/bonding/bond_main.c
drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
drivers/net/dsa/Kconfig
drivers/net/ethernet/amazon/ena/ena_netdev.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
drivers/net/ethernet/cavium/thunder/thunder_bgx.c
drivers/net/ethernet/cortina/gemini.c
drivers/net/ethernet/hisilicon/hip04_eth.c
drivers/net/ethernet/hisilicon/hns3/hnae3.c
drivers/net/ethernet/hisilicon/hns3/hnae3.h
drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
drivers/net/ethernet/intel/e100.c
drivers/net/ethernet/intel/i40e/i40e_main.c
drivers/net/ethernet/intel/ice/ice_controlq.c
drivers/net/ethernet/intel/ice/ice_controlq.h
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c
drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
drivers/net/ethernet/mellanox/mlxfw/mlxfw_mfa2.c
drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
drivers/net/ethernet/qlogic/qede/qede_filter.c
drivers/net/ethernet/qlogic/qede/qede_main.c
drivers/net/ethernet/qlogic/qla3xxx.c
drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
drivers/net/ethernet/ti/cpsw.c
drivers/net/ethernet/ti/cpsw_ale.c
drivers/net/fjes/fjes_main.c
drivers/net/gtp.c
drivers/net/hamradio/6pack.c
drivers/net/hamradio/mkiss.c
drivers/net/phy/dp83867.c
drivers/net/phy/phy_device.c
drivers/net/tun.c
drivers/net/usb/lan78xx.c
drivers/net/wireless/ath/ar5523/ar5523.c
drivers/net/wireless/ath/ath10k/coredump.c
drivers/net/wireless/ath/ath10k/mac.c
drivers/net/wireless/ath/ath10k/pci.c
drivers/net/wireless/ath/ath10k/txrx.c
drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
drivers/net/wireless/intel/iwlwifi/dvm/led.c
drivers/net/wireless/intel/iwlwifi/mvm/led.c
drivers/net/wireless/intel/iwlwifi/mvm/rx.c
drivers/net/wireless/marvell/libertas/if_sdio.c
drivers/net/wireless/marvell/mwifiex/pcie.c
drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8723b.c
drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
drivers/net/wireless/realtek/rtlwifi/rtl8192cu/hw.c
drivers/net/wireless/realtek/rtlwifi/rtl8192de/hw.c
drivers/net/wireless/realtek/rtlwifi/rtl8192de/sw.c
drivers/net/wireless/realtek/rtlwifi/rtl8192de/trx.c
drivers/net/wireless/realtek/rtlwifi/rtl8192de/trx.h
drivers/net/wireless/realtek/rtlwifi/usb.c
drivers/nvdimm/btt.c
drivers/nvme/host/core.c
drivers/nvmem/imx-ocotp.c
drivers/of/overlay.c
drivers/of/unittest.c
drivers/parport/share.c
drivers/pci/controller/pcie-rcar.c
drivers/pci/hotplug/acpiphp_glue.c
drivers/pci/hotplug/pciehp.h
drivers/pci/hotplug/pciehp_ctrl.c
drivers/pci/hotplug/pciehp_hpc.c
drivers/pci/hotplug/rpaphp_core.c
drivers/pci/msi.c
drivers/pci/pci-driver.c
drivers/pci/quirks.c
drivers/phy/qualcomm/phy-qcom-usb-hs.c
drivers/phy/renesas/phy-rcar-gen3-usb2.c
drivers/pinctrl/devicetree.c
drivers/pinctrl/intel/pinctrl-baytrail.c
drivers/pinctrl/mvebu/pinctrl-armada-37xx.c
drivers/pinctrl/pinctrl-amd.c
drivers/pinctrl/samsung/pinctrl-exynos.c
drivers/pinctrl/samsung/pinctrl-s3c24xx.c
drivers/pinctrl/samsung/pinctrl-s3c64xx.c
drivers/pinctrl/samsung/pinctrl-samsung.c
drivers/pinctrl/sh-pfc/pfc-sh7734.c
drivers/platform/x86/hp-wmi.c
drivers/power/supply/cpcap-battery.c
drivers/ptp/ptp_clock.c
drivers/ptp/ptp_private.h
drivers/regulator/88pm800-regulator.c [moved from drivers/regulator/88pm800.c with 100% similarity]
drivers/regulator/Makefile
drivers/regulator/max8907-regulator.c
drivers/rpmsg/qcom_glink_native.c
drivers/rpmsg/qcom_glink_smem.c
drivers/rtc/interface.c
drivers/s390/crypto/zcrypt_error.h
drivers/s390/scsi/zfcp_dbf.c
drivers/scsi/NCR5380.c
drivers/scsi/atari_scsi.c
drivers/scsi/csiostor/csio_lnode.c
drivers/scsi/hisi_sas/hisi_sas.h
drivers/scsi/hisi_sas/hisi_sas_main.c
drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
drivers/scsi/iscsi_tcp.c
drivers/scsi/libiscsi.c
drivers/scsi/lpfc/lpfc.h
drivers/scsi/lpfc/lpfc_attr.c
drivers/scsi/lpfc/lpfc_els.c
drivers/scsi/lpfc/lpfc_hbadisc.c
drivers/scsi/lpfc/lpfc_init.c
drivers/scsi/lpfc/lpfc_mbox.c
drivers/scsi/lpfc/lpfc_nportdisc.c
drivers/scsi/lpfc/lpfc_nvme.c
drivers/scsi/lpfc/lpfc_sli.c
drivers/scsi/mac_scsi.c
drivers/scsi/mpt3sas/mpt3sas_ctl.c
drivers/scsi/pm8001/pm80xx_hwi.c
drivers/scsi/qla2xxx/qla_attr.c
drivers/scsi/qla2xxx/qla_bsg.c
drivers/scsi/qla2xxx/qla_gs.c
drivers/scsi/qla2xxx/qla_init.c
drivers/scsi/qla2xxx/qla_isr.c
drivers/scsi/qla2xxx/qla_mbx.c
drivers/scsi/qla2xxx/qla_mid.c
drivers/scsi/qla2xxx/qla_os.c
drivers/scsi/qla2xxx/qla_target.c
drivers/scsi/scsi_debug.c
drivers/scsi/scsi_trace.c
drivers/scsi/sun3_scsi.c
drivers/scsi/ufs/ufshcd.c
drivers/scsi/zorro_esp.c
drivers/soundwire/intel.c
drivers/spi/spi-fsl-spi.c
drivers/spi/spi-img-spfi.c
drivers/spi/spi-pxa2xx.c
drivers/spi/spi-sprd-adi.c
drivers/spi/spi-st-ssc4.c
drivers/spi/spi-tegra20-slink.c
drivers/spi/spidev.c
drivers/staging/comedi/drivers/gsc_hpdi.c
drivers/staging/erofs/xattr.c
drivers/staging/fbtft/fbtft-core.c
drivers/staging/rtl8188eu/core/rtw_xmit.c
drivers/staging/rtl8188eu/os_dep/usb_intf.c
drivers/staging/rtl8192u/r8192U_core.c
drivers/staging/rtl8712/usb_intf.c
drivers/target/iscsi/iscsi_target.c
drivers/target/iscsi/iscsi_target_auth.c
drivers/tty/serial/atmel_serial.c
drivers/usb/atm/ueagle-atm.c
drivers/usb/core/devio.c
drivers/usb/core/hub.c
drivers/usb/core/urb.c
drivers/usb/dwc3/dwc3-pci.c
drivers/usb/dwc3/ep0.c
drivers/usb/dwc3/gadget.c
drivers/usb/gadget/configfs.c
drivers/usb/gadget/udc/pch_udc.c
drivers/usb/host/ehci-q.c
drivers/usb/host/xhci-hub.c
drivers/usb/host/xhci-mem.c
drivers/usb/host/xhci-pci.c
drivers/usb/host/xhci-ring.c
drivers/usb/host/xhci.c
drivers/usb/host/xhci.h
drivers/usb/misc/adutux.c
drivers/usb/misc/idmouse.c
drivers/usb/mon/mon_bin.c
drivers/usb/renesas_usbhs/common.h
drivers/usb/renesas_usbhs/mod_gadget.c
drivers/usb/roles/class.c
drivers/usb/serial/io_edgeport.c
drivers/usb/storage/uas.c
drivers/usb/typec/class.c
drivers/usb/usbip/usbip_common.c
drivers/usb/usbip/vhci_rx.c
drivers/vfio/pci/vfio_pci_intrs.c
drivers/vhost/vsock.c
drivers/video/hdmi.c
drivers/virtio/virtio_balloon.c
drivers/watchdog/watchdog_dev.c
drivers/xen/Kconfig
drivers/xen/pvcalls-front.c
fs/btrfs/async-thread.c
fs/btrfs/ctree.c
fs/btrfs/ctree.h
fs/btrfs/delayed-inode.c
fs/btrfs/disk-io.c
fs/btrfs/extent-tree.c
fs/btrfs/extent_io.c
fs/btrfs/file-item.c
fs/btrfs/file.c
fs/btrfs/free-space-cache.c
fs/btrfs/inode.c
fs/btrfs/ioctl.c
fs/btrfs/reada.c
fs/btrfs/relocation.c
fs/btrfs/scrub.c
fs/btrfs/send.c
fs/btrfs/tests/free-space-tree-tests.c
fs/btrfs/tests/qgroup-tests.c
fs/btrfs/tree-log.c
fs/btrfs/uuid-tree.c
fs/btrfs/volumes.h
fs/cifs/cifs_debug.c
fs/cifs/file.c
fs/cifs/smb2misc.c
fs/cifs/smb2pdu.c
fs/cifs/smb2proto.h
fs/cifs/smbdirect.c
fs/cifs/transport.c
fs/ext2/inode.c
fs/ext4/dir.c
fs/ext4/inode.c
fs/ext4/namei.c
fs/f2fs/f2fs.h
fs/f2fs/inode.c
fs/f2fs/namei.c
fs/gfs2/log.c
fs/gfs2/log.h
fs/gfs2/lops.c
fs/gfs2/trans.c
fs/jbd2/commit.c
fs/ocfs2/acl.c
fs/ocfs2/quota_global.c
fs/overlayfs/dir.c
fs/overlayfs/inode.c
fs/proc/task_mmu.c
fs/quota/dquot.c
fs/readdir.c
fs/reiserfs/inode.c
fs/reiserfs/namei.c
fs/reiserfs/reiserfs.h
fs/reiserfs/super.c
fs/reiserfs/xattr.c
fs/reiserfs/xattr_acl.c
fs/splice.c
fs/userfaultfd.c
include/drm/drm_dp_mst_helper.h
include/linux/cpufreq.h
include/linux/hrtimer.h
include/linux/huge_mm.h
include/linux/ipmi_smi.h
include/linux/libfdt_env.h
include/linux/mfd/rk808.h
include/linux/miscdevice.h
include/linux/mod_devicetable.h
include/linux/netdevice.h
include/linux/posix-clock.h
include/linux/quota.h
include/linux/quotaops.h
include/linux/rculist_nulls.h
include/linux/sched/cpufreq.h
include/linux/skbuff.h
include/linux/time.h
include/net/dst.h
include/net/dst_ops.h
include/net/inet_hashtables.h
include/net/ip.h
include/net/sock.h
include/net/tcp.h
include/scsi/iscsi_proto.h
include/trace/events/wbt.h
include/uapi/linux/cec-funcs.h
include/uapi/linux/cec.h
kernel/bpf/stackmap.c
kernel/cgroup/pids.c
kernel/dma/debug.c
kernel/module.c
kernel/sched/cpufreq.c
kernel/sched/cpufreq_schedutil.c
kernel/sysctl.c
kernel/time/hrtimer.c
kernel/time/posix-clock.c
kernel/trace/trace.c
kernel/trace/trace_kprobe.c
kernel/workqueue.c
lib/idr.c
lib/raid6/unroll.awk
mm/huge_memory.c
mm/memory.c
mm/shmem.c
net/bluetooth/hci_conn.c
net/bluetooth/hci_core.c
net/bluetooth/hci_request.c
net/bridge/br_device.c
net/bridge/br_netfilter_hooks.c
net/bridge/br_nf_core.c
net/bridge/netfilter/ebtables.c
net/core/dev.c
net/core/flow_dissector.c
net/core/sysctl_net_core.c
net/decnet/dn_route.c
net/ipv4/devinet.c
net/ipv4/gre_demux.c
net/ipv4/icmp.c
net/ipv4/inet_connection_sock.c
net/ipv4/inet_diag.c
net/ipv4/inet_hashtables.c
net/ipv4/inetpeer.c
net/ipv4/ip_output.c
net/ipv4/ip_tunnel.c
net/ipv4/ip_vti.c
net/ipv4/route.c
net/ipv4/tcp_ipv4.c
net/ipv4/tcp_output.c
net/ipv4/udp.c
net/ipv4/xfrm4_policy.c
net/ipv6/inet6_connection_sock.c
net/ipv6/inet6_hashtables.c
net/ipv6/ip6_gre.c
net/ipv6/ip6_tunnel.c
net/ipv6/ip6_vti.c
net/ipv6/route.c
net/ipv6/sit.c
net/ipv6/xfrm6_policy.c
net/mac80211/status.c
net/netfilter/ipvs/ip_vs_xmit.c
net/netfilter/nf_queue.c
net/nfc/nci/uart.c
net/openvswitch/conntrack.c
net/packet/af_packet.c
net/rfkill/core.c
net/sched/sch_cake.c
net/sched/sch_mq.c
net/sched/sch_mqprio.c
net/sctp/protocol.c
net/sctp/transport.c
net/smc/smc_tx.c
net/sunrpc/cache.c
net/tipc/core.c
samples/pktgen/functions.sh
scripts/kallsyms.c
security/apparmor/label.c
sound/core/pcm_native.c
sound/core/timer.c
sound/pci/hda/hda_controller.c
sound/pci/hda/patch_ca0132.c
sound/soc/codecs/rt5645.c
sound/soc/codecs/rt5677.c
sound/soc/codecs/wm2200.c
sound/soc/codecs/wm5100.c
sound/soc/codecs/wm8904.c
sound/soc/intel/boards/bytcr_rt5640.c
sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c
sound/soc/soc-jack.c
tools/lib/bpf/libbpf.c
tools/lib/subcmd/Makefile
tools/lib/traceevent/parse-filter.c
tools/objtool/arch/x86/lib/x86-opcode-map.txt
tools/perf/builtin-report.c
tools/perf/builtin-script.c
tools/perf/pmu-events/jevents.c
tools/perf/tests/bp_signal.c
tools/perf/tests/task-exit.c
tools/perf/util/dwarf-aux.c
tools/perf/util/dwarf-aux.h
tools/perf/util/machine.c
tools/perf/util/parse-events.c
tools/perf/util/perf_regs.h
tools/perf/util/probe-finder.c
tools/perf/util/strbuf.c
tools/power/cpupower/utils/idle_monitor/hsw_ext_idle.c
tools/testing/selftests/bpf/cgroup_helpers.c
tools/testing/selftests/net/forwarding/router_bridge_vlan.sh

index ce1af89..2c0d6ae 100644 (file)
                        Flags is a set of characters, each corresponding
                        to a common usb-storage quirk flag as follows:
                                a = SANE_SENSE (collect more than 18 bytes
-                                       of sense data);
+                                       of sense data, not on uas);
                                b = BAD_SENSE (don't collect more than 18
-                                       bytes of sense data);
+                                       bytes of sense data, not on uas);
                                c = FIX_CAPACITY (decrease the reported
                                        device capacity by one sector);
                                d = NO_READ_DISC_INFO (don't use
-                                       READ_DISC_INFO command);
+                                       READ_DISC_INFO command, not on uas);
                                e = NO_READ_CAPACITY_16 (don't use
                                        READ_CAPACITY_16 command);
                                f = NO_REPORT_OPCODES (don't use report opcodes
                                j = NO_REPORT_LUNS (don't use report luns
                                        command, uas only);
                                l = NOT_LOCKABLE (don't try to lock and
-                                       unlock ejectable media);
+                                       unlock ejectable media, not on uas);
                                m = MAX_SECTORS_64 (don't transfer more
-                                       than 64 sectors = 32 KB at a time);
+                                       than 64 sectors = 32 KB at a time,
+                                       not on uas);
                                n = INITIAL_READ10 (force a retry of the
-                                       initial READ(10) command);
+                                       initial READ(10) command, not on uas);
                                o = CAPACITY_OK (accept the capacity
-                                       reported by the device);
+                                       reported by the device, not on uas);
                                p = WRITE_CACHE (the device cache is ON
-                                       by default);
+                                       by default, not on uas);
                                r = IGNORE_RESIDUE (the device reports
-                                       bogus residue values);
+                                       bogus residue values, not on uas);
                                s = SINGLE_LUN (the device has only one
                                        Logical Unit);
                                t = NO_ATA_1X (don't allow ATA(12) and ATA(16)
                                w = NO_WP_DETECT (don't test whether the
                                        medium is write-protected).
                                y = ALWAYS_SYNC (issue a SYNCHRONIZE_CACHE
-                                       even if the device claims no cache)
+                                       even if the device claims no cache,
+                                       not on uas)
                        Example: quirks=0419:aaf5:rl,0421:0433:rc
 
        user_debug=     [KNL,ARM]
index 06ac6dd..0d0ecc7 100644 (file)
@@ -425,6 +425,7 @@ SwapPss:               0 kB
 KernelPageSize:        4 kB
 MMUPageSize:           4 kB
 Locked:                0 kB
+THPeligible:           0
 VmFlags: rd ex mr mw me dw
 
 the first of these lines shows the same information as is displayed for the
@@ -462,6 +463,8 @@ replaced by copy-on-write) part of the underlying shmem object out on swap.
 "SwapPss" shows proportional swap share of this mapping. Unlike "Swap", this
 does not take into account swapped out page of underlying shmem objects.
 "Locked" indicates whether the mapping is locked in memory or not.
+"THPeligible" indicates whether the mapping is eligible for THP pages - 1 if
+true, 0 otherwise.
 
 "VmFlags" field deserves a separate description. This member represents the kernel
 flags associated with the particular virtual memory area in two letter encoded
index 805dbba..b3b166c 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0
 VERSION = 4
 PATCHLEVEL = 19
-SUBLEVEL = 89
+SUBLEVEL = 93
 EXTRAVERSION =
 NAME = "People's Front"
 
index b36c028..6a0f1f5 100644 (file)
@@ -2,11 +2,13 @@
 #ifndef _ARM_LIBFDT_ENV_H
 #define _ARM_LIBFDT_ENV_H
 
+#include <linux/limits.h>
 #include <linux/types.h>
 #include <linux/string.h>
 #include <asm/byteorder.h>
 
-#define INT_MAX                        ((int)(~0U>>1))
+#define INT32_MAX      S32_MAX
+#define UINT32_MAX     U32_MAX
 
 typedef __be16 fdt16_t;
 typedef __be32 fdt32_t;
index 90c98f9..a51081d 100644 (file)
                gpio = <&gpio6 4 GPIO_ACTIVE_HIGH>;     /* GPIO_164 */
        };
 
+       /* wl1251 wifi+bt module */
+       wlan_en: fixed-regulator-wg7210_en {
+               compatible = "regulator-fixed";
+               regulator-name = "vwlan";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <1800000>;
+               startup-delay-us = <50000>;
+               enable-active-high;
+               gpio = <&gpio1 23 GPIO_ACTIVE_HIGH>;
+       };
+
        /* wg7210 (wifi+bt module) 32k clock buffer */
        wg7210_32k: fixed-regulator-wg7210_32k {
                compatible = "regulator-fixed";
        /*wp-gpios = <&gpio4 31 GPIO_ACTIVE_HIGH>;*/    /* GPIO_127 */
 };
 
-/* mmc3 is probed using pdata-quirks to pass wl1251 card data */
 &mmc3 {
-       status = "disabled";
+       vmmc-supply = <&wlan_en>;
+
+       bus-width = <4>;
+       non-removable;
+       ti,non-removable;
+       cap-power-off-card;
+
+       pinctrl-names = "default";
+       pinctrl-0 = <&mmc3_pins>;
+
+       #address-cells = <1>;
+       #size-cells = <0>;
+
+       wlan: wifi@1 {
+               compatible = "ti,wl1251";
+
+               reg = <1>;
+
+               interrupt-parent = <&gpio1>;
+               interrupts = <21 IRQ_TYPE_LEVEL_HIGH>;  /* GPIO_21 */
+
+               ti,wl1251-has-eeprom;
+       };
 };
 
 /* bluetooth*/
index 6f5bd02..7b4ec2c 100644 (file)
        pinctrl-0 = <&mmc1_pins>;
        vmmc-supply = <&vmmc1>;
        vqmmc-supply = <&vsim>;
-       cd-gpios = <&twl_gpio 0 GPIO_ACTIVE_HIGH>;
+       cd-gpios = <&twl_gpio 0 GPIO_ACTIVE_LOW>;
        bus-width = <8>;
 };
 
index 0e159c8..1aeac33 100644 (file)
        };
 };
 
+&clocks {
+       clocks = <&fin_pll>;
+};
+
 &sdhci0 {
        pinctrl-names = "default";
        pinctrl-0 = <&sd0_clk>, <&sd0_cmd>, <&sd0_cd>, <&sd0_bus4>;
index a9a5689..3bf6c45 100644 (file)
        };
 };
 
+&clocks {
+       clocks = <&fin_pll>;
+};
+
 &sdhci0 {
        pinctrl-names = "default";
        pinctrl-0 = <&sd0_clk>, <&sd0_cmd>, <&sd0_cd>, <&sd0_bus4>;
index 7f02743..dae7262 100644 (file)
@@ -305,108 +305,15 @@ static void __init omap3_logicpd_torpedo_init(void)
 }
 
 /* omap3pandora legacy devices */
-#define PANDORA_WIFI_IRQ_GPIO          21
-#define PANDORA_WIFI_NRESET_GPIO       23
 
 static struct platform_device pandora_backlight = {
        .name   = "pandora-backlight",
        .id     = -1,
 };
 
-static struct regulator_consumer_supply pandora_vmmc3_supply[] = {
-       REGULATOR_SUPPLY("vmmc", "omap_hsmmc.2"),
-};
-
-static struct regulator_init_data pandora_vmmc3 = {
-       .constraints = {
-               .valid_ops_mask         = REGULATOR_CHANGE_STATUS,
-       },
-       .num_consumer_supplies  = ARRAY_SIZE(pandora_vmmc3_supply),
-       .consumer_supplies      = pandora_vmmc3_supply,
-};
-
-static struct fixed_voltage_config pandora_vwlan = {
-       .supply_name            = "vwlan",
-       .microvolts             = 1800000, /* 1.8V */
-       .gpio                   = PANDORA_WIFI_NRESET_GPIO,
-       .startup_delay          = 50000, /* 50ms */
-       .enable_high            = 1,
-       .init_data              = &pandora_vmmc3,
-};
-
-static struct platform_device pandora_vwlan_device = {
-       .name           = "reg-fixed-voltage",
-       .id             = 1,
-       .dev = {
-               .platform_data = &pandora_vwlan,
-       },
-};
-
-static void pandora_wl1251_init_card(struct mmc_card *card)
-{
-       /*
-        * We have TI wl1251 attached to MMC3. Pass this information to
-        * SDIO core because it can't be probed by normal methods.
-        */
-       if (card->type == MMC_TYPE_SDIO || card->type == MMC_TYPE_SD_COMBO) {
-               card->quirks |= MMC_QUIRK_NONSTD_SDIO;
-               card->cccr.wide_bus = 1;
-               card->cis.vendor = 0x104c;
-               card->cis.device = 0x9066;
-               card->cis.blksize = 512;
-               card->cis.max_dtr = 24000000;
-               card->ocr = 0x80;
-       }
-}
-
-static struct omap2_hsmmc_info pandora_mmc3[] = {
-       {
-               .mmc            = 3,
-               .caps           = MMC_CAP_4_BIT_DATA | MMC_CAP_POWER_OFF_CARD,
-               .gpio_cd        = -EINVAL,
-               .gpio_wp        = -EINVAL,
-               .init_card      = pandora_wl1251_init_card,
-       },
-       {}      /* Terminator */
-};
-
-static void __init pandora_wl1251_init(void)
-{
-       struct wl1251_platform_data pandora_wl1251_pdata;
-       int ret;
-
-       memset(&pandora_wl1251_pdata, 0, sizeof(pandora_wl1251_pdata));
-
-       pandora_wl1251_pdata.power_gpio = -1;
-
-       ret = gpio_request_one(PANDORA_WIFI_IRQ_GPIO, GPIOF_IN, "wl1251 irq");
-       if (ret < 0)
-               goto fail;
-
-       pandora_wl1251_pdata.irq = gpio_to_irq(PANDORA_WIFI_IRQ_GPIO);
-       if (pandora_wl1251_pdata.irq < 0)
-               goto fail_irq;
-
-       pandora_wl1251_pdata.use_eeprom = true;
-       ret = wl1251_set_platform_data(&pandora_wl1251_pdata);
-       if (ret < 0)
-               goto fail_irq;
-
-       return;
-
-fail_irq:
-       gpio_free(PANDORA_WIFI_IRQ_GPIO);
-fail:
-       pr_err("wl1251 board initialisation failed\n");
-}
-
 static void __init omap3_pandora_legacy_init(void)
 {
        platform_device_register(&pandora_backlight);
-       platform_device_register(&pandora_vwlan_device);
-       omap_hsmmc_init(pandora_mmc3);
-       omap_hsmmc_late_init(pandora_mmc3);
-       pandora_wl1251_init();
 }
 #endif /* CONFIG_ARCH_OMAP3 */
 
index 805f306..e31f167 100644 (file)
@@ -56,16 +56,16 @@ ENTRY(tegra_resume)
        cmp     r6, #TEGRA20
        beq     1f                              @ Yes
        /* Clear the flow controller flags for this CPU. */
-       cpu_to_csr_reg r1, r0
+       cpu_to_csr_reg r3, r0
        mov32   r2, TEGRA_FLOW_CTRL_BASE
-       ldr     r1, [r2, r1]
+       ldr     r1, [r2, r3]
        /* Clear event & intr flag */
        orr     r1, r1, \
                #FLOW_CTRL_CSR_INTR_FLAG | FLOW_CTRL_CSR_EVENT_FLAG
        movw    r0, #0x3FFD     @ enable, cluster_switch, immed, bitmaps
                                @ & ext flags for CPU power mgnt
        bic     r1, r1, r0
-       str     r1, [r2]
+       str     r1, [r2, r3]
 1:
 
        mov32   r9, 0xc09
index 9a07916..a6554fd 100644 (file)
@@ -65,6 +65,9 @@ static void cpu_v7_spectre_init(void)
                break;
 
 #ifdef CONFIG_ARM_PSCI
+       case ARM_CPU_PART_BRAHMA_B53:
+               /* Requires no workaround */
+               break;
        default:
                /* Other ARM CPUs require no workaround */
                if (read_cpuid_implementor() == ARM_CPU_IMP_ARM)
index 0c10050..5a97ac8 100644 (file)
@@ -683,9 +683,11 @@ USER(\label, ic    ivau, \tmp2)                    // invalidate I line PoU
        .macro          if_will_cond_yield_neon
 #ifdef CONFIG_PREEMPT
        get_thread_info x0
-       ldr             x0, [x0, #TSK_TI_PREEMPT]
-       sub             x0, x0, #PREEMPT_DISABLE_OFFSET
-       cbz             x0, .Lyield_\@
+       ldr             w1, [x0, #TSK_TI_PREEMPT]
+       ldr             x0, [x0, #TSK_TI_FLAGS]
+       cmp             w1, #PREEMPT_DISABLE_OFFSET
+       csel            x0, x0, xzr, eq
+       tbnz            x0, #TIF_NEED_RESCHED, .Lyield_\@       // needs rescheduling?
        /* fall through to endif_yield_neon */
        .subsection     1
 .Lyield_\@ :
index bb68323..5f80038 100644 (file)
@@ -622,8 +622,10 @@ el1_irq:
        irq_handler
 
 #ifdef CONFIG_PREEMPT
-       ldr     x24, [tsk, #TSK_TI_PREEMPT]     // get preempt count
-       cbnz    x24, 1f                         // preempt count != 0
+       ldr     w24, [tsk, #TSK_TI_PREEMPT]     // get preempt count
+       cbnz    w24, 1f                         // preempt count != 0
+       ldr     x0, [tsk, #TSK_TI_FLAGS]        // get flags
+       tbz     x0, #TIF_NEED_RESCHED, 1f       // needs rescheduling?
        bl      el1_preempt
 1:
 #endif
index e8edbf1..3856d51 100644 (file)
@@ -84,7 +84,8 @@ static void cpu_psci_cpu_die(unsigned int cpu)
 
 static int cpu_psci_cpu_kill(unsigned int cpu)
 {
-       int err, i;
+       int err;
+       unsigned long start, end;
 
        if (!psci_ops.affinity_info)
                return 0;
@@ -94,16 +95,18 @@ static int cpu_psci_cpu_kill(unsigned int cpu)
         * while it is dying. So, try again a few times.
         */
 
-       for (i = 0; i < 10; i++) {
+       start = jiffies;
+       end = start + msecs_to_jiffies(100);
+       do {
                err = psci_ops.affinity_info(cpu_logical_map(cpu), 0);
                if (err == PSCI_0_2_AFFINITY_LEVEL_OFF) {
-                       pr_info("CPU%d killed.\n", cpu);
+                       pr_info("CPU%d killed (polled %d ms)\n", cpu,
+                               jiffies_to_msecs(jiffies - start));
                        return 0;
                }
 
-               msleep(10);
-               pr_info("Retrying again to check for CPU kill\n");
-       }
+               usleep_range(100, 1000);
+       } while (time_before(jiffies, end));
 
        pr_warn("CPU%d may not have shut down cleanly (AFFINITY_INFO reports %d)\n",
                        cpu, err);
index 6da2bbd..0c073f3 100644 (file)
@@ -2174,8 +2174,11 @@ static const struct sys_reg_desc *index_to_sys_reg_desc(struct kvm_vcpu *vcpu,
        if ((id & KVM_REG_ARM_COPROC_MASK) != KVM_REG_ARM64_SYSREG)
                return NULL;
 
+       if (!index_to_params(id, &params))
+               return NULL;
+
        table = get_target_table(vcpu->arch.target, true, &num);
-       r = find_reg_by_id(id, &params, table, num);
+       r = find_reg(&params, table, num);
        if (!r)
                r = find_reg(&params, sys_reg_descs, ARRAY_SIZE(sys_reg_descs));
 
index 93a9dce..813dfe5 100644 (file)
 #include <asm/fixmap.h>
 
 #define __ARCH_USE_5LEVEL_HACK
-#if defined(CONFIG_PAGE_SIZE_64KB) && !defined(CONFIG_MIPS_VA_BITS_48)
+#if CONFIG_PGTABLE_LEVELS == 2
 #include <asm-generic/pgtable-nopmd.h>
-#elif !(defined(CONFIG_PAGE_SIZE_4KB) && defined(CONFIG_MIPS_VA_BITS_48))
+#elif CONFIG_PGTABLE_LEVELS == 3
 #include <asm-generic/pgtable-nopud.h>
+#else
+#include <asm-generic/5level-fixup.h>
 #endif
 
 /*
@@ -216,6 +218,9 @@ static inline unsigned long pgd_page_vaddr(pgd_t pgd)
        return pgd_val(pgd);
 }
 
+#define pgd_phys(pgd)          virt_to_phys((void *)pgd_val(pgd))
+#define pgd_page(pgd)          (pfn_to_page(pgd_phys(pgd) >> PAGE_SHIFT))
+
 static inline pud_t *pud_offset(pgd_t *pgd, unsigned long address)
 {
        return (pud_t *)pgd_page_vaddr(*pgd) + pud_index(address);
index dfcb698..e43321f 100644 (file)
@@ -90,11 +90,13 @@ MULTIPLEWORD        := -mmultiple
 endif
 
 ifdef CONFIG_PPC64
+ifndef CONFIG_CC_IS_CLANG
 cflags-$(CONFIG_CPU_BIG_ENDIAN)                += $(call cc-option,-mabi=elfv1)
 cflags-$(CONFIG_CPU_BIG_ENDIAN)                += $(call cc-option,-mcall-aixdesc)
 aflags-$(CONFIG_CPU_BIG_ENDIAN)                += $(call cc-option,-mabi=elfv1)
 aflags-$(CONFIG_CPU_LITTLE_ENDIAN)     += -mabi=elfv2
 endif
+endif
 
 ifneq ($(cc-name),clang)
   cflags-$(CONFIG_CPU_LITTLE_ENDIAN)   += -mno-strict-align
@@ -134,6 +136,7 @@ endif
 endif
 
 CFLAGS-$(CONFIG_PPC64) := $(call cc-option,-mtraceback=no)
+ifndef CONFIG_CC_IS_CLANG
 ifdef CONFIG_CPU_LITTLE_ENDIAN
 CFLAGS-$(CONFIG_PPC64) += $(call cc-option,-mabi=elfv2,$(call cc-option,-mcall-aixdesc))
 AFLAGS-$(CONFIG_PPC64) += $(call cc-option,-mabi=elfv2)
@@ -142,6 +145,7 @@ CFLAGS-$(CONFIG_PPC64)      += $(call cc-option,-mabi=elfv1)
 CFLAGS-$(CONFIG_PPC64) += $(call cc-option,-mcall-aixdesc)
 AFLAGS-$(CONFIG_PPC64) += $(call cc-option,-mabi=elfv1)
 endif
+endif
 CFLAGS-$(CONFIG_PPC64) += $(call cc-option,-mcmodel=medium,$(call cc-option,-mminimal-toc))
 CFLAGS-$(CONFIG_PPC64) += $(call cc-option,-mno-pointers-to-nested-functions)
 
index 2abc8e8..9757d4f 100644 (file)
@@ -6,6 +6,8 @@
 #include <string.h>
 
 #define INT_MAX                        ((int)(~0U>>1))
+#define UINT32_MAX             ((u32)~0U)
+#define INT32_MAX              ((s32)(UINT32_MAX >> 1))
 
 #include "of.h"
 
index bbc06bd..4333b9a 100644 (file)
@@ -86,6 +86,7 @@ struct vdso_data {
        __s32 wtom_clock_nsec;                  /* Wall to monotonic clock nsec */
        __s64 wtom_clock_sec;                   /* Wall to monotonic clock sec */
        struct timespec stamp_xtime;            /* xtime as at tb_orig_stamp */
+       __u32 hrtimer_res;                      /* hrtimer resolution */
        __u32 syscall_map_64[SYSCALL_MAP_SIZE]; /* map of syscalls  */
        __u32 syscall_map_32[SYSCALL_MAP_SIZE]; /* map of syscalls */
 };
@@ -107,6 +108,7 @@ struct vdso_data {
        __s32 wtom_clock_nsec;
        struct timespec stamp_xtime;    /* xtime as at tb_orig_stamp */
        __u32 stamp_sec_fraction;       /* fractional seconds of stamp_xtime */
+       __u32 hrtimer_res;              /* hrtimer resolution */
        __u32 syscall_map_32[SYSCALL_MAP_SIZE]; /* map of syscalls */
        __u32 dcache_block_size;        /* L1 d-cache block size     */
        __u32 icache_block_size;        /* L1 i-cache block size     */
index eac1879..d450280 100644 (file)
@@ -5,8 +5,8 @@
 
 CFLAGS_ptrace.o                += -DUTS_MACHINE='"$(UTS_MACHINE)"'
 
-# Disable clang warning for using setjmp without setjmp.h header
-CFLAGS_crash.o         += $(call cc-disable-warning, builtin-requires-header)
+# Avoid clang warnings around longjmp/setjmp declarations
+CFLAGS_crash.o += -ffreestanding
 
 subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror
 
index 7c3738d..50400f2 100644 (file)
@@ -379,6 +379,7 @@ int main(void)
        OFFSET(WTOM_CLOCK_NSEC, vdso_data, wtom_clock_nsec);
        OFFSET(STAMP_XTIME, vdso_data, stamp_xtime);
        OFFSET(STAMP_SEC_FRAC, vdso_data, stamp_sec_fraction);
+       OFFSET(CLOCK_HRTIMER_RES, vdso_data, hrtimer_res);
        OFFSET(CFG_ICACHE_BLOCKSZ, vdso_data, icache_block_size);
        OFFSET(CFG_DCACHE_BLOCKSZ, vdso_data, dcache_block_size);
        OFFSET(CFG_ICACHE_LOGBLOCKSZ, vdso_data, icache_log_block_size);
@@ -409,7 +410,6 @@ int main(void)
        DEFINE(CLOCK_REALTIME_COARSE, CLOCK_REALTIME_COARSE);
        DEFINE(CLOCK_MONOTONIC_COARSE, CLOCK_MONOTONIC_COARSE);
        DEFINE(NSEC_PER_SEC, NSEC_PER_SEC);
-       DEFINE(CLOCK_REALTIME_RES, MONOTONIC_RES_NSEC);
 
 #ifdef CONFIG_BUG
        DEFINE(BUG_ENTRY_SIZE, sizeof(struct bug_entry));
index 916ddc4..d37704e 100644 (file)
@@ -634,8 +634,6 @@ void __do_irq(struct pt_regs *regs)
 
        trace_irq_entry(regs);
 
-       check_stack_overflow();
-
        /*
         * Query the platform PIC for the interrupt & ack it.
         *
@@ -667,6 +665,8 @@ void do_IRQ(struct pt_regs *regs)
        irqtp = hardirq_ctx[raw_smp_processor_id()];
        sirqtp = softirq_ctx[raw_smp_processor_id()];
 
+       check_stack_overflow();
+
        /* Already there ? */
        if (unlikely(curtp == irqtp || curtp == sirqtp)) {
                __do_irq(regs);
index 1bf6aae..facc029 100644 (file)
@@ -87,7 +87,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE)
        subf    r8,r6,r4                /* compute length */
        add     r8,r8,r5                /* ensure we get enough */
        lwz     r9,DCACHEL1LOGBLOCKSIZE(r10)    /* Get log-2 of cache block size */
-       srw.    r8,r8,r9                /* compute line count */
+       srd.    r8,r8,r9                /* compute line count */
        beqlr                           /* nothing to do? */
        mtctr   r8
 1:     dcbst   0,r6
@@ -103,7 +103,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE)
        subf    r8,r6,r4                /* compute length */
        add     r8,r8,r5
        lwz     r9,ICACHEL1LOGBLOCKSIZE(r10)    /* Get log-2 of Icache block size */
-       srw.    r8,r8,r9                /* compute line count */
+       srd.    r8,r8,r9                /* compute line count */
        beqlr                           /* nothing to do? */
        mtctr   r8
 2:     icbi    0,r6
index a5c5940..6a3dde9 100644 (file)
@@ -134,32 +134,33 @@ ssize_t cpu_show_meltdown(struct device *dev, struct device_attribute *attr, cha
 
        thread_priv = security_ftr_enabled(SEC_FTR_L1D_THREAD_PRIV);
 
-       if (rfi_flush || thread_priv) {
+       if (rfi_flush) {
                struct seq_buf s;
                seq_buf_init(&s, buf, PAGE_SIZE - 1);
 
-               seq_buf_printf(&s, "Mitigation: ");
-
-               if (rfi_flush)
-                       seq_buf_printf(&s, "RFI Flush");
-
-               if (rfi_flush && thread_priv)
-                       seq_buf_printf(&s, ", ");
-
+               seq_buf_printf(&s, "Mitigation: RFI Flush");
                if (thread_priv)
-                       seq_buf_printf(&s, "L1D private per thread");
+                       seq_buf_printf(&s, "L1D private per thread");
 
                seq_buf_printf(&s, "\n");
 
                return s.len;
        }
 
+       if (thread_priv)
+               return sprintf(buf, "Vulnerable: L1D private per thread\n");
+
        if (!security_ftr_enabled(SEC_FTR_L1D_FLUSH_HV) &&
            !security_ftr_enabled(SEC_FTR_L1D_FLUSH_PR))
                return sprintf(buf, "Not affected\n");
 
        return sprintf(buf, "Vulnerable\n");
 }
+
+ssize_t cpu_show_l1tf(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       return cpu_show_meltdown(dev, attr, buf);
+}
 #endif
 
 ssize_t cpu_show_spectre_v1(struct device *dev, struct device_attribute *attr, char *buf)
index 7707990..5449e76 100644 (file)
@@ -235,7 +235,7 @@ static u64 scan_dispatch_log(u64 stop_tb)
  * Accumulate stolen time by scanning the dispatch trace log.
  * Called on entry from user mode.
  */
-void accumulate_stolen_time(void)
+void notrace accumulate_stolen_time(void)
 {
        u64 sst, ust;
        unsigned long save_irq_soft_mask = irq_soft_mask_return();
@@ -929,6 +929,7 @@ void update_vsyscall(struct timekeeper *tk)
        vdso_data->wtom_clock_nsec = tk->wall_to_monotonic.tv_nsec;
        vdso_data->stamp_xtime = xt;
        vdso_data->stamp_sec_fraction = frac_sec;
+       vdso_data->hrtimer_res = hrtimer_resolution;
        smp_wmb();
        ++(vdso_data->tb_update_count);
 }
index afd516b..49eecd2 100644 (file)
@@ -160,12 +160,15 @@ V_FUNCTION_BEGIN(__kernel_clock_getres)
        cror    cr0*4+eq,cr0*4+eq,cr1*4+eq
        bne     cr0,99f
 
+       mflr    r12
+  .cfi_register lr,r12
+       bl      __get_datapage@local    /* get data page */
+       lwz     r5, CLOCK_HRTIMER_RES(r3)
+       mtlr    r12
        li      r3,0
        cmpli   cr0,r4,0
        crclr   cr0*4+so
        beqlr
-       lis     r5,CLOCK_REALTIME_RES@h
-       ori     r5,r5,CLOCK_REALTIME_RES@l
        stw     r3,TSPC32_TV_SEC(r4)
        stw     r5,TSPC32_TV_NSEC(r4)
        blr
index 69c5af2..228a4a2 100644 (file)
@@ -39,7 +39,7 @@ V_FUNCTION_BEGIN(__kernel_sync_dicache)
        subf    r8,r6,r4                /* compute length */
        add     r8,r8,r5                /* ensure we get enough */
        lwz     r9,CFG_DCACHE_LOGBLOCKSZ(r10)
-       srw.    r8,r8,r9                /* compute line count */
+       srd.    r8,r8,r9                /* compute line count */
        crclr   cr0*4+so
        beqlr                           /* nothing to do? */
        mtctr   r8
@@ -56,7 +56,7 @@ V_FUNCTION_BEGIN(__kernel_sync_dicache)
        subf    r8,r6,r4                /* compute length */
        add     r8,r8,r5
        lwz     r9,CFG_ICACHE_LOGBLOCKSZ(r10)
-       srw.    r8,r8,r9                /* compute line count */
+       srd.    r8,r8,r9                /* compute line count */
        crclr   cr0*4+so
        beqlr                           /* nothing to do? */
        mtctr   r8
index 1f324c2..020e90d 100644 (file)
@@ -190,12 +190,15 @@ V_FUNCTION_BEGIN(__kernel_clock_getres)
        cror    cr0*4+eq,cr0*4+eq,cr1*4+eq
        bne     cr0,99f
 
+       mflr    r12
+  .cfi_register lr,r12
+       bl      V_LOCAL_FUNC(__get_datapage)
+       lwz     r5, CLOCK_HRTIMER_RES(r3)
+       mtlr    r12
        li      r3,0
        cmpldi  cr0,r4,0
        crclr   cr0*4+so
        beqlr
-       lis     r5,CLOCK_REALTIME_RES@h
-       ori     r5,r5,CLOCK_REALTIME_RES@l
        std     r3,TSPC64_TV_SEC(r4)
        std     r5,TSPC64_TV_NSEC(r4)
        blr
index b1007e9..8894c8f 100644 (file)
@@ -296,10 +296,18 @@ int htab_bolt_mapping(unsigned long vstart, unsigned long vend,
                ret = mmu_hash_ops.hpte_insert(hpteg, vpn, paddr, tprot,
                                               HPTE_V_BOLTED, psize, psize,
                                               ssize);
-
+               if (ret == -1) {
+                       /* Try to remove a non bolted entry */
+                       ret = mmu_hash_ops.hpte_remove(hpteg);
+                       if (ret != -1)
+                               ret = mmu_hash_ops.hpte_insert(hpteg, vpn, paddr, tprot,
+                                                              HPTE_V_BOLTED, psize, psize,
+                                                              ssize);
+               }
                if (ret < 0)
                        break;
 
+               cond_resched();
 #ifdef CONFIG_DEBUG_PAGEALLOC
                if (debug_pagealloc_enabled() &&
                        (paddr >> PAGE_SHIFT) < linear_map_hash_count)
index 25427a4..502ebcc 100644 (file)
@@ -425,6 +425,10 @@ static struct bus_type cmm_subsys = {
        .dev_name = "cmm",
 };
 
+static void cmm_release_device(struct device *dev)
+{
+}
+
 /**
  * cmm_sysfs_register - Register with sysfs
  *
@@ -440,6 +444,7 @@ static int cmm_sysfs_register(struct device *dev)
 
        dev->id = 0;
        dev->bus = &cmm_subsys;
+       dev->release = cmm_release_device;
 
        if ((rc = device_register(dev)))
                goto subsys_unregister;
index f3af53a..3c939b9 100644 (file)
@@ -968,6 +968,15 @@ static int xive_irq_alloc_data(unsigned int virq, irq_hw_number_t hw)
        xd->target = XIVE_INVALID_TARGET;
        irq_set_handler_data(virq, xd);
 
+       /*
+        * Turn OFF by default the interrupt being mapped. A side
+        * effect of this check is the mapping the ESB page of the
+        * interrupt in the Linux address space. This prevents page
+        * fault issues in the crash handler which masks all
+        * interrupts.
+        */
+       xive_esb_read(xd, XIVE_ESB_SET_PQ_01);
+
        return 0;
 }
 
index 575db3b..e3ebf64 100644 (file)
@@ -359,20 +359,28 @@ static int xive_spapr_populate_irq_data(u32 hw_irq, struct xive_irq_data *data)
        data->esb_shift = esb_shift;
        data->trig_page = trig_page;
 
+       data->hw_irq = hw_irq;
+
        /*
         * No chip-id for the sPAPR backend. This has an impact how we
         * pick a target. See xive_pick_irq_target().
         */
        data->src_chip = XIVE_INVALID_CHIP_ID;
 
+       /*
+        * When the H_INT_ESB flag is set, the H_INT_ESB hcall should
+        * be used for interrupt management. Skip the remapping of the
+        * ESB pages which are not available.
+        */
+       if (data->flags & XIVE_IRQ_FLAG_H_INT_ESB)
+               return 0;
+
        data->eoi_mmio = ioremap(data->eoi_page, 1u << data->esb_shift);
        if (!data->eoi_mmio) {
                pr_err("Failed to map EOI page for irq 0x%x\n", hw_irq);
                return -ENOMEM;
        }
 
-       data->hw_irq = hw_irq;
-
        /* Full function page supports trigger */
        if (flags & XIVE_SRC_TRIGGER) {
                data->trig_mmio = data->eoi_mmio;
index ec2d5c8..d6c16e7 100755 (executable)
@@ -23,7 +23,7 @@ objdump="$1"
 vmlinux="$2"
 
 bad_relocs=$(
-"$objdump" -R "$vmlinux" |
+$objdump -R "$vmlinux" |
        # Only look at relocation lines.
        grep -E '\<R_' |
        # These relocations are okay
index 1e972df..7711475 100755 (executable)
@@ -18,14 +18,14 @@ vmlinux="$2"
 #__end_interrupts should be located within the first 64K
 
 end_intr=0x$(
-"$objdump" -R "$vmlinux" -d --start-address=0xc000000000000000         \
+$objdump -R "$vmlinux" -d --start-address=0xc000000000000000           \
                 --stop-address=0xc000000000010000 |
 grep '\<__end_interrupts>:' |
 awk '{print $1}'
 )
 
 BRANCHES=$(
-"$objdump" -R "$vmlinux" -D --start-address=0xc000000000000000         \
+$objdump -R "$vmlinux" -D --start-address=0xc000000000000000           \
                --stop-address=${end_intr} |
 grep -e "^c[0-9a-f]*:[[:space:]]*\([0-9a-f][0-9a-f][[:space:]]\)\{4\}[[:space:]]*b" |
 grep -v '\<__start_initialization_multiplatform>' |
index 9ba44e1..365e711 100644 (file)
@@ -1,8 +1,8 @@
 # SPDX-License-Identifier: GPL-2.0
 # Makefile for xmon
 
-# Disable clang warning for using setjmp without setjmp.h header
-subdir-ccflags-y := $(call cc-disable-warning, builtin-requires-header)
+# Avoid clang warnings around longjmp/setjmp declarations
+subdir-ccflags-y := -ffreestanding
 
 subdir-ccflags-$(CONFIG_PPC_WERROR) += -Werror
 
index 5ee7337..67838df 100644 (file)
@@ -56,7 +56,12 @@ static inline p4d_t *p4d_alloc_one(struct mm_struct *mm, unsigned long address)
                crst_table_init(table, _REGION2_ENTRY_EMPTY);
        return (p4d_t *) table;
 }
-#define p4d_free(mm, p4d) crst_table_free(mm, (unsigned long *) p4d)
+
+static inline void p4d_free(struct mm_struct *mm, p4d_t *p4d)
+{
+       if (!mm_p4d_folded(mm))
+               crst_table_free(mm, (unsigned long *) p4d);
+}
 
 static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long address)
 {
@@ -65,7 +70,12 @@ static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long address)
                crst_table_init(table, _REGION3_ENTRY_EMPTY);
        return (pud_t *) table;
 }
-#define pud_free(mm, pud) crst_table_free(mm, (unsigned long *) pud)
+
+static inline void pud_free(struct mm_struct *mm, pud_t *pud)
+{
+       if (!mm_pud_folded(mm))
+               crst_table_free(mm, (unsigned long *) pud);
+}
 
 static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long vmaddr)
 {
@@ -83,6 +93,8 @@ static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long vmaddr)
 
 static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd)
 {
+       if (mm_pmd_folded(mm))
+               return;
        pgtable_pmd_page_dtor(virt_to_page(pmd));
        crst_table_free(mm, (unsigned long *) pmd);
 }
index de05466..0a326da 100644 (file)
@@ -1150,8 +1150,6 @@ void gmap_pmdp_idte_global(struct mm_struct *mm, unsigned long vmaddr);
 static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
                              pte_t *ptep, pte_t entry)
 {
-       if (!MACHINE_HAS_NX)
-               pte_val(entry) &= ~_PAGE_NOEXEC;
        if (pte_present(entry))
                pte_val(entry) &= ~_PAGE_UNUSED;
        if (mm_has_pgste(mm))
@@ -1168,6 +1166,8 @@ static inline pte_t mk_pte_phys(unsigned long physpage, pgprot_t pgprot)
 {
        pte_t __pte;
        pte_val(__pte) = physpage + pgprot_val(pgprot);
+       if (!MACHINE_HAS_NX)
+               pte_val(__pte) &= ~_PAGE_NOEXEC;
        return pte_mkyoung(__pte);
 }
 
index 64539c2..2dc9eb4 100644 (file)
@@ -10,8 +10,9 @@
 #ifndef _ASM_S390_TIMEX_H
 #define _ASM_S390_TIMEX_H
 
-#include <asm/lowcore.h>
+#include <linux/preempt.h>
 #include <linux/time64.h>
+#include <asm/lowcore.h>
 
 /* The value of the TOD clock for 1.1.1970. */
 #define TOD_UNIX_EPOCH 0x7d91048bca000000ULL
@@ -186,15 +187,18 @@ extern unsigned char tod_clock_base[16] __aligned(8);
 /**
  * get_clock_monotonic - returns current time in clock rate units
  *
- * The caller must ensure that preemption is disabled.
  * The clock and tod_clock_base get changed via stop_machine.
- * Therefore preemption must be disabled when calling this
- * function, otherwise the returned value is not guaranteed to
- * be monotonic.
+ * Therefore preemption must be disabled, otherwise the returned
+ * value is not guaranteed to be monotonic.
  */
 static inline unsigned long long get_tod_clock_monotonic(void)
 {
-       return get_tod_clock() - *(unsigned long long *) &tod_clock_base[1];
+       unsigned long long tod;
+
+       preempt_disable_notrace();
+       tod = get_tod_clock() - *(unsigned long long *) &tod_clock_base[1];
+       preempt_enable_notrace();
+       return tod;
 }
 
 /**
index b2c68fb..41925f2 100644 (file)
@@ -462,10 +462,11 @@ static int print_insn(char *buffer, unsigned char *code, unsigned long addr)
                                ptr += sprintf(ptr, "%%c%i", value);
                        else if (operand->flags & OPERAND_VR)
                                ptr += sprintf(ptr, "%%v%i", value);
-                       else if (operand->flags & OPERAND_PCREL)
-                               ptr += sprintf(ptr, "%lx", (signed int) value
-                                                                     + addr);
-                       else if (operand->flags & OPERAND_SIGNED)
+                       else if (operand->flags & OPERAND_PCREL) {
+                               void *pcrel = (void *)((int)value + addr);
+
+                               ptr += sprintf(ptr, "%px", pcrel);
+                       } else if (operand->flags & OPERAND_SIGNED)
                                ptr += sprintf(ptr, "%i", value);
                        else
                                ptr += sprintf(ptr, "%u", value);
@@ -537,7 +538,7 @@ void show_code(struct pt_regs *regs)
                else
                        *ptr++ = ' ';
                addr = regs->psw.addr + start - 32;
-               ptr += sprintf(ptr, "%016lx: ", addr);
+               ptr += sprintf(ptr, "%px: ", (void *)addr);
                if (start + opsize >= end)
                        break;
                for (i = 0; i < opsize; i++)
@@ -565,7 +566,7 @@ void print_fn_code(unsigned char *code, unsigned long len)
                opsize = insn_length(*code);
                if (opsize > len)
                        break;
-               ptr += sprintf(ptr, "%p: ", code);
+               ptr += sprintf(ptr, "%px: ", code);
                for (i = 0; i < opsize; i++)
                        ptr += sprintf(ptr, "%02x", code[i]);
                *ptr++ = '\t';
index df92c2a..5c3fd90 100644 (file)
@@ -193,7 +193,7 @@ static int realloc_sampling_buffer(struct sf_buffer *sfb,
                                   unsigned long num_sdb, gfp_t gfp_flags)
 {
        int i, rc;
-       unsigned long *new, *tail;
+       unsigned long *new, *tail, *tail_prev = NULL;
 
        if (!sfb->sdbt || !sfb->tail)
                return -EINVAL;
@@ -232,6 +232,7 @@ static int realloc_sampling_buffer(struct sf_buffer *sfb,
                        sfb->num_sdbt++;
                        /* Link current page to tail of chain */
                        *tail = (unsigned long)(void *) new + 1;
+                       tail_prev = tail;
                        tail = new;
                }
 
@@ -241,10 +242,22 @@ static int realloc_sampling_buffer(struct sf_buffer *sfb,
                 * issue, a new realloc call (if required) might succeed.
                 */
                rc = alloc_sample_data_block(tail, gfp_flags);
-               if (rc)
+               if (rc) {
+                       /* Undo last SDBT. An SDBT with no SDB at its first
+                        * entry but with an SDBT entry instead can not be
+                        * handled by the interrupt handler code.
+                        * Avoid this situation.
+                        */
+                       if (tail_prev) {
+                               sfb->num_sdbt--;
+                               free_page((unsigned long) new);
+                               tail = tail_prev;
+                       }
                        break;
+               }
                sfb->num_sdb++;
                tail++;
+               tail_prev = new = NULL; /* Allocated at least one SBD */
        }
 
        /* Link sampling buffer to its origin */
index da02f40..df2413f 100644 (file)
@@ -261,9 +261,12 @@ static void pcpu_prepare_secondary(struct pcpu *pcpu, int cpu)
        lc->spinlock_index = 0;
        lc->percpu_offset = __per_cpu_offset[cpu];
        lc->kernel_asce = S390_lowcore.kernel_asce;
+       lc->user_asce = S390_lowcore.kernel_asce;
        lc->machine_flags = S390_lowcore.machine_flags;
        lc->user_timer = lc->system_timer = lc->steal_timer = 0;
        __ctl_store(lc->cregs_save_area, 0, 15);
+       lc->cregs_save_area[1] = lc->kernel_asce;
+       lc->cregs_save_area[7] = lc->vdso_asce;
        save_access_regs((unsigned int *) lc->access_regs_save_area);
        memcpy(lc->stfle_fac_list, S390_lowcore.stfle_fac_list,
               sizeof(lc->stfle_fac_list));
@@ -810,6 +813,8 @@ static void smp_start_secondary(void *cpuvoid)
        restore_access_regs(S390_lowcore.access_regs_save_area);
        __ctl_load(S390_lowcore.cregs_save_area, 0, 15);
        __load_psw_mask(PSW_KERNEL_BITS | PSW_MASK_DAT);
+       set_cpu_flag(CIF_ASCE_PRIMARY);
+       set_cpu_flag(CIF_ASCE_SECONDARY);
        cpu_init();
        preempt_disable();
        init_cpu_timer();
index 96f0246..82b6320 100644 (file)
@@ -134,7 +134,7 @@ enum {
        GPIO_FN_EX_WAIT1, GPIO_FN_SD1_DAT0_A, GPIO_FN_DREQ2, GPIO_FN_CAN1_TX_C,
                GPIO_FN_ET0_LINK_C, GPIO_FN_ET0_ETXD5_A,
        GPIO_FN_EX_WAIT0, GPIO_FN_TCLK1_B,
-       GPIO_FN_RD_WR, GPIO_FN_TCLK0,
+       GPIO_FN_RD_WR, GPIO_FN_TCLK0, GPIO_FN_CAN_CLK_B, GPIO_FN_ET0_ETXD4,
        GPIO_FN_EX_CS5, GPIO_FN_SD1_CMD_A, GPIO_FN_ATADIR, GPIO_FN_QSSL_B,
                GPIO_FN_ET0_ETXD3_A,
        GPIO_FN_EX_CS4, GPIO_FN_SD1_WP_A, GPIO_FN_ATAWR, GPIO_FN_QMI_QIO1_B,
index a7adb2b..6b8ad6f 100644 (file)
@@ -2,6 +2,8 @@
 #ifndef _ASM_X86_CRASH_H
 #define _ASM_X86_CRASH_H
 
+struct kimage;
+
 int crash_load_segments(struct kimage *image);
 int crash_copy_backup_region(struct kimage *image);
 int crash_setup_memmap_entries(struct kimage *image,
index 6390bd8..5e12b23 100644 (file)
@@ -159,7 +159,7 @@ extern pte_t *kmap_pte;
 extern pte_t *pkmap_page_table;
 
 void __native_set_fixmap(enum fixed_addresses idx, pte_t pte);
-void native_set_fixmap(enum fixed_addresses idx,
+void native_set_fixmap(unsigned /* enum fixed_addresses */ idx,
                       phys_addr_t phys, pgprot_t flags);
 
 #ifndef CONFIG_PARAVIRT
index e046a40..90eb70d 100644 (file)
  * To keep the naming coherent, re-define SYSCALL_DEFINE0 to create an alias
  * named __ia32_sys_*()
  */
-#define SYSCALL_DEFINE0(sname)                                 \
-       SYSCALL_METADATA(_##sname, 0);                          \
-       asmlinkage long __x64_sys_##sname(void);                \
-       ALLOW_ERROR_INJECTION(__x64_sys_##sname, ERRNO);        \
-       SYSCALL_ALIAS(__ia32_sys_##sname, __x64_sys_##sname);   \
-       asmlinkage long __x64_sys_##sname(void)
+
+#define SYSCALL_DEFINE0(sname)                                         \
+       SYSCALL_METADATA(_##sname, 0);                                  \
+       asmlinkage long __x64_sys_##sname(const struct pt_regs *__unused);\
+       ALLOW_ERROR_INJECTION(__x64_sys_##sname, ERRNO);                \
+       SYSCALL_ALIAS(__ia32_sys_##sname, __x64_sys_##sname);           \
+       asmlinkage long __x64_sys_##sname(const struct pt_regs *__unused)
 
 #define COND_SYSCALL(name)                                             \
        cond_syscall(__x64_sys_##name);                                 \
  * macros to work correctly.
  */
 #ifndef SYSCALL_DEFINE0
-#define SYSCALL_DEFINE0(sname)                                 \
-       SYSCALL_METADATA(_##sname, 0);                          \
-       asmlinkage long __x64_sys_##sname(void);                \
-       ALLOW_ERROR_INJECTION(__x64_sys_##sname, ERRNO);        \
-       asmlinkage long __x64_sys_##sname(void)
+#define SYSCALL_DEFINE0(sname)                                         \
+       SYSCALL_METADATA(_##sname, 0);                                  \
+       asmlinkage long __x64_sys_##sname(const struct pt_regs *__unused);\
+       ALLOW_ERROR_INJECTION(__x64_sys_##sname, ERRNO);                \
+       asmlinkage long __x64_sys_##sname(const struct pt_regs *__unused)
 #endif
 
 #ifndef COND_SYSCALL
index ab22ede..fa3b85b 100644 (file)
@@ -1724,9 +1724,10 @@ static bool io_apic_level_ack_pending(struct mp_chip_data *data)
 
 static inline bool ioapic_irqd_mask(struct irq_data *data)
 {
-       /* If we are moving the irq we need to mask it */
+       /* If we are moving the IRQ we need to mask it */
        if (unlikely(irqd_is_setaffinity_pending(data))) {
-               mask_ioapic_irq(data);
+               if (!irqd_irq_masked(data))
+                       mask_ioapic_irq(data);
                return true;
        }
        return false;
@@ -1763,7 +1764,9 @@ static inline void ioapic_irqd_unmask(struct irq_data *data, bool masked)
                 */
                if (!io_apic_level_ack_pending(data->chip_data))
                        irq_move_masked_irq(data);
-               unmask_ioapic_irq(data);
+               /* If the IRQ is masked in the core, leave it: */
+               if (!irqd_irq_masked(data))
+                       unmask_ioapic_irq(data);
        }
 }
 #else
index fee118b..1f69b12 100644 (file)
@@ -812,8 +812,8 @@ static int mce_no_way_out(struct mce *m, char **msg, unsigned long *validp,
                if (quirk_no_way_out)
                        quirk_no_way_out(i, m, regs);
 
+               m->bank = i;
                if (mce_severity(m, mca_cfg.tolerant, &tmp, true) >= MCE_PANIC_SEVERITY) {
-                       m->bank = i;
                        mce_read_aux(m, i);
                        *msg = tmp;
                        return 1;
@@ -1631,36 +1631,6 @@ static int __mcheck_cpu_apply_quirks(struct cpuinfo_x86 *c)
                if (c->x86 == 0x15 && c->x86_model <= 0xf)
                        mce_flags.overflow_recov = 1;
 
-               /*
-                * Turn off MC4_MISC thresholding banks on those models since
-                * they're not supported there.
-                */
-               if (c->x86 == 0x15 &&
-                   (c->x86_model >= 0x10 && c->x86_model <= 0x1f)) {
-                       int i;
-                       u64 hwcr;
-                       bool need_toggle;
-                       u32 msrs[] = {
-                               0x00000413, /* MC4_MISC0 */
-                               0xc0000408, /* MC4_MISC1 */
-                       };
-
-                       rdmsrl(MSR_K7_HWCR, hwcr);
-
-                       /* McStatusWrEn has to be set */
-                       need_toggle = !(hwcr & BIT(18));
-
-                       if (need_toggle)
-                               wrmsrl(MSR_K7_HWCR, hwcr | BIT(18));
-
-                       /* Clear CntP bit safely */
-                       for (i = 0; i < ARRAY_SIZE(msrs); i++)
-                               msr_clear_bit(msrs[i], 62);
-
-                       /* restore old settings */
-                       if (need_toggle)
-                               wrmsrl(MSR_K7_HWCR, hwcr);
-               }
        }
 
        if (c->x86_vendor == X86_VENDOR_INTEL) {
index 9f915a8..da0b696 100644 (file)
@@ -228,10 +228,10 @@ static void smca_configure(unsigned int bank, unsigned int cpu)
        }
 
        /* Return early if this bank was already initialized. */
-       if (smca_banks[bank].hwid)
+       if (smca_banks[bank].hwid && smca_banks[bank].hwid->hwid_mcatype != 0)
                return;
 
-       if (rdmsr_safe_on_cpu(cpu, MSR_AMD64_SMCA_MCx_IPID(bank), &low, &high)) {
+       if (rdmsr_safe(MSR_AMD64_SMCA_MCx_IPID(bank), &low, &high)) {
                pr_warn("Failed to read MCA_IPID for bank %d\n", bank);
                return;
        }
@@ -545,6 +545,40 @@ out:
        return offset;
 }
 
+/*
+ * Turn off MC4_MISC thresholding banks on all family 0x15 models since
+ * they're not supported there.
+ */
+void disable_err_thresholding(struct cpuinfo_x86 *c)
+{
+       int i;
+       u64 hwcr;
+       bool need_toggle;
+       u32 msrs[] = {
+               0x00000413, /* MC4_MISC0 */
+               0xc0000408, /* MC4_MISC1 */
+       };
+
+       if (c->x86 != 0x15)
+               return;
+
+       rdmsrl(MSR_K7_HWCR, hwcr);
+
+       /* McStatusWrEn has to be set */
+       need_toggle = !(hwcr & BIT(18));
+
+       if (need_toggle)
+               wrmsrl(MSR_K7_HWCR, hwcr | BIT(18));
+
+       /* Clear CntP bit safely */
+       for (i = 0; i < ARRAY_SIZE(msrs); i++)
+               msr_clear_bit(msrs[i], 62);
+
+       /* restore old settings */
+       if (need_toggle)
+               wrmsrl(MSR_K7_HWCR, hwcr);
+}
+
 /* cpu init entry point, called from mce.c with preempt off */
 void mce_amd_feature_init(struct cpuinfo_x86 *c)
 {
@@ -552,6 +586,8 @@ void mce_amd_feature_init(struct cpuinfo_x86 *c)
        unsigned int bank, block, cpu = smp_processor_id();
        int offset = -1;
 
+       disable_err_thresholding(c);
+
        for (bank = 0; bank < mca_cfg.banks; ++bank) {
                if (mce_flags.smca)
                        smca_configure(bank, cpu);
index ee229ce..ec6a07b 100644 (file)
@@ -185,7 +185,7 @@ static void therm_throt_process(bool new_event, int event, int level)
        /* if we just entered the thermal event */
        if (new_event) {
                if (event == THERMAL_THROTTLING_EVENT)
-                       pr_crit("CPU%d: %s temperature above threshold, cpu clock throttled (total events = %lu)\n",
+                       pr_warn("CPU%d: %s temperature above threshold, cpu clock throttled (total events = %lu)\n",
                                this_cpu,
                                level == CORE_LEVEL ? "Core" : "Package",
                                state->count);
index e0b8593..0a0e911 100644 (file)
@@ -333,7 +333,7 @@ AVXcode: 1
 06: CLTS
 07: SYSRET (o64)
 08: INVD
-09: WBINVD
+09: WBINVD | WBNOINVD (F3)
 0a:
 0b: UD2 (1B)
 0c:
@@ -364,7 +364,7 @@ AVXcode: 1
 # a ModR/M byte.
 1a: BNDCL Gv,Ev (F3) | BNDCU Gv,Ev (F2) | BNDMOV Gv,Ev (66) | BNDLDX Gv,Ev
 1b: BNDCN Gv,Ev (F2) | BNDMOV Ev,Gv (66) | BNDMK Gv,Ev (F3) | BNDSTX Ev,Gv
-1c:
+1c: Grp20 (1A),(1C)
 1d:
 1e:
 1f: NOP Ev
@@ -792,6 +792,8 @@ f3: Grp17 (1A)
 f5: BZHI Gy,Ey,By (v) | PEXT Gy,By,Ey (F3),(v) | PDEP Gy,By,Ey (F2),(v)
 f6: ADCX Gy,Ey (66) | ADOX Gy,Ey (F3) | MULX By,Gy,rDX,Ey (F2),(v)
 f7: BEXTR Gy,Ey,By (v) | SHLX Gy,Ey,By (66),(v) | SARX Gy,Ey,By (F3),(v) | SHRX Gy,Ey,By (F2),(v)
+f8: MOVDIR64B Gv,Mdqq (66) | ENQCMD Gv,Mdqq (F2) | ENQCMDS Gv,Mdqq (F3)
+f9: MOVDIRI My,Gy
 EndTable
 
 Table: 3-byte opcode 2 (0x0f 0x3a)
@@ -943,9 +945,9 @@ GrpTable: Grp6
 EndTable
 
 GrpTable: Grp7
-0: SGDT Ms | VMCALL (001),(11B) | VMLAUNCH (010),(11B) | VMRESUME (011),(11B) | VMXOFF (100),(11B)
-1: SIDT Ms | MONITOR (000),(11B) | MWAIT (001),(11B) | CLAC (010),(11B) | STAC (011),(11B)
-2: LGDT Ms | XGETBV (000),(11B) | XSETBV (001),(11B) | VMFUNC (100),(11B) | XEND (101)(11B) | XTEST (110)(11B)
+0: SGDT Ms | VMCALL (001),(11B) | VMLAUNCH (010),(11B) | VMRESUME (011),(11B) | VMXOFF (100),(11B) | PCONFIG (101),(11B) | ENCLV (000),(11B)
+1: SIDT Ms | MONITOR (000),(11B) | MWAIT (001),(11B) | CLAC (010),(11B) | STAC (011),(11B) | ENCLS (111),(11B)
+2: LGDT Ms | XGETBV (000),(11B) | XSETBV (001),(11B) | VMFUNC (100),(11B) | XEND (101)(11B) | XTEST (110)(11B) | ENCLU (111),(11B)
 3: LIDT Ms
 4: SMSW Mw/Rv
 5: rdpkru (110),(11B) | wrpkru (111),(11B)
@@ -1020,7 +1022,7 @@ GrpTable: Grp15
 3: vstmxcsr Md (v1) | WRGSBASE Ry (F3),(11B)
 4: XSAVE | ptwrite Ey (F3),(11B)
 5: XRSTOR | lfence (11B)
-6: XSAVEOPT | clwb (66) | mfence (11B)
+6: XSAVEOPT | clwb (66) | mfence (11B) | TPAUSE Rd (66),(11B) | UMONITOR Rv (F3),(11B) | UMWAIT Rd (F2),(11B)
 7: clflush | clflushopt (66) | sfence (11B)
 EndTable
 
@@ -1051,6 +1053,10 @@ GrpTable: Grp19
 6: vscatterpf1qps/d Wx (66),(ev)
 EndTable
 
+GrpTable: Grp20
+0: cldemote Mb
+EndTable
+
 # AMD's Prefetch Group
 GrpTable: GrpP
 0: PREFETCH
index 59274e2..bf52106 100644 (file)
@@ -660,8 +660,8 @@ void __native_set_fixmap(enum fixed_addresses idx, pte_t pte)
        fixmaps_set++;
 }
 
-void native_set_fixmap(enum fixed_addresses idx, phys_addr_t phys,
-                      pgprot_t flags)
+void native_set_fixmap(unsigned /* enum fixed_addresses */ idx,
+                      phys_addr_t phys, pgprot_t flags)
 {
        /* Sanitize 'prot' against any unsupported bits: */
        pgprot_val(flags) &= __default_kernel_pte_mask;
index 59153d0..b43f036 100644 (file)
@@ -216,6 +216,8 @@ static int check_tlb_entry(unsigned w, unsigned e, bool dtlb)
        unsigned tlbidx = w | (e << PAGE_SHIFT);
        unsigned r0 = dtlb ?
                read_dtlb_virtual(tlbidx) : read_itlb_virtual(tlbidx);
+       unsigned r1 = dtlb ?
+               read_dtlb_translation(tlbidx) : read_itlb_translation(tlbidx);
        unsigned vpn = (r0 & PAGE_MASK) | (e << PAGE_SHIFT);
        unsigned pte = get_pte_for_vaddr(vpn);
        unsigned mm_asid = (get_rasid_register() >> 8) & ASID_MASK;
@@ -231,8 +233,6 @@ static int check_tlb_entry(unsigned w, unsigned e, bool dtlb)
        }
 
        if (tlb_asid == mm_asid) {
-               unsigned r1 = dtlb ? read_dtlb_translation(tlbidx) :
-                       read_itlb_translation(tlbidx);
                if ((pte ^ r1) & PAGE_MASK) {
                        pr_err("%cTLB: way: %u, entry: %u, mapping: %08x->%08x, PTE: %08x\n",
                                        dtlb ? 'D' : 'I', w, e, r0, r1, pte);
index 1dced51..2776ee6 100644 (file)
@@ -774,7 +774,7 @@ static struct request *attempt_merge(struct request_queue *q,
 
        req->__data_len += blk_rq_bytes(next);
 
-       if (req_op(req) != REQ_OP_DISCARD)
+       if (!blk_discard_mergable(req))
                elv_merge_requests(q, req, next);
 
        /*
index 0b7297a..5006a0d 100644 (file)
@@ -151,20 +151,25 @@ static ssize_t blk_mq_hw_sysfs_nr_reserved_tags_show(struct blk_mq_hw_ctx *hctx,
 
 static ssize_t blk_mq_hw_sysfs_cpus_show(struct blk_mq_hw_ctx *hctx, char *page)
 {
+       const size_t size = PAGE_SIZE - 1;
        unsigned int i, first = 1;
-       ssize_t ret = 0;
+       int ret = 0, pos = 0;
 
        for_each_cpu(i, hctx->cpumask) {
                if (first)
-                       ret += sprintf(ret + page, "%u", i);
+                       ret = snprintf(pos + page, size - pos, "%u", i);
                else
-                       ret += sprintf(ret + page, ", %u", i);
+                       ret = snprintf(pos + page, size - pos, ", %u", i);
+
+               if (ret >= size - pos)
+                       break;
 
                first = 0;
+               pos += ret;
        }
 
-       ret += sprintf(ret + page, "\n");
-       return ret;
+       ret = snprintf(pos + page, size + 1 - pos, "\n");
+       return pos + ret;
 }
 
 static struct attribute *default_ctx_attrs[] = {
index d2e29a1..92a1468 100644 (file)
@@ -166,7 +166,7 @@ int acpi_bus_get_private_data(acpi_handle handle, void **data)
 {
        acpi_status status;
 
-       if (!*data)
+       if (!data)
                return -EINVAL;
 
        status = acpi_get_data(handle, acpi_bus_private_data_handler, data);
index a19ff39..870eb5c 100644 (file)
@@ -91,6 +91,17 @@ static const struct dmi_system_id lid_blacklst[] = {
                        DMI_MATCH(DMI_BIOS_VERSION, "BYT70A.YNCHENG.WIN.007"),
                },
        },
+       {
+               /*
+                * Medion Akoya E2215T, notification of the LID device only
+                * happens on close, not on open and _LID always returns closed.
+                */
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "MEDION"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "E2215T MD60198"),
+               },
+               .driver_data = (void *)(long)ACPI_BUTTON_LID_INIT_OPEN,
+       },
        {}
 };
 
index 1806260..e0927c5 100644 (file)
@@ -1254,9 +1254,19 @@ static void acpi_dev_pm_detach(struct device *dev, bool power_off)
  */
 int acpi_dev_pm_attach(struct device *dev, bool power_on)
 {
+       /*
+        * Skip devices whose ACPI companions match the device IDs below,
+        * because they require special power management handling incompatible
+        * with the generic ACPI PM domain.
+        */
+       static const struct acpi_device_id special_pm_ids[] = {
+               {"PNP0C0B", }, /* Generic ACPI fan */
+               {"INT3404", }, /* Fan */
+               {}
+       };
        struct acpi_device *adev = ACPI_COMPANION(dev);
 
-       if (!adev)
+       if (!adev || !acpi_match_device_ids(adev, special_pm_ids))
                return 0;
 
        /*
index b48874b..2261703 100644 (file)
@@ -374,19 +374,21 @@ void *__ref acpi_os_map_memory(acpi_physical_address phys, acpi_size size)
 }
 EXPORT_SYMBOL_GPL(acpi_os_map_memory);
 
-static void acpi_os_drop_map_ref(struct acpi_ioremap *map)
+/* Must be called with mutex_lock(&acpi_ioremap_lock) */
+static unsigned long acpi_os_drop_map_ref(struct acpi_ioremap *map)
 {
-       if (!--map->refcount)
+       unsigned long refcount = --map->refcount;
+
+       if (!refcount)
                list_del_rcu(&map->list);
+       return refcount;
 }
 
 static void acpi_os_map_cleanup(struct acpi_ioremap *map)
 {
-       if (!map->refcount) {
-               synchronize_rcu_expedited();
-               acpi_unmap(map->phys, map->virt);
-               kfree(map);
-       }
+       synchronize_rcu_expedited();
+       acpi_unmap(map->phys, map->virt);
+       kfree(map);
 }
 
 /**
@@ -406,6 +408,7 @@ static void acpi_os_map_cleanup(struct acpi_ioremap *map)
 void __ref acpi_os_unmap_iomem(void __iomem *virt, acpi_size size)
 {
        struct acpi_ioremap *map;
+       unsigned long refcount;
 
        if (!acpi_permanent_mmap) {
                __acpi_unmap_table(virt, size);
@@ -419,10 +422,11 @@ void __ref acpi_os_unmap_iomem(void __iomem *virt, acpi_size size)
                WARN(true, PREFIX "%s: bad address %p\n", __func__, virt);
                return;
        }
-       acpi_os_drop_map_ref(map);
+       refcount = acpi_os_drop_map_ref(map);
        mutex_unlock(&acpi_ioremap_lock);
 
-       acpi_os_map_cleanup(map);
+       if (!refcount)
+               acpi_os_map_cleanup(map);
 }
 EXPORT_SYMBOL_GPL(acpi_os_unmap_iomem);
 
@@ -457,6 +461,7 @@ void acpi_os_unmap_generic_address(struct acpi_generic_address *gas)
 {
        u64 addr;
        struct acpi_ioremap *map;
+       unsigned long refcount;
 
        if (gas->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY)
                return;
@@ -472,10 +477,11 @@ void acpi_os_unmap_generic_address(struct acpi_generic_address *gas)
                mutex_unlock(&acpi_ioremap_lock);
                return;
        }
-       acpi_os_drop_map_ref(map);
+       refcount = acpi_os_drop_map_ref(map);
        mutex_unlock(&acpi_ioremap_lock);
 
-       acpi_os_map_cleanup(map);
+       if (!refcount)
+               acpi_os_map_cleanup(map);
 }
 EXPORT_SYMBOL(acpi_os_unmap_generic_address);
 
index 133fed8..85ee6c3 100644 (file)
@@ -6726,6 +6726,9 @@ void ata_host_detach(struct ata_host *host)
 {
        int i;
 
+       /* Ensure ata_port probe has completed */
+       async_synchronize_full();
+
        for (i = 0; i < host->n_ports; i++)
                ata_port_detach(host->ports[i]);
 
index 0813c65..b452359 100644 (file)
@@ -688,11 +688,9 @@ request_detach(struct drbd_device *device)
                        CS_VERBOSE | CS_ORDERED | CS_INHIBIT_MD_IO);
 }
 
-enum drbd_state_rv
-drbd_request_detach_interruptible(struct drbd_device *device)
+int drbd_request_detach_interruptible(struct drbd_device *device)
 {
-       enum drbd_state_rv rv;
-       int ret;
+       int ret, rv;
 
        drbd_suspend_io(device); /* so no-one is stuck in drbd_al_begin_io */
        wait_event_interruptible(device->state_wait,
index b2a390b..f87371e 100644 (file)
@@ -162,8 +162,7 @@ static inline int drbd_request_state(struct drbd_device *device,
 }
 
 /* for use in adm_detach() (drbd_adm_detach(), drbd_adm_down()) */
-enum drbd_state_rv
-drbd_request_detach_interruptible(struct drbd_device *device);
+int drbd_request_detach_interruptible(struct drbd_device *device);
 
 enum drbd_role conn_highest_role(struct drbd_connection *connection);
 enum drbd_role conn_highest_peer(struct drbd_connection *connection);
index 126c2c5..9cd231a 100644 (file)
@@ -416,18 +416,20 @@ out_free_page:
        return ret;
 }
 
-static int lo_discard(struct loop_device *lo, struct request *rq, loff_t pos)
+static int lo_fallocate(struct loop_device *lo, struct request *rq, loff_t pos,
+                       int mode)
 {
        /*
-        * We use punch hole to reclaim the free space used by the
-        * image a.k.a. discard. However we do not support discard if
-        * encryption is enabled, because it may give an attacker
-        * useful information.
+        * We use fallocate to manipulate the space mappings used by the image
+        * a.k.a. discard/zerorange. However we do not support this if
+        * encryption is enabled, because it may give an attacker useful
+        * information.
         */
        struct file *file = lo->lo_backing_file;
-       int mode = FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE;
        int ret;
 
+       mode |= FALLOC_FL_KEEP_SIZE;
+
        if ((!file->f_op->fallocate) || lo->lo_encrypt_key_size) {
                ret = -EOPNOTSUPP;
                goto out;
@@ -596,9 +598,17 @@ static int do_req_filebacked(struct loop_device *lo, struct request *rq)
        switch (req_op(rq)) {
        case REQ_OP_FLUSH:
                return lo_req_flush(lo, rq);
-       case REQ_OP_DISCARD:
        case REQ_OP_WRITE_ZEROES:
-               return lo_discard(lo, rq, pos);
+               /*
+                * If the caller doesn't want deallocation, call zeroout to
+                * write zeroes the range.  Otherwise, punch them out.
+                */
+               return lo_fallocate(lo, rq, pos,
+                       (rq->cmd_flags & REQ_NOUNMAP) ?
+                               FALLOC_FL_ZERO_RANGE :
+                               FALLOC_FL_PUNCH_HOLE);
+       case REQ_OP_DISCARD:
+               return lo_fallocate(lo, rq, pos, FALLOC_FL_PUNCH_HOLE);
        case REQ_OP_WRITE:
                if (lo->transfer)
                        return lo_write_transfer(lo, rq, pos);
index 996b1ef..b9d321b 100644 (file)
@@ -1247,10 +1247,10 @@ static int nbd_start_device_ioctl(struct nbd_device *nbd, struct block_device *b
        mutex_unlock(&nbd->config_lock);
        ret = wait_event_interruptible(config->recv_wq,
                                         atomic_read(&config->recv_threads) == 0);
-       if (ret) {
+       if (ret)
                sock_shutdown(nbd);
-               flush_workqueue(nbd->recv_workq);
-       }
+       flush_workqueue(nbd->recv_workq);
+
        mutex_lock(&nbd->config_lock);
        nbd_bdev_reset(bdev);
        /* user requested, ignore socket errors */
index 933268b..d394738 100644 (file)
@@ -996,6 +996,12 @@ static void cdrom_count_tracks(struct cdrom_device_info *cdi, tracktype *tracks)
        tracks->xa = 0;
        tracks->error = 0;
        cd_dbg(CD_COUNT_TRACKS, "entering cdrom_count_tracks\n");
+
+       if (!CDROM_CAN(CDC_PLAY_AUDIO)) {
+               tracks->error = CDS_NO_INFO;
+               return;
+       }
+
        /* Grab the TOC header so we can see how many tracks there are */
        ret = cdi->ops->audio_ioctl(cdi, CDROMREADTOCHDR, &header);
        if (ret) {
@@ -1162,7 +1168,8 @@ int cdrom_open(struct cdrom_device_info *cdi, struct block_device *bdev,
                ret = open_for_data(cdi);
                if (ret)
                        goto err;
-               cdrom_mmc3_profile(cdi);
+               if (CDROM_CAN(CDC_GENERIC_PACKET))
+                       cdrom_mmc3_profile(cdi);
                if (mode & FMODE_WRITE) {
                        ret = -EROFS;
                        if (cdrom_open_write(cdi))
@@ -2882,6 +2889,9 @@ int cdrom_get_last_written(struct cdrom_device_info *cdi, long *last_written)
           it doesn't give enough information or fails. then we return
           the toc contents. */
 use_toc:
+       if (!CDROM_CAN(CDC_PLAY_AUDIO))
+               return -ENOSYS;
+
        toc.cdte_format = CDROM_MSF;
        toc.cdte_track = CDROM_LEADOUT;
        if ((ret = cdi->ops->audio_ioctl(cdi, CDROMREADTOCENTRY, &toc)))
index e9b6ac6..4988252 100644 (file)
 #define OMAP4_RNG_OUTPUT_SIZE                  0x8
 #define EIP76_RNG_OUTPUT_SIZE                  0x10
 
+/*
+ * EIP76 RNG takes approx. 700us to produce 16 bytes of output data
+ * as per testing results. And to account for the lack of udelay()'s
+ * reliability, we keep the timeout as 1000us.
+ */
+#define RNG_DATA_FILL_TIMEOUT                  100
+
 enum {
        RNG_OUTPUT_0_REG = 0,
        RNG_OUTPUT_1_REG,
@@ -176,7 +183,7 @@ static int omap_rng_do_read(struct hwrng *rng, void *data, size_t max,
        if (max < priv->pdata->data_size)
                return 0;
 
-       for (i = 0; i < 20; i++) {
+       for (i = 0; i < RNG_DATA_FILL_TIMEOUT; i++) {
                present = priv->pdata->data_present(priv);
                if (present || !wait)
                        break;
index 38b7190..648e39c 100644 (file)
@@ -121,7 +121,8 @@ static int omap3_rom_rng_remove(struct platform_device *pdev)
 {
        cancel_delayed_work_sync(&idle_work);
        hwrng_unregister(&omap3_rom_rng_ops);
-       clk_disable_unprepare(rng_clk);
+       if (!rng_idle)
+               clk_disable_unprepare(rng_clk);
        return 0;
 }
 
index 84c17f9..91f2d92 100644 (file)
@@ -447,6 +447,8 @@ enum ipmi_stat_indexes {
 
 #define IPMI_IPMB_NUM_SEQ      64
 struct ipmi_smi {
+       struct module *owner;
+
        /* What interface number are we? */
        int intf_num;
 
@@ -1139,6 +1141,11 @@ int ipmi_create_user(unsigned int          if_num,
        if (rv)
                goto out_kfree;
 
+       if (!try_module_get(intf->owner)) {
+               rv = -ENODEV;
+               goto out_kfree;
+       }
+
        /* Note that each existing user holds a refcount to the interface. */
        kref_get(&intf->refcount);
 
@@ -1269,6 +1276,7 @@ static void _ipmi_destroy_user(struct ipmi_user *user)
        }
 
        kref_put(&intf->refcount, intf_free);
+       module_put(intf->owner);
 }
 
 int ipmi_destroy_user(struct ipmi_user *user)
@@ -2384,7 +2392,7 @@ static int __get_device_id(struct ipmi_smi *intf, struct bmc_device *bmc)
  * been recently fetched, this will just use the cached data.  Otherwise
  * it will run a new fetch.
  *
- * Except for the first time this is called (in ipmi_register_smi()),
+ * Except for the first time this is called (in ipmi_add_smi()),
  * this will always return good data;
  */
 static int __bmc_get_device_id(struct ipmi_smi *intf, struct bmc_device *bmc,
@@ -3304,10 +3312,11 @@ static void redo_bmc_reg(struct work_struct *work)
        kref_put(&intf->refcount, intf_free);
 }
 
-int ipmi_register_smi(const struct ipmi_smi_handlers *handlers,
-                     void                     *send_info,
-                     struct device            *si_dev,
-                     unsigned char            slave_addr)
+int ipmi_add_smi(struct module         *owner,
+                const struct ipmi_smi_handlers *handlers,
+                void                  *send_info,
+                struct device         *si_dev,
+                unsigned char         slave_addr)
 {
        int              i, j;
        int              rv;
@@ -3333,7 +3342,7 @@ int ipmi_register_smi(const struct ipmi_smi_handlers *handlers,
                return rv;
        }
 
-
+       intf->owner = owner;
        intf->bmc = &intf->tmp_bmc;
        INIT_LIST_HEAD(&intf->bmc->intfs);
        mutex_init(&intf->bmc->dyn_mutex);
@@ -3440,7 +3449,7 @@ int ipmi_register_smi(const struct ipmi_smi_handlers *handlers,
 
        return rv;
 }
-EXPORT_SYMBOL(ipmi_register_smi);
+EXPORT_SYMBOL(ipmi_add_smi);
 
 static void deliver_smi_err_response(struct ipmi_smi *intf,
                                     struct ipmi_smi_msg *msg,
index 1ae77b4..51faafd 100644 (file)
@@ -623,20 +623,27 @@ static int pp_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                if (copy_from_user(time32, argp, sizeof(time32)))
                        return -EFAULT;
 
+               if ((time32[0] < 0) || (time32[1] < 0))
+                       return -EINVAL;
+
                return pp_set_timeout(pp->pdev, time32[0], time32[1]);
 
        case PPSETTIME64:
                if (copy_from_user(time64, argp, sizeof(time64)))
                        return -EFAULT;
 
+               if ((time64[0] < 0) || (time64[1] < 0))
+                       return -EINVAL;
+
+               if (IS_ENABLED(CONFIG_SPARC64) && !in_compat_syscall())
+                       time64[1] >>= 32;
+
                return pp_set_timeout(pp->pdev, time64[0], time64[1]);
 
        case PPGETTIME32:
                jiffies_to_timespec64(pp->pdev->timeout, &ts);
                time32[0] = ts.tv_sec;
                time32[1] = ts.tv_nsec / NSEC_PER_USEC;
-               if ((time32[0] < 0) || (time32[1] < 0))
-                       return -EINVAL;
 
                if (copy_to_user(argp, time32, sizeof(time32)))
                        return -EFAULT;
@@ -647,8 +654,9 @@ static int pp_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                jiffies_to_timespec64(pp->pdev->timeout, &ts);
                time64[0] = ts.tv_sec;
                time64[1] = ts.tv_nsec / NSEC_PER_USEC;
-               if ((time64[0] < 0) || (time64[1] < 0))
-                       return -EINVAL;
+
+               if (IS_ENABLED(CONFIG_SPARC64) && !in_compat_syscall())
+                       time64[1] <<= 32;
 
                if (copy_to_user(argp, time64, sizeof(time64)))
                        return -EFAULT;
index 3acf4fd..ef381ca 100644 (file)
@@ -938,6 +938,10 @@ static int tpm2_get_cc_attrs_tbl(struct tpm_chip *chip)
 
        chip->cc_attrs_tbl = devm_kcalloc(&chip->dev, 4, nr_commands,
                                          GFP_KERNEL);
+       if (!chip->cc_attrs_tbl) {
+               rc = -ENOMEM;
+               goto out;
+       }
 
        rc = tpm_buf_init(&buf, TPM2_ST_NO_SESSIONS, TPM2_CC_GET_CAPABILITY);
        if (rc)
index 40af4fb..af9cc00 100644 (file)
@@ -248,7 +248,7 @@ static int gpio_clk_driver_probe(struct platform_device *pdev)
        else
                clk = clk_register_gpio_gate(&pdev->dev, node->name,
                                parent_names ?  parent_names[0] : NULL, gpiod,
-                               0);
+                               CLK_SET_RATE_PARENT);
        if (IS_ERR(clk))
                return PTR_ERR(clk);
 
index d40b63e..b44c4cf 100644 (file)
@@ -463,6 +463,7 @@ struct dummy_clk {
 };
 static struct dummy_clk dummy_clks[] __initdata = {
        DUMMY_CLK(NULL, "pxa27x-gpio", "osc_32_768khz"),
+       DUMMY_CLK(NULL, "pxa-rtc", "osc_32_768khz"),
        DUMMY_CLK(NULL, "sa1100-rtc", "osc_32_768khz"),
        DUMMY_CLK("UARTCLK", "pxa2xx-ir", "STUART"),
 };
index 52208d4..51b2388 100644 (file)
@@ -206,6 +206,8 @@ static int _freq_tbl_determine_rate(struct clk_hw *hw, const struct freq_tbl *f,
        if (clk_flags & CLK_SET_RATE_PARENT) {
                rate = f->freq;
                if (f->pre_div) {
+                       if (!rate)
+                               rate = req->rate;
                        rate /= 2;
                        rate *= f->pre_div + 1;
                }
index db9b247..bfb6d60 100644 (file)
@@ -29,6 +29,9 @@ struct freq_tbl *qcom_find_freq(const struct freq_tbl *f, unsigned long rate)
        if (!f)
                return NULL;
 
+       if (!f->freq)
+               return f;
+
        for (; f->freq; f++)
                if (rate <= f->freq)
                        return f;
index 38cd2fe..0ce7607 100644 (file)
@@ -198,6 +198,10 @@ static int __init asm9260_timer_init(struct device_node *np)
        }
 
        clk = of_clk_get(np, 0);
+       if (IS_ERR(clk)) {
+               pr_err("Failed to get clk!\n");
+               return PTR_ERR(clk);
+       }
 
        ret = clk_prepare_enable(clk);
        if (ret) {
index 06ed88a..6e2cb36 100644 (file)
@@ -199,7 +199,7 @@ int __init timer_of_init(struct device_node *np, struct timer_of *to)
        }
 
        if (!to->clkevt.name)
-               to->clkevt.name = np->name;
+               to->clkevt.name = np->full_name;
 
        to->np = np;
 
index 9d8d64f..e35c397 100644 (file)
@@ -2480,6 +2480,13 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data)
        if (cpufreq_disabled())
                return -ENODEV;
 
+       /*
+        * The cpufreq core depends heavily on the availability of device
+        * structure, make sure they are available before proceeding further.
+        */
+       if (!get_cpu_device(0))
+               return -EPROBE_DEFER;
+
        if (!driver_data || !driver_data->verify || !driver_data->init ||
            !(driver_data->setpolicy || driver_data->target_index ||
                    driver_data->target) ||
index bf6519c..5fff39d 100644 (file)
@@ -1042,9 +1042,14 @@ static struct cpufreq_driver powernv_cpufreq_driver = {
 
 static int init_chip_info(void)
 {
-       unsigned int chip[256];
+       unsigned int *chip;
        unsigned int cpu, i;
        unsigned int prev_chip_id = UINT_MAX;
+       int ret = 0;
+
+       chip = kcalloc(num_possible_cpus(), sizeof(*chip), GFP_KERNEL);
+       if (!chip)
+               return -ENOMEM;
 
        for_each_possible_cpu(cpu) {
                unsigned int id = cpu_to_chip_id(cpu);
@@ -1056,8 +1061,10 @@ static int init_chip_info(void)
        }
 
        chips = kcalloc(nr_chips, sizeof(struct chip), GFP_KERNEL);
-       if (!chips)
-               return -ENOMEM;
+       if (!chips) {
+               ret = -ENOMEM;
+               goto free_and_return;
+       }
 
        for (i = 0; i < nr_chips; i++) {
                chips[i].id = chip[i];
@@ -1067,7 +1074,9 @@ static int init_chip_info(void)
                        per_cpu(chip_info, cpu) =  &chips[i];
        }
 
-       return 0;
+free_and_return:
+       kfree(chip);
+       return ret;
 }
 
 static inline void clean_chip_info(void)
index dc32f34..01acd88 100644 (file)
@@ -62,24 +62,23 @@ static inline void __cpuidle_unset_driver(struct cpuidle_driver *drv)
  * __cpuidle_set_driver - set per CPU driver variables for the given driver.
  * @drv: a valid pointer to a struct cpuidle_driver
  *
- * For each CPU in the driver's cpumask, unset the registered driver per CPU
- * to @drv.
- *
- * Returns 0 on success, -EBUSY if the CPUs have driver(s) already.
+ * Returns 0 on success, -EBUSY if any CPU in the cpumask have a driver
+ * different from drv already.
  */
 static inline int __cpuidle_set_driver(struct cpuidle_driver *drv)
 {
        int cpu;
 
        for_each_cpu(cpu, drv->cpumask) {
+               struct cpuidle_driver *old_drv;
 
-               if (__cpuidle_get_cpu_driver(cpu)) {
-                       __cpuidle_unset_driver(drv);
+               old_drv = __cpuidle_get_cpu_driver(cpu);
+               if (old_drv && old_drv != drv)
                        return -EBUSY;
-               }
+       }
 
+       for_each_cpu(cpu, drv->cpumask)
                per_cpu(cpuidle_drivers, cpu) = drv;
-       }
 
        return 0;
 }
index f662914..53a7803 100644 (file)
@@ -148,7 +148,7 @@ struct atmel_aes_xts_ctx {
        u32                     key2[AES_KEYSIZE_256 / sizeof(u32)];
 };
 
-#ifdef CONFIG_CRYPTO_DEV_ATMEL_AUTHENC
+#if IS_ENABLED(CONFIG_CRYPTO_DEV_ATMEL_AUTHENC)
 struct atmel_aes_authenc_ctx {
        struct atmel_aes_base_ctx       base;
        struct atmel_sha_authenc_ctx    *auth;
@@ -160,7 +160,7 @@ struct atmel_aes_reqctx {
        u32                     lastc[AES_BLOCK_SIZE / sizeof(u32)];
 };
 
-#ifdef CONFIG_CRYPTO_DEV_ATMEL_AUTHENC
+#if IS_ENABLED(CONFIG_CRYPTO_DEV_ATMEL_AUTHENC)
 struct atmel_aes_authenc_reqctx {
        struct atmel_aes_reqctx base;
 
@@ -489,7 +489,7 @@ static inline bool atmel_aes_is_encrypt(const struct atmel_aes_dev *dd)
        return (dd->flags & AES_FLAGS_ENCRYPT);
 }
 
-#ifdef CONFIG_CRYPTO_DEV_ATMEL_AUTHENC
+#if IS_ENABLED(CONFIG_CRYPTO_DEV_ATMEL_AUTHENC)
 static void atmel_aes_authenc_complete(struct atmel_aes_dev *dd, int err);
 #endif
 
@@ -518,7 +518,7 @@ static void atmel_aes_set_iv_as_last_ciphertext_block(struct atmel_aes_dev *dd)
 
 static inline int atmel_aes_complete(struct atmel_aes_dev *dd, int err)
 {
-#ifdef CONFIG_CRYPTO_DEV_ATMEL_AUTHENC
+#if IS_ENABLED(CONFIG_CRYPTO_DEV_ATMEL_AUTHENC)
        if (dd->ctx->is_aead)
                atmel_aes_authenc_complete(dd, err);
 #endif
@@ -1983,7 +1983,7 @@ static struct crypto_alg aes_xts_alg = {
        }
 };
 
-#ifdef CONFIG_CRYPTO_DEV_ATMEL_AUTHENC
+#if IS_ENABLED(CONFIG_CRYPTO_DEV_ATMEL_AUTHENC)
 /* authenc aead functions */
 
 static int atmel_aes_authenc_start(struct atmel_aes_dev *dd);
@@ -2470,7 +2470,7 @@ static void atmel_aes_unregister_algs(struct atmel_aes_dev *dd)
 {
        int i;
 
-#ifdef CONFIG_CRYPTO_DEV_ATMEL_AUTHENC
+#if IS_ENABLED(CONFIG_CRYPTO_DEV_ATMEL_AUTHENC)
        if (dd->caps.has_authenc)
                for (i = 0; i < ARRAY_SIZE(aes_authenc_algs); i++)
                        crypto_unregister_aead(&aes_authenc_algs[i]);
@@ -2517,7 +2517,7 @@ static int atmel_aes_register_algs(struct atmel_aes_dev *dd)
                        goto err_aes_xts_alg;
        }
 
-#ifdef CONFIG_CRYPTO_DEV_ATMEL_AUTHENC
+#if IS_ENABLED(CONFIG_CRYPTO_DEV_ATMEL_AUTHENC)
        if (dd->caps.has_authenc) {
                for (i = 0; i < ARRAY_SIZE(aes_authenc_algs); i++) {
                        err = crypto_register_aead(&aes_authenc_algs[i]);
@@ -2529,7 +2529,7 @@ static int atmel_aes_register_algs(struct atmel_aes_dev *dd)
 
        return 0;
 
-#ifdef CONFIG_CRYPTO_DEV_ATMEL_AUTHENC
+#if IS_ENABLED(CONFIG_CRYPTO_DEV_ATMEL_AUTHENC)
        /* i = ARRAY_SIZE(aes_authenc_algs); */
 err_aes_authenc_alg:
        for (j = 0; j < i; j++)
@@ -2720,7 +2720,7 @@ static int atmel_aes_probe(struct platform_device *pdev)
 
        atmel_aes_get_cap(aes_dd);
 
-#ifdef CONFIG_CRYPTO_DEV_ATMEL_AUTHENC
+#if IS_ENABLED(CONFIG_CRYPTO_DEV_ATMEL_AUTHENC)
        if (aes_dd->caps.has_authenc && !atmel_sha_authenc_is_ready()) {
                err = -EPROBE_DEFER;
                goto iclk_unprepare;
index 2a60d12..7f6742d 100644 (file)
@@ -23,7 +23,7 @@
 #ifndef __ATMEL_AUTHENC_H__
 #define __ATMEL_AUTHENC_H__
 
-#ifdef CONFIG_CRYPTO_DEV_ATMEL_AUTHENC
+#if IS_ENABLED(CONFIG_CRYPTO_DEV_ATMEL_AUTHENC)
 
 #include <crypto/authenc.h>
 #include <crypto/hash.h>
index 8a19df2..ef125d4 100644 (file)
@@ -2215,7 +2215,7 @@ static struct ahash_alg sha_hmac_algs[] = {
 },
 };
 
-#ifdef CONFIG_CRYPTO_DEV_ATMEL_AUTHENC
+#if IS_ENABLED(CONFIG_CRYPTO_DEV_ATMEL_AUTHENC)
 /* authenc functions */
 
 static int atmel_sha_authenc_init2(struct atmel_sha_dev *dd);
index 5cf6474..22e4918 100644 (file)
@@ -81,7 +81,8 @@ static int sun4i_ss_opti_poll(struct skcipher_request *areq)
        oi = 0;
        oo = 0;
        do {
-               todo = min3(rx_cnt, ileft, (mi.length - oi) / 4);
+               todo = min(rx_cnt, ileft);
+               todo = min_t(size_t, todo, (mi.length - oi) / 4);
                if (todo) {
                        ileft -= todo;
                        writesl(ss->base + SS_RXFIFO, mi.addr + oi, todo);
@@ -96,7 +97,8 @@ static int sun4i_ss_opti_poll(struct skcipher_request *areq)
                rx_cnt = SS_RXFIFO_SPACES(spaces);
                tx_cnt = SS_TXFIFO_SPACES(spaces);
 
-               todo = min3(tx_cnt, oleft, (mo.length - oo) / 4);
+               todo = min(tx_cnt, oleft);
+               todo = min_t(size_t, todo, (mo.length - oo) / 4);
                if (todo) {
                        oleft -= todo;
                        readsl(ss->base + SS_TXFIFO, mo.addr + oo, todo);
@@ -220,7 +222,8 @@ static int sun4i_ss_cipher_poll(struct skcipher_request *areq)
                         * todo is the number of consecutive 4byte word that we
                         * can read from current SG
                         */
-                       todo = min3(rx_cnt, ileft / 4, (mi.length - oi) / 4);
+                       todo = min(rx_cnt, ileft / 4);
+                       todo = min_t(size_t, todo, (mi.length - oi) / 4);
                        if (todo && !ob) {
                                writesl(ss->base + SS_RXFIFO, mi.addr + oi,
                                        todo);
@@ -234,8 +237,8 @@ static int sun4i_ss_cipher_poll(struct skcipher_request *areq)
                                 * we need to be able to write all buf in one
                                 * pass, so it is why we min() with rx_cnt
                                 */
-                               todo = min3(rx_cnt * 4 - ob, ileft,
-                                           mi.length - oi);
+                               todo = min(rx_cnt * 4 - ob, ileft);
+                               todo = min_t(size_t, todo, mi.length - oi);
                                memcpy(buf + ob, mi.addr + oi, todo);
                                ileft -= todo;
                                oi += todo;
@@ -255,7 +258,8 @@ static int sun4i_ss_cipher_poll(struct skcipher_request *areq)
                spaces = readl(ss->base + SS_FCSR);
                rx_cnt = SS_RXFIFO_SPACES(spaces);
                tx_cnt = SS_TXFIFO_SPACES(spaces);
-               dev_dbg(ss->dev, "%x %u/%u %u/%u cnt=%u %u/%u %u/%u cnt=%u %u\n",
+               dev_dbg(ss->dev,
+                       "%x %u/%zu %u/%u cnt=%u %u/%zu %u/%u cnt=%u %u\n",
                        mode,
                        oi, mi.length, ileft, areq->cryptlen, rx_cnt,
                        oo, mo.length, oleft, areq->cryptlen, tx_cnt, ob);
@@ -263,7 +267,8 @@ static int sun4i_ss_cipher_poll(struct skcipher_request *areq)
                if (!tx_cnt)
                        continue;
                /* todo in 4bytes word */
-               todo = min3(tx_cnt, oleft / 4, (mo.length - oo) / 4);
+               todo = min(tx_cnt, oleft / 4);
+               todo = min_t(size_t, todo, (mo.length - oo) / 4);
                if (todo) {
                        readsl(ss->base + SS_TXFIFO, mo.addr + oo, todo);
                        oleft -= todo * 4;
@@ -287,7 +292,8 @@ static int sun4i_ss_cipher_poll(struct skcipher_request *areq)
                                 * no more than remaining buffer
                                 * no need to test against oleft
                                 */
-                               todo = min(mo.length - oo, obl - obo);
+                               todo = min_t(size_t,
+                                            mo.length - oo, obl - obo);
                                memcpy(mo.addr + oo, bufo + obo, todo);
                                oleft -= todo;
                                obo += todo;
index f6936bb..1a72426 100644 (file)
@@ -276,8 +276,8 @@ static int sun4i_hash(struct ahash_request *areq)
                         */
                        while (op->len < 64 && i < end) {
                                /* how many bytes we can read from current SG */
-                               in_r = min3(mi.length - in_i, end - i,
-                                           64 - op->len);
+                               in_r = min(end - i, 64 - op->len);
+                               in_r = min_t(size_t, mi.length - in_i, in_r);
                                memcpy(op->buf + op->len, mi.addr + in_i, in_r);
                                op->len += in_r;
                                i += in_r;
@@ -297,8 +297,8 @@ static int sun4i_hash(struct ahash_request *areq)
                }
                if (mi.length - in_i > 3 && i < end) {
                        /* how many bytes we can read from current SG */
-                       in_r = min3(mi.length - in_i, areq->nbytes - i,
-                                   ((mi.length - in_i) / 4) * 4);
+                       in_r = min_t(size_t, mi.length - in_i, areq->nbytes - i);
+                       in_r = min_t(size_t, ((mi.length - in_i) / 4) * 4, in_r);
                        /* how many bytes we can write in the device*/
                        todo = min3((u32)(end - i) / 4, rx_cnt, (u32)in_r / 4);
                        writesl(ss->base + SS_RXFIFO, mi.addr + in_i, todo);
@@ -324,8 +324,8 @@ static int sun4i_hash(struct ahash_request *areq)
        if ((areq->nbytes - i) < 64) {
                while (i < areq->nbytes && in_i < mi.length && op->len < 64) {
                        /* how many bytes we can read from current SG */
-                       in_r = min3(mi.length - in_i, areq->nbytes - i,
-                                   64 - op->len);
+                       in_r = min(areq->nbytes - i, 64 - op->len);
+                       in_r = min_t(size_t, mi.length - in_i, in_r);
                        memcpy(op->buf + op->len, mi.addr + in_i, in_r);
                        op->len += in_r;
                        i += in_r;
index 2c573d1..523b712 100644 (file)
@@ -117,8 +117,6 @@ virtio_crypto_alg_validate_key(int key_len, uint32_t *alg)
                *alg = VIRTIO_CRYPTO_CIPHER_AES_CBC;
                break;
        default:
-               pr_err("virtio_crypto: Unsupported key length: %d\n",
-                       key_len);
                return -EINVAL;
        }
        return 0;
@@ -498,6 +496,11 @@ static int virtio_crypto_ablkcipher_encrypt(struct ablkcipher_request *req)
        /* Use the first data virtqueue as default */
        struct data_queue *data_vq = &vcrypto->data_vq[0];
 
+       if (!req->nbytes)
+               return 0;
+       if (req->nbytes % AES_BLOCK_SIZE)
+               return -EINVAL;
+
        vc_req->dataq = data_vq;
        vc_req->alg_cb = virtio_crypto_dataq_sym_callback;
        vc_sym_req->ablkcipher_ctx = ctx;
@@ -518,6 +521,11 @@ static int virtio_crypto_ablkcipher_decrypt(struct ablkcipher_request *req)
        /* Use the first data virtqueue as default */
        struct data_queue *data_vq = &vcrypto->data_vq[0];
 
+       if (!req->nbytes)
+               return 0;
+       if (req->nbytes % AES_BLOCK_SIZE)
+               return -EINVAL;
+
        vc_req->dataq = data_vq;
        vc_req->alg_cb = virtio_crypto_dataq_sym_callback;
        vc_sym_req->ablkcipher_ctx = ctx;
index cab32cf..709670d 100644 (file)
@@ -3,13 +3,13 @@ obj-$(CONFIG_CRYPTO_DEV_VMX_ENCRYPT) += vmx-crypto.o
 vmx-crypto-objs := vmx.o aesp8-ppc.o ghashp8-ppc.o aes.o aes_cbc.o aes_ctr.o aes_xts.o ghash.o
 
 ifeq ($(CONFIG_CPU_LITTLE_ENDIAN),y)
-TARGET := linux-ppc64le
+override flavour := linux-ppc64le
 else
-TARGET := linux-ppc64
+override flavour := linux-ppc64
 endif
 
 quiet_cmd_perl = PERL $@
-      cmd_perl = $(PERL) $(<) $(TARGET) > $(@)
+      cmd_perl = $(PERL) $(<) $(flavour) > $(@)
 
 targets += aesp8-ppc.S ghashp8-ppc.S
 
index d350253..61fbaa8 100644 (file)
@@ -163,6 +163,7 @@ int devfreq_update_status(struct devfreq *devfreq, unsigned long freq)
        int lev, prev_lev, ret = 0;
        unsigned long cur_time;
 
+       lockdep_assert_held(&devfreq->lock);
        cur_time = jiffies;
 
        /* Immediately exit if previous_freq is not initialized yet. */
@@ -1287,12 +1288,17 @@ static ssize_t trans_stat_show(struct device *dev,
        int i, j;
        unsigned int max_state = devfreq->profile->max_state;
 
-       if (!devfreq->stop_polling &&
-                       devfreq_update_status(devfreq, devfreq->previous_freq))
-               return 0;
        if (max_state == 0)
                return sprintf(buf, "Not Supported.\n");
 
+       mutex_lock(&devfreq->lock);
+       if (!devfreq->stop_polling &&
+                       devfreq_update_status(devfreq, devfreq->previous_freq)) {
+               mutex_unlock(&devfreq->lock);
+               return 0;
+       }
+       mutex_unlock(&devfreq->lock);
+
        len = sprintf(buf, "     From  :   To\n");
        len += sprintf(buf + len, "           :");
        for (i = 0; i < max_state; i++)
index 35dd064..91d6209 100644 (file)
@@ -230,7 +230,7 @@ static struct sync_file *sync_file_merge(const char *name, struct sync_file *a,
        a_fences = get_fences(a, &a_num_fences);
        b_fences = get_fences(b, &b_num_fences);
        if (a_num_fences > INT_MAX - b_num_fences)
-               return NULL;
+               goto err;
 
        num_fences = a_num_fences + b_num_fences;
 
index 8aec137..d56b6b0 100644 (file)
@@ -1427,6 +1427,7 @@ static int xilinx_dma_reset(struct xilinx_dma_chan *chan)
 
        chan->err = false;
        chan->idle = true;
+       chan->desc_pendingcount = 0;
        chan->desc_submitcount = 0;
 
        return err;
index 574bce6..78c339d 100644 (file)
@@ -210,6 +210,7 @@ void ghes_edac_report_mem_error(int sev, struct cper_sec_mem_err *mem_err)
        /* Cleans the error report buffer */
        memset(e, 0, sizeof (*e));
        e->error_count = 1;
+       e->grain = 1;
        strcpy(e->label, "unknown label");
        e->msg = pvt->msg;
        e->other_detail = pvt->other_detail;
@@ -305,7 +306,7 @@ void ghes_edac_report_mem_error(int sev, struct cper_sec_mem_err *mem_err)
 
        /* Error grain */
        if (mem_err->validation_bits & CPER_MEM_VALID_PA_MASK)
-               e->grain = ~(mem_err->physical_addr_mask & ~PAGE_MASK);
+               e->grain = ~mem_err->physical_addr_mask + 1;
 
        /* Memory error location, mapped on e->location */
        p = e->location;
@@ -412,8 +413,13 @@ void ghes_edac_report_mem_error(int sev, struct cper_sec_mem_err *mem_err)
        if (p > pvt->other_detail)
                *(p - 1) = '\0';
 
+       /* Sanity-check driver-supplied grain value. */
+       if (WARN_ON_ONCE(!e->grain))
+               e->grain = 1;
+
+       grain_bits = fls_long(e->grain - 1);
+
        /* Generate the trace event */
-       grain_bits = fls_long(e->grain);
        snprintf(pvt->detail_location, sizeof(pvt->detail_location),
                 "APEI location: %s %s", e->location, e->other_detail);
        trace_mc_event(type, e->msg, e->label, e->error_count,
index 0cfb5a3..2efcd94 100644 (file)
@@ -69,6 +69,10 @@ struct sm5502_muic_info {
 /* Default value of SM5502 register to bring up MUIC device. */
 static struct reg_data sm5502_reg_data[] = {
        {
+               .reg = SM5502_REG_RESET,
+               .val = SM5502_REG_RESET_MASK,
+               .invert = true,
+       }, {
                .reg = SM5502_REG_CONTROL,
                .val = SM5502_REG_CONTROL_MASK_INT_MASK,
                .invert = false,
index 974b532..12f8b01 100644 (file)
@@ -241,6 +241,8 @@ enum sm5502_reg {
 #define DM_DP_SWITCH_UART                      ((DM_DP_CON_SWITCH_UART <<SM5502_REG_MANUAL_SW1_DP_SHIFT) \
                                                | (DM_DP_CON_SWITCH_UART <<SM5502_REG_MANUAL_SW1_DM_SHIFT))
 
+#define SM5502_REG_RESET_MASK                  (0x1)
+
 /* SM5502 Interrupts */
 enum sm5502_irq {
        /* INT1 */
index 92f843e..7a30952 100644 (file)
@@ -135,8 +135,10 @@ scmi_device_create(struct device_node *np, struct device *parent, int protocol)
                return NULL;
 
        id = ida_simple_get(&scmi_bus_id, 1, 0, GFP_KERNEL);
-       if (id < 0)
-               goto free_mem;
+       if (id < 0) {
+               kfree(scmi_dev);
+               return NULL;
+       }
 
        scmi_dev->id = id;
        scmi_dev->protocol_id = protocol;
@@ -154,8 +156,6 @@ scmi_device_create(struct device_node *np, struct device *parent, int protocol)
 put_dev:
        put_device(&scmi_dev->dev);
        ida_simple_remove(&scmi_bus_id, id);
-free_mem:
-       kfree(scmi_dev);
        return NULL;
 }
 
index 688525d..367e727 100644 (file)
@@ -158,7 +158,7 @@ static int qcom_scm_call(struct device *dev, u32 svc_id, u32 cmd_id,
                kfree(args_virt);
        }
 
-       if (res->a0 < 0)
+       if ((long)res->a0 < 0)
                return qcom_scm_remap_error(res->a0);
 
        return 0;
index 2c31563..c6fa9b3 100644 (file)
@@ -552,6 +552,31 @@ static int fsi_slave_scan(struct fsi_slave *slave)
        return 0;
 }
 
+static unsigned long aligned_access_size(size_t offset, size_t count)
+{
+       unsigned long offset_unit, count_unit;
+
+       /* Criteria:
+        *
+        * 1. Access size must be less than or equal to the maximum access
+        *    width or the highest power-of-two factor of offset
+        * 2. Access size must be less than or equal to the amount specified by
+        *    count
+        *
+        * The access width is optimal if we can calculate 1 to be strictly
+        * equal while still satisfying 2.
+        */
+
+       /* Find 1 by the bottom bit of offset (with a 4 byte access cap) */
+       offset_unit = BIT(__builtin_ctzl(offset | 4));
+
+       /* Find 2 by the top bit of count */
+       count_unit = BIT(8 * sizeof(unsigned long) - 1 - __builtin_clzl(count));
+
+       /* Constrain the maximum access width to the minimum of both criteria */
+       return BIT(__builtin_ctzl(offset_unit | count_unit));
+}
+
 static ssize_t fsi_slave_sysfs_raw_read(struct file *file,
                struct kobject *kobj, struct bin_attribute *attr, char *buf,
                loff_t off, size_t count)
@@ -567,8 +592,7 @@ static ssize_t fsi_slave_sysfs_raw_read(struct file *file,
                return -EINVAL;
 
        for (total_len = 0; total_len < count; total_len += read_len) {
-               read_len = min_t(size_t, count, 4);
-               read_len -= off & 0x3;
+               read_len = aligned_access_size(off, count - total_len);
 
                rc = fsi_slave_read(slave, off, buf + total_len, read_len);
                if (rc)
@@ -595,8 +619,7 @@ static ssize_t fsi_slave_sysfs_raw_write(struct file *file,
                return -EINVAL;
 
        for (total_len = 0; total_len < count; total_len += write_len) {
-               write_len = min_t(size_t, count, 4);
-               write_len -= off & 0x3;
+               write_len = aligned_access_size(off, count - total_len);
 
                rc = fsi_slave_write(slave, off, buf + total_len, write_len);
                if (rc)
index c8673a5..3f10f95 100644 (file)
@@ -348,7 +348,8 @@ static int mpc8xxx_probe(struct platform_device *pdev)
         * It's assumed that only a single type of gpio controller is available
         * on the current machine, so overwriting global data is fine.
         */
-       mpc8xxx_irq_chip.irq_set_type = devtype->irq_set_type;
+       if (devtype->irq_set_type)
+               mpc8xxx_irq_chip.irq_set_type = devtype->irq_set_type;
 
        if (devtype->gpio_dir_out)
                gc->direction_output = devtype->gpio_dir_out;
index cf2604e..8edbb3f 100644 (file)
@@ -1265,11 +1265,28 @@ late_initcall_sync(acpi_gpio_handle_deferred_request_irqs);
 
 static const struct dmi_system_id run_edge_events_on_boot_blacklist[] = {
        {
+               /*
+                * The Minix Neo Z83-4 has a micro-USB-B id-pin handler for
+                * a non existing micro-USB-B connector which puts the HDMI
+                * DDC pins in GPIO mode, breaking HDMI support.
+                */
                .matches = {
                        DMI_MATCH(DMI_SYS_VENDOR, "MINIX"),
                        DMI_MATCH(DMI_PRODUCT_NAME, "Z83-4"),
                }
        },
+       {
+               /*
+                * The Terra Pad 1061 has a micro-USB-B id-pin handler, which
+                * instead of controlling the actual micro-USB-B turns the 5V
+                * boost for its USB-A connector off. The actual micro-USB-B
+                * connector is wired for charging only.
+                */
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Wortmann_AG"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "TERRA_PAD_1061"),
+               }
+       },
        {} /* Terminating entry */
 };
 
index 8904e62..41d3142 100644 (file)
@@ -138,6 +138,7 @@ static void amdgpu_do_test_moves(struct amdgpu_device *adev)
                }
 
                dma_fence_put(fence);
+               fence = NULL;
 
                r = amdgpu_bo_kmap(vram_obj, &vram_map);
                if (r) {
@@ -183,6 +184,7 @@ static void amdgpu_do_test_moves(struct amdgpu_device *adev)
                }
 
                dma_fence_put(fence);
+               fence = NULL;
 
                r = amdgpu_bo_kmap(gtt_obj[i], &gtt_map);
                if (r) {
index 49fe508..f67c332 100644 (file)
@@ -700,10 +700,8 @@ int amdgpu_vm_flush(struct amdgpu_ring *ring, struct amdgpu_job *job, bool need_
                id->oa_base != job->oa_base ||
                id->oa_size != job->oa_size);
        bool vm_flush_needed = job->vm_needs_flush;
-       bool pasid_mapping_needed = id->pasid != job->pasid ||
-               !id->pasid_mapping ||
-               !dma_fence_is_signaled(id->pasid_mapping);
        struct dma_fence *fence = NULL;
+       bool pasid_mapping_needed = false;
        unsigned patch_offset = 0;
        int r;
 
@@ -713,6 +711,12 @@ int amdgpu_vm_flush(struct amdgpu_ring *ring, struct amdgpu_job *job, bool need_
                pasid_mapping_needed = true;
        }
 
+       mutex_lock(&id_mgr->lock);
+       if (id->pasid != job->pasid || !id->pasid_mapping ||
+           !dma_fence_is_signaled(id->pasid_mapping))
+               pasid_mapping_needed = true;
+       mutex_unlock(&id_mgr->lock);
+
        gds_switch_needed &= !!ring->funcs->emit_gds_switch;
        vm_flush_needed &= !!ring->funcs->emit_vm_flush  &&
                        job->vm_pd_addr != AMDGPU_BO_INVALID_OFFSET;
@@ -752,9 +756,11 @@ int amdgpu_vm_flush(struct amdgpu_ring *ring, struct amdgpu_job *job, bool need_
        }
 
        if (pasid_mapping_needed) {
+               mutex_lock(&id_mgr->lock);
                id->pasid = job->pasid;
                dma_fence_put(id->pasid_mapping);
                id->pasid_mapping = dma_fence_get(fence);
+               mutex_unlock(&id_mgr->lock);
        }
        dma_fence_put(fence);
 
index 7824116..28794b1 100644 (file)
@@ -2187,7 +2187,8 @@ static void gfx_v9_0_init_pg(struct amdgpu_device *adev)
         * And it's needed by gfxoff feature.
         */
        if (adev->gfx.rlc.is_rlc_v2_1) {
-               gfx_v9_1_init_rlc_save_restore_list(adev);
+               if (adev->asic_type == CHIP_VEGA12)
+                       gfx_v9_1_init_rlc_save_restore_list(adev);
                gfx_v9_0_enable_save_restore_machine(adev);
        }
 
index 60dad63..e40a3fb 100644 (file)
@@ -62,7 +62,8 @@ static int si_ih_irq_init(struct amdgpu_device *adev)
        u64 wptr_off;
 
        si_ih_disable_interrupts(adev);
-       WREG32(INTERRUPT_CNTL2, adev->irq.ih.gpu_addr >> 8);
+       /* set dummy read address to dummy page address */
+       WREG32(INTERRUPT_CNTL2, adev->dummy_page_addr >> 8);
        interrupt_cntl = RREG32(INTERRUPT_CNTL);
        interrupt_cntl &= ~IH_DUMMY_RD_OVERRIDE;
        interrupt_cntl &= ~IH_REQ_NONSNOOP_EN;
index c56ac47..bc47f6a 100644 (file)
@@ -62,6 +62,11 @@ int kfd_interrupt_init(struct kfd_dev *kfd)
        }
 
        kfd->ih_wq = alloc_workqueue("KFD IH", WQ_HIGHPRI, 1);
+       if (unlikely(!kfd->ih_wq)) {
+               kfifo_free(&kfd->ih_fifo);
+               dev_err(kfd_chardev(), "Failed to allocate KFD IH workqueue\n");
+               return -ENOMEM;
+       }
        spin_lock_init(&kfd->interrupt_lock);
 
        INIT_WORK(&kfd->interrupt_work, interrupt_wq);
index 23a7ef9..c6f7c13 100644 (file)
@@ -1950,7 +1950,7 @@ static bool dp_active_dongle_validate_timing(
                break;
        }
 
-       if (dongle_caps->dongle_type != DISPLAY_DONGLE_DP_HDMI_CONVERTER ||
+       if (dpcd_caps->dongle_type != DISPLAY_DONGLE_DP_HDMI_CONVERTER ||
                dongle_caps->extendedCapValid == false)
                return true;
 
index 05840f5..122249d 100644 (file)
@@ -2172,6 +2172,7 @@ static void get_active_converter_info(
        uint8_t data, struct dc_link *link)
 {
        union dp_downstream_port_present ds_port = { .byte = data };
+       memset(&link->dpcd_caps.dongle_caps, 0, sizeof(link->dpcd_caps.dongle_caps));
 
        /* decode converter info*/
        if (!ds_port.fields.PORT_PRESENT) {
index f8433c9..cc820e9 100644 (file)
@@ -725,7 +725,9 @@ static int anx78xx_init_pdata(struct anx78xx *anx78xx)
        /* 1.0V digital core power regulator  */
        pdata->dvdd10 = devm_regulator_get(dev, "dvdd10");
        if (IS_ERR(pdata->dvdd10)) {
-               DRM_ERROR("DVDD10 regulator not found\n");
+               if (PTR_ERR(pdata->dvdd10) != -EPROBE_DEFER)
+                       DRM_ERROR("DVDD10 regulator not found\n");
+
                return PTR_ERR(pdata->dvdd10);
        }
 
@@ -1341,7 +1343,9 @@ static int anx78xx_i2c_probe(struct i2c_client *client,
 
        err = anx78xx_init_pdata(anx78xx);
        if (err) {
-               DRM_ERROR("Failed to initialize pdata: %d\n", err);
+               if (err != -EPROBE_DEFER)
+                       DRM_ERROR("Failed to initialize pdata: %d\n", err);
+
                return err;
        }
 
index 5971976..2a0a165 100644 (file)
@@ -39,6 +39,7 @@
 
 #include <media/cec-notifier.h>
 
+#define DDC_CI_ADDR            0x37
 #define DDC_SEGMENT_ADDR       0x30
 
 #define HDMI_EDID_LEN          512
@@ -320,6 +321,15 @@ static int dw_hdmi_i2c_xfer(struct i2c_adapter *adap,
        u8 addr = msgs[0].addr;
        int i, ret = 0;
 
+       if (addr == DDC_CI_ADDR)
+               /*
+                * The internal I2C controller does not support the multi-byte
+                * read and write operations needed for DDC/CI.
+                * TOFIX: Blacklist the DDC/CI address until we filter out
+                * unsupported I2C operations.
+                */
+               return -EOPNOTSUPP;
+
        dev_dbg(hdmi->dev, "xfer: num: %d, addr: %#x\n", num, addr);
 
        for (i = 0; i < num; i++) {
@@ -1747,7 +1757,7 @@ static int dw_hdmi_setup(struct dw_hdmi *hdmi, struct drm_display_mode *mode)
 
                /* HDMI Initialization Step E - Configure audio */
                hdmi_clk_regenerator_update_pixel_clock(hdmi);
-               hdmi_enable_audio_clk(hdmi, true);
+               hdmi_enable_audio_clk(hdmi, hdmi->audio_enable);
        }
 
        /* not for DVI mode */
index d1859bc..33a72a8 100644 (file)
@@ -1572,7 +1572,7 @@ int drm_wait_vblank_ioctl(struct drm_device *dev, void *data,
        unsigned int flags, pipe, high_pipe;
 
        if (!dev->irq_enabled)
-               return -EINVAL;
+               return -EOPNOTSUPP;
 
        if (vblwait->request.type & _DRM_VBLANK_SIGNAL)
                return -EINVAL;
@@ -1813,7 +1813,7 @@ int drm_crtc_get_sequence_ioctl(struct drm_device *dev, void *data,
                return -EINVAL;
 
        if (!dev->irq_enabled)
-               return -EINVAL;
+               return -EOPNOTSUPP;
 
        crtc = drm_crtc_find(dev, file_priv, get_seq->crtc_id);
        if (!crtc)
@@ -1871,7 +1871,7 @@ int drm_crtc_queue_sequence_ioctl(struct drm_device *dev, void *data,
                return -EINVAL;
 
        if (!dev->irq_enabled)
-               return -EINVAL;
+               return -EOPNOTSUPP;
 
        crtc = drm_crtc_find(dev, file_priv, queue_seq->crtc_id);
        if (!crtc)
index 1b7fd6a..f73a02a 100644 (file)
@@ -139,6 +139,7 @@ static bool mrst_sdvo_find_best_pll(const struct gma_limit_t *limit,
        s32 freq_error, min_error = 100000;
 
        memset(best_clock, 0, sizeof(*best_clock));
+       memset(&clock, 0, sizeof(clock));
 
        for (clock.m = limit->m.min; clock.m <= limit->m.max; clock.m++) {
                for (clock.n = limit->n.min; clock.n <= limit->n.max;
@@ -195,6 +196,7 @@ static bool mrst_lvds_find_best_pll(const struct gma_limit_t *limit,
        int err = target;
 
        memset(best_clock, 0, sizeof(*best_clock));
+       memset(&clock, 0, sizeof(clock));
 
        for (clock.m = limit->m.min; clock.m <= limit->m.max; clock.m++) {
                for (clock.p1 = limit->p1.min; clock.p1 <= limit->p1.max;
index f7945ba..e176014 100644 (file)
@@ -75,6 +75,25 @@ struct meson_cvbs_mode meson_cvbs_modes[MESON_CVBS_MODES_COUNT] = {
        },
 };
 
+static const struct meson_cvbs_mode *
+meson_cvbs_get_mode(const struct drm_display_mode *req_mode)
+{
+       int i;
+
+       for (i = 0; i < MESON_CVBS_MODES_COUNT; ++i) {
+               struct meson_cvbs_mode *meson_mode = &meson_cvbs_modes[i];
+
+               if (drm_mode_match(req_mode, &meson_mode->mode,
+                                  DRM_MODE_MATCH_TIMINGS |
+                                  DRM_MODE_MATCH_CLOCK |
+                                  DRM_MODE_MATCH_FLAGS |
+                                  DRM_MODE_MATCH_3D_FLAGS))
+                       return meson_mode;
+       }
+
+       return NULL;
+}
+
 /* Connector */
 
 static void meson_cvbs_connector_destroy(struct drm_connector *connector)
@@ -147,14 +166,8 @@ static int meson_venc_cvbs_encoder_atomic_check(struct drm_encoder *encoder,
                                        struct drm_crtc_state *crtc_state,
                                        struct drm_connector_state *conn_state)
 {
-       int i;
-
-       for (i = 0; i < MESON_CVBS_MODES_COUNT; ++i) {
-               struct meson_cvbs_mode *meson_mode = &meson_cvbs_modes[i];
-
-               if (drm_mode_equal(&crtc_state->mode, &meson_mode->mode))
-                       return 0;
-       }
+       if (meson_cvbs_get_mode(&crtc_state->mode))
+               return 0;
 
        return -EINVAL;
 }
@@ -192,24 +205,17 @@ static void meson_venc_cvbs_encoder_mode_set(struct drm_encoder *encoder,
                                   struct drm_display_mode *mode,
                                   struct drm_display_mode *adjusted_mode)
 {
+       const struct meson_cvbs_mode *meson_mode = meson_cvbs_get_mode(mode);
        struct meson_venc_cvbs *meson_venc_cvbs =
                                        encoder_to_meson_venc_cvbs(encoder);
        struct meson_drm *priv = meson_venc_cvbs->priv;
-       int i;
 
-       for (i = 0; i < MESON_CVBS_MODES_COUNT; ++i) {
-               struct meson_cvbs_mode *meson_mode = &meson_cvbs_modes[i];
+       if (meson_mode) {
+               meson_venci_cvbs_mode_set(priv, meson_mode->enci);
 
-               if (drm_mode_equal(mode, &meson_mode->mode)) {
-                       meson_venci_cvbs_mode_set(priv,
-                                                 meson_mode->enci);
-
-                       /* Setup 27MHz vclk2 for ENCI and VDAC */
-                       meson_vclk_setup(priv, MESON_VCLK_TARGET_CVBS,
-                                        MESON_VCLK_CVBS, MESON_VCLK_CVBS,
-                                        MESON_VCLK_CVBS, true);
-                       break;
-               }
+               /* Setup 27MHz vclk2 for ENCI and VDAC */
+               meson_vclk_setup(priv, MESON_VCLK_TARGET_CVBS, MESON_VCLK_CVBS,
+                                MESON_VCLK_CVBS, MESON_VCLK_CVBS, true);
        }
 }
 
index 9a2cb8a..aab6a70 100644 (file)
@@ -427,6 +427,7 @@ static int rpi_touchscreen_probe(struct i2c_client *i2c,
                return PTR_ERR(ts->dsi);
        }
 
+       drm_panel_init(&ts->base);
        ts->base.dev = dev;
        ts->base.funcs = &rpi_touchscreen_funcs;
 
index 74284e5..89fa178 100644 (file)
@@ -380,6 +380,7 @@ static int st7789v_probe(struct spi_device *spi)
        spi_set_drvdata(spi, ctx);
        ctx->spi = spi;
 
+       drm_panel_init(&ctx->panel);
        ctx->panel.dev = &spi->dev;
        ctx->panel.funcs = &st7789v_drm_funcs;
 
index 7d39ed6..b24401f 100644 (file)
@@ -1820,8 +1820,8 @@ static int r100_packet0_check(struct radeon_cs_parser *p,
                        track->textures[i].use_pitch = 1;
                } else {
                        track->textures[i].use_pitch = 0;
-                       track->textures[i].width = 1 << ((idx_value >> RADEON_TXFORMAT_WIDTH_SHIFT) & RADEON_TXFORMAT_WIDTH_MASK);
-                       track->textures[i].height = 1 << ((idx_value >> RADEON_TXFORMAT_HEIGHT_SHIFT) & RADEON_TXFORMAT_HEIGHT_MASK);
+                       track->textures[i].width = 1 << ((idx_value & RADEON_TXFORMAT_WIDTH_MASK) >> RADEON_TXFORMAT_WIDTH_SHIFT);
+                       track->textures[i].height = 1 << ((idx_value & RADEON_TXFORMAT_HEIGHT_MASK) >> RADEON_TXFORMAT_HEIGHT_SHIFT);
                }
                if (idx_value & RADEON_TXFORMAT_CUBIC_MAP_ENABLE)
                        track->textures[i].tex_coord_type = 2;
index c22321c..c2b506c 100644 (file)
@@ -476,8 +476,8 @@ int r200_packet0_check(struct radeon_cs_parser *p,
                        track->textures[i].use_pitch = 1;
                } else {
                        track->textures[i].use_pitch = 0;
-                       track->textures[i].width = 1 << ((idx_value >> RADEON_TXFORMAT_WIDTH_SHIFT) & RADEON_TXFORMAT_WIDTH_MASK);
-                       track->textures[i].height = 1 << ((idx_value >> RADEON_TXFORMAT_HEIGHT_SHIFT) & RADEON_TXFORMAT_HEIGHT_MASK);
+                       track->textures[i].width = 1 << ((idx_value & RADEON_TXFORMAT_WIDTH_MASK) >> RADEON_TXFORMAT_WIDTH_SHIFT);
+                       track->textures[i].height = 1 << ((idx_value & RADEON_TXFORMAT_HEIGHT_MASK) >> RADEON_TXFORMAT_HEIGHT_SHIFT);
                }
                if (idx_value & R200_TXFORMAT_LOOKUP_DISABLE)
                        track->textures[i].lookup_disable = true;
index d7fe9f1..89cb70d 100644 (file)
@@ -2922,6 +2922,11 @@ static int tegra_sor_parse_dt(struct tegra_sor *sor)
                 * earlier
                 */
                sor->pad = TEGRA_IO_PAD_HDMI_DP0 + sor->index;
+       } else {
+               if (sor->soc->supports_edp)
+                       sor->index = 0;
+               else
+                       sor->index = 1;
        }
 
        return 0;
index 527a1cd..916b235 100644 (file)
@@ -447,7 +447,8 @@ out:
        return err;
 }
 
-static inline int copy_gathers(struct host1x_job *job, struct device *dev)
+static inline int copy_gathers(struct device *host, struct host1x_job *job,
+                              struct device *dev)
 {
        struct host1x_firewall fw;
        size_t size = 0;
@@ -470,12 +471,12 @@ static inline int copy_gathers(struct host1x_job *job, struct device *dev)
         * Try a non-blocking allocation from a higher priority pools first,
         * as awaiting for the allocation here is a major performance hit.
         */
-       job->gather_copy_mapped = dma_alloc_wc(dev, size, &job->gather_copy,
+       job->gather_copy_mapped = dma_alloc_wc(host, size, &job->gather_copy,
                                               GFP_NOWAIT);
 
        /* the higher priority allocation failed, try the generic-blocking */
        if (!job->gather_copy_mapped)
-               job->gather_copy_mapped = dma_alloc_wc(dev, size,
+               job->gather_copy_mapped = dma_alloc_wc(host, size,
                                                       &job->gather_copy,
                                                       GFP_KERNEL);
        if (!job->gather_copy_mapped)
@@ -523,7 +524,7 @@ int host1x_job_pin(struct host1x_job *job, struct device *dev)
                goto out;
 
        if (IS_ENABLED(CONFIG_TEGRA_HOST1X_FIREWALL)) {
-               err = copy_gathers(job, dev);
+               err = copy_gathers(host->dev, job, dev);
                if (err)
                        goto out;
        }
@@ -584,7 +585,7 @@ void host1x_job_unpin(struct host1x_job *job)
        job->num_unpins = 0;
 
        if (job->gather_copy_size)
-               dma_free_wc(job->channel->dev, job->gather_copy_size,
+               dma_free_wc(host->dev, job->gather_copy_size,
                            job->gather_copy_mapped, job->gather_copy);
 }
 EXPORT_SYMBOL(host1x_job_unpin);
index b0c8fae..3a35971 100644 (file)
@@ -780,6 +780,10 @@ static void hid_scan_feature_usage(struct hid_parser *parser, u32 usage)
        if (usage == 0xff0000c5 && parser->global.report_count == 256 &&
            parser->global.report_size == 8)
                parser->scan_flags |= HID_SCAN_FLAG_MT_WIN_8;
+
+       if (usage == 0xff0000c6 && parser->global.report_count == 1 &&
+           parser->global.report_size == 8)
+               parser->scan_flags |= HID_SCAN_FLAG_MT_WIN_8;
 }
 
 static void hid_scan_collection(struct hid_parser *parser, unsigned type)
index 5828c9a..eb244a6 100644 (file)
 #define USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE_094A    0x094a
 #define USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE_0941    0x0941
 #define USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE_0641    0x0641
+#define USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE_1f4a    0x1f4a
 
 #define USB_VENDOR_ID_HUION            0x256c
 #define USB_DEVICE_ID_HUION_TABLET     0x006e
index 034c883..504e891 100644 (file)
@@ -978,6 +978,9 @@ static int hidpp20_batterylevel_get_battery_capacity(struct hidpp_device *hidpp,
        ret = hidpp_send_fap_command_sync(hidpp, feature_index,
                                          CMD_BATTERY_LEVEL_STATUS_GET_BATTERY_LEVEL_STATUS,
                                          NULL, 0, &response);
+       /* Ignore these intermittent errors */
+       if (ret == HIDPP_ERROR_RESOURCE_ERROR)
+               return -EIO;
        if (ret > 0) {
                hid_err(hidpp->hid_dev, "%s: received protocol error 0x%02x\n",
                        __func__, ret);
index 5e88bca..0b1ed23 100644 (file)
@@ -97,6 +97,7 @@ static const struct hid_device_id hid_quirks[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE_094A), HID_QUIRK_ALWAYS_POLL },
        { HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE_0941), HID_QUIRK_ALWAYS_POLL },
        { HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE_0641), HID_QUIRK_ALWAYS_POLL },
+       { HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE_1f4a), HID_QUIRK_ALWAYS_POLL },
        { HID_USB_DEVICE(USB_VENDOR_ID_IDEACOM, USB_DEVICE_ID_IDEACOM_IDC6680), HID_QUIRK_MULTI_INPUT },
        { HID_USB_DEVICE(USB_VENDOR_ID_INNOMEDIA, USB_DEVICE_ID_INNEX_GENESIS_ATARI), HID_QUIRK_MULTI_INPUT },
        { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M610X), HID_QUIRK_MULTI_INPUT },
index 9e33165..a5b6b2b 100644 (file)
@@ -737,7 +737,8 @@ static void rmi_remove(struct hid_device *hdev)
 {
        struct rmi_data *hdata = hid_get_drvdata(hdev);
 
-       if (hdata->device_flags & RMI_DEVICE) {
+       if ((hdata->device_flags & RMI_DEVICE)
+           && test_bit(RMI_STARTED, &hdata->flags)) {
                clear_bit(RMI_STARTED, &hdata->flags);
                cancel_work_sync(&hdata->reset_work);
                rmi_unregister_transport_device(&hdata->xport);
index fc6b7f8..a8e7502 100644 (file)
@@ -629,10 +629,8 @@ intel_th_subdevice_alloc(struct intel_th *th,
        }
 
        err = intel_th_device_add_resources(thdev, res, subdev->nres);
-       if (err) {
-               put_device(&thdev->dev);
+       if (err)
                goto fail_put_device;
-       }
 
        if (subdev->type == INTEL_TH_OUTPUT) {
                thdev->dev.devt = MKDEV(th->major, th->num_thdevs);
@@ -646,10 +644,8 @@ intel_th_subdevice_alloc(struct intel_th *th,
        }
 
        err = device_add(&thdev->dev);
-       if (err) {
-               put_device(&thdev->dev);
+       if (err)
                goto fail_free_res;
-       }
 
        /* need switch driver to be loaded to enumerate the rest */
        if (subdev->type == INTEL_TH_SWITCH && !req) {
index 8421009..e63a0c2 100644 (file)
@@ -181,11 +181,26 @@ static const struct pci_device_id intel_th_pci_id_table[] = {
                .driver_data = (kernel_ulong_t)&intel_th_2x,
        },
        {
+               /* Comet Lake PCH-V */
+               PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa3a6),
+               .driver_data = (kernel_ulong_t)&intel_th_2x,
+       },
+       {
                /* Ice Lake NNPI */
                PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x45c5),
                .driver_data = (kernel_ulong_t)&intel_th_2x,
        },
        {
+               /* Ice Lake CPU */
+               PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x8a29),
+               .driver_data = (kernel_ulong_t)&intel_th_2x,
+       },
+       {
+               /* Tiger Lake CPU */
+               PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x9a33),
+               .driver_data = (kernel_ulong_t)&intel_th_2x,
+       },
+       {
                /* Tiger Lake PCH */
                PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa0a6),
                .driver_data = (kernel_ulong_t)&intel_th_2x,
@@ -195,6 +210,11 @@ static const struct pci_device_id intel_th_pci_id_table[] = {
                PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4da6),
                .driver_data = (kernel_ulong_t)&intel_th_2x,
        },
+       {
+               /* Elkhart Lake */
+               PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4b26),
+               .driver_data = (kernel_ulong_t)&intel_th_2x,
+       },
        { 0 },
 };
 
index c64c667..4ab052d 100644 (file)
@@ -527,6 +527,10 @@ static int dln2_adc_triggered_buffer_postenable(struct iio_dev *indio_dev)
        u16 conflict;
        unsigned int trigger_chan;
 
+       ret = iio_triggered_buffer_postenable(indio_dev);
+       if (ret)
+               return ret;
+
        mutex_lock(&dln2->mutex);
 
        /* Enable ADC */
@@ -540,6 +544,7 @@ static int dln2_adc_triggered_buffer_postenable(struct iio_dev *indio_dev)
                                (int)conflict);
                        ret = -EBUSY;
                }
+               iio_triggered_buffer_predisable(indio_dev);
                return ret;
        }
 
@@ -553,6 +558,7 @@ static int dln2_adc_triggered_buffer_postenable(struct iio_dev *indio_dev)
                mutex_unlock(&dln2->mutex);
                if (ret < 0) {
                        dev_dbg(&dln2->pdev->dev, "Problem in %s\n", __func__);
+                       iio_triggered_buffer_predisable(indio_dev);
                        return ret;
                }
        } else {
@@ -560,12 +566,12 @@ static int dln2_adc_triggered_buffer_postenable(struct iio_dev *indio_dev)
                mutex_unlock(&dln2->mutex);
        }
 
-       return iio_triggered_buffer_postenable(indio_dev);
+       return 0;
 }
 
 static int dln2_adc_triggered_buffer_predisable(struct iio_dev *indio_dev)
 {
-       int ret;
+       int ret, ret2;
        struct dln2_adc *dln2 = iio_priv(indio_dev);
 
        mutex_lock(&dln2->mutex);
@@ -580,12 +586,14 @@ static int dln2_adc_triggered_buffer_predisable(struct iio_dev *indio_dev)
        ret = dln2_adc_set_port_enabled(dln2, false, NULL);
 
        mutex_unlock(&dln2->mutex);
-       if (ret < 0) {
+       if (ret < 0)
                dev_dbg(&dln2->pdev->dev, "Problem in %s\n", __func__);
-               return ret;
-       }
 
-       return iio_triggered_buffer_predisable(indio_dev);
+       ret2 = iio_triggered_buffer_predisable(indio_dev);
+       if (ret == 0)
+               ret = ret2;
+
+       return ret;
 }
 
 static const struct iio_buffer_setup_ops dln2_adc_buffer_setup_ops = {
index 311c1a8..0939eb0 100644 (file)
@@ -460,6 +460,14 @@ static int max1027_probe(struct spi_device *spi)
                goto fail_dev_register;
        }
 
+       /* Internal reset */
+       st->reg = MAX1027_RST_REG;
+       ret = spi_write(st->spi, &st->reg, 1);
+       if (ret < 0) {
+               dev_err(&indio_dev->dev, "Failed to reset the ADC\n");
+               return ret;
+       }
+
        /* Disable averaging */
        st->reg = MAX1027_AVG_REG;
        ret = spi_write(st->spi, &st->reg, 1);
index 80beb64..69f4cfa 100644 (file)
@@ -59,8 +59,8 @@ config AD5446
        help
          Say yes here to build support for Analog Devices AD5300, AD5301, AD5310,
          AD5311, AD5320, AD5321, AD5444, AD5446, AD5450, AD5451, AD5452, AD5453,
-         AD5512A, AD5541A, AD5542A, AD5543, AD5553, AD5601, AD5602, AD5611, AD5612,
-         AD5620, AD5621, AD5622, AD5640, AD5641, AD5660, AD5662 DACs
+         AD5512A, AD5541A, AD5542A, AD5543, AD5553, AD5600, AD5601, AD5602, AD5611,
+         AD5612, AD5620, AD5621, AD5622, AD5640, AD5641, AD5660, AD5662 DACs
          as well as Texas Instruments DAC081S101, DAC101S101, DAC121S101.
 
          To compile this driver as a module, choose M here: the
index fd26a42..d3ce5de 100644 (file)
@@ -328,6 +328,7 @@ enum ad5446_supported_spi_device_ids {
        ID_AD5541A,
        ID_AD5512A,
        ID_AD5553,
+       ID_AD5600,
        ID_AD5601,
        ID_AD5611,
        ID_AD5621,
@@ -382,6 +383,10 @@ static const struct ad5446_chip_info ad5446_spi_chip_info[] = {
                .channel = AD5446_CHANNEL(14, 16, 0),
                .write = ad5446_write,
        },
+       [ID_AD5600] = {
+               .channel = AD5446_CHANNEL(16, 16, 0),
+               .write = ad5446_write,
+       },
        [ID_AD5601] = {
                .channel = AD5446_CHANNEL_POWERDOWN(8, 16, 6),
                .write = ad5446_write,
@@ -449,6 +454,7 @@ static const struct spi_device_id ad5446_spi_ids[] = {
        {"ad5542a", ID_AD5541A}, /* ad5541a and ad5542a are compatible */
        {"ad5543", ID_AD5541A}, /* ad5541a and ad5543 are compatible */
        {"ad5553", ID_AD5553},
+       {"ad5600", ID_AD5600},
        {"ad5601", ID_AD5601},
        {"ad5611", ID_AD5611},
        {"ad5621", ID_AD5621},
index 066e05f..ff6666a 100644 (file)
@@ -229,7 +229,7 @@ static int hdc100x_read_raw(struct iio_dev *indio_dev,
                        *val2 = 65536;
                        return IIO_VAL_FRACTIONAL;
                } else {
-                       *val = 100;
+                       *val = 100000;
                        *val2 = 65536;
                        return IIO_VAL_FRACTIONAL;
                }
index d3af4f2..ea24701 100644 (file)
@@ -727,6 +727,7 @@ static const struct iio_info adis16480_info = {
        .read_raw = &adis16480_read_raw,
        .write_raw = &adis16480_write_raw,
        .update_scan_mode = adis_update_scan_mode,
+       .debugfs_reg_access = adis_debugfs_reg_access,
 };
 
 static int adis16480_stop_device(struct iio_dev *indio_dev)
index baba8e5..6b560d9 100644 (file)
@@ -122,6 +122,7 @@ static const struct inv_mpu6050_hw hw_info[] = {
                .reg = &reg_set_6050,
                .config = &chip_config_6050,
                .fifo_size = 1024,
+               .temp = {INV_MPU6050_TEMP_OFFSET, INV_MPU6050_TEMP_SCALE},
        },
        {
                .whoami = INV_MPU6500_WHOAMI_VALUE,
@@ -129,6 +130,7 @@ static const struct inv_mpu6050_hw hw_info[] = {
                .reg = &reg_set_6500,
                .config = &chip_config_6050,
                .fifo_size = 512,
+               .temp = {INV_MPU6500_TEMP_OFFSET, INV_MPU6500_TEMP_SCALE},
        },
        {
                .whoami = INV_MPU6515_WHOAMI_VALUE,
@@ -136,6 +138,7 @@ static const struct inv_mpu6050_hw hw_info[] = {
                .reg = &reg_set_6500,
                .config = &chip_config_6050,
                .fifo_size = 512,
+               .temp = {INV_MPU6500_TEMP_OFFSET, INV_MPU6500_TEMP_SCALE},
        },
        {
                .whoami = INV_MPU6000_WHOAMI_VALUE,
@@ -143,6 +146,7 @@ static const struct inv_mpu6050_hw hw_info[] = {
                .reg = &reg_set_6050,
                .config = &chip_config_6050,
                .fifo_size = 1024,
+               .temp = {INV_MPU6050_TEMP_OFFSET, INV_MPU6050_TEMP_SCALE},
        },
        {
                .whoami = INV_MPU9150_WHOAMI_VALUE,
@@ -150,6 +154,7 @@ static const struct inv_mpu6050_hw hw_info[] = {
                .reg = &reg_set_6050,
                .config = &chip_config_6050,
                .fifo_size = 1024,
+               .temp = {INV_MPU6050_TEMP_OFFSET, INV_MPU6050_TEMP_SCALE},
        },
        {
                .whoami = INV_MPU9250_WHOAMI_VALUE,
@@ -157,6 +162,7 @@ static const struct inv_mpu6050_hw hw_info[] = {
                .reg = &reg_set_6500,
                .config = &chip_config_6050,
                .fifo_size = 512,
+               .temp = {INV_MPU6500_TEMP_OFFSET, INV_MPU6500_TEMP_SCALE},
        },
        {
                .whoami = INV_MPU9255_WHOAMI_VALUE,
@@ -164,6 +170,7 @@ static const struct inv_mpu6050_hw hw_info[] = {
                .reg = &reg_set_6500,
                .config = &chip_config_6050,
                .fifo_size = 512,
+               .temp = {INV_MPU6500_TEMP_OFFSET, INV_MPU6500_TEMP_SCALE},
        },
        {
                .whoami = INV_ICM20608_WHOAMI_VALUE,
@@ -171,6 +178,7 @@ static const struct inv_mpu6050_hw hw_info[] = {
                .reg = &reg_set_6500,
                .config = &chip_config_6050,
                .fifo_size = 512,
+               .temp = {INV_ICM20608_TEMP_OFFSET, INV_ICM20608_TEMP_SCALE},
        },
        {
                .whoami = INV_ICM20602_WHOAMI_VALUE,
@@ -178,6 +186,7 @@ static const struct inv_mpu6050_hw hw_info[] = {
                .reg = &reg_set_icm20602,
                .config = &chip_config_6050,
                .fifo_size = 1008,
+               .temp = {INV_ICM20608_TEMP_OFFSET, INV_ICM20608_TEMP_SCALE},
        },
 };
 
@@ -478,12 +487,8 @@ inv_mpu6050_read_raw(struct iio_dev *indio_dev,
 
                        return IIO_VAL_INT_PLUS_MICRO;
                case IIO_TEMP:
-                       *val = 0;
-                       if (st->chip_type == INV_ICM20602)
-                               *val2 = INV_ICM20602_TEMP_SCALE;
-                       else
-                               *val2 = INV_MPU6050_TEMP_SCALE;
-
+                       *val = st->hw->temp.scale / 1000000;
+                       *val2 = st->hw->temp.scale % 1000000;
                        return IIO_VAL_INT_PLUS_MICRO;
                default:
                        return -EINVAL;
@@ -491,11 +496,7 @@ inv_mpu6050_read_raw(struct iio_dev *indio_dev,
        case IIO_CHAN_INFO_OFFSET:
                switch (chan->type) {
                case IIO_TEMP:
-                       if (st->chip_type == INV_ICM20602)
-                               *val = INV_ICM20602_TEMP_OFFSET;
-                       else
-                               *val = INV_MPU6050_TEMP_OFFSET;
-
+                       *val = st->hw->temp.offset;
                        return IIO_VAL_INT;
                default:
                        return -EINVAL;
@@ -859,6 +860,25 @@ static const struct iio_chan_spec inv_mpu_channels[] = {
        INV_MPU6050_CHAN(IIO_ACCEL, IIO_MOD_Z, INV_MPU6050_SCAN_ACCL_Z),
 };
 
+static const unsigned long inv_mpu_scan_masks[] = {
+       /* 3-axis accel */
+       BIT(INV_MPU6050_SCAN_ACCL_X)
+               | BIT(INV_MPU6050_SCAN_ACCL_Y)
+               | BIT(INV_MPU6050_SCAN_ACCL_Z),
+       /* 3-axis gyro */
+       BIT(INV_MPU6050_SCAN_GYRO_X)
+               | BIT(INV_MPU6050_SCAN_GYRO_Y)
+               | BIT(INV_MPU6050_SCAN_GYRO_Z),
+       /* 6-axis accel + gyro */
+       BIT(INV_MPU6050_SCAN_ACCL_X)
+               | BIT(INV_MPU6050_SCAN_ACCL_Y)
+               | BIT(INV_MPU6050_SCAN_ACCL_Z)
+               | BIT(INV_MPU6050_SCAN_GYRO_X)
+               | BIT(INV_MPU6050_SCAN_GYRO_Y)
+               | BIT(INV_MPU6050_SCAN_GYRO_Z),
+       0,
+};
+
 static const struct iio_chan_spec inv_icm20602_channels[] = {
        IIO_CHAN_SOFT_TIMESTAMP(INV_ICM20602_SCAN_TIMESTAMP),
        {
@@ -885,6 +905,28 @@ static const struct iio_chan_spec inv_icm20602_channels[] = {
        INV_MPU6050_CHAN(IIO_ACCEL, IIO_MOD_Z, INV_ICM20602_SCAN_ACCL_Z),
 };
 
+static const unsigned long inv_icm20602_scan_masks[] = {
+       /* 3-axis accel + temp (mandatory) */
+       BIT(INV_ICM20602_SCAN_ACCL_X)
+               | BIT(INV_ICM20602_SCAN_ACCL_Y)
+               | BIT(INV_ICM20602_SCAN_ACCL_Z)
+               | BIT(INV_ICM20602_SCAN_TEMP),
+       /* 3-axis gyro + temp (mandatory) */
+       BIT(INV_ICM20602_SCAN_GYRO_X)
+               | BIT(INV_ICM20602_SCAN_GYRO_Y)
+               | BIT(INV_ICM20602_SCAN_GYRO_Z)
+               | BIT(INV_ICM20602_SCAN_TEMP),
+       /* 6-axis accel + gyro + temp (mandatory) */
+       BIT(INV_ICM20602_SCAN_ACCL_X)
+               | BIT(INV_ICM20602_SCAN_ACCL_Y)
+               | BIT(INV_ICM20602_SCAN_ACCL_Z)
+               | BIT(INV_ICM20602_SCAN_GYRO_X)
+               | BIT(INV_ICM20602_SCAN_GYRO_Y)
+               | BIT(INV_ICM20602_SCAN_GYRO_Z)
+               | BIT(INV_ICM20602_SCAN_TEMP),
+       0,
+};
+
 /*
  * The user can choose any frequency between INV_MPU6050_MIN_FIFO_RATE and
  * INV_MPU6050_MAX_FIFO_RATE, but only these frequencies are matched by the
@@ -1089,9 +1131,11 @@ int inv_mpu_core_probe(struct regmap *regmap, int irq, const char *name,
        if (chip_type == INV_ICM20602) {
                indio_dev->channels = inv_icm20602_channels;
                indio_dev->num_channels = ARRAY_SIZE(inv_icm20602_channels);
+               indio_dev->available_scan_masks = inv_icm20602_scan_masks;
        } else {
                indio_dev->channels = inv_mpu_channels;
                indio_dev->num_channels = ARRAY_SIZE(inv_mpu_channels);
+               indio_dev->available_scan_masks = inv_mpu_scan_masks;
        }
 
        indio_dev->info = &mpu_info;
index 6ef872f..220eba5 100644 (file)
@@ -109,6 +109,7 @@ struct inv_mpu6050_chip_config {
  *  @reg:   register map of the chip.
  *  @config:    configuration of the chip.
  *  @fifo_size:        size of the FIFO in bytes.
+ *  @temp:     offset and scale to apply to raw temperature.
  */
 struct inv_mpu6050_hw {
        u8 whoami;
@@ -116,6 +117,10 @@ struct inv_mpu6050_hw {
        const struct inv_mpu6050_reg_map *reg;
        const struct inv_mpu6050_chip_config *config;
        size_t fifo_size;
+       struct {
+               int offset;
+               int scale;
+       } temp;
 };
 
 /*
@@ -224,16 +229,19 @@ struct inv_mpu6050_state {
 #define INV_MPU6050_REG_UP_TIME_MIN          5000
 #define INV_MPU6050_REG_UP_TIME_MAX          10000
 
-#define INV_MPU6050_TEMP_OFFSET                     12421
-#define INV_MPU6050_TEMP_SCALE               2941
+#define INV_MPU6050_TEMP_OFFSET                     12420
+#define INV_MPU6050_TEMP_SCALE               2941176
 #define INV_MPU6050_MAX_GYRO_FS_PARAM        3
 #define INV_MPU6050_MAX_ACCL_FS_PARAM        3
 #define INV_MPU6050_THREE_AXIS               3
 #define INV_MPU6050_GYRO_CONFIG_FSR_SHIFT    3
 #define INV_MPU6050_ACCL_CONFIG_FSR_SHIFT    3
 
-#define INV_ICM20602_TEMP_OFFSET            8170
-#define INV_ICM20602_TEMP_SCALE                     3060
+#define INV_MPU6500_TEMP_OFFSET              7011
+#define INV_MPU6500_TEMP_SCALE               2995178
+
+#define INV_ICM20608_TEMP_OFFSET            8170
+#define INV_ICM20608_TEMP_SCALE                     3059976
 
 /* 6 + 6 round up and plus 8 */
 #define INV_MPU6050_OUTPUT_DATA_SIZE         24
index a814828..5f5d54c 100644 (file)
@@ -62,9 +62,9 @@ struct bh1750_chip_info {
 
        u16 int_time_low_mask;
        u16 int_time_high_mask;
-}
+};
 
-static const bh1750_chip_info_tbl[] = {
+static const struct bh1750_chip_info bh1750_chip_info_tbl[] = {
        [BH1710] = { 140, 1022, 300, 400,  250000000, 2, 0x001F, 0x03E0 },
        [BH1721] = { 140, 1020, 300, 400,  250000000, 2, 0x0010, 0x03E0 },
        [BH1750] = { 31,  254,  69,  1740, 57500000,  1, 0x001F, 0x00E0 },
index 8cc3df2..9167a1c 100644 (file)
@@ -1701,6 +1701,14 @@ static void qedr_cleanup_user(struct qedr_dev *dev, struct qedr_qp *qp)
        if (qp->urq.umem)
                ib_umem_release(qp->urq.umem);
        qp->urq.umem = NULL;
+
+       if (rdma_protocol_roce(&dev->ibdev, 1)) {
+               qedr_free_pbl(dev, &qp->usq.pbl_info, qp->usq.pbl_tbl);
+               qedr_free_pbl(dev, &qp->urq.pbl_info, qp->urq.pbl_tbl);
+       } else {
+               kfree(qp->usq.pbl_tbl);
+               kfree(qp->urq.pbl_tbl);
+       }
 }
 
 static int qedr_create_user_qp(struct qedr_dev *dev,
@@ -2809,8 +2817,8 @@ int qedr_dereg_mr(struct ib_mr *ib_mr)
 
        dev->ops->rdma_free_tid(dev->rdma_ctx, mr->hw_mr.itid);
 
-       if ((mr->type != QEDR_MR_DMA) && (mr->type != QEDR_MR_FRMR))
-               qedr_free_pbl(dev, &mr->info.pbl_info, mr->info.pbl_table);
+       if (mr->type != QEDR_MR_DMA)
+               free_mr_info(dev, &mr->info);
 
        /* it could be user registered memory. */
        if (mr->umem)
index 3fecd87..b4e0ae0 100644 (file)
@@ -646,6 +646,7 @@ iscsi_iser_session_create(struct iscsi_endpoint *ep,
                if (ib_conn->pi_support) {
                        u32 sig_caps = ib_conn->device->ib_device->attrs.sig_prot_cap;
 
+                       shost->sg_prot_tablesize = shost->sg_tablesize;
                        scsi_host_set_prot(shost, iser_dif_prot_caps(sig_caps));
                        scsi_host_set_guard(shost, SHOST_DIX_GUARD_IP |
                                                   SHOST_DIX_GUARD_CRC);
index a7ace07..e8f98de 100644 (file)
@@ -3162,6 +3162,8 @@ static int __maybe_unused mxt_suspend(struct device *dev)
 
        mutex_unlock(&input_dev->mutex);
 
+       disable_irq(data->irq);
+
        return 0;
 }
 
@@ -3174,6 +3176,8 @@ static int __maybe_unused mxt_resume(struct device *dev)
        if (!input_dev)
                return 0;
 
+       enable_irq(data->irq);
+
        mutex_lock(&input_dev->mutex);
 
        if (input_dev->users)
index ad3e2b9..140b287 100644 (file)
@@ -977,13 +977,13 @@ static struct iommu_domain *rk_iommu_domain_alloc(unsigned type)
        if (!dma_dev)
                return NULL;
 
-       rk_domain = devm_kzalloc(dma_dev, sizeof(*rk_domain), GFP_KERNEL);
+       rk_domain = kzalloc(sizeof(*rk_domain), GFP_KERNEL);
        if (!rk_domain)
                return NULL;
 
        if (type == IOMMU_DOMAIN_DMA &&
            iommu_get_dma_cookie(&rk_domain->domain))
-               return NULL;
+               goto err_free_domain;
 
        /*
         * rk32xx iommus use a 2 level pagetable.
@@ -1018,6 +1018,8 @@ err_free_dt:
 err_put_cookie:
        if (type == IOMMU_DOMAIN_DMA)
                iommu_put_dma_cookie(&rk_domain->domain);
+err_free_domain:
+       kfree(rk_domain);
 
        return NULL;
 }
@@ -1046,6 +1048,7 @@ static void rk_iommu_domain_free(struct iommu_domain *domain)
 
        if (domain->type == IOMMU_DOMAIN_DMA)
                iommu_put_dma_cookie(&rk_domain->domain);
+       kfree(rk_domain);
 }
 
 static int rk_iommu_add_device(struct device *dev)
index 121d3cb..fa0ecb5 100644 (file)
@@ -164,9 +164,9 @@ static bool smmu_dma_addr_valid(struct tegra_smmu *smmu, dma_addr_t addr)
        return (addr & smmu->pfn_mask) == addr;
 }
 
-static dma_addr_t smmu_pde_to_dma(u32 pde)
+static dma_addr_t smmu_pde_to_dma(struct tegra_smmu *smmu, u32 pde)
 {
-       return pde << 12;
+       return (dma_addr_t)(pde & smmu->pfn_mask) << 12;
 }
 
 static void smmu_flush_ptc_all(struct tegra_smmu *smmu)
@@ -551,6 +551,7 @@ static u32 *tegra_smmu_pte_lookup(struct tegra_smmu_as *as, unsigned long iova,
                                  dma_addr_t *dmap)
 {
        unsigned int pd_index = iova_pd_index(iova);
+       struct tegra_smmu *smmu = as->smmu;
        struct page *pt_page;
        u32 *pd;
 
@@ -559,7 +560,7 @@ static u32 *tegra_smmu_pte_lookup(struct tegra_smmu_as *as, unsigned long iova,
                return NULL;
 
        pd = page_address(as->pd);
-       *dmap = smmu_pde_to_dma(pd[pd_index]);
+       *dmap = smmu_pde_to_dma(smmu, pd[pd_index]);
 
        return tegra_smmu_pte_offset(pt_page, iova);
 }
@@ -601,7 +602,7 @@ static u32 *as_get_pte(struct tegra_smmu_as *as, dma_addr_t iova,
        } else {
                u32 *pd = page_address(as->pd);
 
-               *dmap = smmu_pde_to_dma(pd[pde]);
+               *dmap = smmu_pde_to_dma(smmu, pd[pde]);
        }
 
        return tegra_smmu_pte_offset(as->pts[pde], iova);
@@ -626,7 +627,7 @@ static void tegra_smmu_pte_put_use(struct tegra_smmu_as *as, unsigned long iova)
        if (--as->count[pde] == 0) {
                struct tegra_smmu *smmu = as->smmu;
                u32 *pd = page_address(as->pd);
-               dma_addr_t pte_dma = smmu_pde_to_dma(pd[pde]);
+               dma_addr_t pte_dma = smmu_pde_to_dma(smmu, pd[pde]);
 
                tegra_smmu_set_pde(as, iova, 0);
 
index 0f6e30e..f53dfc5 100644 (file)
@@ -284,6 +284,10 @@ static int __init bcm7038_l1_init_one(struct device_node *dn,
                pr_err("failed to map parent interrupt %d\n", parent_irq);
                return -EINVAL;
        }
+
+       if (of_property_read_bool(dn, "brcm,irq-can-wake"))
+               enable_irq_wake(parent_irq);
+
        irq_set_chained_handler_and_data(parent_irq, bcm7038_l1_irq_handle,
                                         intc);
 
index 2ff0898..be6923a 100644 (file)
@@ -117,6 +117,14 @@ static int __init ingenic_intc_of_init(struct device_node *node,
                goto out_unmap_irq;
        }
 
+       domain = irq_domain_add_legacy(node, num_chips * 32,
+                                      JZ4740_IRQ_BASE, 0,
+                                      &irq_domain_simple_ops, NULL);
+       if (!domain) {
+               err = -ENOMEM;
+               goto out_unmap_base;
+       }
+
        for (i = 0; i < num_chips; i++) {
                /* Mask all irqs */
                writel(0xffffffff, intc->base + (i * CHIP_SIZE) +
@@ -143,14 +151,11 @@ static int __init ingenic_intc_of_init(struct device_node *node,
                                       IRQ_NOPROBE | IRQ_LEVEL);
        }
 
-       domain = irq_domain_add_legacy(node, num_chips * 32, JZ4740_IRQ_BASE, 0,
-                                      &irq_domain_simple_ops, NULL);
-       if (!domain)
-               pr_warn("unable to register IRQ domain\n");
-
        setup_irq(parent_irq, &intc_cascade_action);
        return 0;
 
+out_unmap_base:
+       iounmap(intc->base);
 out_unmap_irq:
        irq_dispose_mapping(parent_irq);
 out_free:
index eade36d..4c239f1 100644 (file)
@@ -574,8 +574,7 @@ static int gigaset_initcshw(struct cardstate *cs)
 {
        struct usb_cardstate *ucs;
 
-       cs->hw.usb = ucs =
-               kmalloc(sizeof(struct usb_cardstate), GFP_KERNEL);
+       cs->hw.usb = ucs = kzalloc(sizeof(struct usb_cardstate), GFP_KERNEL);
        if (!ucs) {
                pr_err("out of memory\n");
                return -ENOMEM;
@@ -587,9 +586,6 @@ static int gigaset_initcshw(struct cardstate *cs)
        ucs->bchars[3] = 0;
        ucs->bchars[4] = 0x11;
        ucs->bchars[5] = 0x13;
-       ucs->bulk_out_buffer = NULL;
-       ucs->bulk_out_urb = NULL;
-       ucs->read_urb = NULL;
        tasklet_init(&cs->write_tasklet,
                     gigaset_modem_fill, (unsigned long) cs);
 
@@ -688,6 +684,11 @@ static int gigaset_probe(struct usb_interface *interface,
                return -ENODEV;
        }
 
+       if (hostif->desc.bNumEndpoints < 2) {
+               dev_err(&interface->dev, "missing endpoints\n");
+               return -ENODEV;
+       }
+
        dev_info(&udev->dev, "%s: Device matched ... !\n", __func__);
 
        /* allocate memory for our device state and initialize it */
@@ -707,6 +708,12 @@ static int gigaset_probe(struct usb_interface *interface,
 
        endpoint = &hostif->endpoint[0].desc;
 
+       if (!usb_endpoint_is_bulk_out(endpoint)) {
+               dev_err(&interface->dev, "missing bulk-out endpoint\n");
+               retval = -ENODEV;
+               goto error;
+       }
+
        buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
        ucs->bulk_out_size = buffer_size;
        ucs->bulk_out_epnum = usb_endpoint_num(endpoint);
@@ -726,6 +733,12 @@ static int gigaset_probe(struct usb_interface *interface,
 
        endpoint = &hostif->endpoint[1].desc;
 
+       if (!usb_endpoint_is_int_in(endpoint)) {
+               dev_err(&interface->dev, "missing int-in endpoint\n");
+               retval = -ENODEV;
+               goto error;
+       }
+
        ucs->busy = 0;
 
        ucs->read_urb = usb_alloc_urb(0, GFP_KERNEL);
index 4f413a7..d79a66a 100644 (file)
@@ -337,9 +337,18 @@ static int lm3692x_probe_dt(struct lm3692x_led *led)
                return ret;
        }
 
-       led->regulator = devm_regulator_get(&led->client->dev, "vled");
-       if (IS_ERR(led->regulator))
+       led->regulator = devm_regulator_get_optional(&led->client->dev, "vled");
+       if (IS_ERR(led->regulator)) {
+               ret = PTR_ERR(led->regulator);
+               if (ret != -ENODEV) {
+                       if (ret != -EPROBE_DEFER)
+                               dev_err(&led->client->dev,
+                                       "Failed to get vled regulator: %d\n",
+                                       ret);
+                       return ret;
+               }
                led->regulator = NULL;
+       }
 
        child = device_get_next_child_node(&led->client->dev, child);
        if (!child) {
index 136f86a..d5e774d 100644 (file)
@@ -302,10 +302,12 @@ static int netdev_trig_notify(struct notifier_block *nb,
                container_of(nb, struct led_netdev_data, notifier);
 
        if (evt != NETDEV_UP && evt != NETDEV_DOWN && evt != NETDEV_CHANGE
-           && evt != NETDEV_REGISTER && evt != NETDEV_UNREGISTER)
+           && evt != NETDEV_REGISTER && evt != NETDEV_UNREGISTER
+           && evt != NETDEV_CHANGENAME)
                return NOTIFY_DONE;
 
        if (!(dev == trigger_data->net_dev ||
+             (evt == NETDEV_CHANGENAME && !strcmp(dev->name, trigger_data->device_name)) ||
              (evt == NETDEV_REGISTER && !strcmp(dev->name, trigger_data->device_name))))
                return NOTIFY_DONE;
 
@@ -315,6 +317,7 @@ static int netdev_trig_notify(struct notifier_block *nb,
 
        clear_bit(NETDEV_LED_MODE_LINKUP, &trigger_data->mode);
        switch (evt) {
+       case NETDEV_CHANGENAME:
        case NETDEV_REGISTER:
                if (trigger_data->net_dev)
                        dev_put(trigger_data->net_dev);
index 363d35d..2f47023 100644 (file)
@@ -214,8 +214,10 @@ static void imx_mu_shutdown(struct mbox_chan *chan)
        struct imx_mu_priv *priv = to_imx_mu_priv(chan->mbox);
        struct imx_mu_con_priv *cp = chan->con_priv;
 
-       if (cp->type == IMX_MU_TYPE_TXDB)
+       if (cp->type == IMX_MU_TYPE_TXDB) {
                tasklet_kill(&cp->txdb_tasklet);
+               return;
+       }
 
        imx_mu_xcr_rmw(priv, 0,
                   IMX_MU_xCR_TIEn(cp->idx) | IMX_MU_xCR_RIEn(cp->idx));
index 9c3beb1..46794ca 100644 (file)
@@ -377,7 +377,10 @@ retry_invalidate:
                        if (!fifo_full(&ca->free_inc))
                                goto retry_invalidate;
 
-                       bch_prio_write(ca);
+                       if (bch_prio_write(ca, false) < 0) {
+                               ca->invalidate_needs_gc = 1;
+                               wake_up_gc(ca->set);
+                       }
                }
        }
 out:
index 83f0b91..4677b18 100644 (file)
@@ -959,7 +959,7 @@ bool bch_cached_dev_error(struct cached_dev *dc);
 __printf(2, 3)
 bool bch_cache_set_error(struct cache_set *c, const char *fmt, ...);
 
-void bch_prio_write(struct cache *ca);
+int bch_prio_write(struct cache *ca, bool wait);
 void bch_write_bdev_super(struct cached_dev *dc, struct closure *parent);
 
 extern struct workqueue_struct *bcache_wq;
index 45f6846..bb40bd6 100644 (file)
@@ -713,6 +713,8 @@ static unsigned long bch_mca_scan(struct shrinker *shrink,
         * IO can always make forward progress:
         */
        nr /= c->btree_pages;
+       if (nr == 0)
+               nr = 1;
        nr = min_t(unsigned long, nr, mca_can_free(c));
 
        i = 0;
index 14d381c..c45d9ad 100644 (file)
@@ -525,12 +525,29 @@ static void prio_io(struct cache *ca, uint64_t bucket, int op,
        closure_sync(cl);
 }
 
-void bch_prio_write(struct cache *ca)
+int bch_prio_write(struct cache *ca, bool wait)
 {
        int i;
        struct bucket *b;
        struct closure cl;
 
+       pr_debug("free_prio=%zu, free_none=%zu, free_inc=%zu",
+                fifo_used(&ca->free[RESERVE_PRIO]),
+                fifo_used(&ca->free[RESERVE_NONE]),
+                fifo_used(&ca->free_inc));
+
+       /*
+        * Pre-check if there are enough free buckets. In the non-blocking
+        * scenario it's better to fail early rather than starting to allocate
+        * buckets and do a cleanup later in case of failure.
+        */
+       if (!wait) {
+               size_t avail = fifo_used(&ca->free[RESERVE_PRIO]) +
+                              fifo_used(&ca->free[RESERVE_NONE]);
+               if (prio_buckets(ca) > avail)
+                       return -ENOMEM;
+       }
+
        closure_init_stack(&cl);
 
        lockdep_assert_held(&ca->set->bucket_lock);
@@ -540,9 +557,6 @@ void bch_prio_write(struct cache *ca)
        atomic_long_add(ca->sb.bucket_size * prio_buckets(ca),
                        &ca->meta_sectors_written);
 
-       //pr_debug("free %zu, free_inc %zu, unused %zu", fifo_used(&ca->free),
-       //       fifo_used(&ca->free_inc), fifo_used(&ca->unused));
-
        for (i = prio_buckets(ca) - 1; i >= 0; --i) {
                long bucket;
                struct prio_set *p = ca->disk_buckets;
@@ -560,7 +574,7 @@ void bch_prio_write(struct cache *ca)
                p->magic        = pset_magic(&ca->sb);
                p->csum         = bch_crc64(&p->magic, bucket_bytes(ca) - 8);
 
-               bucket = bch_bucket_alloc(ca, RESERVE_PRIO, true);
+               bucket = bch_bucket_alloc(ca, RESERVE_PRIO, wait);
                BUG_ON(bucket == -1);
 
                mutex_unlock(&ca->set->bucket_lock);
@@ -589,6 +603,7 @@ void bch_prio_write(struct cache *ca)
 
                ca->prio_last_buckets[i] = ca->prio_buckets[i];
        }
+       return 0;
 }
 
 static void prio_read(struct cache *ca, uint64_t bucket)
@@ -747,20 +762,28 @@ static inline int idx_to_first_minor(int idx)
 
 static void bcache_device_free(struct bcache_device *d)
 {
+       struct gendisk *disk = d->disk;
+
        lockdep_assert_held(&bch_register_lock);
 
-       pr_info("%s stopped", d->disk->disk_name);
+       if (disk)
+               pr_info("%s stopped", disk->disk_name);
+       else
+               pr_err("bcache device (NULL gendisk) stopped");
 
        if (d->c)
                bcache_device_detach(d);
-       if (d->disk && d->disk->flags & GENHD_FL_UP)
-               del_gendisk(d->disk);
-       if (d->disk && d->disk->queue)
-               blk_cleanup_queue(d->disk->queue);
-       if (d->disk) {
+
+       if (disk) {
+               if (disk->flags & GENHD_FL_UP)
+                       del_gendisk(disk);
+
+               if (disk->queue)
+                       blk_cleanup_queue(disk->queue);
+
                ida_simple_remove(&bcache_device_idx,
-                                 first_minor_to_idx(d->disk->first_minor));
-               put_disk(d->disk);
+                                 first_minor_to_idx(disk->first_minor));
+               put_disk(disk);
        }
 
        bioset_exit(&d->bio_split);
@@ -1876,7 +1899,7 @@ static int run_cache_set(struct cache_set *c)
 
                mutex_lock(&c->bucket_lock);
                for_each_cache(ca, c, i)
-                       bch_prio_write(ca);
+                       bch_prio_write(ca, true);
                mutex_unlock(&c->bucket_lock);
 
                err = "cannot allocate new UUID bucket";
index 481e54d..def4f6e 100644 (file)
@@ -609,45 +609,10 @@ static struct pgpath *__map_bio(struct multipath *m, struct bio *bio)
        return pgpath;
 }
 
-static struct pgpath *__map_bio_fast(struct multipath *m, struct bio *bio)
-{
-       struct pgpath *pgpath;
-       unsigned long flags;
-
-       /* Do we need to select a new pgpath? */
-       /*
-        * FIXME: currently only switching path if no path (due to failure, etc)
-        * - which negates the point of using a path selector
-        */
-       pgpath = READ_ONCE(m->current_pgpath);
-       if (!pgpath)
-               pgpath = choose_pgpath(m, bio->bi_iter.bi_size);
-
-       if (!pgpath) {
-               if (test_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags)) {
-                       /* Queue for the daemon to resubmit */
-                       spin_lock_irqsave(&m->lock, flags);
-                       bio_list_add(&m->queued_bios, bio);
-                       spin_unlock_irqrestore(&m->lock, flags);
-                       queue_work(kmultipathd, &m->process_queued_bios);
-
-                       return ERR_PTR(-EAGAIN);
-               }
-               return NULL;
-       }
-
-       return pgpath;
-}
-
 static int __multipath_map_bio(struct multipath *m, struct bio *bio,
                               struct dm_mpath_io *mpio)
 {
-       struct pgpath *pgpath;
-
-       if (!m->hw_handler_name)
-               pgpath = __map_bio_fast(m, bio);
-       else
-               pgpath = __map_bio(m, bio);
+       struct pgpath *pgpath = __map_bio(m, bio);
 
        if (IS_ERR(pgpath))
                return DM_MAPIO_SUBMITTED;
index 5f1f80d..503c426 100644 (file)
@@ -1223,7 +1223,8 @@ bio_copy:
                        }
                } while (bio->bi_iter.bi_size);
 
-               if (unlikely(wc->uncommitted_blocks >= wc->autocommit_blocks))
+               if (unlikely(bio->bi_opf & REQ_FUA ||
+                            wc->uncommitted_blocks >= wc->autocommit_blocks))
                        writecache_flush(wc);
                else
                        writecache_schedule_autocommit(wc);
index 7e8d7fc..c2c1714 100644 (file)
@@ -552,6 +552,7 @@ static struct dmz_mblock *dmz_get_mblock(struct dmz_metadata *zmd,
                       TASK_UNINTERRUPTIBLE);
        if (test_bit(DMZ_META_ERROR, &mblk->state)) {
                dmz_release_mblock(zmd, mblk);
+               dmz_check_bdev(zmd->dev);
                return ERR_PTR(-EIO);
        }
 
@@ -623,6 +624,8 @@ static int dmz_rdwr_block(struct dmz_metadata *zmd, int op, sector_t block,
        ret = submit_bio_wait(bio);
        bio_put(bio);
 
+       if (ret)
+               dmz_check_bdev(zmd->dev);
        return ret;
 }
 
@@ -689,6 +692,7 @@ static int dmz_write_dirty_mblocks(struct dmz_metadata *zmd,
                               TASK_UNINTERRUPTIBLE);
                if (test_bit(DMZ_META_ERROR, &mblk->state)) {
                        clear_bit(DMZ_META_ERROR, &mblk->state);
+                       dmz_check_bdev(zmd->dev);
                        ret = -EIO;
                }
                nr_mblks_submitted--;
@@ -766,7 +770,7 @@ int dmz_flush_metadata(struct dmz_metadata *zmd)
        /* If there are no dirty metadata blocks, just flush the device cache */
        if (list_empty(&write_list)) {
                ret = blkdev_issue_flush(zmd->dev->bdev, GFP_NOIO, NULL);
-               goto out;
+               goto err;
        }
 
        /*
@@ -776,7 +780,7 @@ int dmz_flush_metadata(struct dmz_metadata *zmd)
         */
        ret = dmz_log_dirty_mblocks(zmd, &write_list);
        if (ret)
-               goto out;
+               goto err;
 
        /*
         * The log is on disk. It is now safe to update in place
@@ -784,11 +788,11 @@ int dmz_flush_metadata(struct dmz_metadata *zmd)
         */
        ret = dmz_write_dirty_mblocks(zmd, &write_list, zmd->mblk_primary);
        if (ret)
-               goto out;
+               goto err;
 
        ret = dmz_write_sb(zmd, zmd->mblk_primary);
        if (ret)
-               goto out;
+               goto err;
 
        while (!list_empty(&write_list)) {
                mblk = list_first_entry(&write_list, struct dmz_mblock, link);
@@ -803,16 +807,20 @@ int dmz_flush_metadata(struct dmz_metadata *zmd)
 
        zmd->sb_gen++;
 out:
-       if (ret && !list_empty(&write_list)) {
-               spin_lock(&zmd->mblk_lock);
-               list_splice(&write_list, &zmd->mblk_dirty_list);
-               spin_unlock(&zmd->mblk_lock);
-       }
-
        dmz_unlock_flush(zmd);
        up_write(&zmd->mblk_sem);
 
        return ret;
+
+err:
+       if (!list_empty(&write_list)) {
+               spin_lock(&zmd->mblk_lock);
+               list_splice(&write_list, &zmd->mblk_dirty_list);
+               spin_unlock(&zmd->mblk_lock);
+       }
+       if (!dmz_check_bdev(zmd->dev))
+               ret = -EIO;
+       goto out;
 }
 
 /*
@@ -1235,6 +1243,7 @@ static int dmz_update_zone(struct dmz_metadata *zmd, struct dm_zone *zone)
        if (ret) {
                dmz_dev_err(zmd->dev, "Get zone %u report failed",
                            dmz_id(zmd, zone));
+               dmz_check_bdev(zmd->dev);
                return ret;
        }
 
index 9470b8f..84ac671 100644 (file)
@@ -81,6 +81,7 @@ static int dmz_reclaim_align_wp(struct dmz_reclaim *zrc, struct dm_zone *zone,
                            "Align zone %u wp %llu to %llu (wp+%u) blocks failed %d",
                            dmz_id(zmd, zone), (unsigned long long)wp_block,
                            (unsigned long long)block, nr_blocks, ret);
+               dmz_check_bdev(zrc->dev);
                return ret;
        }
 
@@ -488,12 +489,7 @@ static void dmz_reclaim_work(struct work_struct *work)
        ret = dmz_do_reclaim(zrc);
        if (ret) {
                dmz_dev_debug(zrc->dev, "Reclaim error %d\n", ret);
-               if (ret == -EIO)
-                       /*
-                        * LLD might be performing some error handling sequence
-                        * at the underlying device. To not interfere, do not
-                        * attempt to schedule the next reclaim run immediately.
-                        */
+               if (!dmz_check_bdev(zrc->dev))
                        return;
        }
 
index 3dd668f..971a2da 100644 (file)
@@ -79,6 +79,8 @@ static inline void dmz_bio_endio(struct bio *bio, blk_status_t status)
 
        if (status != BLK_STS_OK && bio->bi_status == BLK_STS_OK)
                bio->bi_status = status;
+       if (bio->bi_status != BLK_STS_OK)
+               bioctx->target->dev->flags |= DMZ_CHECK_BDEV;
 
        if (atomic_dec_and_test(&bioctx->ref)) {
                struct dm_zone *zone = bioctx->zone;
@@ -564,32 +566,52 @@ out:
 }
 
 /*
- * Check the backing device availability. If it's on the way out,
+ * Check if the backing device is being removed. If it's on the way out,
  * start failing I/O. Reclaim and metadata components also call this
  * function to cleanly abort operation in the event of such failure.
  */
 bool dmz_bdev_is_dying(struct dmz_dev *dmz_dev)
 {
-       struct gendisk *disk;
+       if (dmz_dev->flags & DMZ_BDEV_DYING)
+               return true;
 
-       if (!(dmz_dev->flags & DMZ_BDEV_DYING)) {
-               disk = dmz_dev->bdev->bd_disk;
-               if (blk_queue_dying(bdev_get_queue(dmz_dev->bdev))) {
-                       dmz_dev_warn(dmz_dev, "Backing device queue dying");
-                       dmz_dev->flags |= DMZ_BDEV_DYING;
-               } else if (disk->fops->check_events) {
-                       if (disk->fops->check_events(disk, 0) &
-                                       DISK_EVENT_MEDIA_CHANGE) {
-                               dmz_dev_warn(dmz_dev, "Backing device offline");
-                               dmz_dev->flags |= DMZ_BDEV_DYING;
-                       }
-               }
+       if (dmz_dev->flags & DMZ_CHECK_BDEV)
+               return !dmz_check_bdev(dmz_dev);
+
+       if (blk_queue_dying(bdev_get_queue(dmz_dev->bdev))) {
+               dmz_dev_warn(dmz_dev, "Backing device queue dying");
+               dmz_dev->flags |= DMZ_BDEV_DYING;
        }
 
        return dmz_dev->flags & DMZ_BDEV_DYING;
 }
 
 /*
+ * Check the backing device availability. This detects such events as
+ * backing device going offline due to errors, media removals, etc.
+ * This check is less efficient than dmz_bdev_is_dying() and should
+ * only be performed as a part of error handling.
+ */
+bool dmz_check_bdev(struct dmz_dev *dmz_dev)
+{
+       struct gendisk *disk;
+
+       dmz_dev->flags &= ~DMZ_CHECK_BDEV;
+
+       if (dmz_bdev_is_dying(dmz_dev))
+               return false;
+
+       disk = dmz_dev->bdev->bd_disk;
+       if (disk->fops->check_events &&
+           disk->fops->check_events(disk, 0) & DISK_EVENT_MEDIA_CHANGE) {
+               dmz_dev_warn(dmz_dev, "Backing device offline");
+               dmz_dev->flags |= DMZ_BDEV_DYING;
+       }
+
+       return !(dmz_dev->flags & DMZ_BDEV_DYING);
+}
+
+/*
  * Process a new BIO.
  */
 static int dmz_map(struct dm_target *ti, struct bio *bio)
@@ -902,8 +924,8 @@ static int dmz_prepare_ioctl(struct dm_target *ti, struct block_device **bdev)
 {
        struct dmz_target *dmz = ti->private;
 
-       if (dmz_bdev_is_dying(dmz->dev))
-               return -ENODEV;
+       if (!dmz_check_bdev(dmz->dev))
+               return -EIO;
 
        *bdev = dmz->dev->bdev;
 
index 93a6452..2662746 100644 (file)
@@ -71,6 +71,7 @@ struct dmz_dev {
 
 /* Device flags. */
 #define DMZ_BDEV_DYING         (1 << 0)
+#define DMZ_CHECK_BDEV         (2 << 0)
 
 /*
  * Zone descriptor.
@@ -254,5 +255,6 @@ void dmz_schedule_reclaim(struct dmz_reclaim *zrc);
  * Functions defined in dm-zoned-target.c
  */
 bool dmz_bdev_is_dying(struct dmz_dev *dmz_dev);
+bool dmz_check_bdev(struct dmz_dev *dmz_dev);
 
 #endif /* DM_ZONED_H */
index 2fc8c11..fd86071 100644 (file)
@@ -2132,6 +2132,7 @@ int md_bitmap_resize(struct bitmap *bitmap, sector_t blocks,
                memcpy(page_address(store.sb_page),
                       page_address(bitmap->storage.sb_page),
                       sizeof(bitmap_super_t));
+       spin_lock_irq(&bitmap->counts.lock);
        md_bitmap_file_unmap(&bitmap->storage);
        bitmap->storage = store;
 
@@ -2147,7 +2148,6 @@ int md_bitmap_resize(struct bitmap *bitmap, sector_t blocks,
        blocks = min(old_counts.chunks << old_counts.chunkshift,
                     chunks << chunkshift);
 
-       spin_lock_irq(&bitmap->counts.lock);
        /* For cluster raid, need to pre-allocate bitmap */
        if (mddev_is_clustered(bitmap->mddev)) {
                unsigned long page;
index d45c697..9a60231 100644 (file)
@@ -252,10 +252,9 @@ static bool linear_make_request(struct mddev *mddev, struct bio *bio)
        sector_t start_sector, end_sector, data_offset;
        sector_t bio_sector = bio->bi_iter.bi_sector;
 
-       if (unlikely(bio->bi_opf & REQ_PREFLUSH)) {
-               md_flush_request(mddev, bio);
+       if (unlikely(bio->bi_opf & REQ_PREFLUSH)
+           && md_flush_request(mddev, bio))
                return true;
-       }
 
        tmp_dev = which_dev(mddev, bio_sector);
        start_sector = tmp_dev->end_sector - tmp_dev->rdev->sectors;
index 881487d..80c35bf 100644 (file)
@@ -112,10 +112,9 @@ static bool multipath_make_request(struct mddev *mddev, struct bio * bio)
        struct multipath_bh * mp_bh;
        struct multipath_info *multipath;
 
-       if (unlikely(bio->bi_opf & REQ_PREFLUSH)) {
-               md_flush_request(mddev, bio);
+       if (unlikely(bio->bi_opf & REQ_PREFLUSH)
+           && md_flush_request(mddev, bio))
                return true;
-       }
 
        mp_bh = mempool_alloc(&conf->pool, GFP_NOIO);
 
index 2fe4f93..62f214d 100644 (file)
@@ -487,7 +487,13 @@ static void md_submit_flush_data(struct work_struct *ws)
        }
 }
 
-void md_flush_request(struct mddev *mddev, struct bio *bio)
+/*
+ * Manages consolidation of flushes and submitting any flushes needed for
+ * a bio with REQ_PREFLUSH.  Returns true if the bio is finished or is
+ * being finished in another context.  Returns false if the flushing is
+ * complete but still needs the I/O portion of the bio to be processed.
+ */
+bool md_flush_request(struct mddev *mddev, struct bio *bio)
 {
        ktime_t start = ktime_get_boottime();
        spin_lock_irq(&mddev->lock);
@@ -512,9 +518,10 @@ void md_flush_request(struct mddev *mddev, struct bio *bio)
                        bio_endio(bio);
                else {
                        bio->bi_opf &= ~REQ_PREFLUSH;
-                       mddev->pers->make_request(mddev, bio);
+                       return false;
                }
        }
+       return true;
 }
 EXPORT_SYMBOL(md_flush_request);
 
index 4f89463..cce62bb 100644 (file)
@@ -532,7 +532,7 @@ struct md_personality
        int level;
        struct list_head list;
        struct module *owner;
-       bool (*make_request)(struct mddev *mddev, struct bio *bio);
+       bool __must_check (*make_request)(struct mddev *mddev, struct bio *bio);
        /*
         * start up works that do NOT require md_thread. tasks that
         * requires md_thread should go into start()
@@ -684,7 +684,7 @@ extern void md_error(struct mddev *mddev, struct md_rdev *rdev);
 extern void md_finish_reshape(struct mddev *mddev);
 
 extern int mddev_congested(struct mddev *mddev, int bits);
-extern void md_flush_request(struct mddev *mddev, struct bio *bio);
+extern bool __must_check md_flush_request(struct mddev *mddev, struct bio *bio);
 extern void md_super_write(struct mddev *mddev, struct md_rdev *rdev,
                           sector_t sector, int size, struct page *page);
 extern int md_super_wait(struct mddev *mddev);
index 21ea537..eff04fa 100644 (file)
@@ -203,7 +203,13 @@ static void __rebalance2(struct dm_btree_info *info, struct btree_node *parent,
        struct btree_node *right = r->n;
        uint32_t nr_left = le32_to_cpu(left->header.nr_entries);
        uint32_t nr_right = le32_to_cpu(right->header.nr_entries);
-       unsigned threshold = 2 * merge_threshold(left) + 1;
+       /*
+        * Ensure the number of entries in each child will be greater
+        * than or equal to (max_entries / 3 + 1), so no matter which
+        * child is used for removal, the number will still be not
+        * less than (max_entries / 3).
+        */
+       unsigned int threshold = 2 * (merge_threshold(left) + 1);
 
        if (nr_left + nr_right < threshold) {
                /*
index 475e5f8..2e71405 100644 (file)
@@ -580,10 +580,9 @@ static bool raid0_make_request(struct mddev *mddev, struct bio *bio)
        unsigned chunk_sects;
        unsigned sectors;
 
-       if (unlikely(bio->bi_opf & REQ_PREFLUSH)) {
-               md_flush_request(mddev, bio);
+       if (unlikely(bio->bi_opf & REQ_PREFLUSH)
+           && md_flush_request(mddev, bio))
                return true;
-       }
 
        if (unlikely((bio_op(bio) == REQ_OP_DISCARD))) {
                raid0_handle_discard(mddev, bio);
index 6929d11..6800dcd 100644 (file)
@@ -1537,10 +1537,9 @@ static bool raid1_make_request(struct mddev *mddev, struct bio *bio)
 {
        sector_t sectors;
 
-       if (unlikely(bio->bi_opf & REQ_PREFLUSH)) {
-               md_flush_request(mddev, bio);
+       if (unlikely(bio->bi_opf & REQ_PREFLUSH)
+           && md_flush_request(mddev, bio))
                return true;
-       }
 
        /*
         * There is a limit to the maximum size, but
index 4cf3d8a..02c5e39 100644 (file)
@@ -1562,10 +1562,9 @@ static bool raid10_make_request(struct mddev *mddev, struct bio *bio)
        int chunk_sects = chunk_mask + 1;
        int sectors = bio_sectors(bio);
 
-       if (unlikely(bio->bi_opf & REQ_PREFLUSH)) {
-               md_flush_request(mddev, bio);
+       if (unlikely(bio->bi_opf & REQ_PREFLUSH)
+           && md_flush_request(mddev, bio))
                return true;
-       }
 
        if (!md_write_start(mddev, bio))
                return false;
index 4a5aad2..0102138 100644 (file)
@@ -5590,8 +5590,8 @@ static bool raid5_make_request(struct mddev *mddev, struct bio * bi)
                if (ret == 0)
                        return true;
                if (ret == -ENODEV) {
-                       md_flush_request(mddev, bi);
-                       return true;
+                       if (md_flush_request(mddev, bi))
+                               return true;
                }
                /* ret == -EAGAIN, fallback */
                /*
@@ -5724,7 +5724,7 @@ static bool raid5_make_request(struct mddev *mddev, struct bio * bi)
                                do_flush = false;
                        }
 
-                       if (!sh->batch_head)
+                       if (!sh->batch_head || sh == sh->batch_head)
                                set_bit(STRIPE_HANDLE, &sh->state);
                        clear_bit(STRIPE_DELAYED, &sh->state);
                        if ((!sh->batch_head || sh == sh->batch_head) &&
index e6a8b56..4b6be3b 100644 (file)
@@ -419,10 +419,14 @@ static struct sensor_register ov2659_720p[] = {
        { REG_TIMING_YINC, 0x11 },
        { REG_TIMING_VERT_FORMAT, 0x80 },
        { REG_TIMING_HORIZ_FORMAT, 0x00 },
+       { 0x370a, 0x12 },
        { 0x3a03, 0xe8 },
        { 0x3a09, 0x6f },
        { 0x3a0b, 0x5d },
        { 0x3a15, 0x9a },
+       { REG_VFIFO_READ_START_H, 0x00 },
+       { REG_VFIFO_READ_START_L, 0x80 },
+       { REG_ISP_CTRL02, 0x00 },
        { REG_NULL, 0x00 },
 };
 
@@ -1203,11 +1207,15 @@ static int ov2659_s_stream(struct v4l2_subdev *sd, int on)
                goto unlock;
        }
 
-       ov2659_set_pixel_clock(ov2659);
-       ov2659_set_frame_size(ov2659);
-       ov2659_set_format(ov2659);
-       ov2659_set_streaming(ov2659, 1);
-       ov2659->streaming = on;
+       ret = ov2659_set_pixel_clock(ov2659);
+       if (!ret)
+               ret = ov2659_set_frame_size(ov2659);
+       if (!ret)
+               ret = ov2659_set_format(ov2659);
+       if (!ret) {
+               ov2659_set_streaming(ov2659, 1);
+               ov2659->streaming = on;
+       }
 
 unlock:
        mutex_unlock(&ov2659->lock);
index edded86..c5aadd8 100644 (file)
@@ -469,38 +469,39 @@ static int ov6650_set_selection(struct v4l2_subdev *sd,
 {
        struct i2c_client *client = v4l2_get_subdevdata(sd);
        struct ov6650 *priv = to_ov6650(client);
-       struct v4l2_rect rect = sel->r;
        int ret;
 
        if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE ||
            sel->target != V4L2_SEL_TGT_CROP)
                return -EINVAL;
 
-       v4l_bound_align_image(&rect.width, 2, W_CIF, 1,
-                             &rect.height, 2, H_CIF, 1, 0);
-       v4l_bound_align_image(&rect.left, DEF_HSTRT << 1,
-                             (DEF_HSTRT << 1) + W_CIF - (__s32)rect.width, 1,
-                             &rect.top, DEF_VSTRT << 1,
-                             (DEF_VSTRT << 1) + H_CIF - (__s32)rect.height, 1,
-                             0);
+       v4l_bound_align_image(&sel->r.width, 2, W_CIF, 1,
+                             &sel->r.height, 2, H_CIF, 1, 0);
+       v4l_bound_align_image(&sel->r.left, DEF_HSTRT << 1,
+                             (DEF_HSTRT << 1) + W_CIF - (__s32)sel->r.width, 1,
+                             &sel->r.top, DEF_VSTRT << 1,
+                             (DEF_VSTRT << 1) + H_CIF - (__s32)sel->r.height,
+                             1, 0);
 
-       ret = ov6650_reg_write(client, REG_HSTRT, rect.left >> 1);
+       ret = ov6650_reg_write(client, REG_HSTRT, sel->r.left >> 1);
        if (!ret) {
-               priv->rect.left = rect.left;
+               priv->rect.width += priv->rect.left - sel->r.left;
+               priv->rect.left = sel->r.left;
                ret = ov6650_reg_write(client, REG_HSTOP,
-                               (rect.left + rect.width) >> 1);
+                                      (sel->r.left + sel->r.width) >> 1);
        }
        if (!ret) {
-               priv->rect.width = rect.width;
-               ret = ov6650_reg_write(client, REG_VSTRT, rect.top >> 1);
+               priv->rect.width = sel->r.width;
+               ret = ov6650_reg_write(client, REG_VSTRT, sel->r.top >> 1);
        }
        if (!ret) {
-               priv->rect.top = rect.top;
+               priv->rect.height += priv->rect.top - sel->r.top;
+               priv->rect.top = sel->r.top;
                ret = ov6650_reg_write(client, REG_VSTOP,
-                               (rect.top + rect.height) >> 1);
+                                      (sel->r.top + sel->r.height) >> 1);
        }
        if (!ret)
-               priv->rect.height = rect.height;
+               priv->rect.height = sel->r.height;
 
        return ret;
 }
@@ -614,7 +615,6 @@ static int ov6650_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
                dev_err(&client->dev, "Pixel format not handled: 0x%x\n", code);
                return -EINVAL;
        }
-       priv->code = code;
 
        if (code == MEDIA_BUS_FMT_Y8_1X8 ||
                        code == MEDIA_BUS_FMT_SBGGR8_1X8) {
@@ -640,7 +640,6 @@ static int ov6650_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
                dev_dbg(&client->dev, "max resolution: CIF\n");
                coma_mask |= COMA_QCIF;
        }
-       priv->half_scale = half_scale;
 
        clkrc = CLKRC_12MHz;
        mclk = 12000000;
@@ -658,8 +657,13 @@ static int ov6650_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
                ret = ov6650_reg_rmw(client, REG_COMA, coma_set, coma_mask);
        if (!ret)
                ret = ov6650_reg_write(client, REG_CLKRC, clkrc);
-       if (!ret)
+       if (!ret) {
+               priv->half_scale = half_scale;
+
                ret = ov6650_reg_rmw(client, REG_COML, coml_set, coml_mask);
+       }
+       if (!ret)
+               priv->code = code;
 
        if (!ret) {
                mf->colorspace  = priv->colorspace;
index 1236683..4731e1c 100644 (file)
@@ -3108,19 +3108,23 @@ static int smiapp_probe(struct i2c_client *client,
        if (rval < 0)
                goto out_media_entity_cleanup;
 
-       rval = v4l2_async_register_subdev_sensor_common(&sensor->src->sd);
-       if (rval < 0)
-               goto out_media_entity_cleanup;
-
        pm_runtime_set_active(&client->dev);
        pm_runtime_get_noresume(&client->dev);
        pm_runtime_enable(&client->dev);
+
+       rval = v4l2_async_register_subdev_sensor_common(&sensor->src->sd);
+       if (rval < 0)
+               goto out_disable_runtime_pm;
+
        pm_runtime_set_autosuspend_delay(&client->dev, 1000);
        pm_runtime_use_autosuspend(&client->dev);
        pm_runtime_put_autosuspend(&client->dev);
 
        return 0;
 
+out_disable_runtime_pm:
+       pm_runtime_disable(&client->dev);
+
 out_media_entity_cleanup:
        media_entity_cleanup(&sensor->src->sd.entity);
 
index 7b113ba..248fb3b 100644 (file)
@@ -1312,7 +1312,7 @@ static int cx8800_initdev(struct pci_dev *pci_dev,
        core = cx88_core_get(dev->pci);
        if (!core) {
                err = -EINVAL;
-               goto fail_free;
+               goto fail_disable;
        }
        dev->core = core;
 
@@ -1358,7 +1358,7 @@ static int cx8800_initdev(struct pci_dev *pci_dev,
                                       cc->step, cc->default_value);
                if (!vc) {
                        err = core->audio_hdl.error;
-                       goto fail_core;
+                       goto fail_irq;
                }
                vc->priv = (void *)cc;
        }
@@ -1372,7 +1372,7 @@ static int cx8800_initdev(struct pci_dev *pci_dev,
                                       cc->step, cc->default_value);
                if (!vc) {
                        err = core->video_hdl.error;
-                       goto fail_core;
+                       goto fail_irq;
                }
                vc->priv = (void *)cc;
                if (vc->id == V4L2_CID_CHROMA_AGC)
@@ -1535,11 +1535,14 @@ static int cx8800_initdev(struct pci_dev *pci_dev,
 
 fail_unreg:
        cx8800_unregister_video(dev);
-       free_irq(pci_dev->irq, dev);
        mutex_unlock(&core->lock);
+fail_irq:
+       free_irq(pci_dev->irq, dev);
 fail_core:
        core->v4ldev = NULL;
        cx88_core_put(core, dev->pci);
+fail_disable:
+       pci_disable_device(pci_dev);
 fail_free:
        kfree(dev);
        return err;
index b05738a..809320d 100644 (file)
@@ -1848,6 +1848,10 @@ static int vpfe_s_std(struct file *file, void *priv, v4l2_std_id std_id)
        if (!(sdinfo->inputs[0].capabilities & V4L2_IN_CAP_STD))
                return -ENODATA;
 
+       /* if trying to set the same std then nothing to do */
+       if (vpfe_standards[vpfe->std_index].std_id == std_id)
+               return 0;
+
        /* If streaming is started, return error */
        if (vb2_is_busy(&vpfe->buffer_queue)) {
                vpfe_err(vpfe, "%s device busy\n", __func__);
index 5b8350e..6006986 100644 (file)
@@ -430,10 +430,11 @@ static const struct venus_resources msm8916_res = {
 };
 
 static const struct freq_tbl msm8996_freq_table[] = {
-       { 1944000, 490000000 }, /* 4k UHD @ 60 */
-       {  972000, 320000000 }, /* 4k UHD @ 30 */
-       {  489600, 150000000 }, /* 1080p @ 60 */
-       {  244800,  75000000 }, /* 1080p @ 30 */
+       { 1944000, 520000000 }, /* 4k UHD @ 60 (decode only) */
+       {  972000, 520000000 }, /* 4k UHD @ 30 */
+       {  489600, 346666667 }, /* 1080p @ 60 */
+       {  244800, 150000000 }, /* 1080p @ 30 */
+       {  108000,  75000000 }, /* 720p @ 30 */
 };
 
 static const struct reg_val msm8996_reg_preset[] = {
index 1240855..fbcc67c 100644 (file)
@@ -1484,6 +1484,7 @@ static int venus_suspend_3xx(struct venus_core *core)
 {
        struct venus_hfi_device *hdev = to_hfi_priv(core);
        struct device *dev = core->dev;
+       u32 ctrl_status;
        bool val;
        int ret;
 
@@ -1499,6 +1500,10 @@ static int venus_suspend_3xx(struct venus_core *core)
                return -EINVAL;
        }
 
+       ctrl_status = venus_readl(hdev, CPU_CS_SCIACMDARG0);
+       if (ctrl_status & CPU_CS_SCIACMDARG0_PC_READY)
+               goto power_off;
+
        /*
         * Power collapse sequence for Venus 3xx and 4xx versions:
         * 1. Check for ARM9 and video core to be idle by checking WFI bit
@@ -1523,6 +1528,7 @@ static int venus_suspend_3xx(struct venus_core *core)
        if (ret)
                return ret;
 
+power_off:
        mutex_lock(&hdev->lock);
 
        ret = venus_power_off(hdev);
index e40fdf9..e3972db 100644 (file)
@@ -1115,9 +1115,6 @@ static const struct v4l2_file_operations vdec_fops = {
        .unlocked_ioctl = video_ioctl2,
        .poll = v4l2_m2m_fop_poll,
        .mmap = v4l2_m2m_fop_mmap,
-#ifdef CONFIG_COMPAT
-       .compat_ioctl32 = v4l2_compat_ioctl32,
-#endif
 };
 
 static int vdec_probe(struct platform_device *pdev)
index 41249d1..4208972 100644 (file)
@@ -1220,9 +1220,6 @@ static const struct v4l2_file_operations venc_fops = {
        .unlocked_ioctl = video_ioctl2,
        .poll = v4l2_m2m_fop_poll,
        .mmap = v4l2_m2m_fop_mmap,
-#ifdef CONFIG_COMPAT
-       .compat_ioctl32 = v4l2_compat_ioctl32,
-#endif
 };
 
 static int venc_probe(struct platform_device *pdev)
index 81413ab..b677d01 100644 (file)
@@ -912,6 +912,7 @@ static int rcar_drif_g_fmt_sdr_cap(struct file *file, void *priv,
 {
        struct rcar_drif_sdr *sdr = video_drvdata(file);
 
+       memset(f->fmt.sdr.reserved, 0, sizeof(f->fmt.sdr.reserved));
        f->fmt.sdr.pixelformat = sdr->fmt->pixelformat;
        f->fmt.sdr.buffersize = sdr->fmt->buffersize;
 
index 66b6409..40c4eef 100644 (file)
@@ -651,8 +651,7 @@ static int bdisp_release(struct file *file)
 
        dev_dbg(bdisp->dev, "%s\n", __func__);
 
-       if (mutex_lock_interruptible(&bdisp->lock))
-               return -ERESTARTSYS;
+       mutex_lock(&bdisp->lock);
 
        v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
 
index 7e61150..f29074c 100644 (file)
@@ -60,6 +60,7 @@ struct vpdma_data_format {
                                                 * line stride of source and dest
                                                 * buffers should be 16 byte aligned
                                                 */
+#define VPDMA_MAX_STRIDE               65520   /* Max line stride 16 byte aligned */
 #define VPDMA_DTD_DESC_SIZE            32      /* 8 words */
 #define VPDMA_CFD_CTD_DESC_SIZE                16      /* 4 words */
 
index d70871d..a285b9d 100644 (file)
@@ -352,20 +352,25 @@ enum {
 };
 
 /* find our format description corresponding to the passed v4l2_format */
-static struct vpe_fmt *find_format(struct v4l2_format *f)
+static struct vpe_fmt *__find_format(u32 fourcc)
 {
        struct vpe_fmt *fmt;
        unsigned int k;
 
        for (k = 0; k < ARRAY_SIZE(vpe_formats); k++) {
                fmt = &vpe_formats[k];
-               if (fmt->fourcc == f->fmt.pix.pixelformat)
+               if (fmt->fourcc == fourcc)
                        return fmt;
        }
 
        return NULL;
 }
 
+static struct vpe_fmt *find_format(struct v4l2_format *f)
+{
+       return __find_format(f->fmt.pix.pixelformat);
+}
+
 /*
  * there is one vpe_dev structure in the driver, it is shared by
  * all instances.
@@ -1027,11 +1032,14 @@ static void add_out_dtd(struct vpe_ctx *ctx, int port)
        dma_addr_t dma_addr;
        u32 flags = 0;
        u32 offset = 0;
+       u32 stride;
 
        if (port == VPE_PORT_MV_OUT) {
                vpdma_fmt = &vpdma_misc_fmts[VPDMA_DATA_FMT_MV];
                dma_addr = ctx->mv_buf_dma[mv_buf_selector];
                q_data = &ctx->q_data[Q_DATA_SRC];
+               stride = ALIGN((q_data->width * vpdma_fmt->depth) >> 3,
+                              VPDMA_STRIDE_ALIGN);
        } else {
                /* to incorporate interleaved formats */
                int plane = fmt->coplanar ? p_data->vb_part : 0;
@@ -1058,6 +1066,7 @@ static void add_out_dtd(struct vpe_ctx *ctx, int port)
                }
                /* Apply the offset */
                dma_addr += offset;
+               stride = q_data->bytesperline[VPE_LUMA];
        }
 
        if (q_data->flags & Q_DATA_FRAME_1D)
@@ -1069,7 +1078,7 @@ static void add_out_dtd(struct vpe_ctx *ctx, int port)
                           MAX_W, MAX_H);
 
        vpdma_add_out_dtd(&ctx->desc_list, q_data->width,
-                         q_data->bytesperline[VPE_LUMA], &q_data->c_rect,
+                         stride, &q_data->c_rect,
                          vpdma_fmt, dma_addr, MAX_OUT_WIDTH_REG1,
                          MAX_OUT_HEIGHT_REG1, p_data->channel, flags);
 }
@@ -1088,10 +1097,13 @@ static void add_in_dtd(struct vpe_ctx *ctx, int port)
        dma_addr_t dma_addr;
        u32 flags = 0;
        u32 offset = 0;
+       u32 stride;
 
        if (port == VPE_PORT_MV_IN) {
                vpdma_fmt = &vpdma_misc_fmts[VPDMA_DATA_FMT_MV];
                dma_addr = ctx->mv_buf_dma[mv_buf_selector];
+               stride = ALIGN((q_data->width * vpdma_fmt->depth) >> 3,
+                              VPDMA_STRIDE_ALIGN);
        } else {
                /* to incorporate interleaved formats */
                int plane = fmt->coplanar ? p_data->vb_part : 0;
@@ -1118,6 +1130,7 @@ static void add_in_dtd(struct vpe_ctx *ctx, int port)
                }
                /* Apply the offset */
                dma_addr += offset;
+               stride = q_data->bytesperline[VPE_LUMA];
 
                if (q_data->flags & Q_DATA_INTERLACED_SEQ_TB) {
                        /*
@@ -1153,10 +1166,10 @@ static void add_in_dtd(struct vpe_ctx *ctx, int port)
        if (p_data->vb_part && fmt->fourcc == V4L2_PIX_FMT_NV12)
                frame_height /= 2;
 
-       vpdma_add_in_dtd(&ctx->desc_list, q_data->width,
-                        q_data->bytesperline[VPE_LUMA], &q_data->c_rect,
-               vpdma_fmt, dma_addr, p_data->channel, field, flags, frame_width,
-               frame_height, 0, 0);
+       vpdma_add_in_dtd(&ctx->desc_list, q_data->width, stride,
+                        &q_data->c_rect, vpdma_fmt, dma_addr,
+                        p_data->channel, field, flags, frame_width,
+                        frame_height, 0, 0);
 }
 
 /*
@@ -1405,9 +1418,6 @@ static irqreturn_t vpe_irq(int irq_vpe, void *data)
         /* the previous dst mv buffer becomes the next src mv buffer */
        ctx->src_mv_buf_selector = !ctx->src_mv_buf_selector;
 
-       if (ctx->aborting)
-               goto finished;
-
        s_vb = ctx->src_vbs[0];
        d_vb = ctx->dst_vb;
 
@@ -1418,6 +1428,7 @@ static irqreturn_t vpe_irq(int irq_vpe, void *data)
                d_vb->timecode = s_vb->timecode;
 
        d_vb->sequence = ctx->sequence;
+       s_vb->sequence = ctx->sequence;
 
        d_q_data = &ctx->q_data[Q_DATA_DST];
        if (d_q_data->flags & Q_IS_INTERLACED) {
@@ -1471,6 +1482,9 @@ static irqreturn_t vpe_irq(int irq_vpe, void *data)
        ctx->src_vbs[0] = NULL;
        ctx->dst_vb = NULL;
 
+       if (ctx->aborting)
+               goto finished;
+
        ctx->bufs_completed++;
        if (ctx->bufs_completed < ctx->bufs_per_job && job_ready(ctx)) {
                device_run(ctx);
@@ -1583,9 +1597,9 @@ static int __vpe_try_fmt(struct vpe_ctx *ctx, struct v4l2_format *f,
        unsigned int stride = 0;
 
        if (!fmt || !(fmt->types & type)) {
-               vpe_err(ctx->dev, "Fourcc format (0x%08x) invalid.\n",
+               vpe_dbg(ctx->dev, "Fourcc format (0x%08x) invalid.\n",
                        pix->pixelformat);
-               return -EINVAL;
+               fmt = __find_format(V4L2_PIX_FMT_YUYV);
        }
 
        if (pix->field != V4L2_FIELD_NONE && pix->field != V4L2_FIELD_ALTERNATE
@@ -1632,7 +1646,7 @@ static int __vpe_try_fmt(struct vpe_ctx *ctx, struct v4l2_format *f,
                              &pix->height, MIN_H, MAX_H, H_ALIGN,
                              S_ALIGN);
 
-       if (!pix->num_planes)
+       if (!pix->num_planes || pix->num_planes > 2)
                pix->num_planes = fmt->coplanar ? 2 : 1;
        else if (pix->num_planes > 1 && !fmt->coplanar)
                pix->num_planes = 1;
@@ -1671,6 +1685,10 @@ static int __vpe_try_fmt(struct vpe_ctx *ctx, struct v4l2_format *f,
                if (stride > plane_fmt->bytesperline)
                        plane_fmt->bytesperline = stride;
 
+               plane_fmt->bytesperline = clamp_t(u32, plane_fmt->bytesperline,
+                                                 stride,
+                                                 VPDMA_MAX_STRIDE);
+
                plane_fmt->bytesperline = ALIGN(plane_fmt->bytesperline,
                                                VPDMA_STRIDE_ALIGN);
 
@@ -2291,7 +2309,7 @@ static int vpe_open(struct file *file)
        v4l2_ctrl_handler_setup(hdl);
 
        s_q_data = &ctx->q_data[Q_DATA_SRC];
-       s_q_data->fmt = &vpe_formats[2];
+       s_q_data->fmt = __find_format(V4L2_PIX_FMT_YUYV);
        s_q_data->width = 1920;
        s_q_data->height = 1080;
        s_q_data->nplanes = 1;
@@ -2369,6 +2387,12 @@ static int vpe_release(struct file *file)
 
        mutex_lock(&dev->dev_mutex);
        free_mv_buffers(ctx);
+
+       vpdma_unmap_desc_buf(dev->vpdma, &ctx->desc_list.buf);
+       vpdma_unmap_desc_buf(dev->vpdma, &ctx->mmr_adb);
+       vpdma_unmap_desc_buf(dev->vpdma, &ctx->sc_coeff_h);
+       vpdma_unmap_desc_buf(dev->vpdma, &ctx->sc_coeff_v);
+
        vpdma_free_desc_list(&ctx->desc_list);
        vpdma_free_desc_buf(&ctx->mmr_adb);
 
index 27db883..8548fa9 100644 (file)
@@ -243,10 +243,7 @@ static void vimc_comp_unbind(struct device *master)
 
 static int vimc_comp_compare(struct device *comp, void *data)
 {
-       const struct platform_device *pdev = to_platform_device(comp);
-       const char *name = data;
-
-       return !strcmp(pdev->dev.platform_data, name);
+       return comp == data;
 }
 
 static struct component_match *vimc_add_subdevs(struct vimc_device *vimc)
@@ -276,7 +273,7 @@ static struct component_match *vimc_add_subdevs(struct vimc_device *vimc)
                }
 
                component_match_add(&vimc->pdev.dev, &match, vimc_comp_compare,
-                                   (void *)vimc->pipe_cfg->ents[i].name);
+                                   &vimc->subdevs[i]->dev);
        }
 
        return match;
index 11aa94f..5000269 100644 (file)
@@ -1156,8 +1156,7 @@ static int wl1273_fm_fops_release(struct file *file)
        if (radio->rds_users > 0) {
                radio->rds_users--;
                if (radio->rds_users == 0) {
-                       if (mutex_lock_interruptible(&core->lock))
-                               return -EINTR;
+                       mutex_lock(&core->lock);
 
                        radio->irq_flags &= ~WL1273_RDS_EVENT;
 
index e3b3ecd..ae7540b 100644 (file)
@@ -485,6 +485,8 @@ static int si470x_i2c_remove(struct i2c_client *client)
        video_unregister_device(&radio->videodev);
        kfree(radio);
 
+       v4l2_ctrl_handler_free(&radio->hdl);
+       v4l2_device_unregister(&radio->v4l2_dev);
        return 0;
 }
 
index ac4fddf..f1807c1 100644 (file)
@@ -503,7 +503,13 @@ urb_error:
 static int flexcop_usb_init(struct flexcop_usb *fc_usb)
 {
        /* use the alternate setting with the larges buffer */
-       usb_set_interface(fc_usb->udev,0,1);
+       int ret = usb_set_interface(fc_usb->udev, 0, 1);
+
+       if (ret) {
+               err("set interface failed.");
+               return ret;
+       }
+
        switch (fc_usb->udev->speed) {
        case USB_SPEED_LOW:
                err("cannot handle USB speed because it is too slow.");
index e53a80b..04d3341 100644 (file)
@@ -916,8 +916,12 @@ static void pvr2_v4l2_internal_check(struct pvr2_channel *chp)
        pvr2_v4l2_dev_disassociate_parent(vp->dev_video);
        pvr2_v4l2_dev_disassociate_parent(vp->dev_radio);
        if (!list_empty(&vp->dev_video->devbase.fh_list) ||
-           !list_empty(&vp->dev_radio->devbase.fh_list))
+           (vp->dev_radio &&
+            !list_empty(&vp->dev_radio->devbase.fh_list))) {
+               pvr2_trace(PVR2_TRACE_STRUCT,
+                          "pvr2_v4l2 internal_check exit-empty id=%p", vp);
                return;
+       }
        pvr2_v4l2_destroy_no_lock(vp);
 }
 
@@ -953,7 +957,8 @@ static int pvr2_v4l2_release(struct file *file)
        kfree(fhp);
        if (vp->channel.mc_head->disconnect_flag &&
            list_empty(&vp->dev_video->devbase.fh_list) &&
-           list_empty(&vp->dev_radio->devbase.fh_list)) {
+           (!vp->dev_radio ||
+            list_empty(&vp->dev_radio->devbase.fh_list))) {
                pvr2_v4l2_destroy_no_lock(vp);
        }
        return 0;
index f30f7a1..4f422ed 100644 (file)
@@ -1415,10 +1415,26 @@ static int v4l_enum_fmt(const struct v4l2_ioctl_ops *ops,
        return ret;
 }
 
+static void v4l_pix_format_touch(struct v4l2_pix_format *p)
+{
+       /*
+        * The v4l2_pix_format structure contains fields that make no sense for
+        * touch. Set them to default values in this case.
+        */
+
+       p->field = V4L2_FIELD_NONE;
+       p->colorspace = V4L2_COLORSPACE_RAW;
+       p->flags = 0;
+       p->ycbcr_enc = 0;
+       p->quantization = 0;
+       p->xfer_func = 0;
+}
+
 static int v4l_g_fmt(const struct v4l2_ioctl_ops *ops,
                                struct file *file, void *fh, void *arg)
 {
        struct v4l2_format *p = arg;
+       struct video_device *vfd = video_devdata(file);
        int ret = check_fmt(file, p->type);
 
        if (ret)
@@ -1456,6 +1472,8 @@ static int v4l_g_fmt(const struct v4l2_ioctl_ops *ops,
                ret = ops->vidioc_g_fmt_vid_cap(file, fh, arg);
                /* just in case the driver zeroed it again */
                p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
+               if (vfd->vfl_type == VFL_TYPE_TOUCH)
+                       v4l_pix_format_touch(&p->fmt.pix);
                return ret;
        case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
                return ops->vidioc_g_fmt_vid_cap_mplane(file, fh, arg);
@@ -1491,21 +1509,6 @@ static int v4l_g_fmt(const struct v4l2_ioctl_ops *ops,
        return -EINVAL;
 }
 
-static void v4l_pix_format_touch(struct v4l2_pix_format *p)
-{
-       /*
-        * The v4l2_pix_format structure contains fields that make no sense for
-        * touch. Set them to default values in this case.
-        */
-
-       p->field = V4L2_FIELD_NONE;
-       p->colorspace = V4L2_COLORSPACE_RAW;
-       p->flags = 0;
-       p->ycbcr_enc = 0;
-       p->quantization = 0;
-       p->xfer_func = 0;
-}
-
 static int v4l_s_fmt(const struct v4l2_ioctl_ops *ops,
                                struct file *file, void *fh, void *arg)
 {
index 81ab6a3..daa2584 100644 (file)
@@ -416,38 +416,6 @@ static int mmc_blk_ioctl_copy_to_user(struct mmc_ioc_cmd __user *ic_ptr,
        return 0;
 }
 
-static int ioctl_rpmb_card_status_poll(struct mmc_card *card, u32 *status,
-                                      u32 retries_max)
-{
-       int err;
-       u32 retry_count = 0;
-
-       if (!status || !retries_max)
-               return -EINVAL;
-
-       do {
-               err = __mmc_send_status(card, status, 5);
-               if (err)
-                       break;
-
-               if (!R1_STATUS(*status) &&
-                               (R1_CURRENT_STATE(*status) != R1_STATE_PRG))
-                       break; /* RPMB programming operation complete */
-
-               /*
-                * Rechedule to give the MMC device a chance to continue
-                * processing the previous command without being polled too
-                * frequently.
-                */
-               usleep_range(1000, 5000);
-       } while (++retry_count < retries_max);
-
-       if (retry_count == retries_max)
-               err = -EPERM;
-
-       return err;
-}
-
 static int ioctl_do_sanitize(struct mmc_card *card)
 {
        int err;
@@ -476,6 +444,58 @@ out:
        return err;
 }
 
+static inline bool mmc_blk_in_tran_state(u32 status)
+{
+       /*
+        * Some cards mishandle the status bits, so make sure to check both the
+        * busy indication and the card state.
+        */
+       return status & R1_READY_FOR_DATA &&
+              (R1_CURRENT_STATE(status) == R1_STATE_TRAN);
+}
+
+static int card_busy_detect(struct mmc_card *card, unsigned int timeout_ms,
+                           u32 *resp_errs)
+{
+       unsigned long timeout = jiffies + msecs_to_jiffies(timeout_ms);
+       int err = 0;
+       u32 status;
+
+       do {
+               bool done = time_after(jiffies, timeout);
+
+               err = __mmc_send_status(card, &status, 5);
+               if (err) {
+                       dev_err(mmc_dev(card->host),
+                               "error %d requesting status\n", err);
+                       return err;
+               }
+
+               /* Accumulate any response error bits seen */
+               if (resp_errs)
+                       *resp_errs |= status;
+
+               /*
+                * Timeout if the device never becomes ready for data and never
+                * leaves the program state.
+                */
+               if (done) {
+                       dev_err(mmc_dev(card->host),
+                               "Card stuck in wrong state! %s status: %#x\n",
+                                __func__, status);
+                       return -ETIMEDOUT;
+               }
+
+               /*
+                * Some cards mishandle the status bits,
+                * so make sure to check both the busy
+                * indication and the card state.
+                */
+       } while (!mmc_blk_in_tran_state(status));
+
+       return err;
+}
+
 static int __mmc_blk_ioctl_cmd(struct mmc_card *card, struct mmc_blk_data *md,
                               struct mmc_blk_ioc_data *idata)
 {
@@ -485,7 +505,6 @@ static int __mmc_blk_ioctl_cmd(struct mmc_card *card, struct mmc_blk_data *md,
        struct scatterlist sg;
        int err;
        unsigned int target_part;
-       u32 status = 0;
 
        if (!card || !md || !idata)
                return -EINVAL;
@@ -619,16 +638,12 @@ static int __mmc_blk_ioctl_cmd(struct mmc_card *card, struct mmc_blk_data *md,
 
        memcpy(&(idata->ic.response), cmd.resp, sizeof(cmd.resp));
 
-       if (idata->rpmb) {
+       if (idata->rpmb || (cmd.flags & MMC_RSP_R1B)) {
                /*
-                * Ensure RPMB command has completed by polling CMD13
+                * Ensure RPMB/R1B command has completed by polling CMD13
                 * "Send Status".
                 */
-               err = ioctl_rpmb_card_status_poll(card, &status, 5);
-               if (err)
-                       dev_err(mmc_dev(card->host),
-                                       "%s: Card Status=0x%08X, error %d\n",
-                                       __func__, status, err);
+               err = card_busy_detect(card, MMC_BLK_TIMEOUT_MS, NULL);
        }
 
        return err;
@@ -978,58 +993,6 @@ static unsigned int mmc_blk_data_timeout_ms(struct mmc_host *host,
        return ms;
 }
 
-static inline bool mmc_blk_in_tran_state(u32 status)
-{
-       /*
-        * Some cards mishandle the status bits, so make sure to check both the
-        * busy indication and the card state.
-        */
-       return status & R1_READY_FOR_DATA &&
-              (R1_CURRENT_STATE(status) == R1_STATE_TRAN);
-}
-
-static int card_busy_detect(struct mmc_card *card, unsigned int timeout_ms,
-                           struct request *req, u32 *resp_errs)
-{
-       unsigned long timeout = jiffies + msecs_to_jiffies(timeout_ms);
-       int err = 0;
-       u32 status;
-
-       do {
-               bool done = time_after(jiffies, timeout);
-
-               err = __mmc_send_status(card, &status, 5);
-               if (err) {
-                       pr_err("%s: error %d requesting status\n",
-                              req->rq_disk->disk_name, err);
-                       return err;
-               }
-
-               /* Accumulate any response error bits seen */
-               if (resp_errs)
-                       *resp_errs |= status;
-
-               /*
-                * Timeout if the device never becomes ready for data and never
-                * leaves the program state.
-                */
-               if (done) {
-                       pr_err("%s: Card stuck in wrong state! %s %s status: %#x\n",
-                               mmc_hostname(card->host),
-                               req->rq_disk->disk_name, __func__, status);
-                       return -ETIMEDOUT;
-               }
-
-               /*
-                * Some cards mishandle the status bits,
-                * so make sure to check both the busy
-                * indication and the card state.
-                */
-       } while (!mmc_blk_in_tran_state(status));
-
-       return err;
-}
-
 static int mmc_blk_reset(struct mmc_blk_data *md, struct mmc_host *host,
                         int type)
 {
@@ -1685,7 +1648,7 @@ static int mmc_blk_fix_state(struct mmc_card *card, struct request *req)
 
        mmc_blk_send_stop(card, timeout);
 
-       err = card_busy_detect(card, timeout, req, NULL);
+       err = card_busy_detect(card, timeout, NULL);
 
        mmc_retune_release(card->host);
 
@@ -1909,7 +1872,7 @@ static int mmc_blk_card_busy(struct mmc_card *card, struct request *req)
        if (mmc_host_is_spi(card->host) || rq_data_dir(req) == READ)
                return 0;
 
-       err = card_busy_detect(card, MMC_BLK_TIMEOUT_MS, req, &status);
+       err = card_busy_detect(card, MMC_BLK_TIMEOUT_MS, &status);
 
        /*
         * Do not assume data transferred correctly if there are any error bits
index 673f6a9..9ecf86b 100644 (file)
 #define MSDC_PATCH_BIT_SPCPUSH    (0x1 << 29)  /* RW */
 #define MSDC_PATCH_BIT_DECRCTMO   (0x1 << 30)  /* RW */
 
+#define MSDC_PATCH_BIT1_CMDTA     (0x7 << 3)    /* RW */
 #define MSDC_PATCH_BIT1_STOP_DLY  (0xf << 8)    /* RW */
 
 #define MSDC_PATCH_BIT2_CFGRESP   (0x1 << 15)   /* RW */
@@ -1673,6 +1674,7 @@ static int hs400_tune_response(struct mmc_host *mmc, u32 opcode)
 
        /* select EMMC50 PAD CMD tune */
        sdr_set_bits(host->base + PAD_CMD_TUNE, BIT(0));
+       sdr_set_field(host->base + MSDC_PATCH_BIT1, MSDC_PATCH_BIT1_CMDTA, 2);
 
        if (mmc->ios.timing == MMC_TIMING_MMC_HS200 ||
            mmc->ios.timing == MMC_TIMING_UHS_SDR104)
index b23c57e..0135693 100644 (file)
@@ -1661,6 +1661,36 @@ static void omap_hsmmc_init_card(struct mmc_host *mmc, struct mmc_card *card)
 
        if (mmc_pdata(host)->init_card)
                mmc_pdata(host)->init_card(card);
+       else if (card->type == MMC_TYPE_SDIO ||
+                card->type == MMC_TYPE_SD_COMBO) {
+               struct device_node *np = mmc_dev(mmc)->of_node;
+
+               /*
+                * REVISIT: should be moved to sdio core and made more
+                * general e.g. by expanding the DT bindings of child nodes
+                * to provide a mechanism to provide this information:
+                * Documentation/devicetree/bindings/mmc/mmc-card.txt
+                */
+
+               np = of_get_compatible_child(np, "ti,wl1251");
+               if (np) {
+                       /*
+                        * We have TI wl1251 attached to MMC3. Pass this
+                        * information to the SDIO core because it can't be
+                        * probed by normal methods.
+                        */
+
+                       dev_info(host->dev, "found wl1251\n");
+                       card->quirks |= MMC_QUIRK_NONSTD_SDIO;
+                       card->cccr.wide_bus = 1;
+                       card->cis.vendor = 0x104c;
+                       card->cis.device = 0x9066;
+                       card->cis.blksize = 512;
+                       card->cis.max_dtr = 24000000;
+                       card->ocr = 0x80;
+                       of_node_put(np);
+               }
+       }
 }
 
 static void omap_hsmmc_enable_sdio_irq(struct mmc_host *mmc, int enable)
index ad02751..17b2054 100644 (file)
 
 #define CORE_PWRSAVE_DLL       BIT(3)
 
-#define DDR_CONFIG_POR_VAL     0x80040853
+#define DDR_CONFIG_POR_VAL     0x80040873
 
 
 #define INVALID_TUNING_PHASE   -1
@@ -157,8 +157,9 @@ struct sdhci_msm_offset {
        u32 core_ddr_200_cfg;
        u32 core_vendor_spec3;
        u32 core_dll_config_2;
+       u32 core_dll_config_3;
+       u32 core_ddr_config_old; /* Applicable to sdcc minor ver < 0x49 */
        u32 core_ddr_config;
-       u32 core_ddr_config_2;
 };
 
 static const struct sdhci_msm_offset sdhci_msm_v5_offset = {
@@ -186,8 +187,8 @@ static const struct sdhci_msm_offset sdhci_msm_v5_offset = {
        .core_ddr_200_cfg = 0x224,
        .core_vendor_spec3 = 0x250,
        .core_dll_config_2 = 0x254,
-       .core_ddr_config = 0x258,
-       .core_ddr_config_2 = 0x25c,
+       .core_dll_config_3 = 0x258,
+       .core_ddr_config = 0x25c,
 };
 
 static const struct sdhci_msm_offset sdhci_msm_mci_offset = {
@@ -216,8 +217,8 @@ static const struct sdhci_msm_offset sdhci_msm_mci_offset = {
        .core_ddr_200_cfg = 0x184,
        .core_vendor_spec3 = 0x1b0,
        .core_dll_config_2 = 0x1b4,
-       .core_ddr_config = 0x1b8,
-       .core_ddr_config_2 = 0x1bc,
+       .core_ddr_config_old = 0x1b8,
+       .core_ddr_config = 0x1bc,
 };
 
 struct sdhci_msm_variant_ops {
@@ -260,6 +261,7 @@ struct sdhci_msm_host {
        const struct sdhci_msm_offset *offset;
        bool use_cdr;
        u32 transfer_mode;
+       bool updated_ddr_cfg;
 };
 
 static const struct sdhci_msm_offset *sdhci_priv_msm_offset(struct sdhci_host *host)
@@ -931,8 +933,10 @@ out:
 static int sdhci_msm_cm_dll_sdc4_calibration(struct sdhci_host *host)
 {
        struct mmc_host *mmc = host->mmc;
-       u32 dll_status, config;
+       u32 dll_status, config, ddr_cfg_offset;
        int ret;
+       struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+       struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host);
        const struct sdhci_msm_offset *msm_offset =
                                        sdhci_priv_msm_offset(host);
 
@@ -945,8 +949,11 @@ static int sdhci_msm_cm_dll_sdc4_calibration(struct sdhci_host *host)
         * bootloaders. In the future, if this changes, then the desired
         * values will need to be programmed appropriately.
         */
-       writel_relaxed(DDR_CONFIG_POR_VAL, host->ioaddr +
-                       msm_offset->core_ddr_config);
+       if (msm_host->updated_ddr_cfg)
+               ddr_cfg_offset = msm_offset->core_ddr_config;
+       else
+               ddr_cfg_offset = msm_offset->core_ddr_config_old;
+       writel_relaxed(DDR_CONFIG_POR_VAL, host->ioaddr + ddr_cfg_offset);
 
        if (mmc->ios.enhanced_strobe) {
                config = readl_relaxed(host->ioaddr +
@@ -1862,6 +1869,9 @@ static int sdhci_msm_probe(struct platform_device *pdev)
                                msm_offset->core_vendor_spec_capabilities0);
        }
 
+       if (core_major == 1 && core_minor >= 0x49)
+               msm_host->updated_ddr_cfg = true;
+
        /*
         * Power on reset state may trigger power irq if previous status of
         * PWRCTL was either BUS_ON or IO_HIGH_V. So before enabling pwr irq
index 6627523..2c9110f 100644 (file)
@@ -648,9 +648,6 @@ static void esdhc_reset(struct sdhci_host *host, u8 mask)
        sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
        sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
 
-       if (of_find_compatible_node(NULL, NULL, "fsl,p2020-esdhc"))
-               mdelay(5);
-
        if (mask & SDHCI_RESET_ALL) {
                val = sdhci_readl(host, ESDHC_TBCTL);
                val &= ~ESDHC_TB_EN;
@@ -926,8 +923,8 @@ static int sdhci_esdhc_probe(struct platform_device *pdev)
                host->quirks &= ~SDHCI_QUIRK_NO_BUSY_IRQ;
 
        if (of_find_compatible_node(NULL, NULL, "fsl,p2020-esdhc")) {
-               host->quirks2 |= SDHCI_QUIRK_RESET_AFTER_REQUEST;
-               host->quirks2 |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL;
+               host->quirks |= SDHCI_QUIRK_RESET_AFTER_REQUEST;
+               host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL;
        }
 
        if (of_device_is_compatible(np, "fsl,p5040-esdhc") ||
index 7179439..65985dc 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/mmc/slot-gpio.h>
 #include <linux/mmc/sdhci-pci-data.h>
 #include <linux/acpi.h>
+#include <linux/dmi.h>
 
 #include "cqhci.h"
 
@@ -732,11 +733,18 @@ static int byt_emmc_probe_slot(struct sdhci_pci_slot *slot)
        return 0;
 }
 
+static bool glk_broken_cqhci(struct sdhci_pci_slot *slot)
+{
+       return slot->chip->pdev->device == PCI_DEVICE_ID_INTEL_GLK_EMMC &&
+              dmi_match(DMI_BIOS_VENDOR, "LENOVO");
+}
+
 static int glk_emmc_probe_slot(struct sdhci_pci_slot *slot)
 {
        int ret = byt_emmc_probe_slot(slot);
 
-       slot->host->mmc->caps2 |= MMC_CAP2_CQE;
+       if (!glk_broken_cqhci(slot))
+               slot->host->mmc->caps2 |= MMC_CAP2_CQE;
 
        if (slot->chip->pdev->device != PCI_DEVICE_ID_INTEL_GLK_EMMC) {
                slot->host->mmc->caps2 |= MMC_CAP2_HS400_ES,
index 191dc7e..a20aee5 100644 (file)
@@ -1713,9 +1713,7 @@ void sdhci_set_uhs_signaling(struct sdhci_host *host, unsigned timing)
                ctrl_2 |= SDHCI_CTRL_UHS_SDR104;
        else if (timing == MMC_TIMING_UHS_SDR12)
                ctrl_2 |= SDHCI_CTRL_UHS_SDR12;
-       else if (timing == MMC_TIMING_SD_HS ||
-                timing == MMC_TIMING_MMC_HS ||
-                timing == MMC_TIMING_UHS_SDR25)
+       else if (timing == MMC_TIMING_UHS_SDR25)
                ctrl_2 |= SDHCI_CTRL_UHS_SDR25;
        else if (timing == MMC_TIMING_UHS_SDR50)
                ctrl_2 |= SDHCI_CTRL_UHS_SDR50;
@@ -2246,8 +2244,8 @@ static void __sdhci_execute_tuning(struct sdhci_host *host, u32 opcode)
                sdhci_send_tuning(host, opcode);
 
                if (!host->tuning_done) {
-                       pr_info("%s: Tuning timeout, falling back to fixed sampling clock\n",
-                               mmc_hostname(host->mmc));
+                       pr_debug("%s: Tuning timeout, falling back to fixed sampling clock\n",
+                                mmc_hostname(host->mmc));
                        sdhci_abort_tuning(host, opcode);
                        return;
                }
@@ -3555,6 +3553,9 @@ int sdhci_setup_host(struct sdhci_host *host)
                       mmc_hostname(mmc), host->version);
        }
 
+       if (host->quirks & SDHCI_QUIRK_BROKEN_CQE)
+               mmc->caps2 &= ~MMC_CAP2_CQE;
+
        if (host->quirks & SDHCI_QUIRK_FORCE_DMA)
                host->flags |= SDHCI_USE_SDMA;
        else if (!(host->caps & SDHCI_CAN_DO_SDMA))
index 0f8c4f3..c0372e3 100644 (file)
@@ -391,6 +391,8 @@ struct sdhci_host {
 #define SDHCI_QUIRK_BROKEN_CARD_DETECTION              (1<<15)
 /* Controller reports inverted write-protect state */
 #define SDHCI_QUIRK_INVERTED_WRITE_PROTECT             (1<<16)
+/* Controller has unusable command queue engine */
+#define SDHCI_QUIRK_BROKEN_CQE                         (1<<17)
 /* Controller does not like fast PIO transfers */
 #define SDHCI_QUIRK_PIO_NEEDS_DELAY                    (1<<18)
 /* Controller has to be forced to use block size of 2048 bytes */
index 35630cc..33c9ca8 100644 (file)
@@ -1267,7 +1267,7 @@ int tmio_mmc_host_probe(struct tmio_mmc_host *_host)
                        return ret;
        }
 
-       mmc->caps |= MMC_CAP_4_BIT_DATA | pdata->capabilities;
+       mmc->caps |= MMC_CAP_ERASE | MMC_CAP_4_BIT_DATA | pdata->capabilities;
        mmc->caps2 |= pdata->capabilities2;
        mmc->max_segs = pdata->max_segs ? : 32;
        mmc->max_blk_size = 512;
index 986f81d..47ad076 100644 (file)
@@ -592,6 +592,26 @@ static int spear_mtd_read(struct mtd_info *mtd, loff_t from, size_t len,
        return 0;
 }
 
+/*
+ * The purpose of this function is to ensure a memcpy_toio() with byte writes
+ * only. Its structure is inspired from the ARM implementation of _memcpy_toio()
+ * which also does single byte writes but cannot be used here as this is just an
+ * implementation detail and not part of the API. Not mentioning the comment
+ * stating that _memcpy_toio() should be optimized.
+ */
+static void spear_smi_memcpy_toio_b(volatile void __iomem *dest,
+                                   const void *src, size_t len)
+{
+       const unsigned char *from = src;
+
+       while (len) {
+               len--;
+               writeb(*from, dest);
+               from++;
+               dest++;
+       }
+}
+
 static inline int spear_smi_cpy_toio(struct spear_smi *dev, u32 bank,
                void __iomem *dest, const void *src, size_t len)
 {
@@ -614,7 +634,23 @@ static inline int spear_smi_cpy_toio(struct spear_smi *dev, u32 bank,
        ctrlreg1 = readl(dev->io_base + SMI_CR1);
        writel((ctrlreg1 | WB_MODE) & ~SW_MODE, dev->io_base + SMI_CR1);
 
-       memcpy_toio(dest, src, len);
+       /*
+        * In Write Burst mode (WB_MODE), the specs states that writes must be:
+        * - incremental
+        * - of the same size
+        * The ARM implementation of memcpy_toio() will optimize the number of
+        * I/O by using as much 4-byte writes as possible, surrounded by
+        * 2-byte/1-byte access if:
+        * - the destination is not 4-byte aligned
+        * - the length is not a multiple of 4-byte.
+        * Avoid this alternance of write access size by using our own 'byte
+        * access' helper if at least one of the two conditions above is true.
+        */
+       if (IS_ALIGNED(len, sizeof(u32)) &&
+           IS_ALIGNED((uintptr_t)dest, sizeof(u32)))
+               memcpy_toio(dest, src, len);
+       else
+               spear_smi_memcpy_toio_b(dest, src, len);
 
        writel(ctrlreg1, dev->io_base + SMI_CR1);
 
index 9b8143d..f57b86f 100644 (file)
@@ -2223,9 +2223,6 @@ static void bond_miimon_commit(struct bonding *bond)
                        } else if (BOND_MODE(bond) != BOND_MODE_ACTIVEBACKUP) {
                                /* make it immediately active */
                                bond_set_active_slave(slave);
-                       } else if (slave != primary) {
-                               /* prevent it from being the active one */
-                               bond_set_backup_slave(slave);
                        }
 
                        netdev_info(bond->dev, "link status definitely up for interface %s, %u Mbps %s duplex\n",
index 07d2f3a..ae4c37e 100644 (file)
@@ -608,7 +608,7 @@ static int kvaser_usb_leaf_simple_cmd_async(struct kvaser_usb_net_priv *priv,
        struct kvaser_cmd *cmd;
        int err;
 
-       cmd = kmalloc(sizeof(*cmd), GFP_ATOMIC);
+       cmd = kzalloc(sizeof(*cmd), GFP_ATOMIC);
        if (!cmd)
                return -ENOMEM;
 
@@ -1140,7 +1140,7 @@ static int kvaser_usb_leaf_set_opt_mode(const struct kvaser_usb_net_priv *priv)
        struct kvaser_cmd *cmd;
        int rc;
 
-       cmd = kmalloc(sizeof(*cmd), GFP_KERNEL);
+       cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
        if (!cmd)
                return -ENOMEM;
 
@@ -1206,7 +1206,7 @@ static int kvaser_usb_leaf_flush_queue(struct kvaser_usb_net_priv *priv)
        struct kvaser_cmd *cmd;
        int rc;
 
-       cmd = kmalloc(sizeof(*cmd), GFP_KERNEL);
+       cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
        if (!cmd)
                return -ENOMEM;
 
index d3ce1e4..dbfb6ad 100644 (file)
@@ -66,6 +66,7 @@ config NET_DSA_REALTEK_SMI
 config NET_DSA_SMSC_LAN9303
        tristate
        select NET_DSA_TAG_LAN9303
+       select REGMAP
        ---help---
          This enables support for the SMSC/Microchip LAN9303 3 port ethernet
          switch chips.
index b5d7281..e26c195 100644 (file)
@@ -1197,8 +1197,8 @@ static int ena_io_poll(struct napi_struct *napi, int budget)
        struct ena_napi *ena_napi = container_of(napi, struct ena_napi, napi);
        struct ena_ring *tx_ring, *rx_ring;
 
-       u32 tx_work_done;
-       u32 rx_work_done;
+       int tx_work_done;
+       int rx_work_done = 0;
        int tx_budget;
        int napi_comp_call = 0;
        int ret;
@@ -1215,7 +1215,11 @@ static int ena_io_poll(struct napi_struct *napi, int budget)
        }
 
        tx_work_done = ena_clean_tx_irq(tx_ring, tx_budget);
-       rx_work_done = ena_clean_rx_irq(rx_ring, napi, budget);
+       /* On netpoll the budget is zero and the handler should only clean the
+        * tx completions.
+        */
+       if (likely(budget))
+               rx_work_done = ena_clean_rx_irq(rx_ring, napi, budget);
 
        /* If the device is about to reset or down, avoid unmask
         * the interrupt and return 0 so NAPI won't reschedule
index 62da465..ab60f4f 100644 (file)
@@ -2394,15 +2394,21 @@ static int bnx2x_set_pf_tx_switching(struct bnx2x *bp, bool enable)
        /* send the ramrod on all the queues of the PF */
        for_each_eth_queue(bp, i) {
                struct bnx2x_fastpath *fp = &bp->fp[i];
+               int tx_idx;
 
                /* Set the appropriate Queue object */
                q_params.q_obj = &bnx2x_sp_obj(bp, fp).q_obj;
 
-               /* Update the Queue state */
-               rc = bnx2x_queue_state_change(bp, &q_params);
-               if (rc) {
-                       BNX2X_ERR("Failed to configure Tx switching\n");
-                       return rc;
+               for (tx_idx = FIRST_TX_COS_INDEX;
+                    tx_idx < fp->max_cos; tx_idx++) {
+                       q_params.params.update.cid_index = tx_idx;
+
+                       /* Update the Queue state */
+                       rc = bnx2x_queue_state_change(bp, &q_params);
+                       if (rc) {
+                               BNX2X_ERR("Failed to configure Tx switching\n");
+                               return rc;
+                       }
                }
        }
 
index e337da6..8ae28f8 100644 (file)
@@ -1118,7 +1118,7 @@ static int bgx_lmac_enable(struct bgx *bgx, u8 lmacid)
                                       phy_interface_mode(lmac->lmac_type)))
                        return -ENODEV;
 
-               phy_start_aneg(lmac->phydev);
+               phy_start(lmac->phydev);
                return 0;
        }
 
index 4af78de..01a2120 100644 (file)
@@ -577,6 +577,8 @@ static int gmac_setup_txqs(struct net_device *netdev)
 
        if (port->txq_dma_base & ~DMA_Q_BASE_MASK) {
                dev_warn(geth->dev, "TX queue base is not aligned\n");
+               dma_free_coherent(geth->dev, len * sizeof(*desc_ring),
+                                 desc_ring, port->txq_dma_base);
                kfree(skb_tab);
                return -ENOMEM;
        }
index e8936ae..718afa4 100644 (file)
@@ -456,9 +456,9 @@ hip04_mac_start_xmit(struct sk_buff *skb, struct net_device *ndev)
        skb_tx_timestamp(skb);
 
        hip04_set_xmit_desc(priv, phys);
-       priv->tx_head = TX_NEXT(tx_head);
        count++;
        netdev_sent_queue(ndev, skb->len);
+       priv->tx_head = TX_NEXT(tx_head);
 
        stats->tx_bytes += skb->len;
        stats->tx_packets++;
index 2097f92..f9259e5 100644 (file)
@@ -173,8 +173,12 @@ void hnae3_register_ae_algo(struct hnae3_ae_algo *ae_algo)
                if (!id)
                        continue;
 
-               /* ae_dev init should set flag */
+               if (!ae_algo->ops) {
+                       dev_err(&ae_dev->pdev->dev, "ae_algo ops are null\n");
+                       continue;
+               }
                ae_dev->ops = ae_algo->ops;
+
                ret = ae_algo->ops->init_ae_dev(ae_dev);
                if (ret) {
                        dev_err(&ae_dev->pdev->dev,
@@ -182,6 +186,7 @@ void hnae3_register_ae_algo(struct hnae3_ae_algo *ae_algo)
                        continue;
                }
 
+               /* ae_dev init should set flag */
                hnae3_set_bit(ae_dev->flag, HNAE3_DEV_INITED_B, 1);
 
                /* check the client list for the match with this ae_dev type and
@@ -239,7 +244,7 @@ EXPORT_SYMBOL(hnae3_unregister_ae_algo);
  * @ae_dev: the AE device
  * NOTE: the duplicated name will not be checked
  */
-void hnae3_register_ae_dev(struct hnae3_ae_dev *ae_dev)
+int hnae3_register_ae_dev(struct hnae3_ae_dev *ae_dev)
 {
        const struct pci_device_id *id;
        struct hnae3_ae_algo *ae_algo;
@@ -256,14 +261,13 @@ void hnae3_register_ae_dev(struct hnae3_ae_dev *ae_dev)
                if (!id)
                        continue;
 
-               ae_dev->ops = ae_algo->ops;
-
-               if (!ae_dev->ops) {
-                       dev_err(&ae_dev->pdev->dev, "ae_dev ops are null\n");
+               if (!ae_algo->ops) {
+                       dev_err(&ae_dev->pdev->dev, "ae_algo ops are null\n");
+                       ret = -EOPNOTSUPP;
                        goto out_err;
                }
+               ae_dev->ops = ae_algo->ops;
 
-               /* ae_dev init should set flag */
                ret = ae_dev->ops->init_ae_dev(ae_dev);
                if (ret) {
                        dev_err(&ae_dev->pdev->dev,
@@ -271,6 +275,7 @@ void hnae3_register_ae_dev(struct hnae3_ae_dev *ae_dev)
                        goto out_err;
                }
 
+               /* ae_dev init should set flag */
                hnae3_set_bit(ae_dev->flag, HNAE3_DEV_INITED_B, 1);
                break;
        }
@@ -286,8 +291,15 @@ void hnae3_register_ae_dev(struct hnae3_ae_dev *ae_dev)
                                ret);
        }
 
+       mutex_unlock(&hnae3_common_lock);
+
+       return 0;
+
 out_err:
+       list_del(&ae_dev->node);
        mutex_unlock(&hnae3_common_lock);
+
+       return ret;
 }
 EXPORT_SYMBOL(hnae3_register_ae_dev);
 
index f5c7fc9..5e1a7ab 100644 (file)
@@ -513,7 +513,7 @@ struct hnae3_handle {
 #define hnae3_get_bit(origin, shift) \
        hnae3_get_field((origin), (0x1 << (shift)), (shift))
 
-void hnae3_register_ae_dev(struct hnae3_ae_dev *ae_dev);
+int hnae3_register_ae_dev(struct hnae3_ae_dev *ae_dev);
 void hnae3_unregister_ae_dev(struct hnae3_ae_dev *ae_dev);
 
 void hnae3_unregister_ae_algo(struct hnae3_ae_algo *ae_algo);
index b286008..1aaf6e2 100644 (file)
@@ -1474,6 +1474,9 @@ static bool hns3_get_tx_timeo_queue_info(struct net_device *ndev)
                    time_after(jiffies,
                               (trans_start + ndev->watchdog_timeo))) {
                        timeout_queue = i;
+                       netdev_info(ndev, "queue state: 0x%lx, delta msecs: %u\n",
+                                   q->state,
+                                   jiffies_to_msecs(jiffies - trans_start));
                        break;
                }
        }
@@ -1604,9 +1607,13 @@ static int hns3_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        ae_dev->dev_type = HNAE3_DEV_KNIC;
        pci_set_drvdata(pdev, ae_dev);
 
-       hnae3_register_ae_dev(ae_dev);
+       ret = hnae3_register_ae_dev(ae_dev);
+       if (ret) {
+               devm_kfree(&pdev->dev, ae_dev);
+               pci_set_drvdata(pdev, NULL);
+       }
 
-       return 0;
+       return ret;
 }
 
 /* hns3_remove - Device removal routine
@@ -1620,6 +1627,7 @@ static void hns3_remove(struct pci_dev *pdev)
                hns3_disable_sriov(pdev);
 
        hnae3_unregister_ae_dev(ae_dev);
+       pci_set_drvdata(pdev, NULL);
 }
 
 /**
index 27d5f27..78b44d7 100644 (file)
@@ -1345,8 +1345,8 @@ static inline int e100_load_ucode_wait(struct nic *nic)
 
        fw = e100_request_firmware(nic);
        /* If it's NULL, then no ucode is required */
-       if (!fw || IS_ERR(fw))
-               return PTR_ERR(fw);
+       if (IS_ERR_OR_NULL(fw))
+               return PTR_ERR_OR_ZERO(fw);
 
        if ((err = e100_exec_cb(nic, (void *)fw, e100_setup_ucode)))
                netif_err(nic, probe, nic->netdev,
index 1a66373..23b31b2 100644 (file)
@@ -3441,14 +3441,14 @@ static void i40e_vsi_configure_msix(struct i40e_vsi *vsi)
                q_vector->rx.target_itr =
                        ITR_TO_REG(vsi->rx_rings[i]->itr_setting);
                wr32(hw, I40E_PFINT_ITRN(I40E_RX_ITR, vector - 1),
-                    q_vector->rx.target_itr);
+                    q_vector->rx.target_itr >> 1);
                q_vector->rx.current_itr = q_vector->rx.target_itr;
 
                q_vector->tx.next_update = jiffies + 1;
                q_vector->tx.target_itr =
                        ITR_TO_REG(vsi->tx_rings[i]->itr_setting);
                wr32(hw, I40E_PFINT_ITRN(I40E_TX_ITR, vector - 1),
-                    q_vector->tx.target_itr);
+                    q_vector->tx.target_itr >> 1);
                q_vector->tx.current_itr = q_vector->tx.target_itr;
 
                wr32(hw, I40E_PFINT_RATEN(vector - 1),
@@ -3553,11 +3553,11 @@ static void i40e_configure_msi_and_legacy(struct i40e_vsi *vsi)
        /* set the ITR configuration */
        q_vector->rx.next_update = jiffies + 1;
        q_vector->rx.target_itr = ITR_TO_REG(vsi->rx_rings[0]->itr_setting);
-       wr32(hw, I40E_PFINT_ITR0(I40E_RX_ITR), q_vector->rx.target_itr);
+       wr32(hw, I40E_PFINT_ITR0(I40E_RX_ITR), q_vector->rx.target_itr >> 1);
        q_vector->rx.current_itr = q_vector->rx.target_itr;
        q_vector->tx.next_update = jiffies + 1;
        q_vector->tx.target_itr = ITR_TO_REG(vsi->tx_rings[0]->itr_setting);
-       wr32(hw, I40E_PFINT_ITR0(I40E_TX_ITR), q_vector->tx.target_itr);
+       wr32(hw, I40E_PFINT_ITR0(I40E_TX_ITR), q_vector->tx.target_itr >> 1);
        q_vector->tx.current_itr = q_vector->tx.target_itr;
 
        i40e_enable_misc_int_causes(pf);
@@ -10735,7 +10735,7 @@ static int i40e_setup_misc_vector(struct i40e_pf *pf)
 
        /* associate no queues to the misc vector */
        wr32(hw, I40E_PFINT_LNKLST0, I40E_QUEUE_END_OF_LIST);
-       wr32(hw, I40E_PFINT_ITR0(I40E_RX_ITR), I40E_ITR_8K);
+       wr32(hw, I40E_PFINT_ITR0(I40E_RX_ITR), I40E_ITR_8K >> 1);
 
        i40e_flush(hw);
 
index 89f18fe..921cc0c 100644 (file)
@@ -911,7 +911,7 @@ ice_sq_send_cmd(struct ice_hw *hw, struct ice_ctl_q_info *cq,
                if (ice_sq_done(hw, cq))
                        break;
 
-               mdelay(1);
+               udelay(ICE_CTL_Q_SQ_CMD_USEC);
                total_delay++;
        } while (total_delay < cq->sq_cmd_timeout);
 
index ea02b89..0f2cdb0 100644 (file)
@@ -30,8 +30,9 @@ enum ice_ctl_q {
        ICE_CTL_Q_ADMIN,
 };
 
-/* Control Queue default settings */
-#define ICE_CTL_Q_SQ_CMD_TIMEOUT       250  /* msecs */
+/* Control Queue timeout settings - max delay 250ms */
+#define ICE_CTL_Q_SQ_CMD_TIMEOUT       2500  /* Count 2500 times */
+#define ICE_CTL_Q_SQ_CMD_USEC          100   /* Check every 100usec */
 
 struct ice_ctl_q_ring {
        void *dma_head;                 /* Virtual address to dma head */
index b45a6e2..de65ca1 100644 (file)
@@ -8551,7 +8551,8 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb,
 
        if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) &&
            adapter->ptp_clock) {
-               if (!test_and_set_bit_lock(__IXGBE_PTP_TX_IN_PROGRESS,
+               if (adapter->tstamp_config.tx_type == HWTSTAMP_TX_ON &&
+                   !test_and_set_bit_lock(__IXGBE_PTP_TX_IN_PROGRESS,
                                           &adapter->state)) {
                        skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
                        tx_flags |= IXGBE_TX_FLAGS_TSTAMP;
index a50977c..04bee45 100644 (file)
@@ -3341,7 +3341,7 @@ static int mvpp2_open(struct net_device *dev)
                valid = true;
        }
 
-       if (priv->hw_version == MVPP22 && port->link_irq && !port->phylink) {
+       if (priv->hw_version == MVPP22 && port->link_irq) {
                err = request_irq(port->link_irq, mvpp2_link_status_isr, 0,
                                  dev->name, port);
                if (err) {
index 4ab0d03..28d56e4 100644 (file)
@@ -155,8 +155,11 @@ static int update_xoff_threshold(struct mlx5e_port_buffer *port_buffer,
                }
 
                if (port_buffer->buffer[i].size <
-                   (xoff + max_mtu + (1 << MLX5E_BUFFER_CELL_SHIFT)))
+                   (xoff + max_mtu + (1 << MLX5E_BUFFER_CELL_SHIFT))) {
+                       pr_err("buffer_size[%d]=%d is not enough for lossless buffer\n",
+                              i, port_buffer->buffer[i].size);
                        return -ENOMEM;
+               }
 
                port_buffer->buffer[i].xoff = port_buffer->buffer[i].size - xoff;
                port_buffer->buffer[i].xon  =
@@ -232,6 +235,26 @@ static int update_buffer_lossy(unsigned int max_mtu,
        return 0;
 }
 
+static int fill_pfc_en(struct mlx5_core_dev *mdev, u8 *pfc_en)
+{
+       u32 g_rx_pause, g_tx_pause;
+       int err;
+
+       err = mlx5_query_port_pause(mdev, &g_rx_pause, &g_tx_pause);
+       if (err)
+               return err;
+
+       /* If global pause enabled, set all active buffers to lossless.
+        * Otherwise, check PFC setting.
+        */
+       if (g_rx_pause || g_tx_pause)
+               *pfc_en = 0xff;
+       else
+               err = mlx5_query_port_pfc(mdev, pfc_en, NULL);
+
+       return err;
+}
+
 #define MINIMUM_MAX_MTU 9216
 int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
                                    u32 change, unsigned int mtu,
@@ -277,7 +300,7 @@ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
 
        if (change & MLX5E_PORT_BUFFER_PRIO2BUFFER) {
                update_prio2buffer = true;
-               err = mlx5_query_port_pfc(priv->mdev, &curr_pfc_en, NULL);
+               err = fill_pfc_en(priv->mdev, &curr_pfc_en);
                if (err)
                        return err;
 
index 10d72c8..a383276 100644 (file)
@@ -1320,7 +1320,7 @@ static int mlx5e_get_module_info(struct net_device *netdev,
                break;
        case MLX5_MODULE_ID_SFP:
                modinfo->type       = ETH_MODULE_SFF_8472;
-               modinfo->eeprom_len = MLX5_EEPROM_PAGE_LENGTH;
+               modinfo->eeprom_len = ETH_MODULE_SFF_8472_LEN;
                break;
        default:
                netdev_err(priv->netdev, "%s: cable type not recognized:0x%x\n",
index 993cb5b..b99169a 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/netlink.h>
+#include <linux/vmalloc.h>
 #include <linux/xz.h>
 #include "mlxfw_mfa2.h"
 #include "mlxfw_mfa2_file.h"
@@ -579,7 +580,7 @@ mlxfw_mfa2_file_component_get(const struct mlxfw_mfa2_file *mfa2_file,
        comp_size = be32_to_cpu(comp->size);
        comp_buf_size = comp_size + mlxfw_mfa2_comp_magic_len;
 
-       comp_data = kmalloc(sizeof(*comp_data) + comp_buf_size, GFP_KERNEL);
+       comp_data = vzalloc(sizeof(*comp_data) + comp_buf_size);
        if (!comp_data)
                return ERR_PTR(-ENOMEM);
        comp_data->comp.data_size = comp_size;
@@ -601,7 +602,7 @@ mlxfw_mfa2_file_component_get(const struct mlxfw_mfa2_file *mfa2_file,
        comp_data->comp.data = comp_data->buff + mlxfw_mfa2_comp_magic_len;
        return &comp_data->comp;
 err_out:
-       kfree(comp_data);
+       vfree(comp_data);
        return ERR_PTR(err);
 }
 
@@ -610,7 +611,7 @@ void mlxfw_mfa2_file_component_put(struct mlxfw_mfa2_component *comp)
        const struct mlxfw_mfa2_comp_data *comp_data;
 
        comp_data = container_of(comp, struct mlxfw_mfa2_comp_data, comp);
-       kfree(comp_data);
+       vfree(comp_data);
 }
 
 void mlxfw_mfa2_file_fini(struct mlxfw_mfa2_file *mfa2_file)
index 44b6c2a..76960d3 100644 (file)
@@ -2228,7 +2228,7 @@ static void mlxsw_sp_router_probe_unresolved_nexthops(struct work_struct *work)
 static void
 mlxsw_sp_nexthop_neigh_update(struct mlxsw_sp *mlxsw_sp,
                              struct mlxsw_sp_neigh_entry *neigh_entry,
-                             bool removing);
+                             bool removing, bool dead);
 
 static enum mlxsw_reg_rauht_op mlxsw_sp_rauht_op(bool adding)
 {
@@ -2359,7 +2359,8 @@ static void mlxsw_sp_router_neigh_event_work(struct work_struct *work)
 
        memcpy(neigh_entry->ha, ha, ETH_ALEN);
        mlxsw_sp_neigh_entry_update(mlxsw_sp, neigh_entry, entry_connected);
-       mlxsw_sp_nexthop_neigh_update(mlxsw_sp, neigh_entry, !entry_connected);
+       mlxsw_sp_nexthop_neigh_update(mlxsw_sp, neigh_entry, !entry_connected,
+                                     dead);
 
        if (!neigh_entry->connected && list_empty(&neigh_entry->nexthop_list))
                mlxsw_sp_neigh_entry_destroy(mlxsw_sp, neigh_entry);
@@ -3323,13 +3324,79 @@ static void __mlxsw_sp_nexthop_neigh_update(struct mlxsw_sp_nexthop *nh,
        nh->update = 1;
 }
 
+static int
+mlxsw_sp_nexthop_dead_neigh_replace(struct mlxsw_sp *mlxsw_sp,
+                                   struct mlxsw_sp_neigh_entry *neigh_entry)
+{
+       struct neighbour *n, *old_n = neigh_entry->key.n;
+       struct mlxsw_sp_nexthop *nh;
+       bool entry_connected;
+       u8 nud_state, dead;
+       int err;
+
+       nh = list_first_entry(&neigh_entry->nexthop_list,
+                             struct mlxsw_sp_nexthop, neigh_list_node);
+
+       n = neigh_lookup(nh->nh_grp->neigh_tbl, &nh->gw_addr, nh->rif->dev);
+       if (!n) {
+               n = neigh_create(nh->nh_grp->neigh_tbl, &nh->gw_addr,
+                                nh->rif->dev);
+               if (IS_ERR(n))
+                       return PTR_ERR(n);
+               neigh_event_send(n, NULL);
+       }
+
+       mlxsw_sp_neigh_entry_remove(mlxsw_sp, neigh_entry);
+       neigh_entry->key.n = n;
+       err = mlxsw_sp_neigh_entry_insert(mlxsw_sp, neigh_entry);
+       if (err)
+               goto err_neigh_entry_insert;
+
+       read_lock_bh(&n->lock);
+       nud_state = n->nud_state;
+       dead = n->dead;
+       read_unlock_bh(&n->lock);
+       entry_connected = nud_state & NUD_VALID && !dead;
+
+       list_for_each_entry(nh, &neigh_entry->nexthop_list,
+                           neigh_list_node) {
+               neigh_release(old_n);
+               neigh_clone(n);
+               __mlxsw_sp_nexthop_neigh_update(nh, !entry_connected);
+               mlxsw_sp_nexthop_group_refresh(mlxsw_sp, nh->nh_grp);
+       }
+
+       neigh_release(n);
+
+       return 0;
+
+err_neigh_entry_insert:
+       neigh_entry->key.n = old_n;
+       mlxsw_sp_neigh_entry_insert(mlxsw_sp, neigh_entry);
+       neigh_release(n);
+       return err;
+}
+
 static void
 mlxsw_sp_nexthop_neigh_update(struct mlxsw_sp *mlxsw_sp,
                              struct mlxsw_sp_neigh_entry *neigh_entry,
-                             bool removing)
+                             bool removing, bool dead)
 {
        struct mlxsw_sp_nexthop *nh;
 
+       if (list_empty(&neigh_entry->nexthop_list))
+               return;
+
+       if (dead) {
+               int err;
+
+               err = mlxsw_sp_nexthop_dead_neigh_replace(mlxsw_sp,
+                                                         neigh_entry);
+               if (err)
+                       dev_err(mlxsw_sp->bus_info->dev, "Failed to replace dead neigh\n");
+               return;
+       }
+
        list_for_each_entry(nh, &neigh_entry->nexthop_list,
                            neigh_list_node) {
                __mlxsw_sp_nexthop_neigh_update(nh, removing);
index b16ce7d..c3d5d40 100644 (file)
@@ -1230,7 +1230,7 @@ qede_configure_mcast_filtering(struct net_device *ndev,
        netif_addr_lock_bh(ndev);
 
        mc_count = netdev_mc_count(ndev);
-       if (mc_count < 64) {
+       if (mc_count <= 64) {
                netdev_for_each_mc_addr(ha, ndev) {
                        ether_addr_copy(temp, ha->addr);
                        temp += ETH_ALEN;
index 630b13a..0d8e39f 100644 (file)
@@ -1362,6 +1362,7 @@ static int qede_alloc_mem_rxq(struct qede_dev *edev, struct qede_rx_queue *rxq)
                rxq->rx_buf_seg_size = roundup_pow_of_two(size);
        } else {
                rxq->rx_buf_seg_size = PAGE_SIZE;
+               edev->ndev->features &= ~NETIF_F_GRO_HW;
        }
 
        /* Allocate the parallel driver ring for Rx buffers */
@@ -1406,6 +1407,7 @@ static int qede_alloc_mem_rxq(struct qede_dev *edev, struct qede_rx_queue *rxq)
                }
        }
 
+       edev->gro_disable = !(edev->ndev->features & NETIF_F_GRO_HW);
        if (!edev->gro_disable)
                qede_set_tpa_param(rxq);
 err:
@@ -1606,8 +1608,6 @@ static void qede_init_fp(struct qede_dev *edev)
                snprintf(fp->name, sizeof(fp->name), "%s-fp-%d",
                         edev->ndev->name, queue_id);
        }
-
-       edev->gro_disable = !(edev->ndev->features & NETIF_F_GRO_HW);
 }
 
 static int qede_set_real_num_queues(struct qede_dev *edev)
index 783ee6a..1b5e098 100644 (file)
@@ -2757,6 +2757,9 @@ static int ql_alloc_large_buffers(struct ql3_adapter *qdev)
        int err;
 
        for (i = 0; i < qdev->num_large_buffers; i++) {
+               lrg_buf_cb = &qdev->lrg_buf[i];
+               memset(lrg_buf_cb, 0, sizeof(struct ql_rcv_buf_cb));
+
                skb = netdev_alloc_skb(qdev->ndev,
                                       qdev->lrg_buffer_len);
                if (unlikely(!skb)) {
@@ -2767,11 +2770,7 @@ static int ql_alloc_large_buffers(struct ql3_adapter *qdev)
                        ql_free_large_buffers(qdev);
                        return -ENOMEM;
                } else {
-
-                       lrg_buf_cb = &qdev->lrg_buf[i];
-                       memset(lrg_buf_cb, 0, sizeof(struct ql_rcv_buf_cb));
                        lrg_buf_cb->index = i;
-                       lrg_buf_cb->skb = skb;
                        /*
                         * We save some space to copy the ethhdr from first
                         * buffer
@@ -2793,6 +2792,7 @@ static int ql_alloc_large_buffers(struct ql3_adapter *qdev)
                                return -ENOMEM;
                        }
 
+                       lrg_buf_cb->skb = skb;
                        dma_unmap_addr_set(lrg_buf_cb, mapaddr, map);
                        dma_unmap_len_set(lrg_buf_cb, maplen,
                                          qdev->lrg_buffer_len -
index c597956..94b4625 100644 (file)
@@ -118,6 +118,14 @@ static int meson8b_init_rgmii_tx_clk(struct meson8b_dwmac *dwmac)
        struct device *dev = dwmac->dev;
        const char *parent_name, *mux_parent_names[MUX_CLK_NUM_PARENTS];
        struct meson8b_dwmac_clk_configs *clk_configs;
+       static const struct clk_div_table div_table[] = {
+               { .div = 2, .val = 2, },
+               { .div = 3, .val = 3, },
+               { .div = 4, .val = 4, },
+               { .div = 5, .val = 5, },
+               { .div = 6, .val = 6, },
+               { .div = 7, .val = 7, },
+       };
 
        clk_configs = devm_kzalloc(dev, sizeof(*clk_configs), GFP_KERNEL);
        if (!clk_configs)
@@ -152,9 +160,9 @@ static int meson8b_init_rgmii_tx_clk(struct meson8b_dwmac *dwmac)
        clk_configs->m250_div.reg = dwmac->regs + PRG_ETH0;
        clk_configs->m250_div.shift = PRG_ETH0_CLK_M250_DIV_SHIFT;
        clk_configs->m250_div.width = PRG_ETH0_CLK_M250_DIV_WIDTH;
-       clk_configs->m250_div.flags = CLK_DIVIDER_ONE_BASED |
-                               CLK_DIVIDER_ALLOW_ZERO |
-                               CLK_DIVIDER_ROUND_CLOSEST;
+       clk_configs->m250_div.table = div_table;
+       clk_configs->m250_div.flags = CLK_DIVIDER_ALLOW_ZERO |
+                                     CLK_DIVIDER_ROUND_CLOSEST;
        clk = meson8b_dwmac_register_clk(dwmac, "m250_div", &parent_name, 1,
                                         &clk_divider_ops,
                                         &clk_configs->m250_div.hw);
index 8417d4c..0b7a3eb 100644 (file)
@@ -954,8 +954,8 @@ static irqreturn_t cpsw_rx_interrupt(int irq, void *dev_id)
 {
        struct cpsw_common *cpsw = dev_id;
 
-       cpdma_ctlr_eoi(cpsw->dma, CPDMA_EOI_RX);
        writel(0, &cpsw->wr_regs->rx_en);
+       cpdma_ctlr_eoi(cpsw->dma, CPDMA_EOI_RX);
 
        if (cpsw->quirk_irq) {
                disable_irq_nosync(cpsw->irqs_table[0]);
index 5766225..c245629 100644 (file)
@@ -793,6 +793,7 @@ EXPORT_SYMBOL_GPL(cpsw_ale_start);
 void cpsw_ale_stop(struct cpsw_ale *ale)
 {
        del_timer_sync(&ale->timer);
+       cpsw_ale_control_set(ale, 0, ALE_CLEAR, 1);
        cpsw_ale_control_set(ale, 0, ALE_ENABLE, 0);
 }
 EXPORT_SYMBOL_GPL(cpsw_ale_stop);
@@ -877,6 +878,7 @@ struct cpsw_ale *cpsw_ale_create(struct cpsw_ale_params *params)
                                        ALE_UNKNOWNVLAN_FORCE_UNTAG_EGRESS;
        }
 
+       cpsw_ale_control_set(ale, 0, ALE_CLEAR, 1);
        return ale;
 }
 EXPORT_SYMBOL_GPL(cpsw_ale_create);
index 61a9843..1979f8f 100644 (file)
@@ -181,6 +181,9 @@ static int fjes_acpi_add(struct acpi_device *device)
        /* create platform_device */
        plat_dev = platform_device_register_simple(DRV_NAME, 0, fjes_resource,
                                                   ARRAY_SIZE(fjes_resource));
+       if (IS_ERR(plat_dev))
+               return PTR_ERR(plat_dev);
+
        device->driver_data = plat_dev;
 
        return 0;
index d178d5b..494f00b 100644 (file)
@@ -42,7 +42,6 @@ struct pdp_ctx {
        struct hlist_node       hlist_addr;
 
        union {
-               u64             tid;
                struct {
                        u64     tid;
                        u16     flow;
@@ -545,7 +544,7 @@ static int gtp_build_skb_ip4(struct sk_buff *skb, struct net_device *dev,
                mtu = dst_mtu(&rt->dst);
        }
 
-       rt->dst.ops->update_pmtu(&rt->dst, NULL, skb, mtu);
+       rt->dst.ops->update_pmtu(&rt->dst, NULL, skb, mtu, false);
 
        if (!skb_is_gso(skb) && (iph->frag_off & htons(IP_DF)) &&
            mtu < ntohs(iph->tot_len)) {
@@ -645,9 +644,16 @@ static void gtp_link_setup(struct net_device *dev)
 }
 
 static int gtp_hashtable_new(struct gtp_dev *gtp, int hsize);
-static void gtp_hashtable_free(struct gtp_dev *gtp);
 static int gtp_encap_enable(struct gtp_dev *gtp, struct nlattr *data[]);
 
+static void gtp_destructor(struct net_device *dev)
+{
+       struct gtp_dev *gtp = netdev_priv(dev);
+
+       kfree(gtp->addr_hash);
+       kfree(gtp->tid_hash);
+}
+
 static int gtp_newlink(struct net *src_net, struct net_device *dev,
                       struct nlattr *tb[], struct nlattr *data[],
                       struct netlink_ext_ack *extack)
@@ -665,10 +671,13 @@ static int gtp_newlink(struct net *src_net, struct net_device *dev,
        if (err < 0)
                return err;
 
-       if (!data[IFLA_GTP_PDP_HASHSIZE])
+       if (!data[IFLA_GTP_PDP_HASHSIZE]) {
                hashsize = 1024;
-       else
+       } else {
                hashsize = nla_get_u32(data[IFLA_GTP_PDP_HASHSIZE]);
+               if (!hashsize)
+                       hashsize = 1024;
+       }
 
        err = gtp_hashtable_new(gtp, hashsize);
        if (err < 0)
@@ -682,13 +691,15 @@ static int gtp_newlink(struct net *src_net, struct net_device *dev,
 
        gn = net_generic(dev_net(dev), gtp_net_id);
        list_add_rcu(&gtp->list, &gn->gtp_dev_list);
+       dev->priv_destructor = gtp_destructor;
 
        netdev_dbg(dev, "registered new GTP interface\n");
 
        return 0;
 
 out_hashtable:
-       gtp_hashtable_free(gtp);
+       kfree(gtp->addr_hash);
+       kfree(gtp->tid_hash);
 out_encap:
        gtp_encap_disable(gtp);
        return err;
@@ -697,9 +708,14 @@ out_encap:
 static void gtp_dellink(struct net_device *dev, struct list_head *head)
 {
        struct gtp_dev *gtp = netdev_priv(dev);
+       struct pdp_ctx *pctx;
+       int i;
+
+       for (i = 0; i < gtp->hash_size; i++)
+               hlist_for_each_entry_rcu(pctx, &gtp->tid_hash[i], hlist_tid)
+                       pdp_context_delete(pctx);
 
        gtp_encap_disable(gtp);
-       gtp_hashtable_free(gtp);
        list_del_rcu(&gtp->list);
        unregister_netdevice_queue(dev, head);
 }
@@ -777,20 +793,6 @@ err1:
        return -ENOMEM;
 }
 
-static void gtp_hashtable_free(struct gtp_dev *gtp)
-{
-       struct pdp_ctx *pctx;
-       int i;
-
-       for (i = 0; i < gtp->hash_size; i++)
-               hlist_for_each_entry_rcu(pctx, &gtp->tid_hash[i], hlist_tid)
-                       pdp_context_delete(pctx);
-
-       synchronize_rcu();
-       kfree(gtp->addr_hash);
-       kfree(gtp->tid_hash);
-}
-
 static struct sock *gtp_encap_enable_socket(int fd, int type,
                                            struct gtp_dev *gtp)
 {
@@ -931,24 +933,31 @@ static void ipv4_pdp_fill(struct pdp_ctx *pctx, struct genl_info *info)
        }
 }
 
-static int ipv4_pdp_add(struct gtp_dev *gtp, struct sock *sk,
-                       struct genl_info *info)
+static int gtp_pdp_add(struct gtp_dev *gtp, struct sock *sk,
+                      struct genl_info *info)
 {
+       struct pdp_ctx *pctx, *pctx_tid = NULL;
        struct net_device *dev = gtp->dev;
        u32 hash_ms, hash_tid = 0;
-       struct pdp_ctx *pctx;
+       unsigned int version;
        bool found = false;
        __be32 ms_addr;
 
        ms_addr = nla_get_be32(info->attrs[GTPA_MS_ADDRESS]);
        hash_ms = ipv4_hashfn(ms_addr) % gtp->hash_size;
+       version = nla_get_u32(info->attrs[GTPA_VERSION]);
 
-       hlist_for_each_entry_rcu(pctx, &gtp->addr_hash[hash_ms], hlist_addr) {
-               if (pctx->ms_addr_ip4.s_addr == ms_addr) {
-                       found = true;
-                       break;
-               }
-       }
+       pctx = ipv4_pdp_find(gtp, ms_addr);
+       if (pctx)
+               found = true;
+       if (version == GTP_V0)
+               pctx_tid = gtp0_pdp_find(gtp,
+                                        nla_get_u64(info->attrs[GTPA_TID]));
+       else if (version == GTP_V1)
+               pctx_tid = gtp1_pdp_find(gtp,
+                                        nla_get_u32(info->attrs[GTPA_I_TEI]));
+       if (pctx_tid)
+               found = true;
 
        if (found) {
                if (info->nlhdr->nlmsg_flags & NLM_F_EXCL)
@@ -956,6 +965,11 @@ static int ipv4_pdp_add(struct gtp_dev *gtp, struct sock *sk,
                if (info->nlhdr->nlmsg_flags & NLM_F_REPLACE)
                        return -EOPNOTSUPP;
 
+               if (pctx && pctx_tid)
+                       return -EEXIST;
+               if (!pctx)
+                       pctx = pctx_tid;
+
                ipv4_pdp_fill(pctx, info);
 
                if (pctx->gtp_version == GTP_V0)
@@ -1079,7 +1093,7 @@ static int gtp_genl_new_pdp(struct sk_buff *skb, struct genl_info *info)
                goto out_unlock;
        }
 
-       err = ipv4_pdp_add(gtp, sk, info);
+       err = gtp_pdp_add(gtp, sk, info);
 
 out_unlock:
        rcu_read_unlock();
@@ -1237,43 +1251,46 @@ static int gtp_genl_dump_pdp(struct sk_buff *skb,
                                struct netlink_callback *cb)
 {
        struct gtp_dev *last_gtp = (struct gtp_dev *)cb->args[2], *gtp;
+       int i, j, bucket = cb->args[0], skip = cb->args[1];
        struct net *net = sock_net(skb->sk);
-       struct gtp_net *gn = net_generic(net, gtp_net_id);
-       unsigned long tid = cb->args[1];
-       int i, k = cb->args[0], ret;
        struct pdp_ctx *pctx;
+       struct gtp_net *gn;
+
+       gn = net_generic(net, gtp_net_id);
 
        if (cb->args[4])
                return 0;
 
+       rcu_read_lock();
        list_for_each_entry_rcu(gtp, &gn->gtp_dev_list, list) {
                if (last_gtp && last_gtp != gtp)
                        continue;
                else
                        last_gtp = NULL;
 
-               for (i = k; i < gtp->hash_size; i++) {
-                       hlist_for_each_entry_rcu(pctx, &gtp->tid_hash[i], hlist_tid) {
-                               if (tid && tid != pctx->u.tid)
-                                       continue;
-                               else
-                                       tid = 0;
-
-                               ret = gtp_genl_fill_info(skb,
-                                                        NETLINK_CB(cb->skb).portid,
-                                                        cb->nlh->nlmsg_seq,
-                                                        cb->nlh->nlmsg_type, pctx);
-                               if (ret < 0) {
+               for (i = bucket; i < gtp->hash_size; i++) {
+                       j = 0;
+                       hlist_for_each_entry_rcu(pctx, &gtp->tid_hash[i],
+                                                hlist_tid) {
+                               if (j >= skip &&
+                                   gtp_genl_fill_info(skb,
+                                           NETLINK_CB(cb->skb).portid,
+                                           cb->nlh->nlmsg_seq,
+                                           cb->nlh->nlmsg_type, pctx)) {
                                        cb->args[0] = i;
-                                       cb->args[1] = pctx->u.tid;
+                                       cb->args[1] = j;
                                        cb->args[2] = (unsigned long)gtp;
                                        goto out;
                                }
+                               j++;
                        }
+                       skip = 0;
                }
+               bucket = 0;
        }
        cb->args[4] = 1;
 out:
+       rcu_read_unlock();
        return skb->len;
 }
 
index 54e63ec..8c636c4 100644 (file)
@@ -654,10 +654,10 @@ static void sixpack_close(struct tty_struct *tty)
 {
        struct sixpack *sp;
 
-       write_lock_bh(&disc_data_lock);
+       write_lock_irq(&disc_data_lock);
        sp = tty->disc_data;
        tty->disc_data = NULL;
-       write_unlock_bh(&disc_data_lock);
+       write_unlock_irq(&disc_data_lock);
        if (!sp)
                return;
 
index 13e4c1e..3b14e6e 100644 (file)
@@ -783,10 +783,10 @@ static void mkiss_close(struct tty_struct *tty)
 {
        struct mkiss *ax;
 
-       write_lock_bh(&disc_data_lock);
+       write_lock_irq(&disc_data_lock);
        ax = tty->disc_data;
        tty->disc_data = NULL;
-       write_unlock_bh(&disc_data_lock);
+       write_unlock_irq(&disc_data_lock);
 
        if (!ax)
                return;
index eeadfde..879096d 100644 (file)
 #define DP83867_IO_MUX_CFG_CLK_O_SEL_MASK      (0x1f << 8)
 #define DP83867_IO_MUX_CFG_CLK_O_SEL_SHIFT     8
 
+/* CFG3 bits */
+#define DP83867_CFG3_INT_OE                    BIT(7)
+#define DP83867_CFG3_ROBUST_AUTO_MDIX          BIT(9)
+
 /* CFG4 bits */
 #define DP83867_CFG4_PORT_MIRROR_EN              BIT(0)
 
@@ -331,12 +335,13 @@ static int dp83867_config_init(struct phy_device *phydev)
                        return ret;
        }
 
+       val = phy_read(phydev, DP83867_CFG3);
        /* Enable Interrupt output INT_OE in CFG3 register */
-       if (phy_interrupt_is_valid(phydev)) {
-               val = phy_read(phydev, DP83867_CFG3);
-               val |= BIT(7);
-               phy_write(phydev, DP83867_CFG3, val);
-       }
+       if (phy_interrupt_is_valid(phydev))
+               val |= DP83867_CFG3_INT_OE;
+
+       val |= DP83867_CFG3_ROBUST_AUTO_MDIX;
+       phy_write(phydev, DP83867_CFG3, val);
 
        if (dp83867->port_mirroring != DP83867_PORT_MIRROING_KEEP)
                dp83867_config_port_mirroring(phydev);
index 6144146..43c4f35 100644 (file)
@@ -420,8 +420,8 @@ struct phy_device *phy_device_create(struct mii_bus *bus, int addr, int phy_id,
        mdiodev->device_free = phy_mdio_device_free;
        mdiodev->device_remove = phy_mdio_device_remove;
 
-       dev->speed = 0;
-       dev->duplex = -1;
+       dev->speed = SPEED_UNKNOWN;
+       dev->duplex = DUPLEX_UNKNOWN;
        dev->pause = 0;
        dev->asym_pause = 0;
        dev->link = 0;
index e1ac1c5..bbd9222 100644 (file)
@@ -319,8 +319,8 @@ static void tun_napi_init(struct tun_struct *tun, struct tun_file *tfile,
        tfile->napi_enabled = napi_en;
        tfile->napi_frags_enabled = napi_en && napi_frags;
        if (napi_en) {
-               netif_napi_add(tun->dev, &tfile->napi, tun_napi_poll,
-                              NAPI_POLL_WEIGHT);
+               netif_tx_napi_add(tun->dev, &tfile->napi, tun_napi_poll,
+                                 NAPI_POLL_WEIGHT);
                napi_enable(&tfile->napi);
        }
 }
index 042c77b..1e86cd0 100644 (file)
@@ -1837,6 +1837,7 @@ static int lan78xx_mdio_init(struct lan78xx_net *dev)
        dev->mdiobus->read = lan78xx_mdiobus_read;
        dev->mdiobus->write = lan78xx_mdiobus_write;
        dev->mdiobus->name = "lan78xx-mdiobus";
+       dev->mdiobus->parent = &dev->udev->dev;
 
        snprintf(dev->mdiobus->id, MII_BUS_ID_SIZE, "usb-%03d:%03d",
                 dev->udev->bus->busnum, dev->udev->devnum);
index b94759d..da2d179 100644 (file)
@@ -255,7 +255,8 @@ static int ar5523_cmd(struct ar5523 *ar, u32 code, const void *idata,
 
        if (flags & AR5523_CMD_FLAG_MAGIC)
                hdr->magic = cpu_to_be32(1 << 24);
-       memcpy(hdr + 1, idata, ilen);
+       if (ilen)
+               memcpy(hdr + 1, idata, ilen);
 
        cmd->odata = odata;
        cmd->olen = olen;
index 4d28063..385b84f 100644 (file)
@@ -1105,9 +1105,11 @@ static struct ath10k_dump_file_data *ath10k_coredump_build(struct ath10k *ar)
                dump_tlv = (struct ath10k_tlv_dump_data *)(buf + sofar);
                dump_tlv->type = cpu_to_le32(ATH10K_FW_CRASH_DUMP_RAM_DATA);
                dump_tlv->tlv_len = cpu_to_le32(crash_data->ramdump_buf_len);
-               memcpy(dump_tlv->tlv_data, crash_data->ramdump_buf,
-                      crash_data->ramdump_buf_len);
-               sofar += sizeof(*dump_tlv) + crash_data->ramdump_buf_len;
+               if (crash_data->ramdump_buf_len) {
+                       memcpy(dump_tlv->tlv_data, crash_data->ramdump_buf,
+                              crash_data->ramdump_buf_len);
+                       sofar += sizeof(*dump_tlv) + crash_data->ramdump_buf_len;
+               }
        }
 
        spin_unlock_bh(&ar->data_lock);
@@ -1154,6 +1156,9 @@ int ath10k_coredump_register(struct ath10k *ar)
        if (test_bit(ATH10K_FW_CRASH_DUMP_RAM_DATA, &ath10k_coredump_mask)) {
                crash_data->ramdump_buf_len = ath10k_coredump_get_ramdump_size(ar);
 
+               if (!crash_data->ramdump_buf_len)
+                       return 0;
+
                crash_data->ramdump_buf = vzalloc(crash_data->ramdump_buf_len);
                if (!crash_data->ramdump_buf)
                        return -ENOMEM;
index 613ca74..448e3a8 100644 (file)
@@ -3651,7 +3651,7 @@ static int ath10k_mac_tx(struct ath10k *ar,
                         struct ieee80211_vif *vif,
                         enum ath10k_hw_txrx_mode txmode,
                         enum ath10k_mac_tx_path txpath,
-                        struct sk_buff *skb)
+                        struct sk_buff *skb, bool noque_offchan)
 {
        struct ieee80211_hw *hw = ar->hw;
        struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
@@ -3679,10 +3679,10 @@ static int ath10k_mac_tx(struct ath10k *ar,
                }
        }
 
-       if (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN) {
+       if (!noque_offchan && info->flags & IEEE80211_TX_CTL_TX_OFFCHAN) {
                if (!ath10k_mac_tx_frm_has_freq(ar)) {
-                       ath10k_dbg(ar, ATH10K_DBG_MAC, "queued offchannel skb %pK\n",
-                                  skb);
+                       ath10k_dbg(ar, ATH10K_DBG_MAC, "mac queued offchannel skb %pK len %d\n",
+                                  skb, skb->len);
 
                        skb_queue_tail(&ar->offchan_tx_queue, skb);
                        ieee80211_queue_work(hw, &ar->offchan_tx_work);
@@ -3744,8 +3744,8 @@ void ath10k_offchan_tx_work(struct work_struct *work)
 
                mutex_lock(&ar->conf_mutex);
 
-               ath10k_dbg(ar, ATH10K_DBG_MAC, "mac offchannel skb %pK\n",
-                          skb);
+               ath10k_dbg(ar, ATH10K_DBG_MAC, "mac offchannel skb %pK len %d\n",
+                          skb, skb->len);
 
                hdr = (struct ieee80211_hdr *)skb->data;
                peer_addr = ieee80211_get_DA(hdr);
@@ -3791,7 +3791,7 @@ void ath10k_offchan_tx_work(struct work_struct *work)
                txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta, skb);
                txpath = ath10k_mac_tx_h_get_txpath(ar, skb, txmode);
 
-               ret = ath10k_mac_tx(ar, vif, txmode, txpath, skb);
+               ret = ath10k_mac_tx(ar, vif, txmode, txpath, skb, true);
                if (ret) {
                        ath10k_warn(ar, "failed to transmit offchannel frame: %d\n",
                                    ret);
@@ -3801,8 +3801,8 @@ void ath10k_offchan_tx_work(struct work_struct *work)
                time_left =
                wait_for_completion_timeout(&ar->offchan_tx_completed, 3 * HZ);
                if (time_left == 0)
-                       ath10k_warn(ar, "timed out waiting for offchannel skb %pK\n",
-                                   skb);
+                       ath10k_warn(ar, "timed out waiting for offchannel skb %pK, len: %d\n",
+                                   skb, skb->len);
 
                if (!peer && tmp_peer_created) {
                        ret = ath10k_peer_delete(ar, vdev_id, peer_addr);
@@ -3844,8 +3844,10 @@ void ath10k_mgmt_over_wmi_tx_work(struct work_struct *work)
                             ar->running_fw->fw_file.fw_features)) {
                        paddr = dma_map_single(ar->dev, skb->data,
                                               skb->len, DMA_TO_DEVICE);
-                       if (!paddr)
+                       if (dma_mapping_error(ar->dev, paddr)) {
+                               ieee80211_free_txskb(ar->hw, skb);
                                continue;
+                       }
                        ret = ath10k_wmi_mgmt_tx_send(ar, skb, paddr);
                        if (ret) {
                                ath10k_warn(ar, "failed to transmit management frame by ref via WMI: %d\n",
@@ -3998,7 +4000,7 @@ int ath10k_mac_tx_push_txq(struct ieee80211_hw *hw,
                spin_unlock_bh(&ar->htt.tx_lock);
        }
 
-       ret = ath10k_mac_tx(ar, vif, txmode, txpath, skb);
+       ret = ath10k_mac_tx(ar, vif, txmode, txpath, skb, false);
        if (unlikely(ret)) {
                ath10k_warn(ar, "failed to push frame: %d\n", ret);
 
@@ -4280,7 +4282,7 @@ static void ath10k_mac_op_tx(struct ieee80211_hw *hw,
                spin_unlock_bh(&ar->htt.tx_lock);
        }
 
-       ret = ath10k_mac_tx(ar, vif, txmode, txpath, skb);
+       ret = ath10k_mac_tx(ar, vif, txmode, txpath, skb, false);
        if (ret) {
                ath10k_warn(ar, "failed to transmit frame: %d\n", ret);
                if (is_htt) {
index 50a801a..2a503aa 100644 (file)
@@ -2052,6 +2052,11 @@ static void ath10k_pci_hif_stop(struct ath10k *ar)
 
        ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot hif stop\n");
 
+       ath10k_pci_irq_disable(ar);
+       ath10k_pci_irq_sync(ar);
+       napi_synchronize(&ar->napi);
+       napi_disable(&ar->napi);
+
        /* Most likely the device has HTT Rx ring configured. The only way to
         * prevent the device from accessing (and possible corrupting) host
         * memory is to reset the chip now.
@@ -2065,10 +2070,6 @@ static void ath10k_pci_hif_stop(struct ath10k *ar)
         */
        ath10k_pci_safe_chip_reset(ar);
 
-       ath10k_pci_irq_disable(ar);
-       ath10k_pci_irq_sync(ar);
-       napi_synchronize(&ar->napi);
-       napi_disable(&ar->napi);
        ath10k_pci_flush(ar);
 
        spin_lock_irqsave(&ar_pci->ps_lock, flags);
index 6f62ddc..6c47e4b 100644 (file)
@@ -101,6 +101,8 @@ int ath10k_txrx_tx_unref(struct ath10k_htt *htt,
 
        info = IEEE80211_SKB_CB(msdu);
        memset(&info->status, 0, sizeof(info->status));
+       info->status.rates[0].idx = -1;
+
        trace_ath10k_txrx_tx_unref(ar, tx_done->msdu_id);
 
        if (!(info->flags & IEEE80211_TX_CTL_NO_ACK))
index 17e2fdf..4f573b5 100644 (file)
@@ -1247,6 +1247,11 @@ void brcmf_detach(struct device *dev)
 
        brcmf_proto_detach_pre_delif(drvr);
 
+       if (drvr->mon_if) {
+               brcmf_net_detach(drvr->mon_if->ndev, false);
+               drvr->mon_if = NULL;
+       }
+
        /* make sure primary interface removed last */
        for (i = BRCMF_MAX_IFS-1; i > -1; i--)
                brcmf_remove_interface(drvr->iflist[i], false);
index 1bbd17a..20e16c4 100644 (file)
@@ -185,6 +185,9 @@ void iwl_leds_init(struct iwl_priv *priv)
 
        priv->led.name = kasprintf(GFP_KERNEL, "%s-led",
                                   wiphy_name(priv->hw->wiphy));
+       if (!priv->led.name)
+               return;
+
        priv->led.brightness_set = iwl_led_brightness_set;
        priv->led.blink_set = iwl_led_blink_set;
        priv->led.max_brightness = 1;
index b272695..072f80c 100644 (file)
@@ -131,6 +131,9 @@ int iwl_mvm_leds_init(struct iwl_mvm *mvm)
 
        mvm->led.name = kasprintf(GFP_KERNEL, "%s-led",
                                   wiphy_name(mvm->hw->wiphy));
+       if (!mvm->led.name)
+               return -ENOMEM;
+
        mvm->led.brightness_set = iwl_led_brightness_set;
        mvm->led.max_brightness = 1;
 
index bfb1634..e6a67bc 100644 (file)
@@ -62,6 +62,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
+#include <asm/unaligned.h>
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
 #include "iwl-trans.h"
@@ -360,7 +361,7 @@ void iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct napi_struct *napi,
        rx_res = (struct iwl_rx_mpdu_res_start *)pkt->data;
        hdr = (struct ieee80211_hdr *)(pkt->data + sizeof(*rx_res));
        len = le16_to_cpu(rx_res->byte_count);
-       rx_pkt_status = le32_to_cpup((__le32 *)
+       rx_pkt_status = get_unaligned_le32((__le32 *)
                (pkt->data + sizeof(*rx_res) + len));
 
        /* Dont use dev_alloc_skb(), we'll have enough headroom once
index 39bf85d..c7f8a29 100644 (file)
@@ -1183,6 +1183,10 @@ static int if_sdio_probe(struct sdio_func *func,
 
        spin_lock_init(&card->lock);
        card->workqueue = alloc_workqueue("libertas_sdio", WQ_MEM_RECLAIM, 0);
+       if (unlikely(!card->workqueue)) {
+               ret = -ENOMEM;
+               goto err_queue;
+       }
        INIT_WORK(&card->packet_worker, if_sdio_host_to_card_worker);
        init_waitqueue_head(&card->pwron_waitq);
 
@@ -1234,6 +1238,7 @@ err_activate_card:
        lbs_remove_card(priv);
 free:
        destroy_workqueue(card->workqueue);
+err_queue:
        while (card->packets) {
                packet = card->packets;
                card->packets = card->packets->next;
index 3fe81b2..918c699 100644 (file)
@@ -691,8 +691,11 @@ static int mwifiex_pcie_init_evt_ring(struct mwifiex_adapter *adapter)
                skb_put(skb, MAX_EVENT_SIZE);
 
                if (mwifiex_map_pci_memory(adapter, skb, MAX_EVENT_SIZE,
-                                          PCI_DMA_FROMDEVICE))
+                                          PCI_DMA_FROMDEVICE)) {
+                       kfree_skb(skb);
+                       kfree(card->evtbd_ring_vbase);
                        return -1;
+               }
 
                buf_pa = MWIFIEX_SKB_DMA_ADDR(skb);
 
index 8828baf..47c2bfe 100644 (file)
@@ -1349,6 +1349,7 @@ struct rtl8xxxu_fileops {
        u8 has_s0s1:1;
        u8 has_tx_report:1;
        u8 gen2_thermal_meter:1;
+       u8 needs_full_init:1;
        u32 adda_1t_init;
        u32 adda_1t_path_on;
        u32 adda_2t_path_on_a;
index 26b674a..14e207f 100644 (file)
@@ -1673,6 +1673,7 @@ struct rtl8xxxu_fileops rtl8723bu_fops = {
        .has_s0s1 = 1,
        .has_tx_report = 1,
        .gen2_thermal_meter = 1,
+       .needs_full_init = 1,
        .adda_1t_init = 0x01c00014,
        .adda_1t_path_on = 0x01c00014,
        .adda_2t_path_on_a = 0x01c00014,
index 2b4fcdf..66c6ee7 100644 (file)
@@ -3905,6 +3905,9 @@ static int rtl8xxxu_init_device(struct ieee80211_hw *hw)
        else
                macpower = true;
 
+       if (fops->needs_full_init)
+               macpower = false;
+
        ret = fops->power_on(priv);
        if (ret < 0) {
                dev_warn(dev, "%s: Failed power on\n", __func__);
index 1e60f70..8c60a84 100644 (file)
@@ -1556,6 +1556,8 @@ static bool usb_cmd_send_packet(struct ieee80211_hw *hw, struct sk_buff *skb)
    * This is maybe necessary:
    * rtlpriv->cfg->ops->fill_tx_cmddesc(hw, buffer, 1, 1, skb);
    */
+       dev_kfree_skb(skb);
+
        return true;
 }
 
index 80123fd..ee5ff72 100644 (file)
@@ -1198,6 +1198,7 @@ void rtl92de_enable_interrupt(struct ieee80211_hw *hw)
 
        rtl_write_dword(rtlpriv, REG_HIMR, rtlpci->irq_mask[0] & 0xFFFFFFFF);
        rtl_write_dword(rtlpriv, REG_HIMRE, rtlpci->irq_mask[1] & 0xFFFFFFFF);
+       rtlpci->irq_enabled = true;
 }
 
 void rtl92de_disable_interrupt(struct ieee80211_hw *hw)
@@ -1207,7 +1208,7 @@ void rtl92de_disable_interrupt(struct ieee80211_hw *hw)
 
        rtl_write_dword(rtlpriv, REG_HIMR, IMR8190_DISABLED);
        rtl_write_dword(rtlpriv, REG_HIMRE, IMR8190_DISABLED);
-       synchronize_irq(rtlpci->pdev->irq);
+       rtlpci->irq_enabled = false;
 }
 
 static void _rtl92de_poweroff_adapter(struct ieee80211_hw *hw)
@@ -1373,7 +1374,7 @@ void rtl92de_set_beacon_related_registers(struct ieee80211_hw *hw)
 
        bcn_interval = mac->beacon_interval;
        atim_window = 2;
-       /*rtl92de_disable_interrupt(hw);  */
+       rtl92de_disable_interrupt(hw);
        rtl_write_word(rtlpriv, REG_ATIMWND, atim_window);
        rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval);
        rtl_write_word(rtlpriv, REG_BCNTCFG, 0x660f);
@@ -1393,9 +1394,9 @@ void rtl92de_set_beacon_interval(struct ieee80211_hw *hw)
 
        RT_TRACE(rtlpriv, COMP_BEACON, DBG_DMESG,
                 "beacon_interval:%d\n", bcn_interval);
-       /* rtl92de_disable_interrupt(hw); */
+       rtl92de_disable_interrupt(hw);
        rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval);
-       /* rtl92de_enable_interrupt(hw); */
+       rtl92de_enable_interrupt(hw);
 }
 
 void rtl92de_update_interrupt_mask(struct ieee80211_hw *hw,
index d5ba2ba..2b0c030 100644 (file)
@@ -238,6 +238,7 @@ static struct rtl_hal_ops rtl8192de_hal_ops = {
        .led_control = rtl92de_led_control,
        .set_desc = rtl92de_set_desc,
        .get_desc = rtl92de_get_desc,
+       .is_tx_desc_closed = rtl92de_is_tx_desc_closed,
        .tx_polling = rtl92de_tx_polling,
        .enable_hw_sec = rtl92de_enable_hw_security_config,
        .set_key = rtl92de_set_key,
index d7b023c..76f1224 100644 (file)
@@ -840,13 +840,15 @@ u64 rtl92de_get_desc(struct ieee80211_hw *hw,
                        break;
                }
        } else {
-               struct rx_desc_92c *pdesc = (struct rx_desc_92c *)p_desc;
                switch (desc_name) {
                case HW_DESC_OWN:
-                       ret = GET_RX_DESC_OWN(pdesc);
+                       ret = GET_RX_DESC_OWN(p_desc);
                        break;
                case HW_DESC_RXPKT_LEN:
-                       ret = GET_RX_DESC_PKT_LEN(pdesc);
+                       ret = GET_RX_DESC_PKT_LEN(p_desc);
+                       break;
+               case HW_DESC_RXBUFF_ADDR:
+                       ret = GET_RX_DESC_BUFF_ADDR(p_desc);
                        break;
                default:
                        WARN_ONCE(true, "rtl8192de: ERR rxdesc :%d not processed\n",
@@ -857,6 +859,23 @@ u64 rtl92de_get_desc(struct ieee80211_hw *hw,
        return ret;
 }
 
+bool rtl92de_is_tx_desc_closed(struct ieee80211_hw *hw,
+                              u8 hw_queue, u16 index)
+{
+       struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+       struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[hw_queue];
+       u8 *entry = (u8 *)(&ring->desc[ring->idx]);
+       u8 own = (u8)rtl92de_get_desc(hw, entry, true, HW_DESC_OWN);
+
+       /* a beacon packet will only use the first
+        * descriptor by defaut, and the own bit may not
+        * be cleared by the hardware
+        */
+       if (own)
+               return false;
+       return true;
+}
+
 void rtl92de_tx_polling(struct ieee80211_hw *hw, u8 hw_queue)
 {
        struct rtl_priv *rtlpriv = rtl_priv(hw);
index f7f7765..3d026e5 100644 (file)
@@ -737,6 +737,8 @@ void rtl92de_set_desc(struct ieee80211_hw *hw, u8 *pdesc, bool istx,
                      u8 desc_name, u8 *val);
 u64 rtl92de_get_desc(struct ieee80211_hw *hw,
                     u8 *p_desc, bool istx, u8 desc_name);
+bool rtl92de_is_tx_desc_closed(struct ieee80211_hw *hw,
+                              u8 hw_queue, u16 index);
 void rtl92de_tx_polling(struct ieee80211_hw *hw, u8 hw_queue);
 void rtl92de_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc,
                             bool b_firstseg, bool b_lastseg,
index 5adb939..1181b72 100644 (file)
@@ -1050,8 +1050,10 @@ int rtl_usb_probe(struct usb_interface *intf,
        rtlpriv->hw = hw;
        rtlpriv->usb_data = kcalloc(RTL_USB_MAX_RX_COUNT, sizeof(u32),
                                    GFP_KERNEL);
-       if (!rtlpriv->usb_data)
+       if (!rtlpriv->usb_data) {
+               ieee80211_free_hw(hw);
                return -ENOMEM;
+       }
 
        /* this spin lock must be initialized early */
        spin_lock_init(&rtlpriv->locks.usb_lock);
@@ -1112,6 +1114,7 @@ error_out2:
        _rtl_usb_io_handler_release(hw);
        usb_put_dev(udev);
        complete(&rtlpriv->firmware_loading_complete);
+       kfree(rtlpriv->usb_data);
        return -ENODEV;
 }
 EXPORT_SYMBOL(rtl_usb_probe);
index 0360c01..75ae2c5 100644 (file)
@@ -1260,11 +1260,11 @@ static int btt_read_pg(struct btt *btt, struct bio_integrity_payload *bip,
 
                ret = btt_data_read(arena, page, off, postmap, cur_len);
                if (ret) {
-                       int rc;
-
                        /* Media error - set the e_flag */
-                       rc = btt_map_write(arena, premap, postmap, 0, 1,
-                               NVDIMM_IO_ATOMIC);
+                       if (btt_map_write(arena, premap, postmap, 0, 1, NVDIMM_IO_ATOMIC))
+                               dev_warn_ratelimited(to_dev(arena),
+                                       "Error persistently tracking bad blocks at %#x\n",
+                                       premap);
                        goto out_rtt;
                }
 
index b2d9bd5..b7bd89b 100644 (file)
@@ -551,8 +551,14 @@ static blk_status_t nvme_setup_discard(struct nvme_ns *ns, struct request *req,
        struct nvme_dsm_range *range;
        struct bio *bio;
 
-       range = kmalloc_array(segments, sizeof(*range),
-                               GFP_ATOMIC | __GFP_NOWARN);
+       /*
+        * Some devices do not consider the DSM 'Number of Ranges' field when
+        * determining how much data to DMA. Always allocate memory for maximum
+        * number of segments to prevent device reading beyond end of buffer.
+        */
+       static const size_t alloc_size = sizeof(*range) * NVME_DSM_MAX_RANGES;
+
+       range = kzalloc(alloc_size, GFP_ATOMIC | __GFP_NOWARN);
        if (!range) {
                /*
                 * If we fail allocation our range, fallback to the controller
@@ -593,7 +599,7 @@ static blk_status_t nvme_setup_discard(struct nvme_ns *ns, struct request *req,
 
        req->special_vec.bv_page = virt_to_page(range);
        req->special_vec.bv_offset = offset_in_page(range);
-       req->special_vec.bv_len = sizeof(*range) * segments;
+       req->special_vec.bv_len = alloc_size;
        req->rq_flags |= RQF_SPECIAL_PAYLOAD;
 
        return BLK_STS_OK;
index afb429a..926d9cc 100644 (file)
@@ -466,6 +466,10 @@ static int imx_ocotp_probe(struct platform_device *pdev)
        if (IS_ERR(priv->clk))
                return PTR_ERR(priv->clk);
 
+       clk_prepare_enable(priv->clk);
+       imx_ocotp_clr_err_if_set(priv->base);
+       clk_disable_unprepare(priv->clk);
+
        priv->params = of_device_get_match_data(&pdev->dev);
        imx_ocotp_nvmem_config.size = 4 * priv->params->nregs;
        imx_ocotp_nvmem_config.dev = dev;
index 2edb590..514528b 100644 (file)
@@ -305,7 +305,6 @@ static int add_changeset_property(struct overlay_changeset *ovcs,
 {
        struct property *new_prop = NULL, *prop;
        int ret = 0;
-       bool check_for_non_overlay_node = false;
 
        if (target->in_livetree)
                if (!of_prop_cmp(overlay_prop->name, "name") ||
@@ -318,6 +317,25 @@ static int add_changeset_property(struct overlay_changeset *ovcs,
        else
                prop = NULL;
 
+       if (prop) {
+               if (!of_prop_cmp(prop->name, "#address-cells")) {
+                       if (!of_prop_val_eq(prop, overlay_prop)) {
+                               pr_err("ERROR: changing value of #address-cells is not allowed in %pOF\n",
+                                      target->np);
+                               ret = -EINVAL;
+                       }
+                       return ret;
+
+               } else if (!of_prop_cmp(prop->name, "#size-cells")) {
+                       if (!of_prop_val_eq(prop, overlay_prop)) {
+                               pr_err("ERROR: changing value of #size-cells is not allowed in %pOF\n",
+                                      target->np);
+                               ret = -EINVAL;
+                       }
+                       return ret;
+               }
+       }
+
        if (is_symbols_prop) {
                if (prop)
                        return -EINVAL;
@@ -330,33 +348,18 @@ static int add_changeset_property(struct overlay_changeset *ovcs,
                return -ENOMEM;
 
        if (!prop) {
-               check_for_non_overlay_node = true;
                if (!target->in_livetree) {
                        new_prop->next = target->np->deadprops;
                        target->np->deadprops = new_prop;
                }
                ret = of_changeset_add_property(&ovcs->cset, target->np,
                                                new_prop);
-       } else if (!of_prop_cmp(prop->name, "#address-cells")) {
-               if (!of_prop_val_eq(prop, new_prop)) {
-                       pr_err("ERROR: changing value of #address-cells is not allowed in %pOF\n",
-                              target->np);
-                       ret = -EINVAL;
-               }
-       } else if (!of_prop_cmp(prop->name, "#size-cells")) {
-               if (!of_prop_val_eq(prop, new_prop)) {
-                       pr_err("ERROR: changing value of #size-cells is not allowed in %pOF\n",
-                              target->np);
-                       ret = -EINVAL;
-               }
        } else {
-               check_for_non_overlay_node = true;
                ret = of_changeset_update_property(&ovcs->cset, target->np,
                                                   new_prop);
        }
 
-       if (check_for_non_overlay_node &&
-           !of_node_check_flag(target->np, OF_OVERLAY))
+       if (!of_node_check_flag(target->np, OF_OVERLAY))
                pr_err("WARNING: memory leak will occur if overlay removed, property: %pOF/%s\n",
                       target->np, new_prop->name);
 
index 68f5296..808571f 100644 (file)
@@ -1133,8 +1133,10 @@ static void attach_node_and_children(struct device_node *np)
        full_name = kasprintf(GFP_KERNEL, "%pOF", np);
 
        if (!strcmp(full_name, "/__local_fixups__") ||
-           !strcmp(full_name, "/__fixups__"))
+           !strcmp(full_name, "/__fixups__")) {
+               kfree(full_name);
                return;
+       }
 
        dup = of_find_node_by_path(full_name);
        kfree(full_name);
index 7b4ee33..15c81cf 100644 (file)
@@ -230,6 +230,18 @@ static int port_check(struct device *dev, void *dev_drv)
        return 0;
 }
 
+/*
+ * Iterates through all the devices connected to the bus and return 1
+ * if the device is a parallel port.
+ */
+
+static int port_detect(struct device *dev, void *dev_drv)
+{
+       if (is_parport(dev))
+               return 1;
+       return 0;
+}
+
 /**
  *     parport_register_driver - register a parallel port device driver
  *     @drv: structure describing the driver
@@ -282,6 +294,15 @@ int __parport_register_driver(struct parport_driver *drv, struct module *owner,
                if (ret)
                        return ret;
 
+               /*
+                * check if bus has any parallel port registered, if
+                * none is found then load the lowlevel driver.
+                */
+               ret = bus_for_each_dev(&parport_bus_type, NULL, NULL,
+                                      port_detect);
+               if (!ret)
+                       get_lowlevel_driver();
+
                mutex_lock(&registration_lock);
                if (drv->match_port)
                        bus_for_each_dev(&parport_bus_type, NULL, drv,
index 9b9c677..333ab60 100644 (file)
 #define  LINK_SPEED_2_5GTS     (1 << 16)
 #define  LINK_SPEED_5_0GTS     (2 << 16)
 #define MACCTLR                        0x011058
+#define  MACCTLR_NFTS_MASK     GENMASK(23, 16) /* The name is from SH7786 */
 #define  SPEED_CHANGE          BIT(24)
 #define  SCRAMBLE_DISABLE      BIT(27)
+#define  LTSMDIS               BIT(31)
+#define  MACCTLR_INIT_VAL      (LTSMDIS | MACCTLR_NFTS_MASK)
 #define PMSR                   0x01105c
 #define MACS2R                 0x011078
 #define MACCGSPSETR            0x011084
@@ -615,6 +618,8 @@ static int rcar_pcie_hw_init(struct rcar_pcie *pcie)
        if (IS_ENABLED(CONFIG_PCI_MSI))
                rcar_pci_write_reg(pcie, 0x801f0000, PCIEMSITXR);
 
+       rcar_pci_write_reg(pcie, MACCTLR_INIT_VAL, MACCTLR);
+
        /* Finish initialization - establish a PCI Express link */
        rcar_pci_write_reg(pcie, CFINIT, PCIETCTLR);
 
@@ -1237,6 +1242,7 @@ static int rcar_pcie_resume_noirq(struct device *dev)
                return 0;
 
        /* Re-establish the PCIe link */
+       rcar_pci_write_reg(pcie, MACCTLR_INIT_VAL, MACCTLR);
        rcar_pci_write_reg(pcie, CFINIT, PCIETCTLR);
        return rcar_pcie_wait_for_dl(pcie);
 }
index 12afa7f..c94c135 100644 (file)
@@ -449,8 +449,15 @@ static void acpiphp_native_scan_bridge(struct pci_dev *bridge)
 
        /* Scan non-hotplug bridges that need to be reconfigured */
        for_each_pci_bridge(dev, bus) {
-               if (!hotplug_is_native(dev))
-                       max = pci_scan_bridge(bus, dev, max, 1);
+               if (hotplug_is_native(dev))
+                       continue;
+
+               max = pci_scan_bridge(bus, dev, max, 1);
+               if (dev->subordinate) {
+                       pcibios_resource_survey_bus(dev->subordinate);
+                       pci_bus_size_bridges(dev->subordinate);
+                       pci_bus_assign_resources(dev->subordinate);
+               }
        }
 }
 
@@ -480,7 +487,6 @@ static void enable_slot(struct acpiphp_slot *slot, bool bridge)
                        if (PCI_SLOT(dev->devfn) == slot->device)
                                acpiphp_native_scan_bridge(dev);
                }
-               pci_assign_unassigned_bridge_resources(bus->self);
        } else {
                LIST_HEAD(add_list);
                int max, pass;
index 811cf83..ef60718 100644 (file)
@@ -106,6 +106,7 @@ struct slot {
  *     that has not yet been cleared by the user
  * @pending_events: used by the IRQ handler to save events retrieved from the
  *     Slot Status register for later consumption by the IRQ thread
+ * @ist_running: flag to keep user request waiting while IRQ thread is running
  * @request_result: result of last user request submitted to the IRQ thread
  * @requester: wait queue to wake up on completion of user request,
  *     used for synchronous slot enable/disable request via sysfs
@@ -125,6 +126,7 @@ struct controller {
        unsigned int notification_enabled:1;
        unsigned int power_fault_detected;
        atomic_t pending_events;
+       unsigned int ist_running;
        int request_result;
        wait_queue_head_t requester;
 };
index 9c397fa..c71964e 100644 (file)
@@ -383,7 +383,8 @@ int pciehp_sysfs_enable_slot(struct slot *p_slot)
                ctrl->request_result = -ENODEV;
                pciehp_request(ctrl, PCI_EXP_SLTSTA_PDC);
                wait_event(ctrl->requester,
-                          !atomic_read(&ctrl->pending_events));
+                          !atomic_read(&ctrl->pending_events) &&
+                          !ctrl->ist_running);
                return ctrl->request_result;
        case POWERON_STATE:
                ctrl_info(ctrl, "Slot(%s): Already in powering on state\n",
@@ -416,7 +417,8 @@ int pciehp_sysfs_disable_slot(struct slot *p_slot)
                mutex_unlock(&p_slot->lock);
                pciehp_request(ctrl, DISABLE_SLOT);
                wait_event(ctrl->requester,
-                          !atomic_read(&ctrl->pending_events));
+                          !atomic_read(&ctrl->pending_events) &&
+                          !ctrl->ist_running);
                return ctrl->request_result;
        case POWEROFF_STATE:
                ctrl_info(ctrl, "Slot(%s): Already in powering off state\n",
index a938abd..c3e3f53 100644 (file)
@@ -620,6 +620,7 @@ static irqreturn_t pciehp_ist(int irq, void *dev_id)
        irqreturn_t ret;
        u32 events;
 
+       ctrl->ist_running = true;
        pci_config_pm_runtime_get(pdev);
 
        /* rerun pciehp_isr() if the port was inaccessible on interrupt */
@@ -666,6 +667,7 @@ static irqreturn_t pciehp_ist(int irq, void *dev_id)
        up_read(&ctrl->reset_lock);
 
        pci_config_pm_runtime_put(pdev);
+       ctrl->ist_running = false;
        wake_up(&ctrl->requester);
        return IRQ_HANDLED;
 }
index cc860c5..a306cad 100644 (file)
@@ -154,11 +154,11 @@ static enum pci_bus_speed get_max_bus_speed(struct slot *slot)
        return speed;
 }
 
-static int get_children_props(struct device_node *dn, const int **drc_indexes,
-               const int **drc_names, const int **drc_types,
-               const int **drc_power_domains)
+static int get_children_props(struct device_node *dn, const __be32 **drc_indexes,
+                             const __be32 **drc_names, const __be32 **drc_types,
+                             const __be32 **drc_power_domains)
 {
-       const int *indexes, *names, *types, *domains;
+       const __be32 *indexes, *names, *types, *domains;
 
        indexes = of_get_property(dn, "ibm,drc-indexes", NULL);
        names = of_get_property(dn, "ibm,drc-names", NULL);
@@ -194,8 +194,8 @@ static int rpaphp_check_drc_props_v1(struct device_node *dn, char *drc_name,
                                char *drc_type, unsigned int my_index)
 {
        char *name_tmp, *type_tmp;
-       const int *indexes, *names;
-       const int *types, *domains;
+       const __be32 *indexes, *names;
+       const __be32 *types, *domains;
        int i, rc;
 
        rc = get_children_props(dn->parent, &indexes, &names, &types, &domains);
@@ -208,7 +208,7 @@ static int rpaphp_check_drc_props_v1(struct device_node *dn, char *drc_name,
 
        /* Iterate through parent properties, looking for my-drc-index */
        for (i = 0; i < be32_to_cpu(indexes[0]); i++) {
-               if ((unsigned int) indexes[i + 1] == my_index)
+               if (be32_to_cpu(indexes[i + 1]) == my_index)
                        break;
 
                name_tmp += (strlen(name_tmp) + 1);
@@ -239,6 +239,8 @@ static int rpaphp_check_drc_props_v2(struct device_node *dn, char *drc_name,
        value = of_prop_next_u32(info, NULL, &entries);
        if (!value)
                return -EINVAL;
+       else
+               value++;
 
        for (j = 0; j < entries; j++) {
                of_read_drc_info_cell(&info, &value, &drc);
@@ -246,9 +248,10 @@ static int rpaphp_check_drc_props_v2(struct device_node *dn, char *drc_name,
                /* Should now know end of current entry */
 
                /* Found it */
-               if (my_index <= drc.last_drc_index) {
+               if (my_index >= drc.drc_index_start && my_index <= drc.last_drc_index) {
+                       int index = my_index - drc.drc_index_start;
                        sprintf(cell_drc_name, "%s%d", drc.drc_name_prefix,
-                               my_index);
+                               drc.drc_name_suffix_start + index);
                        break;
                }
        }
@@ -265,7 +268,7 @@ static int rpaphp_check_drc_props_v2(struct device_node *dn, char *drc_name,
 int rpaphp_check_drc_props(struct device_node *dn, char *drc_name,
                        char *drc_type)
 {
-       const unsigned int *my_index;
+       const __be32 *my_index;
 
        my_index = of_get_property(dn, "ibm,my-drc-index", NULL);
        if (!my_index) {
@@ -273,12 +276,12 @@ int rpaphp_check_drc_props(struct device_node *dn, char *drc_name,
                return -EINVAL;
        }
 
-       if (firmware_has_feature(FW_FEATURE_DRC_INFO))
+       if (of_find_property(dn->parent, "ibm,drc-info", NULL))
                return rpaphp_check_drc_props_v2(dn, drc_name, drc_type,
-                                               *my_index);
+                                               be32_to_cpu(*my_index));
        else
                return rpaphp_check_drc_props_v1(dn, drc_name, drc_type,
-                                               *my_index);
+                                               be32_to_cpu(*my_index));
 }
 EXPORT_SYMBOL_GPL(rpaphp_check_drc_props);
 
@@ -309,10 +312,11 @@ static int is_php_type(char *drc_type)
  * for built-in pci slots (even when the built-in slots are
  * dlparable.)
  */
-static int is_php_dn(struct device_node *dn, const int **indexes,
-               const int **names, const int **types, const int **power_domains)
+static int is_php_dn(struct device_node *dn, const __be32 **indexes,
+                    const __be32 **names, const __be32 **types,
+                    const __be32 **power_domains)
 {
-       const int *drc_types;
+       const __be32 *drc_types;
        int rc;
 
        rc = get_children_props(dn, indexes, names, &drc_types, power_domains);
@@ -347,7 +351,7 @@ int rpaphp_add_slot(struct device_node *dn)
        struct slot *slot;
        int retval = 0;
        int i;
-       const int *indexes, *names, *types, *power_domains;
+       const __be32 *indexes, *names, *types, *power_domains;
        char *name, *type;
 
        if (!dn->name || strcmp(dn->name, "pci"))
index 971dddf..23a363f 100644 (file)
@@ -211,7 +211,7 @@ u32 __pci_msix_desc_mask_irq(struct msi_desc *desc, u32 flag)
                return 0;
 
        mask_bits &= ~PCI_MSIX_ENTRY_CTRL_MASKBIT;
-       if (flag)
+       if (flag & PCI_MSIX_ENTRY_CTRL_MASKBIT)
                mask_bits |= PCI_MSIX_ENTRY_CTRL_MASKBIT;
        writel(mask_bits, pci_msix_desc_addr(desc) + PCI_MSIX_ENTRY_VECTOR_CTRL);
 
index ec317bc..bc1ff41 100644 (file)
@@ -1042,17 +1042,22 @@ static int pci_pm_thaw_noirq(struct device *dev)
                        return error;
        }
 
-       if (pci_has_legacy_pm_support(pci_dev))
-               return pci_legacy_resume_early(dev);
-
        /*
-        * pci_restore_state() requires the device to be in D0 (because of MSI
-        * restoration among other things), so force it into D0 in case the
-        * driver's "freeze" callbacks put it into a low-power state directly.
+        * Both the legacy ->resume_early() and the new pm->thaw_noirq()
+        * callbacks assume the device has been returned to D0 and its
+        * config state has been restored.
+        *
+        * In addition, pci_restore_state() restores MSI-X state in MMIO
+        * space, which requires the device to be in D0, so return it to D0
+        * in case the driver's "freeze" callbacks put it into a low-power
+        * state.
         */
        pci_set_power_state(pci_dev, PCI_D0);
        pci_restore_state(pci_dev);
 
+       if (pci_has_legacy_pm_support(pci_dev))
+               return pci_legacy_resume_early(dev);
+
        if (drv && drv->pm && drv->pm->thaw_noirq)
                error = drv->pm->thaw_noirq(dev);
 
index 6493399..20a57a4 100644 (file)
@@ -4219,15 +4219,21 @@ static int pci_quirk_amd_sb_acs(struct pci_dev *dev, u16 acs_flags)
 
 static bool pci_quirk_cavium_acs_match(struct pci_dev *dev)
 {
+       if (!pci_is_pcie(dev) || pci_pcie_type(dev) != PCI_EXP_TYPE_ROOT_PORT)
+               return false;
+
+       switch (dev->device) {
        /*
-        * Effectively selects all downstream ports for whole ThunderX 1
-        * family by 0xf800 mask (which represents 8 SoCs), while the lower
-        * bits of device ID are used to indicate which subdevice is used
-        * within the SoC.
+        * Effectively selects all downstream ports for whole ThunderX1
+        * (which represents 8 SoCs).
         */
-       return (pci_is_pcie(dev) &&
-               (pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT) &&
-               ((dev->device & 0xf800) == 0xa000));
+       case 0xa000 ... 0xa7ff: /* ThunderX1 */
+       case 0xaf84:  /* ThunderX2 */
+       case 0xb884:  /* ThunderX3 */
+               return true;
+       default:
+               return false;
+       }
 }
 
 static int pci_quirk_cavium_acs(struct pci_dev *dev, u16 acs_flags)
@@ -4576,7 +4582,7 @@ int pci_dev_specific_acs_enabled(struct pci_dev *dev, u16 acs_flags)
 #define INTEL_BSPR_REG_BPPD  (1 << 9)
 
 /* Upstream Peer Decode Configuration Register */
-#define INTEL_UPDCR_REG 0x1114
+#define INTEL_UPDCR_REG 0x1014
 /* 5:0 Peer Decode Enable bits */
 #define INTEL_UPDCR_REG_MASK 0x3f
 
index abbbe75..5629d56 100644 (file)
@@ -160,8 +160,8 @@ static int qcom_usb_hs_phy_power_on(struct phy *phy)
                /* setup initial state */
                qcom_usb_hs_phy_vbus_notifier(&uphy->vbus_notify, state,
                                              uphy->vbus_edev);
-               ret = devm_extcon_register_notifier(&ulpi->dev, uphy->vbus_edev,
-                               EXTCON_USB, &uphy->vbus_notify);
+               ret = extcon_register_notifier(uphy->vbus_edev, EXTCON_USB,
+                                              &uphy->vbus_notify);
                if (ret)
                        goto err_ulpi;
        }
@@ -182,6 +182,9 @@ static int qcom_usb_hs_phy_power_off(struct phy *phy)
 {
        struct qcom_usb_hs_phy *uphy = phy_get_drvdata(phy);
 
+       if (uphy->vbus_edev)
+               extcon_unregister_notifier(uphy->vbus_edev, EXTCON_USB,
+                                          &uphy->vbus_notify);
        regulator_disable(uphy->v3p3);
        regulator_disable(uphy->v1p8);
        clk_disable_unprepare(uphy->sleep_clk);
index d22b1ec..50cdf20 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
 #include <linux/regulator/consumer.h>
+#include <linux/string.h>
 #include <linux/usb/of.h>
 #include <linux/workqueue.h>
 
@@ -241,9 +242,9 @@ static ssize_t role_store(struct device *dev, struct device_attribute *attr,
        if (!ch->has_otg_pins || !ch->phy->init_count)
                return -EIO;
 
-       if (!strncmp(buf, "host", strlen("host")))
+       if (sysfs_streq(buf, "host"))
                new_mode = PHY_MODE_USB_HOST;
-       else if (!strncmp(buf, "peripheral", strlen("peripheral")))
+       else if (sysfs_streq(buf, "peripheral"))
                new_mode = PHY_MODE_USB_DEVICE;
        else
                return -EINVAL;
index 2969ff3..177ee11 100644 (file)
@@ -40,6 +40,13 @@ struct pinctrl_dt_map {
 static void dt_free_map(struct pinctrl_dev *pctldev,
                     struct pinctrl_map *map, unsigned num_maps)
 {
+       int i;
+
+       for (i = 0; i < num_maps; ++i) {
+               kfree_const(map[i].dev_name);
+               map[i].dev_name = NULL;
+       }
+
        if (pctldev) {
                const struct pinctrl_ops *ops = pctldev->desc->pctlops;
                if (ops->dt_free_map)
@@ -74,7 +81,13 @@ static int dt_remember_or_free_map(struct pinctrl *p, const char *statename,
 
        /* Initialize common mapping table entry fields */
        for (i = 0; i < num_maps; i++) {
-               map[i].dev_name = dev_name(p->dev);
+               const char *devname;
+
+               devname = kstrdup_const(dev_name(p->dev), GFP_KERNEL);
+               if (!devname)
+                       goto err_free_map;
+
+               map[i].dev_name = devname;
                map[i].name = statename;
                if (pctldev)
                        map[i].ctrl_dev_name = dev_name(pctldev->dev);
@@ -82,10 +95,8 @@ static int dt_remember_or_free_map(struct pinctrl *p, const char *statename,
 
        /* Remember the converted mapping table entries */
        dt_map = kzalloc(sizeof(*dt_map), GFP_KERNEL);
-       if (!dt_map) {
-               dt_free_map(pctldev, map, num_maps);
-               return -ENOMEM;
-       }
+       if (!dt_map)
+               goto err_free_map;
 
        dt_map->pctldev = pctldev;
        dt_map->map = map;
@@ -93,6 +104,10 @@ static int dt_remember_or_free_map(struct pinctrl *p, const char *statename,
        list_add_tail(&dt_map->node, &p->dt_maps);
 
        return pinctrl_register_map(map, num_maps, false);
+
+err_free_map:
+       dt_free_map(pctldev, map, num_maps);
+       return -ENOMEM;
 }
 
 struct pinctrl_dev *of_pinctrl_get(struct device_node *np)
index f38d596..021e28f 100644 (file)
@@ -196,7 +196,6 @@ struct byt_gpio {
        struct platform_device *pdev;
        struct pinctrl_dev *pctl_dev;
        struct pinctrl_desc pctl_desc;
-       raw_spinlock_t lock;
        const struct byt_pinctrl_soc_data *soc_data;
        struct byt_community *communities_copy;
        struct byt_gpio_pin_context *saved_context;
@@ -707,6 +706,8 @@ static const struct byt_pinctrl_soc_data *byt_soc_data[] = {
        NULL,
 };
 
+static DEFINE_RAW_SPINLOCK(byt_lock);
+
 static struct byt_community *byt_get_community(struct byt_gpio *vg,
                                               unsigned int pin)
 {
@@ -848,7 +849,7 @@ static void byt_set_group_simple_mux(struct byt_gpio *vg,
        unsigned long flags;
        int i;
 
-       raw_spin_lock_irqsave(&vg->lock, flags);
+       raw_spin_lock_irqsave(&byt_lock, flags);
 
        for (i = 0; i < group.npins; i++) {
                void __iomem *padcfg0;
@@ -868,7 +869,7 @@ static void byt_set_group_simple_mux(struct byt_gpio *vg,
                writel(value, padcfg0);
        }
 
-       raw_spin_unlock_irqrestore(&vg->lock, flags);
+       raw_spin_unlock_irqrestore(&byt_lock, flags);
 }
 
 static void byt_set_group_mixed_mux(struct byt_gpio *vg,
@@ -878,7 +879,7 @@ static void byt_set_group_mixed_mux(struct byt_gpio *vg,
        unsigned long flags;
        int i;
 
-       raw_spin_lock_irqsave(&vg->lock, flags);
+       raw_spin_lock_irqsave(&byt_lock, flags);
 
        for (i = 0; i < group.npins; i++) {
                void __iomem *padcfg0;
@@ -898,7 +899,7 @@ static void byt_set_group_mixed_mux(struct byt_gpio *vg,
                writel(value, padcfg0);
        }
 
-       raw_spin_unlock_irqrestore(&vg->lock, flags);
+       raw_spin_unlock_irqrestore(&byt_lock, flags);
 }
 
 static int byt_set_mux(struct pinctrl_dev *pctldev, unsigned int func_selector,
@@ -947,11 +948,11 @@ static void byt_gpio_clear_triggering(struct byt_gpio *vg, unsigned int offset)
        unsigned long flags;
        u32 value;
 
-       raw_spin_lock_irqsave(&vg->lock, flags);
+       raw_spin_lock_irqsave(&byt_lock, flags);
        value = readl(reg);
        value &= ~(BYT_TRIG_POS | BYT_TRIG_NEG | BYT_TRIG_LVL);
        writel(value, reg);
-       raw_spin_unlock_irqrestore(&vg->lock, flags);
+       raw_spin_unlock_irqrestore(&byt_lock, flags);
 }
 
 static int byt_gpio_request_enable(struct pinctrl_dev *pctl_dev,
@@ -963,7 +964,7 @@ static int byt_gpio_request_enable(struct pinctrl_dev *pctl_dev,
        u32 value, gpio_mux;
        unsigned long flags;
 
-       raw_spin_lock_irqsave(&vg->lock, flags);
+       raw_spin_lock_irqsave(&byt_lock, flags);
 
        /*
         * In most cases, func pin mux 000 means GPIO function.
@@ -985,7 +986,7 @@ static int byt_gpio_request_enable(struct pinctrl_dev *pctl_dev,
                         "pin %u forcibly re-configured as GPIO\n", offset);
        }
 
-       raw_spin_unlock_irqrestore(&vg->lock, flags);
+       raw_spin_unlock_irqrestore(&byt_lock, flags);
 
        pm_runtime_get(&vg->pdev->dev);
 
@@ -1013,7 +1014,7 @@ static int byt_gpio_set_direction(struct pinctrl_dev *pctl_dev,
        unsigned long flags;
        u32 value;
 
-       raw_spin_lock_irqsave(&vg->lock, flags);
+       raw_spin_lock_irqsave(&byt_lock, flags);
 
        value = readl(val_reg);
        value &= ~BYT_DIR_MASK;
@@ -1030,7 +1031,7 @@ static int byt_gpio_set_direction(struct pinctrl_dev *pctl_dev,
                     "Potential Error: Setting GPIO with direct_irq_en to output");
        writel(value, val_reg);
 
-       raw_spin_unlock_irqrestore(&vg->lock, flags);
+       raw_spin_unlock_irqrestore(&byt_lock, flags);
 
        return 0;
 }
@@ -1099,11 +1100,11 @@ static int byt_pin_config_get(struct pinctrl_dev *pctl_dev, unsigned int offset,
        u32 conf, pull, val, debounce;
        u16 arg = 0;
 
-       raw_spin_lock_irqsave(&vg->lock, flags);
+       raw_spin_lock_irqsave(&byt_lock, flags);
        conf = readl(conf_reg);
        pull = conf & BYT_PULL_ASSIGN_MASK;
        val = readl(val_reg);
-       raw_spin_unlock_irqrestore(&vg->lock, flags);
+       raw_spin_unlock_irqrestore(&byt_lock, flags);
 
        switch (param) {
        case PIN_CONFIG_BIAS_DISABLE:
@@ -1130,9 +1131,9 @@ static int byt_pin_config_get(struct pinctrl_dev *pctl_dev, unsigned int offset,
                if (!(conf & BYT_DEBOUNCE_EN))
                        return -EINVAL;
 
-               raw_spin_lock_irqsave(&vg->lock, flags);
+               raw_spin_lock_irqsave(&byt_lock, flags);
                debounce = readl(db_reg);
-               raw_spin_unlock_irqrestore(&vg->lock, flags);
+               raw_spin_unlock_irqrestore(&byt_lock, flags);
 
                switch (debounce & BYT_DEBOUNCE_PULSE_MASK) {
                case BYT_DEBOUNCE_PULSE_375US:
@@ -1184,7 +1185,7 @@ static int byt_pin_config_set(struct pinctrl_dev *pctl_dev,
        u32 conf, val, debounce;
        int i, ret = 0;
 
-       raw_spin_lock_irqsave(&vg->lock, flags);
+       raw_spin_lock_irqsave(&byt_lock, flags);
 
        conf = readl(conf_reg);
        val = readl(val_reg);
@@ -1292,7 +1293,7 @@ static int byt_pin_config_set(struct pinctrl_dev *pctl_dev,
        if (!ret)
                writel(conf, conf_reg);
 
-       raw_spin_unlock_irqrestore(&vg->lock, flags);
+       raw_spin_unlock_irqrestore(&byt_lock, flags);
 
        return ret;
 }
@@ -1317,9 +1318,9 @@ static int byt_gpio_get(struct gpio_chip *chip, unsigned offset)
        unsigned long flags;
        u32 val;
 
-       raw_spin_lock_irqsave(&vg->lock, flags);
+       raw_spin_lock_irqsave(&byt_lock, flags);
        val = readl(reg);
-       raw_spin_unlock_irqrestore(&vg->lock, flags);
+       raw_spin_unlock_irqrestore(&byt_lock, flags);
 
        return !!(val & BYT_LEVEL);
 }
@@ -1334,13 +1335,13 @@ static void byt_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
        if (!reg)
                return;
 
-       raw_spin_lock_irqsave(&vg->lock, flags);
+       raw_spin_lock_irqsave(&byt_lock, flags);
        old_val = readl(reg);
        if (value)
                writel(old_val | BYT_LEVEL, reg);
        else
                writel(old_val & ~BYT_LEVEL, reg);
-       raw_spin_unlock_irqrestore(&vg->lock, flags);
+       raw_spin_unlock_irqrestore(&byt_lock, flags);
 }
 
 static int byt_gpio_get_direction(struct gpio_chip *chip, unsigned int offset)
@@ -1353,9 +1354,9 @@ static int byt_gpio_get_direction(struct gpio_chip *chip, unsigned int offset)
        if (!reg)
                return -EINVAL;
 
-       raw_spin_lock_irqsave(&vg->lock, flags);
+       raw_spin_lock_irqsave(&byt_lock, flags);
        value = readl(reg);
-       raw_spin_unlock_irqrestore(&vg->lock, flags);
+       raw_spin_unlock_irqrestore(&byt_lock, flags);
 
        if (!(value & BYT_OUTPUT_EN))
                return GPIOF_DIR_OUT;
@@ -1398,14 +1399,14 @@ static void byt_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
                const char *label;
                unsigned int pin;
 
-               raw_spin_lock_irqsave(&vg->lock, flags);
+               raw_spin_lock_irqsave(&byt_lock, flags);
                pin = vg->soc_data->pins[i].number;
                reg = byt_gpio_reg(vg, pin, BYT_CONF0_REG);
                if (!reg) {
                        seq_printf(s,
                                   "Could not retrieve pin %i conf0 reg\n",
                                   pin);
-                       raw_spin_unlock_irqrestore(&vg->lock, flags);
+                       raw_spin_unlock_irqrestore(&byt_lock, flags);
                        continue;
                }
                conf0 = readl(reg);
@@ -1414,11 +1415,11 @@ static void byt_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
                if (!reg) {
                        seq_printf(s,
                                   "Could not retrieve pin %i val reg\n", pin);
-                       raw_spin_unlock_irqrestore(&vg->lock, flags);
+                       raw_spin_unlock_irqrestore(&byt_lock, flags);
                        continue;
                }
                val = readl(reg);
-               raw_spin_unlock_irqrestore(&vg->lock, flags);
+               raw_spin_unlock_irqrestore(&byt_lock, flags);
 
                comm = byt_get_community(vg, pin);
                if (!comm) {
@@ -1502,9 +1503,9 @@ static void byt_irq_ack(struct irq_data *d)
        if (!reg)
                return;
 
-       raw_spin_lock(&vg->lock);
+       raw_spin_lock(&byt_lock);
        writel(BIT(offset % 32), reg);
-       raw_spin_unlock(&vg->lock);
+       raw_spin_unlock(&byt_lock);
 }
 
 static void byt_irq_mask(struct irq_data *d)
@@ -1528,7 +1529,7 @@ static void byt_irq_unmask(struct irq_data *d)
        if (!reg)
                return;
 
-       raw_spin_lock_irqsave(&vg->lock, flags);
+       raw_spin_lock_irqsave(&byt_lock, flags);
        value = readl(reg);
 
        switch (irqd_get_trigger_type(d)) {
@@ -1551,7 +1552,7 @@ static void byt_irq_unmask(struct irq_data *d)
 
        writel(value, reg);
 
-       raw_spin_unlock_irqrestore(&vg->lock, flags);
+       raw_spin_unlock_irqrestore(&byt_lock, flags);
 }
 
 static int byt_irq_type(struct irq_data *d, unsigned int type)
@@ -1565,7 +1566,7 @@ static int byt_irq_type(struct irq_data *d, unsigned int type)
        if (!reg || offset >= vg->chip.ngpio)
                return -EINVAL;
 
-       raw_spin_lock_irqsave(&vg->lock, flags);
+       raw_spin_lock_irqsave(&byt_lock, flags);
        value = readl(reg);
 
        WARN(value & BYT_DIRECT_IRQ_EN,
@@ -1587,7 +1588,7 @@ static int byt_irq_type(struct irq_data *d, unsigned int type)
        else if (type & IRQ_TYPE_LEVEL_MASK)
                irq_set_handler_locked(d, handle_level_irq);
 
-       raw_spin_unlock_irqrestore(&vg->lock, flags);
+       raw_spin_unlock_irqrestore(&byt_lock, flags);
 
        return 0;
 }
@@ -1623,9 +1624,9 @@ static void byt_gpio_irq_handler(struct irq_desc *desc)
                        continue;
                }
 
-               raw_spin_lock(&vg->lock);
+               raw_spin_lock(&byt_lock);
                pending = readl(reg);
-               raw_spin_unlock(&vg->lock);
+               raw_spin_unlock(&byt_lock);
                for_each_set_bit(pin, &pending, 32) {
                        virq = irq_find_mapping(vg->chip.irq.domain, base + pin);
                        generic_handle_irq(virq);
@@ -1828,8 +1829,6 @@ static int byt_pinctrl_probe(struct platform_device *pdev)
                return PTR_ERR(vg->pctl_dev);
        }
 
-       raw_spin_lock_init(&vg->lock);
-
        ret = byt_gpio_probe(vg);
        if (ret)
                return ret;
@@ -1845,8 +1844,11 @@ static int byt_gpio_suspend(struct device *dev)
 {
        struct platform_device *pdev = to_platform_device(dev);
        struct byt_gpio *vg = platform_get_drvdata(pdev);
+       unsigned long flags;
        int i;
 
+       raw_spin_lock_irqsave(&byt_lock, flags);
+
        for (i = 0; i < vg->soc_data->npins; i++) {
                void __iomem *reg;
                u32 value;
@@ -1867,6 +1869,7 @@ static int byt_gpio_suspend(struct device *dev)
                vg->saved_context[i].val = value;
        }
 
+       raw_spin_unlock_irqrestore(&byt_lock, flags);
        return 0;
 }
 
@@ -1874,8 +1877,11 @@ static int byt_gpio_resume(struct device *dev)
 {
        struct platform_device *pdev = to_platform_device(dev);
        struct byt_gpio *vg = platform_get_drvdata(pdev);
+       unsigned long flags;
        int i;
 
+       raw_spin_lock_irqsave(&byt_lock, flags);
+
        for (i = 0; i < vg->soc_data->npins; i++) {
                void __iomem *reg;
                u32 value;
@@ -1913,6 +1919,7 @@ static int byt_gpio_resume(struct device *dev)
                }
        }
 
+       raw_spin_unlock_irqrestore(&byt_lock, flags);
        return 0;
 }
 #endif
index 3aac640..d76ac6b 100644 (file)
@@ -592,10 +592,10 @@ static int armada_37xx_irq_set_type(struct irq_data *d, unsigned int type)
                regmap_read(info->regmap, in_reg, &in_val);
 
                /* Set initial polarity based on current input level. */
-               if (in_val & d->mask)
-                       val |= d->mask;         /* falling */
+               if (in_val & BIT(d->hwirq % GPIO_PER_REG))
+                       val |= BIT(d->hwirq % GPIO_PER_REG);    /* falling */
                else
-                       val &= ~d->mask;        /* rising */
+                       val &= ~(BIT(d->hwirq % GPIO_PER_REG)); /* rising */
                break;
        }
        default:
index cd7a5d9..b1ffdd3 100644 (file)
@@ -544,7 +544,8 @@ static irqreturn_t amd_gpio_irq_handler(int irq, void *dev_id)
        irqreturn_t ret = IRQ_NONE;
        unsigned int i, irqnr;
        unsigned long flags;
-       u32 *regs, regval;
+       u32 __iomem *regs;
+       u32  regval;
        u64 status, mask;
 
        /* Read the wake status */
index f49ea3d..e87ee43 100644 (file)
@@ -494,8 +494,10 @@ int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d)
                if (match) {
                        irq_chip = kmemdup(match->data,
                                sizeof(*irq_chip), GFP_KERNEL);
-                       if (!irq_chip)
+                       if (!irq_chip) {
+                               of_node_put(np);
                                return -ENOMEM;
+                       }
                        wkup_np = np;
                        break;
                }
@@ -512,6 +514,7 @@ int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d)
                                bank->nr_pins, &exynos_eint_irqd_ops, bank);
                if (!bank->irq_domain) {
                        dev_err(dev, "wkup irq domain add failed\n");
+                       of_node_put(wkup_np);
                        return -ENXIO;
                }
 
@@ -526,8 +529,10 @@ int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d)
                weint_data = devm_kcalloc(dev,
                                          bank->nr_pins, sizeof(*weint_data),
                                          GFP_KERNEL);
-               if (!weint_data)
+               if (!weint_data) {
+                       of_node_put(wkup_np);
                        return -ENOMEM;
+               }
 
                for (idx = 0; idx < bank->nr_pins; ++idx) {
                        irq = irq_of_parse_and_map(bank->of_node, idx);
@@ -544,10 +549,13 @@ int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d)
                }
        }
 
-       if (!muxed_banks)
+       if (!muxed_banks) {
+               of_node_put(wkup_np);
                return 0;
+       }
 
        irq = irq_of_parse_and_map(wkup_np, 0);
+       of_node_put(wkup_np);
        if (!irq) {
                dev_err(dev, "irq number for muxed EINTs not found\n");
                return 0;
index 7e824e4..9bd0a3d 100644 (file)
@@ -490,8 +490,10 @@ static int s3c24xx_eint_init(struct samsung_pinctrl_drv_data *d)
                return -ENODEV;
 
        eint_data = devm_kzalloc(dev, sizeof(*eint_data), GFP_KERNEL);
-       if (!eint_data)
+       if (!eint_data) {
+               of_node_put(eint_np);
                return -ENOMEM;
+       }
 
        eint_data->drvdata = d;
 
@@ -503,12 +505,14 @@ static int s3c24xx_eint_init(struct samsung_pinctrl_drv_data *d)
                irq = irq_of_parse_and_map(eint_np, i);
                if (!irq) {
                        dev_err(dev, "failed to get wakeup EINT IRQ %d\n", i);
+                       of_node_put(eint_np);
                        return -ENXIO;
                }
 
                eint_data->parents[i] = irq;
                irq_set_chained_handler_and_data(irq, handlers[i], eint_data);
        }
+       of_node_put(eint_np);
 
        bank = d->pin_banks;
        for (i = 0; i < d->nr_banks; ++i, ++bank) {
index c399f09..f97f817 100644 (file)
@@ -704,8 +704,10 @@ static int s3c64xx_eint_eint0_init(struct samsung_pinctrl_drv_data *d)
                return -ENODEV;
 
        data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
-       if (!data)
+       if (!data) {
+               of_node_put(eint0_np);
                return -ENOMEM;
+       }
        data->drvdata = d;
 
        for (i = 0; i < NUM_EINT0_IRQ; ++i) {
@@ -714,6 +716,7 @@ static int s3c64xx_eint_eint0_init(struct samsung_pinctrl_drv_data *d)
                irq = irq_of_parse_and_map(eint0_np, i);
                if (!irq) {
                        dev_err(dev, "failed to get wakeup EINT IRQ %d\n", i);
+                       of_node_put(eint0_np);
                        return -ENXIO;
                }
 
@@ -721,6 +724,7 @@ static int s3c64xx_eint_eint0_init(struct samsung_pinctrl_drv_data *d)
                                                 s3c64xx_eint0_handlers[i],
                                                 data);
        }
+       of_node_put(eint0_np);
 
        bank = d->pin_banks;
        for (i = 0; i < d->nr_banks; ++i, ++bank) {
index 698c7d8..c05217e 100644 (file)
@@ -272,6 +272,7 @@ static int samsung_dt_node_to_map(struct pinctrl_dev *pctldev,
                                                &reserved_maps, num_maps);
                if (ret < 0) {
                        samsung_dt_free_map(pctldev, *map, *num_maps);
+                       of_node_put(np);
                        return ret;
                }
        }
@@ -785,8 +786,10 @@ static struct samsung_pmx_func *samsung_pinctrl_create_functions(
                if (!of_get_child_count(cfg_np)) {
                        ret = samsung_pinctrl_create_function(dev, drvdata,
                                                        cfg_np, func);
-                       if (ret < 0)
+                       if (ret < 0) {
+                               of_node_put(cfg_np);
                                return ERR_PTR(ret);
+                       }
                        if (ret > 0) {
                                ++func;
                                ++func_cnt;
@@ -797,8 +800,11 @@ static struct samsung_pmx_func *samsung_pinctrl_create_functions(
                for_each_child_of_node(cfg_np, func_np) {
                        ret = samsung_pinctrl_create_function(dev, drvdata,
                                                func_np, func);
-                       if (ret < 0)
+                       if (ret < 0) {
+                               of_node_put(func_np);
+                               of_node_put(cfg_np);
                                return ERR_PTR(ret);
+                       }
                        if (ret > 0) {
                                ++func;
                                ++func_cnt;
index 3323204..3eccc9b 100644 (file)
@@ -1453,7 +1453,7 @@ static const struct pinmux_func pinmux_func_gpios[] = {
        GPIO_FN(ET0_ETXD2_A),
        GPIO_FN(EX_CS5), GPIO_FN(SD1_CMD_A), GPIO_FN(ATADIR), GPIO_FN(QSSL_B),
        GPIO_FN(ET0_ETXD3_A),
-       GPIO_FN(RD_WR), GPIO_FN(TCLK1_B),
+       GPIO_FN(RD_WR), GPIO_FN(TCLK0), GPIO_FN(CAN_CLK_B), GPIO_FN(ET0_ETXD4),
        GPIO_FN(EX_WAIT0), GPIO_FN(TCLK1_B),
        GPIO_FN(EX_WAIT1), GPIO_FN(SD1_DAT0_A), GPIO_FN(DREQ2),
                GPIO_FN(CAN1_TX_C), GPIO_FN(ET0_LINK_C), GPIO_FN(ET0_ETXD5_A),
@@ -1949,7 +1949,7 @@ static const struct pinmux_cfg_reg pinmux_config_regs[] = {
            /* IP3_20 [1] */
                FN_EX_WAIT0, FN_TCLK1_B,
            /* IP3_19_18 [2] */
-               FN_RD_WR, FN_TCLK1_B, 0, 0,
+               FN_RD_WR, FN_TCLK0, FN_CAN_CLK_B, FN_ET0_ETXD4,
            /* IP3_17_15 [3] */
                FN_EX_CS5, FN_SD1_CMD_A, FN_ATADIR, FN_QSSL_B,
                FN_ET0_ETXD3_A, 0, 0, 0,
index d0ffdd5..06a3c1e 100644 (file)
@@ -313,7 +313,7 @@ static int __init hp_wmi_bios_2008_later(void)
 
 static int __init hp_wmi_bios_2009_later(void)
 {
-       int state = 0;
+       u8 state[128];
        int ret = hp_wmi_perform_query(HPWMI_FEATURE2_QUERY, HPWMI_READ, &state,
                                       sizeof(state), sizeof(state));
        if (!ret)
index 3bae023..e183a22 100644 (file)
@@ -82,7 +82,7 @@ struct cpcap_battery_config {
 };
 
 struct cpcap_coulomb_counter_data {
-       s32 sample;             /* 24-bits */
+       s32 sample;             /* 24 or 32 bits */
        s32 accumulator;
        s16 offset;             /* 10-bits */
 };
@@ -213,7 +213,7 @@ static int cpcap_battery_get_current(struct cpcap_battery_ddata *ddata)
  * TI or ST coulomb counter in the PMIC.
  */
 static int cpcap_battery_cc_raw_div(struct cpcap_battery_ddata *ddata,
-                                   u32 sample, s32 accumulator,
+                                   s32 sample, s32 accumulator,
                                    s16 offset, u32 divider)
 {
        s64 acc;
@@ -224,7 +224,6 @@ static int cpcap_battery_cc_raw_div(struct cpcap_battery_ddata *ddata,
        if (!divider)
                return 0;
 
-       sample &= 0xffffff;             /* 24-bits, unsigned */
        offset &= 0x7ff;                /* 10-bits, signed */
 
        switch (ddata->vendor) {
@@ -259,7 +258,7 @@ static int cpcap_battery_cc_raw_div(struct cpcap_battery_ddata *ddata,
 
 /* 3600000μAms = 1μAh */
 static int cpcap_battery_cc_to_uah(struct cpcap_battery_ddata *ddata,
-                                  u32 sample, s32 accumulator,
+                                  s32 sample, s32 accumulator,
                                   s16 offset)
 {
        return cpcap_battery_cc_raw_div(ddata, sample,
@@ -268,7 +267,7 @@ static int cpcap_battery_cc_to_uah(struct cpcap_battery_ddata *ddata,
 }
 
 static int cpcap_battery_cc_to_ua(struct cpcap_battery_ddata *ddata,
-                                 u32 sample, s32 accumulator,
+                                 s32 sample, s32 accumulator,
                                  s16 offset)
 {
        return cpcap_battery_cc_raw_div(ddata, sample,
@@ -312,6 +311,8 @@ cpcap_battery_read_accumulated(struct cpcap_battery_ddata *ddata,
        /* Sample value CPCAP_REG_CCS1 & 2 */
        ccd->sample = (buf[1] & 0x0fff) << 16;
        ccd->sample |= buf[0];
+       if (ddata->vendor == CPCAP_VENDOR_TI)
+               ccd->sample = sign_extend32(24, ccd->sample);
 
        /* Accumulator value CPCAP_REG_CCA1 & 2 */
        ccd->accumulator = ((s16)buf[3]) << 16;
index c64903a..b818f65 100644 (file)
@@ -175,9 +175,9 @@ static struct posix_clock_operations ptp_clock_ops = {
        .read           = ptp_read,
 };
 
-static void delete_ptp_clock(struct posix_clock *pc)
+static void ptp_clock_release(struct device *dev)
 {
-       struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock);
+       struct ptp_clock *ptp = container_of(dev, struct ptp_clock, dev);
 
        mutex_destroy(&ptp->tsevq_mux);
        mutex_destroy(&ptp->pincfg_mux);
@@ -222,7 +222,6 @@ struct ptp_clock *ptp_clock_register(struct ptp_clock_info *info,
        }
 
        ptp->clock.ops = ptp_clock_ops;
-       ptp->clock.release = delete_ptp_clock;
        ptp->info = info;
        ptp->devid = MKDEV(major, index);
        ptp->index = index;
@@ -249,15 +248,6 @@ struct ptp_clock *ptp_clock_register(struct ptp_clock_info *info,
        if (err)
                goto no_pin_groups;
 
-       /* Create a new device in our class. */
-       ptp->dev = device_create_with_groups(ptp_class, parent, ptp->devid,
-                                            ptp, ptp->pin_attr_groups,
-                                            "ptp%d", ptp->index);
-       if (IS_ERR(ptp->dev)) {
-               err = PTR_ERR(ptp->dev);
-               goto no_device;
-       }
-
        /* Register a new PPS source. */
        if (info->pps) {
                struct pps_source_info pps;
@@ -273,8 +263,18 @@ struct ptp_clock *ptp_clock_register(struct ptp_clock_info *info,
                }
        }
 
-       /* Create a posix clock. */
-       err = posix_clock_register(&ptp->clock, ptp->devid);
+       /* Initialize a new device of our class in our clock structure. */
+       device_initialize(&ptp->dev);
+       ptp->dev.devt = ptp->devid;
+       ptp->dev.class = ptp_class;
+       ptp->dev.parent = parent;
+       ptp->dev.groups = ptp->pin_attr_groups;
+       ptp->dev.release = ptp_clock_release;
+       dev_set_drvdata(&ptp->dev, ptp);
+       dev_set_name(&ptp->dev, "ptp%d", ptp->index);
+
+       /* Create a posix clock and link it to the device. */
+       err = posix_clock_register(&ptp->clock, &ptp->dev);
        if (err) {
                pr_err("failed to create posix clock\n");
                goto no_clock;
@@ -286,8 +286,6 @@ no_clock:
        if (ptp->pps_source)
                pps_unregister_source(ptp->pps_source);
 no_pps:
-       device_destroy(ptp_class, ptp->devid);
-no_device:
        ptp_cleanup_pin_groups(ptp);
 no_pin_groups:
        if (ptp->kworker)
@@ -317,7 +315,6 @@ int ptp_clock_unregister(struct ptp_clock *ptp)
        if (ptp->pps_source)
                pps_unregister_source(ptp->pps_source);
 
-       device_destroy(ptp_class, ptp->devid);
        ptp_cleanup_pin_groups(ptp);
 
        posix_clock_unregister(&ptp->clock);
index c7c62b7..05f6b6a 100644 (file)
@@ -41,7 +41,7 @@ struct timestamp_event_queue {
 
 struct ptp_clock {
        struct posix_clock clock;
-       struct device *dev;
+       struct device dev;
        struct ptp_clock_info *info;
        dev_t devid;
        int index; /* index into clocks.map */
index 801d9a3..bba9c48 100644 (file)
@@ -11,7 +11,7 @@ obj-$(CONFIG_REGULATOR_VIRTUAL_CONSUMER) += virtual.o
 obj-$(CONFIG_REGULATOR_USERSPACE_CONSUMER) += userspace-consumer.o
 
 obj-$(CONFIG_REGULATOR_88PG86X) += 88pg86x.o
-obj-$(CONFIG_REGULATOR_88PM800) += 88pm800.o
+obj-$(CONFIG_REGULATOR_88PM800) += 88pm800-regulator.o
 obj-$(CONFIG_REGULATOR_88PM8607) += 88pm8607.o
 obj-$(CONFIG_REGULATOR_CPCAP) += cpcap-regulator.o
 obj-$(CONFIG_REGULATOR_AAT2870) += aat2870-regulator.o
index 860400d..a8f2f07 100644 (file)
@@ -299,7 +299,10 @@ static int max8907_regulator_probe(struct platform_device *pdev)
        memcpy(pmic->desc, max8907_regulators, sizeof(pmic->desc));
 
        /* Backwards compatibility with MAX8907B; SD1 uses different voltages */
-       regmap_read(max8907->regmap_gen, MAX8907_REG_II2RR, &val);
+       ret = regmap_read(max8907->regmap_gen, MAX8907_REG_II2RR, &val);
+       if (ret)
+               return ret;
+
        if ((val & MAX8907_II2RR_VERSION_MASK) ==
            MAX8907_II2RR_VERSION_REV_B) {
                pmic->desc[MAX8907_SD1].min_uV = 637500;
@@ -336,14 +339,20 @@ static int max8907_regulator_probe(struct platform_device *pdev)
                }
 
                if (pmic->desc[i].ops == &max8907_ldo_ops) {
-                       regmap_read(config.regmap, pmic->desc[i].enable_reg,
+                       ret = regmap_read(config.regmap, pmic->desc[i].enable_reg,
                                    &val);
+                       if (ret)
+                               return ret;
+
                        if ((val & MAX8907_MASK_LDO_SEQ) !=
                            MAX8907_MASK_LDO_SEQ)
                                pmic->desc[i].ops = &max8907_ldo_hwctl_ops;
                } else if (pmic->desc[i].ops == &max8907_out5v_ops) {
-                       regmap_read(config.regmap, pmic->desc[i].enable_reg,
+                       ret = regmap_read(config.regmap, pmic->desc[i].enable_reg,
                                    &val);
+                       if (ret)
+                               return ret;
+
                        if ((val & (MAX8907_MASK_OUT5V_VINEN |
                                                MAX8907_MASK_OUT5V_ENSRC)) !=
                            MAX8907_MASK_OUT5V_ENSRC)
index e2ce4e6..25c394a 100644 (file)
@@ -241,10 +241,31 @@ static void qcom_glink_channel_release(struct kref *ref)
 {
        struct glink_channel *channel = container_of(ref, struct glink_channel,
                                                     refcount);
+       struct glink_core_rx_intent *intent;
+       struct glink_core_rx_intent *tmp;
        unsigned long flags;
+       int iid;
+
+       /* cancel pending rx_done work */
+       cancel_work_sync(&channel->intent_work);
 
        spin_lock_irqsave(&channel->intent_lock, flags);
+       /* Free all non-reuse intents pending rx_done work */
+       list_for_each_entry_safe(intent, tmp, &channel->done_intents, node) {
+               if (!intent->reuse) {
+                       kfree(intent->data);
+                       kfree(intent);
+               }
+       }
+
+       idr_for_each_entry(&channel->liids, tmp, iid) {
+               kfree(tmp->data);
+               kfree(tmp);
+       }
        idr_destroy(&channel->liids);
+
+       idr_for_each_entry(&channel->riids, tmp, iid)
+               kfree(tmp);
        idr_destroy(&channel->riids);
        spin_unlock_irqrestore(&channel->intent_lock, flags);
 
@@ -1097,13 +1118,12 @@ static int qcom_glink_create_remote(struct qcom_glink *glink,
 close_link:
        /*
         * Send a close request to "undo" our open-ack. The close-ack will
-        * release the last reference.
+        * release qcom_glink_send_open_req() reference and the last reference
+        * will be relesed after receiving remote_close or transport unregister
+        * by calling qcom_glink_native_remove().
         */
        qcom_glink_send_close_req(glink, channel);
 
-       /* Release qcom_glink_send_open_req() reference */
-       kref_put(&channel->refcount, qcom_glink_channel_release);
-
        return ret;
 }
 
@@ -1418,15 +1438,13 @@ static int qcom_glink_rx_open(struct qcom_glink *glink, unsigned int rcid,
 
                ret = rpmsg_register_device(rpdev);
                if (ret)
-                       goto free_rpdev;
+                       goto rcid_remove;
 
                channel->rpdev = rpdev;
        }
 
        return 0;
 
-free_rpdev:
-       kfree(rpdev);
 rcid_remove:
        spin_lock_irqsave(&glink->idr_lock, flags);
        idr_remove(&glink->rcids, channel->rcid);
@@ -1547,6 +1565,18 @@ static void qcom_glink_work(struct work_struct *work)
        }
 }
 
+static void qcom_glink_cancel_rx_work(struct qcom_glink *glink)
+{
+       struct glink_defer_cmd *dcmd;
+       struct glink_defer_cmd *tmp;
+
+       /* cancel any pending deferred rx_work */
+       cancel_work_sync(&glink->rx_work);
+
+       list_for_each_entry_safe(dcmd, tmp, &glink->rx_queue, node)
+               kfree(dcmd);
+}
+
 struct qcom_glink *qcom_glink_native_probe(struct device *dev,
                                           unsigned long features,
                                           struct qcom_glink_pipe *rx,
@@ -1622,23 +1652,24 @@ void qcom_glink_native_remove(struct qcom_glink *glink)
        struct glink_channel *channel;
        int cid;
        int ret;
-       unsigned long flags;
 
        disable_irq(glink->irq);
-       cancel_work_sync(&glink->rx_work);
+       qcom_glink_cancel_rx_work(glink);
 
        ret = device_for_each_child(glink->dev, NULL, qcom_glink_remove_device);
        if (ret)
                dev_warn(glink->dev, "Can't remove GLINK devices: %d\n", ret);
 
-       spin_lock_irqsave(&glink->idr_lock, flags);
        /* Release any defunct local channels, waiting for close-ack */
        idr_for_each_entry(&glink->lcids, channel, cid)
                kref_put(&channel->refcount, qcom_glink_channel_release);
 
+       /* Release any defunct local channels, waiting for close-req */
+       idr_for_each_entry(&glink->rcids, channel, cid)
+               kref_put(&channel->refcount, qcom_glink_channel_release);
+
        idr_destroy(&glink->lcids);
        idr_destroy(&glink->rcids);
-       spin_unlock_irqrestore(&glink->idr_lock, flags);
        mbox_free_channel(glink->mbox_chan);
 }
 EXPORT_SYMBOL_GPL(qcom_glink_native_remove);
index 7b65443..bbd5759 100644 (file)
@@ -105,7 +105,7 @@ static void glink_smem_rx_advance(struct qcom_glink_pipe *np,
        tail = le32_to_cpu(*pipe->tail);
 
        tail += count;
-       if (tail > pipe->native.length)
+       if (tail >= pipe->native.length)
                tail -= pipe->native.length;
 
        *pipe->tail = cpu_to_le32(tail);
index 3d577e2..ce051f9 100644 (file)
@@ -127,7 +127,7 @@ EXPORT_SYMBOL_GPL(rtc_read_time);
 
 int rtc_set_time(struct rtc_device *rtc, struct rtc_time *tm)
 {
-       int err;
+       int err, uie;
 
        err = rtc_valid_tm(tm);
        if (err != 0)
@@ -139,6 +139,17 @@ int rtc_set_time(struct rtc_device *rtc, struct rtc_time *tm)
 
        rtc_subtract_offset(rtc, tm);
 
+#ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL
+       uie = rtc->uie_rtctimer.enabled || rtc->uie_irq_active;
+#else
+       uie = rtc->uie_rtctimer.enabled;
+#endif
+       if (uie) {
+               err = rtc_update_irq_enable(rtc, 0);
+               if (err)
+                       return err;
+       }
+
        err = mutex_lock_interruptible(&rtc->ops_lock);
        if (err)
                return err;
@@ -162,6 +173,12 @@ int rtc_set_time(struct rtc_device *rtc, struct rtc_time *tm)
        /* A timer might have just expired */
        schedule_work(&rtc->irqwork);
 
+       if (uie) {
+               err = rtc_update_irq_enable(rtc, 1);
+               if (err)
+                       return err;
+       }
+
        trace_rtc_set_time(rtc_tm_to_time64(tm), err);
        return err;
 }
index 2e1a27b..2126f4c 100644 (file)
@@ -62,6 +62,7 @@ struct error_hdr {
 #define REP82_ERROR_EVEN_MOD_IN_OPND       0x85
 #define REP82_ERROR_RESERVED_FIELD         0x88
 #define REP82_ERROR_INVALID_DOMAIN_PENDING  0x8A
+#define REP82_ERROR_FILTERED_BY_HYPERVISOR  0x8B
 #define REP82_ERROR_TRANSPORT_FAIL         0x90
 #define REP82_ERROR_PACKET_TRUNCATED       0xA0
 #define REP82_ERROR_ZERO_BUFFER_LEN        0xB0
@@ -92,6 +93,7 @@ static inline int convert_error(struct zcrypt_queue *zq,
        case REP82_ERROR_INVALID_DOMAIN_PRECHECK:
        case REP82_ERROR_INVALID_DOMAIN_PENDING:
        case REP82_ERROR_INVALID_SPECIAL_CMD:
+       case REP82_ERROR_FILTERED_BY_HYPERVISOR:
        //   REP88_ERROR_INVALID_KEY            // '82' CEX2A
        //   REP88_ERROR_OPERAND                // '84' CEX2A
        //   REP88_ERROR_OPERAND_EVEN_MOD       // '85' CEX2A
index 3b368fc..946380f 100644 (file)
@@ -94,11 +94,9 @@ void zfcp_dbf_hba_fsf_res(char *tag, int level, struct zfcp_fsf_req *req)
        memcpy(rec->u.res.fsf_status_qual, &q_head->fsf_status_qual,
               FSF_STATUS_QUALIFIER_SIZE);
 
-       if (req->fsf_command != FSF_QTCB_FCP_CMND) {
-               rec->pl_len = q_head->log_length;
-               zfcp_dbf_pl_write(dbf, (char *)q_pref + q_head->log_start,
-                                 rec->pl_len, "fsf_res", req->req_id);
-       }
+       rec->pl_len = q_head->log_length;
+       zfcp_dbf_pl_write(dbf, (char *)q_pref + q_head->log_start,
+                         rec->pl_len, "fsf_res", req->req_id);
 
        debug_event(dbf->hba, level, rec, sizeof(*rec));
        spin_unlock_irqrestore(&dbf->hba_lock, flags);
index 8ec68dc..95a3e3b 100644 (file)
 #define NCR5380_release_dma_irq(x)
 #endif
 
+static unsigned int disconnect_mask = ~0;
+module_param(disconnect_mask, int, 0444);
+
 static int do_abort(struct Scsi_Host *);
 static void do_reset(struct Scsi_Host *);
 static void bus_reset_cleanup(struct Scsi_Host *);
@@ -946,7 +949,8 @@ static bool NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd)
        int err;
        bool ret = true;
        bool can_disconnect = instance->irq != NO_IRQ &&
-                             cmd->cmnd[0] != REQUEST_SENSE;
+                             cmd->cmnd[0] != REQUEST_SENSE &&
+                             (disconnect_mask & BIT(scmd_id(cmd)));
 
        NCR5380_dprint(NDEBUG_ARBITRATION, instance);
        dsprintk(NDEBUG_ARBITRATION, instance, "starting arbitration, id = %d\n",
index 89f5154..764c46d 100644 (file)
@@ -742,7 +742,7 @@ static int __init atari_scsi_probe(struct platform_device *pdev)
                atari_scsi_template.sg_tablesize = SG_ALL;
        } else {
                atari_scsi_template.can_queue    = 1;
-               atari_scsi_template.sg_tablesize = SG_NONE;
+               atari_scsi_template.sg_tablesize = 1;
        }
 
        if (setup_can_queue > 0)
@@ -751,8 +751,8 @@ static int __init atari_scsi_probe(struct platform_device *pdev)
        if (setup_cmd_per_lun > 0)
                atari_scsi_template.cmd_per_lun = setup_cmd_per_lun;
 
-       /* Leave sg_tablesize at 0 on a Falcon! */
-       if (ATARIHW_PRESENT(TT_SCSI) && setup_sg_tablesize >= 0)
+       /* Don't increase sg_tablesize on Falcon! */
+       if (ATARIHW_PRESENT(TT_SCSI) && setup_sg_tablesize > 0)
                atari_scsi_template.sg_tablesize = setup_sg_tablesize;
 
        if (setup_hostid >= 0) {
index cc5611e..a8e29e3 100644 (file)
@@ -301,6 +301,7 @@ csio_ln_fdmi_rhba_cbfn(struct csio_hw *hw, struct csio_ioreq *fdmi_req)
        struct fc_fdmi_port_name *port_name;
        uint8_t buf[64];
        uint8_t *fc4_type;
+       unsigned long flags;
 
        if (fdmi_req->wr_status != FW_SUCCESS) {
                csio_ln_dbg(ln, "WR error:%x in processing fdmi rhba cmd\n",
@@ -385,13 +386,13 @@ csio_ln_fdmi_rhba_cbfn(struct csio_hw *hw, struct csio_ioreq *fdmi_req)
        len = (uint32_t)(pld - (uint8_t *)cmd);
 
        /* Submit FDMI RPA request */
-       spin_lock_irq(&hw->lock);
+       spin_lock_irqsave(&hw->lock, flags);
        if (csio_ln_mgmt_submit_req(fdmi_req, csio_ln_fdmi_done,
                                FCOE_CT, &fdmi_req->dma_buf, len)) {
                CSIO_INC_STATS(ln, n_fdmi_err);
                csio_ln_dbg(ln, "Failed to issue fdmi rpa req\n");
        }
-       spin_unlock_irq(&hw->lock);
+       spin_unlock_irqrestore(&hw->lock, flags);
 }
 
 /*
@@ -412,6 +413,7 @@ csio_ln_fdmi_dprt_cbfn(struct csio_hw *hw, struct csio_ioreq *fdmi_req)
        struct fc_fdmi_rpl *reg_pl;
        struct fs_fdmi_attrs *attrib_blk;
        uint8_t buf[64];
+       unsigned long flags;
 
        if (fdmi_req->wr_status != FW_SUCCESS) {
                csio_ln_dbg(ln, "WR error:%x in processing fdmi dprt cmd\n",
@@ -491,13 +493,13 @@ csio_ln_fdmi_dprt_cbfn(struct csio_hw *hw, struct csio_ioreq *fdmi_req)
        attrib_blk->numattrs = htonl(numattrs);
 
        /* Submit FDMI RHBA request */
-       spin_lock_irq(&hw->lock);
+       spin_lock_irqsave(&hw->lock, flags);
        if (csio_ln_mgmt_submit_req(fdmi_req, csio_ln_fdmi_rhba_cbfn,
                                FCOE_CT, &fdmi_req->dma_buf, len)) {
                CSIO_INC_STATS(ln, n_fdmi_err);
                csio_ln_dbg(ln, "Failed to issue fdmi rhba req\n");
        }
-       spin_unlock_irq(&hw->lock);
+       spin_unlock_irqrestore(&hw->lock, flags);
 }
 
 /*
@@ -512,6 +514,7 @@ csio_ln_fdmi_dhba_cbfn(struct csio_hw *hw, struct csio_ioreq *fdmi_req)
        void *cmd;
        struct fc_fdmi_port_name *port_name;
        uint32_t len;
+       unsigned long flags;
 
        if (fdmi_req->wr_status != FW_SUCCESS) {
                csio_ln_dbg(ln, "WR error:%x in processing fdmi dhba cmd\n",
@@ -542,13 +545,13 @@ csio_ln_fdmi_dhba_cbfn(struct csio_hw *hw, struct csio_ioreq *fdmi_req)
        len += sizeof(*port_name);
 
        /* Submit FDMI request */
-       spin_lock_irq(&hw->lock);
+       spin_lock_irqsave(&hw->lock, flags);
        if (csio_ln_mgmt_submit_req(fdmi_req, csio_ln_fdmi_dprt_cbfn,
                                FCOE_CT, &fdmi_req->dma_buf, len)) {
                CSIO_INC_STATS(ln, n_fdmi_err);
                csio_ln_dbg(ln, "Failed to issue fdmi dprt req\n");
        }
-       spin_unlock_irq(&hw->lock);
+       spin_unlock_irqrestore(&hw->lock, flags);
 }
 
 /**
index 6c7d2e2..d499c44 100644 (file)
@@ -220,7 +220,7 @@ struct hisi_sas_hw {
        int (*slot_index_alloc)(struct hisi_hba *hisi_hba, int *slot_idx,
                                struct domain_device *device);
        struct hisi_sas_device *(*alloc_dev)(struct domain_device *device);
-       void (*sl_notify)(struct hisi_hba *hisi_hba, int phy_no);
+       void (*sl_notify_ssp)(struct hisi_hba *hisi_hba, int phy_no);
        int (*get_free_slot)(struct hisi_hba *hisi_hba, struct hisi_sas_dq *dq);
        void (*start_delivery)(struct hisi_sas_dq *dq);
        void (*prep_ssp)(struct hisi_hba *hisi_hba,
index f478d1f..3319167 100644 (file)
@@ -485,7 +485,13 @@ static int hisi_sas_task_exec(struct sas_task *task, gfp_t gfp_flags,
        struct hisi_sas_dq *dq = NULL;
 
        if (unlikely(test_bit(HISI_SAS_REJECT_CMD_BIT, &hisi_hba->flags))) {
-               if (in_softirq())
+               /*
+                * For IOs from upper layer, it may already disable preempt
+                * in the IO path, if disable preempt again in down(),
+                * function schedule() will report schedule_bug(), so check
+                * preemptible() before goto down().
+                */
+               if (!preemptible())
                        return -EINVAL;
 
                down(&hisi_hba->sem);
@@ -716,7 +722,8 @@ static void hisi_sas_phyup_work(struct work_struct *work)
        struct asd_sas_phy *sas_phy = &phy->sas_phy;
        int phy_no = sas_phy->id;
 
-       hisi_hba->hw->sl_notify(hisi_hba, phy_no); /* This requires a sleep */
+       if (phy->identify.target_port_protocols == SAS_PROTOCOL_SSP)
+               hisi_hba->hw->sl_notify_ssp(hisi_hba, phy_no);
        hisi_sas_bytes_dmaed(hisi_hba, phy_no);
 }
 
@@ -885,7 +892,7 @@ static int hisi_sas_queue_command(struct sas_task *task, gfp_t gfp_flags)
        return hisi_sas_task_exec(task, gfp_flags, 0, NULL);
 }
 
-static void hisi_sas_phy_set_linkrate(struct hisi_hba *hisi_hba, int phy_no,
+static int hisi_sas_phy_set_linkrate(struct hisi_hba *hisi_hba, int phy_no,
                        struct sas_phy_linkrates *r)
 {
        struct sas_phy_linkrates _r;
@@ -894,6 +901,9 @@ static void hisi_sas_phy_set_linkrate(struct hisi_hba *hisi_hba, int phy_no,
        struct asd_sas_phy *sas_phy = &phy->sas_phy;
        enum sas_linkrate min, max;
 
+       if (r->minimum_linkrate > SAS_LINK_RATE_1_5_GBPS)
+               return -EINVAL;
+
        if (r->maximum_linkrate == SAS_LINK_RATE_UNKNOWN) {
                max = sas_phy->phy->maximum_linkrate;
                min = r->minimum_linkrate;
@@ -901,7 +911,7 @@ static void hisi_sas_phy_set_linkrate(struct hisi_hba *hisi_hba, int phy_no,
                max = r->maximum_linkrate;
                min = sas_phy->phy->minimum_linkrate;
        } else
-               return;
+               return -EINVAL;
 
        _r.maximum_linkrate = max;
        _r.minimum_linkrate = min;
@@ -913,6 +923,8 @@ static void hisi_sas_phy_set_linkrate(struct hisi_hba *hisi_hba, int phy_no,
        msleep(100);
        hisi_hba->hw->phy_set_linkrate(hisi_hba, phy_no, &_r);
        hisi_hba->hw->phy_start(hisi_hba, phy_no);
+
+       return 0;
 }
 
 static int hisi_sas_control_phy(struct asd_sas_phy *sas_phy, enum phy_func func,
@@ -938,8 +950,7 @@ static int hisi_sas_control_phy(struct asd_sas_phy *sas_phy, enum phy_func func,
                break;
 
        case PHY_FUNC_SET_LINK_RATE:
-               hisi_sas_phy_set_linkrate(hisi_hba, phy_no, funcdata);
-               break;
+               return hisi_sas_phy_set_linkrate(hisi_hba, phy_no, funcdata);
        case PHY_FUNC_GET_EVENTS:
                if (hisi_hba->hw->get_events) {
                        hisi_hba->hw->get_events(hisi_hba, phy_no);
index 410eccf..8aa3222 100644 (file)
@@ -834,7 +834,7 @@ static void phys_init_v1_hw(struct hisi_hba *hisi_hba)
        mod_timer(timer, jiffies + HZ);
 }
 
-static void sl_notify_v1_hw(struct hisi_hba *hisi_hba, int phy_no)
+static void sl_notify_ssp_v1_hw(struct hisi_hba *hisi_hba, int phy_no)
 {
        u32 sl_control;
 
@@ -1822,7 +1822,7 @@ static struct scsi_host_template sht_v1_hw = {
 static const struct hisi_sas_hw hisi_sas_v1_hw = {
        .hw_init = hisi_sas_v1_init,
        .setup_itct = setup_itct_v1_hw,
-       .sl_notify = sl_notify_v1_hw,
+       .sl_notify_ssp = sl_notify_ssp_v1_hw,
        .clear_itct = clear_itct_v1_hw,
        .prep_smp = prep_smp_v1_hw,
        .prep_ssp = prep_ssp_v1_hw,
index c4774d6..ebc984f 100644 (file)
@@ -1584,7 +1584,7 @@ static void phys_init_v2_hw(struct hisi_hba *hisi_hba)
        }
 }
 
-static void sl_notify_v2_hw(struct hisi_hba *hisi_hba, int phy_no)
+static void sl_notify_ssp_v2_hw(struct hisi_hba *hisi_hba, int phy_no)
 {
        u32 sl_control;
 
@@ -3575,7 +3575,7 @@ static const struct hisi_sas_hw hisi_sas_v2_hw = {
        .setup_itct = setup_itct_v2_hw,
        .slot_index_alloc = slot_index_alloc_quirk_v2_hw,
        .alloc_dev = alloc_dev_quirk_v2_hw,
-       .sl_notify = sl_notify_v2_hw,
+       .sl_notify_ssp = sl_notify_ssp_v2_hw,
        .get_wideport_bitmap = get_wideport_bitmap_v2_hw,
        .clear_itct = clear_itct_v2_hw,
        .free_device = free_device_v2_hw,
index a7407d5..ce2f232 100644 (file)
@@ -827,7 +827,7 @@ static void phys_init_v3_hw(struct hisi_hba *hisi_hba)
        }
 }
 
-static void sl_notify_v3_hw(struct hisi_hba *hisi_hba, int phy_no)
+static void sl_notify_ssp_v3_hw(struct hisi_hba *hisi_hba, int phy_no)
 {
        u32 sl_control;
 
@@ -2127,7 +2127,7 @@ static const struct hisi_sas_hw hisi_sas_v3_hw = {
        .get_wideport_bitmap = get_wideport_bitmap_v3_hw,
        .complete_hdr_size = sizeof(struct hisi_sas_complete_v3_hdr),
        .clear_itct = clear_itct_v3_hw,
-       .sl_notify = sl_notify_v3_hw,
+       .sl_notify_ssp = sl_notify_ssp_v3_hw,
        .prep_ssp = prep_ssp_v3_hw,
        .prep_smp = prep_smp_v3_hw,
        .prep_stp = prep_ata_v3_hw,
index 23354f2..55181d2 100644 (file)
@@ -374,8 +374,16 @@ static int iscsi_sw_tcp_pdu_xmit(struct iscsi_task *task)
 {
        struct iscsi_conn *conn = task->conn;
        unsigned int noreclaim_flag;
+       struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
+       struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data;
        int rc = 0;
 
+       if (!tcp_sw_conn->sock) {
+               iscsi_conn_printk(KERN_ERR, conn,
+                                 "Transport not bound to socket!\n");
+               return -EINVAL;
+       }
+
        noreclaim_flag = memalloc_noreclaim_save();
 
        while (iscsi_sw_tcp_xmit_qlen(conn)) {
index 4ad61cf..7a05c72 100644 (file)
@@ -1983,7 +1983,7 @@ enum blk_eh_timer_return iscsi_eh_cmd_timed_out(struct scsi_cmnd *sc)
 
        ISCSI_DBG_EH(session, "scsi cmd %p timedout\n", sc);
 
-       spin_lock(&session->frwd_lock);
+       spin_lock_bh(&session->frwd_lock);
        task = (struct iscsi_task *)sc->SCp.ptr;
        if (!task) {
                /*
@@ -2110,7 +2110,7 @@ enum blk_eh_timer_return iscsi_eh_cmd_timed_out(struct scsi_cmnd *sc)
 done:
        if (task)
                task->last_timeout = jiffies;
-       spin_unlock(&session->frwd_lock);
+       spin_unlock_bh(&session->frwd_lock);
        ISCSI_DBG_EH(session, "return %s\n", rc == BLK_EH_RESET_TIMER ?
                     "timer reset" : "shutdown or nh");
        return rc;
index a62e85c..706aca3 100644 (file)
@@ -966,7 +966,8 @@ struct lpfc_hba {
        struct list_head port_list;
        struct lpfc_vport *pport;       /* physical lpfc_vport pointer */
        uint16_t max_vpi;               /* Maximum virtual nports */
-#define LPFC_MAX_VPI 0xFFFF            /* Max number of VPI supported */
+#define LPFC_MAX_VPI   0xFF            /* Max number VPI supported 0 - 0xff */
+#define LPFC_MAX_VPORTS        0x100           /* Max vports per port, with pport */
        uint16_t max_vports;            /*
                                         * For IOV HBAs max_vpi can change
                                         * after a reset. max_vports is max
index 3f69a5e..fe084d4 100644 (file)
@@ -1632,6 +1632,9 @@ lpfc_get_hba_info(struct lpfc_hba *phba,
                max_vpi = (bf_get(lpfc_mbx_rd_conf_vpi_count, rd_config) > 0) ?
                        (bf_get(lpfc_mbx_rd_conf_vpi_count, rd_config) - 1) : 0;
 
+               /* Limit the max we support */
+               if (max_vpi > LPFC_MAX_VPI)
+                       max_vpi = LPFC_MAX_VPI;
                if (mvpi)
                        *mvpi = max_vpi;
                if (avpi)
@@ -1647,8 +1650,13 @@ lpfc_get_hba_info(struct lpfc_hba *phba,
                        *axri = pmb->un.varRdConfig.avail_xri;
                if (mvpi)
                        *mvpi = pmb->un.varRdConfig.max_vpi;
-               if (avpi)
-                       *avpi = pmb->un.varRdConfig.avail_vpi;
+               if (avpi) {
+                       /* avail_vpi is only valid if link is up and ready */
+                       if (phba->link_state == LPFC_HBA_READY)
+                               *avpi = pmb->un.varRdConfig.avail_vpi;
+                       else
+                               *avpi = pmb->un.varRdConfig.max_vpi;
+               }
        }
 
        mempool_free(pmboxq, phba->mbox_mem_pool);
@@ -3841,8 +3849,9 @@ lpfc_topology_store(struct device *dev, struct device_attribute *attr,
                                val);
                        return -EINVAL;
                }
-               if (phba->pcidev->device == PCI_DEVICE_ID_LANCER_G6_FC &&
-                       val == 4) {
+               if ((phba->pcidev->device == PCI_DEVICE_ID_LANCER_G6_FC ||
+                    phba->pcidev->device == PCI_DEVICE_ID_LANCER_G7_FC) &&
+                   val == 4) {
                        lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
                                "3114 Loop mode not supported\n");
                        return -EINVAL;
index 4f4d1b3..7398350 100644 (file)
@@ -4110,7 +4110,7 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
                mempool_free(mbox, phba->mbox_mem_pool);
        }
 out:
-       if (ndlp && NLP_CHK_NODE_ACT(ndlp)) {
+       if (ndlp && NLP_CHK_NODE_ACT(ndlp) && shost) {
                spin_lock_irq(shost->host_lock);
                ndlp->nlp_flag &= ~(NLP_ACC_REGLOGIN | NLP_RM_DFLT_RPI);
                spin_unlock_irq(shost->host_lock);
index b36b3da..5d65717 100644 (file)
@@ -5231,9 +5231,14 @@ lpfc_setup_disc_node(struct lpfc_vport *vport, uint32_t did)
                        /* If we've already received a PLOGI from this NPort
                         * we don't need to try to discover it again.
                         */
-                       if (ndlp->nlp_flag & NLP_RCV_PLOGI)
+                       if (ndlp->nlp_flag & NLP_RCV_PLOGI &&
+                           !(ndlp->nlp_type &
+                            (NLP_FCP_TARGET | NLP_NVME_TARGET)))
                                return NULL;
 
+                       ndlp->nlp_prev_state = ndlp->nlp_state;
+                       lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
+
                        spin_lock_irq(shost->host_lock);
                        ndlp->nlp_flag |= NLP_NPR_2B_DISC;
                        spin_unlock_irq(shost->host_lock);
index da63c02..57510a8 100644 (file)
@@ -7766,6 +7766,9 @@ lpfc_sli4_read_config(struct lpfc_hba *phba)
                        bf_get(lpfc_mbx_rd_conf_xri_base, rd_config);
                phba->sli4_hba.max_cfg_param.max_vpi =
                        bf_get(lpfc_mbx_rd_conf_vpi_count, rd_config);
+               /* Limit the max we support */
+               if (phba->sli4_hba.max_cfg_param.max_vpi > LPFC_MAX_VPORTS)
+                       phba->sli4_hba.max_cfg_param.max_vpi = LPFC_MAX_VPORTS;
                phba->sli4_hba.max_cfg_param.vpi_base =
                        bf_get(lpfc_mbx_rd_conf_vpi_base, rd_config);
                phba->sli4_hba.max_cfg_param.max_rpi =
index deb094f..e6bf5e8 100644 (file)
@@ -513,9 +513,9 @@ lpfc_init_link(struct lpfc_hba * phba,
                break;
        }
 
-       if (phba->pcidev->device == PCI_DEVICE_ID_LANCER_G6_FC &&
-               mb->un.varInitLnk.link_flags & FLAGS_TOPOLOGY_MODE_LOOP) {
-               /* Failover is not tried for Lancer G6 */
+       if ((phba->pcidev->device == PCI_DEVICE_ID_LANCER_G6_FC ||
+            phba->pcidev->device == PCI_DEVICE_ID_LANCER_G7_FC) &&
+           mb->un.varInitLnk.link_flags & FLAGS_TOPOLOGY_MODE_LOOP) {
                mb->un.varInitLnk.link_flags = FLAGS_TOPOLOGY_MODE_PT_PT;
                phba->cfg_topology = FLAGS_TOPOLOGY_MODE_PT_PT;
        }
index bd8dc6a..3dfed19 100644 (file)
@@ -483,8 +483,10 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
         * single discovery thread, this will cause a huge delay in
         * discovery. Also this will cause multiple state machines
         * running in parallel for this node.
+        * This only applies to a fabric environment.
         */
-       if (ndlp->nlp_state == NLP_STE_PLOGI_ISSUE) {
+       if ((ndlp->nlp_state == NLP_STE_PLOGI_ISSUE) &&
+           (vport->fc_flag & FC_FABRIC)) {
                /* software abort outstanding PLOGI */
                lpfc_els_abort(phba, ndlp);
        }
index 8ee585e..f73726e 100644 (file)
@@ -1856,7 +1856,6 @@ lpfc_nvme_fcp_abort(struct nvme_fc_local_port *pnvme_lport,
        bf_set(abort_cmd_criteria, &abts_wqe->abort_cmd, T_XRI_TAG);
 
        /* word 7 */
-       bf_set(wqe_ct, &abts_wqe->abort_cmd.wqe_com, 0);
        bf_set(wqe_cmnd, &abts_wqe->abort_cmd.wqe_com, CMD_ABORT_XRI_CX);
        bf_set(wqe_class, &abts_wqe->abort_cmd.wqe_com,
               nvmereq_wqe->iocb.ulpClass);
@@ -1871,7 +1870,6 @@ lpfc_nvme_fcp_abort(struct nvme_fc_local_port *pnvme_lport,
               abts_buf->iotag);
 
        /* word 10 */
-       bf_set(wqe_wqid, &abts_wqe->abort_cmd.wqe_com, nvmereq_wqe->hba_wqidx);
        bf_set(wqe_qosd, &abts_wqe->abort_cmd.wqe_com, 1);
        bf_set(wqe_lenloc, &abts_wqe->abort_cmd.wqe_com, LPFC_WQE_LENLOC_NONE);
 
index 755803f..a801917 100644 (file)
@@ -10989,19 +10989,12 @@ lpfc_sli4_abort_nvme_io(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
 
        /* Complete prepping the abort wqe and issue to the FW. */
        abts_wqe = &abtsiocbp->wqe;
-       bf_set(abort_cmd_ia, &abts_wqe->abort_cmd, 0);
-       bf_set(abort_cmd_criteria, &abts_wqe->abort_cmd, T_XRI_TAG);
-
-       /* Explicitly set reserved fields to zero.*/
-       abts_wqe->abort_cmd.rsrvd4 = 0;
-       abts_wqe->abort_cmd.rsrvd5 = 0;
 
-       /* WQE Common - word 6.  Context is XRI tag.  Set 0. */
-       bf_set(wqe_xri_tag, &abts_wqe->abort_cmd.wqe_com, 0);
-       bf_set(wqe_ctxt_tag, &abts_wqe->abort_cmd.wqe_com, 0);
+       /* Clear any stale WQE contents */
+       memset(abts_wqe, 0, sizeof(union lpfc_wqe));
+       bf_set(abort_cmd_criteria, &abts_wqe->abort_cmd, T_XRI_TAG);
 
        /* word 7 */
-       bf_set(wqe_ct, &abts_wqe->abort_cmd.wqe_com, 0);
        bf_set(wqe_cmnd, &abts_wqe->abort_cmd.wqe_com, CMD_ABORT_XRI_CX);
        bf_set(wqe_class, &abts_wqe->abort_cmd.wqe_com,
               cmdiocb->iocb.ulpClass);
@@ -11016,7 +11009,6 @@ lpfc_sli4_abort_nvme_io(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
               abtsiocbp->iotag);
 
        /* word 10 */
-       bf_set(wqe_wqid, &abts_wqe->abort_cmd.wqe_com, cmdiocb->hba_wqidx);
        bf_set(wqe_qosd, &abts_wqe->abort_cmd.wqe_com, 1);
        bf_set(wqe_lenloc, &abts_wqe->abort_cmd.wqe_com, LPFC_WQE_LENLOC_NONE);
 
@@ -12936,13 +12928,19 @@ send_current_mbox:
        phba->sli.sli_flag &= ~LPFC_SLI_MBOX_ACTIVE;
        /* Setting active mailbox pointer need to be in sync to flag clear */
        phba->sli.mbox_active = NULL;
+       if (bf_get(lpfc_trailer_consumed, mcqe))
+               lpfc_sli4_mq_release(phba->sli4_hba.mbx_wq);
        spin_unlock_irqrestore(&phba->hbalock, iflags);
        /* Wake up worker thread to post the next pending mailbox command */
        lpfc_worker_wake_up(phba);
+       return workposted;
+
 out_no_mqe_complete:
+       spin_lock_irqsave(&phba->hbalock, iflags);
        if (bf_get(lpfc_trailer_consumed, mcqe))
                lpfc_sli4_mq_release(phba->sli4_hba.mbx_wq);
-       return workposted;
+       spin_unlock_irqrestore(&phba->hbalock, iflags);
+       return false;
 }
 
 /**
@@ -17869,6 +17867,13 @@ lpfc_sli4_alloc_rpi(struct lpfc_hba *phba)
 static void
 __lpfc_sli4_free_rpi(struct lpfc_hba *phba, int rpi)
 {
+       /*
+        * if the rpi value indicates a prior unreg has already
+        * been done, skip the unreg.
+        */
+       if (rpi == LPFC_RPI_ALLOC_ERROR)
+               return;
+
        if (test_and_clear_bit(rpi, phba->sli4_hba.rpi_bmask)) {
                phba->sli4_hba.rpi_count--;
                phba->sli4_hba.max_cfg_param.rpi_used--;
index 643321f..b5050c2 100644 (file)
@@ -429,7 +429,7 @@ static int __init mac_scsi_probe(struct platform_device *pdev)
                mac_scsi_template.can_queue = setup_can_queue;
        if (setup_cmd_per_lun > 0)
                mac_scsi_template.cmd_per_lun = setup_cmd_per_lun;
-       if (setup_sg_tablesize >= 0)
+       if (setup_sg_tablesize > 0)
                mac_scsi_template.sg_tablesize = setup_sg_tablesize;
        if (setup_hostid >= 0)
                mac_scsi_template.this_id = setup_hostid & 7;
index 5e8c059..0734501 100644 (file)
@@ -1597,7 +1597,8 @@ _ctl_diag_register_2(struct MPT3SAS_ADAPTER *ioc,
                            " for diag buffers, requested size(%d)\n",
                            ioc->name, __func__, request_data_sz);
                        mpt3sas_base_free_smid(ioc, smid);
-                       return -ENOMEM;
+                       rc = -ENOMEM;
+                       goto out;
                }
                ioc->diag_buffer[buffer_type] = request_data;
                ioc->diag_buffer_sz[buffer_type] = request_data_sz;
index 5021aed..8627feb 100644 (file)
@@ -2382,6 +2382,8 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
                        pm8001_printk("task 0x%p done with io_status 0x%x"
                        " resp 0x%x stat 0x%x but aborted by upper layer!\n",
                        t, status, ts->resp, ts->stat));
+               if (t->slow_task)
+                       complete(&t->slow_task->completion);
                pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
        } else {
                spin_unlock_irqrestore(&t->task_state_lock, flags);
index 3e9c49b..b008d58 100644 (file)
@@ -655,7 +655,8 @@ qla2x00_sysfs_write_reset(struct file *filp, struct kobject *kobj,
                        break;
                } else {
                        /* Make sure FC side is not in reset */
-                       qla2x00_wait_for_hba_online(vha);
+                       WARN_ON_ONCE(qla2x00_wait_for_hba_online(vha) !=
+                                    QLA_SUCCESS);
 
                        /* Issue MPI reset */
                        scsi_block_requests(vha->host);
index 85b03a7..47f062e 100644 (file)
@@ -342,6 +342,8 @@ qla2x00_process_els(struct bsg_job *bsg_job)
                dma_map_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list,
                bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
        if (!req_sg_cnt) {
+               dma_unmap_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list,
+                   bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
                rval = -ENOMEM;
                goto done_free_fcport;
        }
@@ -349,6 +351,8 @@ qla2x00_process_els(struct bsg_job *bsg_job)
        rsp_sg_cnt = dma_map_sg(&ha->pdev->dev, bsg_job->reply_payload.sg_list,
                bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
         if (!rsp_sg_cnt) {
+               dma_unmap_sg(&ha->pdev->dev, bsg_job->reply_payload.sg_list,
+                   bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
                rval = -ENOMEM;
                goto done_free_fcport;
        }
@@ -1775,8 +1779,8 @@ qla24xx_process_bidir_cmd(struct bsg_job *bsg_job)
        uint16_t nextlid = 0;
        uint32_t tot_dsds;
        srb_t *sp = NULL;
-       uint32_t req_data_len = 0;
-       uint32_t rsp_data_len = 0;
+       uint32_t req_data_len;
+       uint32_t rsp_data_len;
 
        /* Check the type of the adapter */
        if (!IS_BIDI_CAPABLE(ha)) {
@@ -1881,6 +1885,9 @@ qla24xx_process_bidir_cmd(struct bsg_job *bsg_job)
                goto done_unmap_sg;
        }
 
+       req_data_len = bsg_job->request_payload.payload_len;
+       rsp_data_len = bsg_job->reply_payload.payload_len;
+
        if (req_data_len != rsp_data_len) {
                rval = EXT_STATUS_BUSY;
                ql_log(ql_log_warn, vha, 0x70aa,
@@ -1888,10 +1895,6 @@ qla24xx_process_bidir_cmd(struct bsg_job *bsg_job)
                goto done_unmap_sg;
        }
 
-       req_data_len = bsg_job->request_payload.payload_len;
-       rsp_data_len = bsg_job->reply_payload.payload_len;
-
-
        /* Alloc SRB structure */
        sp = qla2x00_get_sp(vha, &(vha->bidir_fcport), GFP_KERNEL);
        if (!sp) {
index b8d3403..f621cb5 100644 (file)
@@ -3264,7 +3264,7 @@ static void qla24xx_async_gpsc_sp_done(void *s, int res)
        fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE);
 
        if (res == QLA_FUNCTION_TIMEOUT)
-               return;
+               goto done;
 
        if (res == (DID_ERROR << 16)) {
                /* entry status error */
index f7dd289..4512aaa 100644 (file)
@@ -291,9 +291,6 @@ qla2x00_async_logout(struct scsi_qla_host *vha, fc_port_t *fcport)
        struct srb_iocb *lio;
        int rval = QLA_FUNCTION_FAILED;
 
-       if (!vha->flags.online || (fcport->flags & FCF_ASYNC_SENT))
-               return rval;
-
        fcport->flags |= FCF_ASYNC_SENT;
        sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
        if (!sp)
@@ -436,6 +433,7 @@ int qla_post_els_plogi_work(struct scsi_qla_host *vha, fc_port_t *fcport)
 
        e->u.fcport.fcport = fcport;
        fcport->flags |= FCF_ASYNC_ACTIVE;
+       fcport->disc_state = DSC_LOGIN_PEND;
        return qla2x00_post_work(vha, e);
 }
 
@@ -968,6 +966,7 @@ int qla24xx_post_gnl_work(struct scsi_qla_host *vha, fc_port_t *fcport)
 
        e->u.fcport.fcport = fcport;
        fcport->flags |= FCF_ASYNC_ACTIVE;
+       fcport->disc_state = DSC_LOGIN_PEND;
        return qla2x00_post_work(vha, e);
 }
 
@@ -985,13 +984,11 @@ void qla24xx_async_gpdb_sp_done(void *s, int res)
            "Async done-%s res %x, WWPN %8phC mb[1]=%x mb[2]=%x \n",
            sp->name, res, fcport->port_name, mb[1], mb[2]);
 
-       if (res == QLA_FUNCTION_TIMEOUT) {
-               dma_pool_free(sp->vha->hw->s_dma_pool, sp->u.iocb_cmd.u.mbx.in,
-                       sp->u.iocb_cmd.u.mbx.in_dma);
-               return;
-       }
-
        fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE);
+
+       if (res == QLA_FUNCTION_TIMEOUT)
+               goto done;
+
        memset(&ea, 0, sizeof(ea));
        ea.event = FCME_GPDB_DONE;
        ea.fcport = fcport;
@@ -999,6 +996,7 @@ void qla24xx_async_gpdb_sp_done(void *s, int res)
 
        qla2x00_fcport_event_handler(vha, &ea);
 
+done:
        dma_pool_free(ha->s_dma_pool, sp->u.iocb_cmd.u.mbx.in,
                sp->u.iocb_cmd.u.mbx.in_dma);
 
@@ -8725,8 +8723,6 @@ int qla2xxx_delete_qpair(struct scsi_qla_host *vha, struct qla_qpair *qpair)
        struct qla_hw_data *ha = qpair->hw;
 
        qpair->delete_in_progress = 1;
-       while (atomic_read(&qpair->ref_count))
-               msleep(500);
 
        ret = qla25xx_delete_req_que(vha, qpair->req);
        if (ret != QLA_SUCCESS)
index 8fa7242..afe15b3 100644 (file)
@@ -3418,10 +3418,8 @@ qla24xx_enable_msix(struct qla_hw_data *ha, struct rsp_que *rsp)
                    ha->msix_count, ret);
                goto msix_out;
        } else if (ret < ha->msix_count) {
-               ql_log(ql_log_warn, vha, 0x00c6,
-                   "MSI-X: Failed to enable support "
-                    "with %d vectors, using %d vectors.\n",
-                   ha->msix_count, ret);
+               ql_log(ql_log_info, vha, 0x00c6,
+                   "MSI-X: Using %d vectors\n", ret);
                ha->msix_count = ret;
                /* Recalculate queue values */
                if (ha->mqiobase && (ql2xmqsupport || ql2xnvmeenable)) {
index 128fcff..b01f69d 100644 (file)
@@ -6131,17 +6131,13 @@ int qla24xx_send_mb_cmd(struct scsi_qla_host *vha, mbx_cmd_t *mcp)
        case  QLA_SUCCESS:
                ql_dbg(ql_dbg_mbx, vha, 0x119d, "%s: %s done.\n",
                    __func__, sp->name);
-               sp->free(sp);
                break;
        default:
                ql_dbg(ql_dbg_mbx, vha, 0x119e, "%s: %s Failed. %x.\n",
                    __func__, sp->name, rval);
-               sp->free(sp);
                break;
        }
 
-       return rval;
-
 done_free_sp:
        sp->free(sp);
 done:
index d620f4b..516fccd 100644 (file)
@@ -931,7 +931,7 @@ int qla24xx_control_vp(scsi_qla_host_t *vha, int cmd)
 
        sp = qla2x00_get_sp(base_vha, NULL, GFP_KERNEL);
        if (!sp)
-               goto done;
+               return rval;
 
        sp->type = SRB_CTRL_VP;
        sp->name = "ctrl_vp";
@@ -946,7 +946,7 @@ int qla24xx_control_vp(scsi_qla_host_t *vha, int cmd)
                ql_dbg(ql_dbg_async, vha, 0xffff,
                    "%s: %s Failed submission. %x.\n",
                    __func__, sp->name, rval);
-               goto done_free_sp;
+               goto done;
        }
 
        ql_dbg(ql_dbg_vport, vha, 0x113f, "%s hndl %x submitted\n",
@@ -962,16 +962,13 @@ int qla24xx_control_vp(scsi_qla_host_t *vha, int cmd)
        case QLA_SUCCESS:
                ql_dbg(ql_dbg_vport, vha, 0xffff, "%s: %s done.\n",
                    __func__, sp->name);
-               goto done_free_sp;
+               break;
        default:
                ql_dbg(ql_dbg_vport, vha, 0xffff, "%s: %s Failed. %x.\n",
                    __func__, sp->name, rval);
-               goto done_free_sp;
+               break;
        }
 done:
-       return rval;
-
-done_free_sp:
        sp->free(sp);
        return rval;
 }
index 183bfda..bb20a4a 100644 (file)
@@ -1029,7 +1029,7 @@ qla2xxx_mqueuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd,
                ql_dbg(ql_dbg_io + ql_dbg_verbose, vha, 0x3078,
                    "Start scsi failed rval=%d for cmd=%p.\n", rval, cmd);
                if (rval == QLA_INTERFACE_ERROR)
-                       goto qc24_fail_command;
+                       goto qc24_free_sp_fail_command;
                goto qc24_host_busy_free_sp;
        }
 
@@ -1044,6 +1044,11 @@ qc24_host_busy:
 qc24_target_busy:
        return SCSI_MLQUEUE_TARGET_BUSY;
 
+qc24_free_sp_fail_command:
+       sp->free(sp);
+       CMD_SP(cmd) = NULL;
+       qla2xxx_rel_qpair_sp(sp->qpair, sp);
+
 qc24_fail_command:
        cmd->scsi_done(cmd);
 
index 078d124..210ce29 100644 (file)
@@ -6062,7 +6062,6 @@ static void qlt_abort_work(struct qla_tgt *tgt,
        struct qla_hw_data *ha = vha->hw;
        struct fc_port *sess = NULL;
        unsigned long flags = 0, flags2 = 0;
-       uint32_t be_s_id;
        uint8_t s_id[3];
        int rc;
 
@@ -6075,8 +6074,7 @@ static void qlt_abort_work(struct qla_tgt *tgt,
        s_id[1] = prm->abts.fcp_hdr_le.s_id[1];
        s_id[2] = prm->abts.fcp_hdr_le.s_id[0];
 
-       sess = ha->tgt.tgt_ops->find_sess_by_s_id(vha,
-           (unsigned char *)&be_s_id);
+       sess = ha->tgt.tgt_ops->find_sess_by_s_id(vha, s_id);
        if (!sess) {
                spin_unlock_irqrestore(&ha->tgt.sess_lock, flags2);
 
@@ -6545,7 +6543,8 @@ qlt_enable_vha(struct scsi_qla_host *vha)
        } else {
                set_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags);
                qla2xxx_wake_dpc(base_vha);
-               qla2x00_wait_for_hba_online(base_vha);
+               WARN_ON_ONCE(qla2x00_wait_for_hba_online(base_vha) !=
+                            QLA_SUCCESS);
        }
 }
 EXPORT_SYMBOL(qlt_enable_vha);
@@ -6575,7 +6574,9 @@ static void qlt_disable_vha(struct scsi_qla_host *vha)
 
        set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
        qla2xxx_wake_dpc(vha);
-       qla2x00_wait_for_hba_online(vha);
+       if (qla2x00_wait_for_hba_online(vha) != QLA_SUCCESS)
+               ql_dbg(ql_dbg_tgt, vha, 0xe081,
+                      "qla2x00_wait_for_hba_online() failed\n");
 }
 
 /*
index 65305b3..a1dbae8 100644 (file)
@@ -5351,6 +5351,11 @@ static int __init scsi_debug_init(void)
                return -EINVAL;
        }
 
+       if (sdebug_num_tgts < 0) {
+               pr_err("num_tgts must be >= 0\n");
+               return -EINVAL;
+       }
+
        if (sdebug_guard > 1) {
                pr_err("guard must be 0 or 1\n");
                return -EINVAL;
index 0ff083b..617a607 100644 (file)
@@ -30,15 +30,18 @@ static const char *
 scsi_trace_rw6(struct trace_seq *p, unsigned char *cdb, int len)
 {
        const char *ret = trace_seq_buffer_ptr(p);
-       sector_t lba = 0, txlen = 0;
+       u32 lba = 0, txlen;
 
        lba |= ((cdb[1] & 0x1F) << 16);
        lba |=  (cdb[2] << 8);
        lba |=   cdb[3];
-       txlen = cdb[4];
+       /*
+        * From SBC-2: a TRANSFER LENGTH field set to zero specifies that 256
+        * logical blocks shall be read (READ(6)) or written (WRITE(6)).
+        */
+       txlen = cdb[4] ? cdb[4] : 256;
 
-       trace_seq_printf(p, "lba=%llu txlen=%llu",
-                        (unsigned long long)lba, (unsigned long long)txlen);
+       trace_seq_printf(p, "lba=%u txlen=%u", lba, txlen);
        trace_seq_putc(p, 0);
 
        return ret;
index 9492638..af8a7ef 100644 (file)
@@ -498,7 +498,7 @@ static struct scsi_host_template sun3_scsi_template = {
        .eh_host_reset_handler  = sun3scsi_host_reset,
        .can_queue              = 16,
        .this_id                = 7,
-       .sg_tablesize           = SG_NONE,
+       .sg_tablesize           = 1,
        .cmd_per_lun            = 2,
        .use_clustering         = DISABLE_CLUSTERING,
        .cmd_size               = NCR5380_CMD_SIZE,
@@ -520,7 +520,7 @@ static int __init sun3_scsi_probe(struct platform_device *pdev)
                sun3_scsi_template.can_queue = setup_can_queue;
        if (setup_cmd_per_lun > 0)
                sun3_scsi_template.cmd_per_lun = setup_cmd_per_lun;
-       if (setup_sg_tablesize >= 0)
+       if (setup_sg_tablesize > 0)
                sun3_scsi_template.sg_tablesize = setup_sg_tablesize;
        if (setup_hostid >= 0)
                sun3_scsi_template.this_id = setup_hostid & 7;
index 8bce755..3601e77 100644 (file)
@@ -3011,10 +3011,10 @@ static int __ufshcd_query_descriptor(struct ufs_hba *hba,
                goto out_unlock;
        }
 
-       hba->dev_cmd.query.descriptor = NULL;
        *buf_len = be16_to_cpu(response->upiu_res.length);
 
 out_unlock:
+       hba->dev_cmd.query.descriptor = NULL;
        mutex_unlock(&hba->dev_cmd.lock);
 out:
        ufshcd_release(hba);
@@ -3875,15 +3875,24 @@ static int __ufshcd_uic_hibern8_enter(struct ufs_hba *hba)
                             ktime_to_us(ktime_sub(ktime_get(), start)), ret);
 
        if (ret) {
+               int err;
+
                dev_err(hba->dev, "%s: hibern8 enter failed. ret = %d\n",
                        __func__, ret);
 
                /*
-                * If link recovery fails then return error so that caller
-                * don't retry the hibern8 enter again.
+                * If link recovery fails then return error code returned from
+                * ufshcd_link_recovery().
+                * If link recovery succeeds then return -EAGAIN to attempt
+                * hibern8 enter retry again.
                 */
-               if (ufshcd_link_recovery(hba))
-                       ret = -ENOLINK;
+               err = ufshcd_link_recovery(hba);
+               if (err) {
+                       dev_err(hba->dev, "%s: link recovery failed", __func__);
+                       ret = err;
+               } else {
+                       ret = -EAGAIN;
+               }
        } else
                ufshcd_vops_hibern8_notify(hba, UIC_CMD_DME_HIBER_ENTER,
                                                                POST_CHANGE);
@@ -3897,7 +3906,7 @@ static int ufshcd_uic_hibern8_enter(struct ufs_hba *hba)
 
        for (retries = UIC_HIBERN8_ENTER_RETRIES; retries > 0; retries--) {
                ret = __ufshcd_uic_hibern8_enter(hba);
-               if (!ret || ret == -ENOLINK)
+               if (!ret)
                        goto out;
        }
 out:
index be79127..6a5b547 100644 (file)
@@ -245,7 +245,14 @@ static int fastlane_esp_irq_pending(struct esp *esp)
 static u32 zorro_esp_dma_length_limit(struct esp *esp, u32 dma_addr,
                                        u32 dma_len)
 {
-       return dma_len > 0xFFFF ? 0xFFFF : dma_len;
+       return dma_len > (1U << 16) ? (1U << 16) : dma_len;
+}
+
+static u32 fastlane_esp_dma_length_limit(struct esp *esp, u32 dma_addr,
+                                       u32 dma_len)
+{
+       /* The old driver used 0xfffc as limit, so do that here too */
+       return dma_len > 0xfffc ? 0xfffc : dma_len;
 }
 
 static void zorro_esp_reset_dma(struct esp *esp)
@@ -818,7 +825,7 @@ static const struct esp_driver_ops fastlane_esp_ops = {
        .unmap_single           = zorro_esp_unmap_single,
        .unmap_sg               = zorro_esp_unmap_sg,
        .irq_pending            = fastlane_esp_irq_pending,
-       .dma_length_limit       = zorro_esp_dma_length_limit,
+       .dma_length_limit       = fastlane_esp_dma_length_limit,
        .reset_dma              = zorro_esp_reset_dma,
        .dma_drain              = zorro_esp_dma_drain,
        .dma_invalidate         = fastlane_esp_dma_invalidate,
index 29bc99c..e49d3c8 100644 (file)
@@ -352,7 +352,10 @@ intel_pdi_shim_configure(struct sdw_intel *sdw, struct sdw_cdns_pdi *pdi)
        unsigned int link_id = sdw->instance;
        int pdi_conf = 0;
 
-       pdi->intel_alh_id = (link_id * 16) + pdi->num + 5;
+       /* the Bulk and PCM streams are not contiguous */
+       pdi->intel_alh_id = (link_id * 16) + pdi->num + 3;
+       if (pdi->num >= 2)
+               pdi->intel_alh_id += 2;
 
        /*
         * Program stream parameters to stream SHIM register
@@ -381,7 +384,10 @@ intel_pdi_alh_configure(struct sdw_intel *sdw, struct sdw_cdns_pdi *pdi)
        unsigned int link_id = sdw->instance;
        unsigned int conf;
 
-       pdi->intel_alh_id = (link_id * 16) + pdi->num + 5;
+       /* the Bulk and PCM streams are not contiguous */
+       pdi->intel_alh_id = (link_id * 16) + pdi->num + 3;
+       if (pdi->num >= 2)
+               pdi->intel_alh_id += 2;
 
        /* Program Stream config ALH register */
        conf = intel_readl(alh, SDW_ALH_STRMZCFG(pdi->intel_alh_id));
index 8f2e978..8b79e36 100644 (file)
@@ -832,9 +832,9 @@ static int of_fsl_spi_probe(struct platform_device *ofdev)
        if (ret)
                goto err;
 
-       irq = irq_of_parse_and_map(np, 0);
-       if (!irq) {
-               ret = -EINVAL;
+       irq = platform_get_irq(ofdev, 0);
+       if (irq < 0) {
+               ret = irq;
                goto err;
        }
 
@@ -847,7 +847,6 @@ static int of_fsl_spi_probe(struct platform_device *ofdev)
        return 0;
 
 err:
-       irq_dispose_mapping(irq);
        if (type == TYPE_FSL)
                of_fsl_spi_free_chipselects(dev);
        return ret;
index e6eb979..e4b31d6 100644 (file)
@@ -676,6 +676,8 @@ static int img_spfi_probe(struct platform_device *pdev)
                        dma_release_channel(spfi->tx_ch);
                if (spfi->rx_ch)
                        dma_release_channel(spfi->rx_ch);
+               spfi->tx_ch = NULL;
+               spfi->rx_ch = NULL;
                dev_warn(spfi->dev, "Failed to get DMA channels, falling back to PIO mode\n");
        } else {
                master->dma_tx = spfi->tx_ch;
index f413338..5253881 100644 (file)
@@ -1470,7 +1470,13 @@ pxa2xx_spi_init_pdata(struct platform_device *pdev)
        }
 
        ssp->clk = devm_clk_get(&pdev->dev, NULL);
+       if (IS_ERR(ssp->clk))
+               return NULL;
+
        ssp->irq = platform_get_irq(pdev, 0);
+       if (ssp->irq < 0)
+               return NULL;
+
        ssp->type = type;
        ssp->pdev = pdev;
        ssp->port_id = pxa2xx_spi_get_port_id(adev);
index df5960b..f1fc2bd 100644 (file)
@@ -367,6 +367,9 @@ static int sprd_adi_restart_handler(struct notifier_block *this,
        val |= BIT_WDG_RUN | BIT_WDG_RST;
        sprd_adi_write(sadi, sadi->slave_pbase + REG_WDG_CTRL, val);
 
+       /* Lock the watchdog */
+       sprd_adi_write(sadi, sadi->slave_pbase + REG_WDG_LOCK, ~WDG_UNLOCK_KEY);
+
        mdelay(1000);
 
        dev_emerg(sadi->dev, "Unable to restart system\n");
index a4e43fc..5df01ff 100644 (file)
@@ -385,6 +385,7 @@ static int spi_st_probe(struct platform_device *pdev)
        return 0;
 
 clk_disable:
+       pm_runtime_disable(&pdev->dev);
        clk_disable_unprepare(spi_st->clk);
 put_master:
        spi_master_put(master);
@@ -396,6 +397,8 @@ static int spi_st_remove(struct platform_device *pdev)
        struct spi_master *master = platform_get_drvdata(pdev);
        struct spi_st *spi_st = spi_master_get_devdata(master);
 
+       pm_runtime_disable(&pdev->dev);
+
        clk_disable_unprepare(spi_st->clk);
 
        pinctrl_pm_select_sleep_state(&pdev->dev);
index 1427f34..d118731 100644 (file)
@@ -1078,7 +1078,7 @@ static int tegra_slink_probe(struct platform_device *pdev)
        ret = clk_enable(tspi->clk);
        if (ret < 0) {
                dev_err(&pdev->dev, "Clock enable failed %d\n", ret);
-               goto exit_free_master;
+               goto exit_clk_unprepare;
        }
 
        spi_irq = platform_get_irq(pdev, 0);
@@ -1151,6 +1151,8 @@ exit_free_irq:
        free_irq(spi_irq, tspi);
 exit_clk_disable:
        clk_disable(tspi->clk);
+exit_clk_unprepare:
+       clk_unprepare(tspi->clk);
 exit_free_master:
        spi_master_put(master);
        return ret;
@@ -1164,6 +1166,7 @@ static int tegra_slink_remove(struct platform_device *pdev)
        free_irq(tspi->irq, tspi);
 
        clk_disable(tspi->clk);
+       clk_unprepare(tspi->clk);
 
        if (tspi->tx_dma_chan)
                tegra_slink_deinit_dma_param(tspi, false);
index c62ba8f..f74eeca 100644 (file)
@@ -634,6 +634,9 @@ static int spidev_release(struct inode *inode, struct file *filp)
                if (dofree)
                        kfree(spidev);
        }
+#ifdef CONFIG_SPI_SLAVE
+       spi_slave_abort(spidev->spi);
+#endif
        mutex_unlock(&device_list_lock);
 
        return 0;
index 4bdf44d..dc62db1 100644 (file)
@@ -623,6 +623,11 @@ static int gsc_hpdi_auto_attach(struct comedi_device *dev,
                    dma_alloc_coherent(&pcidev->dev, DMA_BUFFER_SIZE,
                                       &devpriv->dio_buffer_phys_addr[i],
                                       GFP_KERNEL);
+               if (!devpriv->dio_buffer[i]) {
+                       dev_warn(dev->class_dev,
+                                "failed to allocate DMA buffer\n");
+                       return -ENOMEM;
+               }
        }
        /* allocate dma descriptors */
        devpriv->dma_desc = dma_alloc_coherent(&pcidev->dev,
@@ -630,6 +635,11 @@ static int gsc_hpdi_auto_attach(struct comedi_device *dev,
                                               NUM_DMA_DESCRIPTORS,
                                               &devpriv->dma_desc_phys_addr,
                                               GFP_KERNEL);
+       if (!devpriv->dma_desc) {
+               dev_warn(dev->class_dev,
+                        "failed to allocate DMA descriptors\n");
+               return -ENOMEM;
+       }
        if (devpriv->dma_desc_phys_addr & 0xf) {
                dev_warn(dev->class_dev,
                         " dma descriptors not quad-word aligned (bug)\n");
index 2db99cf..d48687c 100644 (file)
@@ -638,6 +638,8 @@ ssize_t erofs_listxattr(struct dentry *dentry,
        struct listxattr_iter it;
 
        ret = init_inode_xattrs(d_inode(dentry));
+       if (ret == -ENOATTR)
+               return 0;
        if (ret)
                return ret;
 
index 16fcf63..3fe4738 100644 (file)
@@ -771,7 +771,7 @@ struct fb_info *fbtft_framebuffer_alloc(struct fbtft_display *display,
        fbdefio->deferred_io =     fbtft_deferred_io;
        fb_deferred_io_init(info);
 
-       strncpy(info->fix.id, dev->driver->name, 16);
+       snprintf(info->fix.id, sizeof(info->fix.id), "%s", dev->driver->name);
        info->fix.type =           FB_TYPE_PACKED_PIXELS;
        info->fix.visual =         FB_VISUAL_TRUECOLOR;
        info->fix.xpanstep =       0;
index dd9b02d..c6a5b62 100644 (file)
@@ -778,7 +778,7 @@ s32 rtw_make_wlanhdr(struct adapter *padapter, u8 *hdr, struct pkt_attrib *pattr
                        memcpy(pwlanhdr->addr2, get_bssid(pmlmepriv), ETH_ALEN);
                        memcpy(pwlanhdr->addr3, pattrib->src, ETH_ALEN);
 
-                       if (psta->qos_option)
+                       if (psta && psta->qos_option)
                                qos_option = true;
                } else if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) ||
                           check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) {
@@ -786,7 +786,7 @@ s32 rtw_make_wlanhdr(struct adapter *padapter, u8 *hdr, struct pkt_attrib *pattr
                        memcpy(pwlanhdr->addr2, pattrib->src, ETH_ALEN);
                        memcpy(pwlanhdr->addr3, get_bssid(pmlmepriv), ETH_ALEN);
 
-                       if (psta->qos_option)
+                       if (psta && psta->qos_option)
                                qos_option = true;
                } else {
                        RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("fw_state:%x is not allowed to xmit frame\n", get_fwstate(pmlmepriv)));
index 8ef7b44..55952dd 100644 (file)
@@ -70,7 +70,7 @@ static struct dvobj_priv *usb_dvobj_init(struct usb_interface *usb_intf)
        phost_conf = pusbd->actconfig;
        pconf_desc = &phost_conf->desc;
 
-       phost_iface = &usb_intf->altsetting[0];
+       phost_iface = usb_intf->cur_altsetting;
        piface_desc = &phost_iface->desc;
 
        pdvobjpriv->NumInterfaces = pconf_desc->bNumInterfaces;
index e218b5c..2066a1d 100644 (file)
@@ -1467,7 +1467,7 @@ short rtl8192_tx(struct net_device *dev, struct sk_buff *skb)
                (struct tx_fwinfo_819x_usb *)(skb->data + USB_HWDESC_HEADER_LEN);
        struct usb_device *udev = priv->udev;
        int pend;
-       int status;
+       int status, rt = -1;
        struct urb *tx_urb = NULL, *tx_urb_zero = NULL;
        unsigned int idx_pipe;
 
@@ -1611,8 +1611,10 @@ short rtl8192_tx(struct net_device *dev, struct sk_buff *skb)
                }
                if (bSend0Byte) {
                        tx_urb_zero = usb_alloc_urb(0, GFP_ATOMIC);
-                       if (!tx_urb_zero)
-                               return -ENOMEM;
+                       if (!tx_urb_zero) {
+                               rt = -ENOMEM;
+                               goto error;
+                       }
                        usb_fill_bulk_urb(tx_urb_zero, udev,
                                          usb_sndbulkpipe(udev, idx_pipe),
                                          &zero, 0, tx_zero_isr, dev);
@@ -1622,7 +1624,7 @@ short rtl8192_tx(struct net_device *dev, struct sk_buff *skb)
                                         "Error TX URB for zero byte %d, error %d",
                                         atomic_read(&priv->tx_pending[tcb_desc->queue_index]),
                                         status);
-                               return -1;
+                               goto error;
                        }
                }
                netif_trans_update(dev);
@@ -1633,7 +1635,12 @@ short rtl8192_tx(struct net_device *dev, struct sk_buff *skb)
        RT_TRACE(COMP_ERR, "Error TX URB %d, error %d",
                 atomic_read(&priv->tx_pending[tcb_desc->queue_index]),
                 status);
-       return -1;
+
+error:
+       dev_kfree_skb_any(skb);
+       usb_free_urb(tx_urb);
+       usb_free_urb(tx_urb_zero);
+       return rt;
 }
 
 static short rtl8192_usb_initendpoints(struct net_device *dev)
index 85eaddd..5e2cdc2 100644 (file)
@@ -275,7 +275,7 @@ static uint r8712_usb_dvobj_init(struct _adapter *padapter)
 
        pdvobjpriv->padapter = padapter;
        padapter->EepromAddressSize = 6;
-       phost_iface = &pintf->altsetting[0];
+       phost_iface = pintf->cur_altsetting;
        piface_desc = &phost_iface->desc;
        pdvobjpriv->nr_endpoint = piface_desc->bNumEndpoints;
        if (pusbd->speed == USB_SPEED_HIGH) {
index 03e9cb1..317d0f3 100644 (file)
@@ -1157,7 +1157,9 @@ int iscsit_setup_scsi_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
                hdr->cmdsn, be32_to_cpu(hdr->data_length), payload_length,
                conn->cid);
 
-       target_get_sess_cmd(&cmd->se_cmd, true);
+       if (target_get_sess_cmd(&cmd->se_cmd, true) < 0)
+               return iscsit_add_reject_cmd(cmd,
+                               ISCSI_REASON_WAITING_FOR_LOGOUT, buf);
 
        cmd->sense_reason = transport_lookup_cmd_lun(&cmd->se_cmd,
                                                     scsilun_to_int(&hdr->lun));
@@ -1998,7 +2000,9 @@ iscsit_handle_task_mgt_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
                              conn->sess->se_sess, 0, DMA_NONE,
                              TCM_SIMPLE_TAG, cmd->sense_buffer + 2);
 
-       target_get_sess_cmd(&cmd->se_cmd, true);
+       if (target_get_sess_cmd(&cmd->se_cmd, true) < 0)
+               return iscsit_add_reject_cmd(cmd,
+                               ISCSI_REASON_WAITING_FOR_LOGOUT, buf);
 
        /*
         * TASK_REASSIGN for ERL=2 / connection stays inside of
@@ -4204,6 +4208,8 @@ int iscsit_close_connection(
         * must wait until they have completed.
         */
        iscsit_check_conn_usage_count(conn);
+       target_sess_cmd_list_set_waiting(sess->se_sess);
+       target_wait_for_sess_cmds(sess->se_sess);
 
        ahash_request_free(conn->conn_tx_hash);
        if (conn->conn_rx_hash) {
index e2fa3a3..b6bf605 100644 (file)
@@ -78,7 +78,7 @@ static int chap_check_algorithm(const char *a_str)
                if (!token)
                        goto out;
 
-               if (!strncmp(token, "5", 1)) {
+               if (!strcmp(token, "5")) {
                        pr_debug("Selected MD5 Algorithm\n");
                        kfree(orig);
                        return CHAP_DIGEST_MD5;
index dd8949e..f34520e 100644 (file)
@@ -2154,27 +2154,6 @@ static void atmel_set_termios(struct uart_port *port, struct ktermios *termios,
                mode |= ATMEL_US_USMODE_NORMAL;
        }
 
-       /* set the mode, clock divisor, parity, stop bits and data size */
-       atmel_uart_writel(port, ATMEL_US_MR, mode);
-
-       /*
-        * when switching the mode, set the RTS line state according to the
-        * new mode, otherwise keep the former state
-        */
-       if ((old_mode & ATMEL_US_USMODE) != (mode & ATMEL_US_USMODE)) {
-               unsigned int rts_state;
-
-               if ((mode & ATMEL_US_USMODE) == ATMEL_US_USMODE_HWHS) {
-                       /* let the hardware control the RTS line */
-                       rts_state = ATMEL_US_RTSDIS;
-               } else {
-                       /* force RTS line to low level */
-                       rts_state = ATMEL_US_RTSEN;
-               }
-
-               atmel_uart_writel(port, ATMEL_US_CR, rts_state);
-       }
-
        /*
         * Set the baud rate:
         * Fractional baudrate allows to setup output frequency more
@@ -2200,6 +2179,28 @@ static void atmel_set_termios(struct uart_port *port, struct ktermios *termios,
        quot = cd | fp << ATMEL_US_FP_OFFSET;
 
        atmel_uart_writel(port, ATMEL_US_BRGR, quot);
+
+       /* set the mode, clock divisor, parity, stop bits and data size */
+       atmel_uart_writel(port, ATMEL_US_MR, mode);
+
+       /*
+        * when switching the mode, set the RTS line state according to the
+        * new mode, otherwise keep the former state
+        */
+       if ((old_mode & ATMEL_US_USMODE) != (mode & ATMEL_US_USMODE)) {
+               unsigned int rts_state;
+
+               if ((mode & ATMEL_US_USMODE) == ATMEL_US_USMODE_HWHS) {
+                       /* let the hardware control the RTS line */
+                       rts_state = ATMEL_US_RTSDIS;
+               } else {
+                       /* force RTS line to low level */
+                       rts_state = ATMEL_US_RTSEN;
+               }
+
+               atmel_uart_writel(port, ATMEL_US_CR, rts_state);
+       }
+
        atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_RSTSTA | ATMEL_US_RSTRX);
        atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_TXEN | ATMEL_US_RXEN);
        atmel_port->tx_stopped = false;
index 2754b4c..60e292c 100644 (file)
@@ -2168,10 +2168,11 @@ resubmit:
 /*
  * Start the modem : init the data and start kernel thread
  */
-static int uea_boot(struct uea_softc *sc)
+static int uea_boot(struct uea_softc *sc, struct usb_interface *intf)
 {
-       int ret, size;
        struct intr_pkt *intr;
+       int ret = -ENOMEM;
+       int size;
 
        uea_enters(INS_TO_USBDEV(sc));
 
@@ -2196,6 +2197,11 @@ static int uea_boot(struct uea_softc *sc)
        if (UEA_CHIP_VERSION(sc) == ADI930)
                load_XILINX_firmware(sc);
 
+       if (intf->cur_altsetting->desc.bNumEndpoints < 1) {
+               ret = -ENODEV;
+               goto err0;
+       }
+
        intr = kmalloc(size, GFP_KERNEL);
        if (!intr)
                goto err0;
@@ -2207,8 +2213,7 @@ static int uea_boot(struct uea_softc *sc)
        usb_fill_int_urb(sc->urb_int, sc->usb_dev,
                         usb_rcvintpipe(sc->usb_dev, UEA_INTR_PIPE),
                         intr, size, uea_intr, sc,
-                        sc->usb_dev->actconfig->interface[0]->altsetting[0].
-                        endpoint[0].desc.bInterval);
+                        intf->cur_altsetting->endpoint[0].desc.bInterval);
 
        ret = usb_submit_urb(sc->urb_int, GFP_KERNEL);
        if (ret < 0) {
@@ -2223,6 +2228,7 @@ static int uea_boot(struct uea_softc *sc)
        sc->kthread = kthread_create(uea_kthread, sc, "ueagle-atm");
        if (IS_ERR(sc->kthread)) {
                uea_err(INS_TO_USBDEV(sc), "failed to create thread\n");
+               ret = PTR_ERR(sc->kthread);
                goto err2;
        }
 
@@ -2237,7 +2243,7 @@ err1:
        kfree(intr);
 err0:
        uea_leaves(INS_TO_USBDEV(sc));
-       return -ENOMEM;
+       return ret;
 }
 
 /*
@@ -2598,7 +2604,7 @@ static int uea_bind(struct usbatm_data *usbatm, struct usb_interface *intf,
        if (ret < 0)
                goto error;
 
-       ret = uea_boot(sc);
+       ret = uea_boot(sc, intf);
        if (ret < 0)
                goto error_rm_grp;
 
index 29c6414..0020482 100644 (file)
@@ -739,8 +739,15 @@ static int claimintf(struct usb_dev_state *ps, unsigned int ifnum)
        intf = usb_ifnum_to_if(dev, ifnum);
        if (!intf)
                err = -ENOENT;
-       else
+       else {
+               unsigned int old_suppress;
+
+               /* suppress uevents while claiming interface */
+               old_suppress = dev_get_uevent_suppress(&intf->dev);
+               dev_set_uevent_suppress(&intf->dev, 1);
                err = usb_driver_claim_interface(&usbfs_driver, intf, ps);
+               dev_set_uevent_suppress(&intf->dev, old_suppress);
+       }
        if (err == 0)
                set_bit(ifnum, &ps->ifclaimed);
        return err;
@@ -760,7 +767,13 @@ static int releaseintf(struct usb_dev_state *ps, unsigned int ifnum)
        if (!intf)
                err = -ENOENT;
        else if (test_and_clear_bit(ifnum, &ps->ifclaimed)) {
+               unsigned int old_suppress;
+
+               /* suppress uevents while releasing interface */
+               old_suppress = dev_get_uevent_suppress(&intf->dev);
+               dev_set_uevent_suppress(&intf->dev, 1);
                usb_driver_release_interface(&usbfs_driver, intf);
+               dev_set_uevent_suppress(&intf->dev, old_suppress);
                err = 0;
        }
        return err;
index 0efe1fa..5be3371 100644 (file)
@@ -5740,7 +5740,7 @@ re_enumerate_no_bos:
 
 /**
  * usb_reset_device - warn interface drivers and perform a USB port reset
- * @udev: device to reset (not in SUSPENDED or NOTATTACHED state)
+ * @udev: device to reset (not in NOTATTACHED state)
  *
  * Warns all drivers bound to registered interfaces (using their pre_reset
  * method), performs the port reset, and then lets the drivers know that
@@ -5768,8 +5768,7 @@ int usb_reset_device(struct usb_device *udev)
        struct usb_host_config *config = udev->actconfig;
        struct usb_hub *hub = usb_hub_to_struct_hub(udev->parent);
 
-       if (udev->state == USB_STATE_NOTATTACHED ||
-                       udev->state == USB_STATE_SUSPENDED) {
+       if (udev->state == USB_STATE_NOTATTACHED) {
                dev_dbg(&udev->dev, "device reset not allowed in state %d\n",
                                udev->state);
                return -EINVAL;
index f51750b..5e84409 100644 (file)
@@ -45,6 +45,7 @@ void usb_init_urb(struct urb *urb)
        if (urb) {
                memset(urb, 0, sizeof(*urb));
                kref_init(&urb->kref);
+               INIT_LIST_HEAD(&urb->urb_list);
                INIT_LIST_HEAD(&urb->anchor_list);
        }
 }
index b4e42d5..8fa39e6 100644 (file)
@@ -29,7 +29,8 @@
 #define PCI_DEVICE_ID_INTEL_BXT_M              0x1aaa
 #define PCI_DEVICE_ID_INTEL_APL                        0x5aaa
 #define PCI_DEVICE_ID_INTEL_KBP                        0xa2b0
-#define PCI_DEVICE_ID_INTEL_CMLH               0x02ee
+#define PCI_DEVICE_ID_INTEL_CMLLP              0x02ee
+#define PCI_DEVICE_ID_INTEL_CMLH               0x06ee
 #define PCI_DEVICE_ID_INTEL_GLK                        0x31aa
 #define PCI_DEVICE_ID_INTEL_CNPLP              0x9dee
 #define PCI_DEVICE_ID_INTEL_CNPH               0xa36e
@@ -306,6 +307,9 @@ static const struct pci_device_id dwc3_pci_id_table[] = {
        { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_MRFLD),
          (kernel_ulong_t) &dwc3_pci_mrfld_properties, },
 
+       { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_CMLLP),
+         (kernel_ulong_t) &dwc3_pci_intel_properties, },
+
        { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_CMLH),
          (kernel_ulong_t) &dwc3_pci_intel_properties, },
 
index 8efde17..2fb02f8 100644 (file)
@@ -1110,6 +1110,9 @@ static void dwc3_ep0_xfernotready(struct dwc3 *dwc,
 void dwc3_ep0_interrupt(struct dwc3 *dwc,
                const struct dwc3_event_depevt *event)
 {
+       struct dwc3_ep  *dep = dwc->eps[event->endpoint_number];
+       u8              cmd;
+
        switch (event->endpoint_event) {
        case DWC3_DEPEVT_XFERCOMPLETE:
                dwc3_ep0_xfer_complete(dwc, event);
@@ -1122,7 +1125,12 @@ void dwc3_ep0_interrupt(struct dwc3 *dwc,
        case DWC3_DEPEVT_XFERINPROGRESS:
        case DWC3_DEPEVT_RXTXFIFOEVT:
        case DWC3_DEPEVT_STREAMEVT:
+               break;
        case DWC3_DEPEVT_EPCMDCMPLT:
+               cmd = DEPEVT_PARAMETER_CMD(event->parameters);
+
+               if (cmd == DWC3_DEPCMD_ENDTRANSFER)
+                       dep->flags &= ~DWC3_EP_TRANSFER_STARTED;
                break;
        }
 }
index 3e04004..3a24230 100644 (file)
@@ -2295,7 +2295,7 @@ static int dwc3_gadget_ep_cleanup_completed_request(struct dwc3_ep *dep,
 
        req->request.actual = req->request.length - req->remaining;
 
-       if (!dwc3_gadget_ep_request_completed(req) &&
+       if (!dwc3_gadget_ep_request_completed(req) ||
                        req->num_pending_sgs) {
                __dwc3_gadget_kick_transfer(dep);
                goto out;
index 33852c2..ab9ac48 100644 (file)
@@ -1544,6 +1544,7 @@ static struct config_group *gadgets_make(
        gi->composite.resume = NULL;
        gi->composite.max_speed = USB_SPEED_SUPER;
 
+       spin_lock_init(&gi->spinlock);
        mutex_init(&gi->lock);
        INIT_LIST_HEAD(&gi->string_list);
        INIT_LIST_HEAD(&gi->available_func);
index afaea11..991184b 100644 (file)
@@ -1520,7 +1520,6 @@ static void pch_udc_free_dma_chain(struct pch_udc_dev *dev,
                td = phys_to_virt(addr);
                addr2 = (dma_addr_t)td->next;
                dma_pool_free(dev->data_requests, td, addr);
-               td->next = 0x00;
                addr = addr2;
        }
        req->chain_len = 1;
index 3276304..f643603 100644 (file)
 
 /*-------------------------------------------------------------------------*/
 
+/* PID Codes that are used here, from EHCI specification, Table 3-16. */
+#define PID_CODE_IN    1
+#define PID_CODE_SETUP 2
+
 /* fill a qtd, returning how much of the buffer we were able to queue up */
 
 static int
@@ -190,7 +194,7 @@ static int qtd_copy_status (
        int     status = -EINPROGRESS;
 
        /* count IN/OUT bytes, not SETUP (even short packets) */
-       if (likely (QTD_PID (token) != 2))
+       if (likely(QTD_PID(token) != PID_CODE_SETUP))
                urb->actual_length += length - QTD_LENGTH (token);
 
        /* don't modify error codes */
@@ -206,6 +210,13 @@ static int qtd_copy_status (
                if (token & QTD_STS_BABBLE) {
                        /* FIXME "must" disable babbling device's port too */
                        status = -EOVERFLOW;
+               /*
+                * When MMF is active and PID Code is IN, queue is halted.
+                * EHCI Specification, Table 4-13.
+                */
+               } else if ((token & QTD_STS_MMF) &&
+                                       (QTD_PID(token) == PID_CODE_IN)) {
+                       status = -EPROTO;
                /* CERR nonzero + halt --> stall */
                } else if (QTD_CERR(token)) {
                        status = -EPIPE;
index 333f920..8f180bf 100644 (file)
@@ -831,7 +831,7 @@ static u32 xhci_get_ext_port_status(u32 raw_port_status, u32 port_li)
 static u32 xhci_get_port_status(struct usb_hcd *hcd,
                struct xhci_bus_state *bus_state,
        u16 wIndex, u32 raw_port_status,
-               unsigned long flags)
+               unsigned long *flags)
        __releases(&xhci->lock)
        __acquires(&xhci->lock)
 {
@@ -868,6 +868,14 @@ static u32 xhci_get_port_status(struct usb_hcd *hcd,
                        status |= USB_PORT_STAT_C_BH_RESET << 16;
                if ((raw_port_status & PORT_CEC))
                        status |= USB_PORT_STAT_C_CONFIG_ERROR << 16;
+
+               /* USB3 remote wake resume signaling completed */
+               if (bus_state->port_remote_wakeup & (1 << wIndex) &&
+                   (raw_port_status & PORT_PLS_MASK) != XDEV_RESUME &&
+                   (raw_port_status & PORT_PLS_MASK) != XDEV_RECOVERY) {
+                       bus_state->port_remote_wakeup &= ~(1 << wIndex);
+                       usb_hcd_end_port_resume(&hcd->self, wIndex);
+               }
        }
 
        if (hcd->speed < HCD_USB3) {
@@ -917,12 +925,12 @@ static u32 xhci_get_port_status(struct usb_hcd *hcd,
                        xhci_test_and_clear_bit(xhci, port, PORT_PLC);
                        xhci_set_link_state(xhci, port, XDEV_U0);
 
-                       spin_unlock_irqrestore(&xhci->lock, flags);
+                       spin_unlock_irqrestore(&xhci->lock, *flags);
                        time_left = wait_for_completion_timeout(
                                        &bus_state->rexit_done[wIndex],
                                        msecs_to_jiffies(
                                                XHCI_MAX_REXIT_TIMEOUT_MS));
-                       spin_lock_irqsave(&xhci->lock, flags);
+                       spin_lock_irqsave(&xhci->lock, *flags);
 
                        if (time_left) {
                                slot_id = xhci_find_slot_id_by_port(hcd,
@@ -1076,7 +1084,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
                }
                trace_xhci_get_port_status(wIndex, temp);
                status = xhci_get_port_status(hcd, bus_state, wIndex, temp,
-                                             flags);
+                                             &flags);
                if (status == 0xffffffff)
                        goto error;
 
index 7e417b7..be1f9dd 100644 (file)
@@ -1909,13 +1909,17 @@ no_bw:
        xhci->usb3_rhub.num_ports = 0;
        xhci->num_active_eps = 0;
        kfree(xhci->usb2_rhub.ports);
+       kfree(xhci->usb2_rhub.psi);
        kfree(xhci->usb3_rhub.ports);
+       kfree(xhci->usb3_rhub.psi);
        kfree(xhci->hw_ports);
        kfree(xhci->rh_bw);
        kfree(xhci->ext_caps);
 
        xhci->usb2_rhub.ports = NULL;
+       xhci->usb2_rhub.psi = NULL;
        xhci->usb3_rhub.ports = NULL;
+       xhci->usb3_rhub.psi = NULL;
        xhci->hw_ports = NULL;
        xhci->rh_bw = NULL;
        xhci->ext_caps = NULL;
index 3348011..8d54c51 100644 (file)
@@ -499,6 +499,18 @@ static int xhci_pci_resume(struct usb_hcd *hcd, bool hibernated)
        retval = xhci_resume(xhci, hibernated);
        return retval;
 }
+
+static void xhci_pci_shutdown(struct usb_hcd *hcd)
+{
+       struct xhci_hcd         *xhci = hcd_to_xhci(hcd);
+       struct pci_dev          *pdev = to_pci_dev(hcd->self.controller);
+
+       xhci_shutdown(hcd);
+
+       /* Yet another workaround for spurious wakeups at shutdown with HSW */
+       if (xhci->quirks & XHCI_SPURIOUS_WAKEUP)
+               pci_set_power_state(pdev, PCI_D3hot);
+}
 #endif /* CONFIG_PM */
 
 /*-------------------------------------------------------------------------*/
@@ -536,6 +548,7 @@ static int __init xhci_pci_init(void)
 #ifdef CONFIG_PM
        xhci_pci_hc_driver.pci_suspend = xhci_pci_suspend;
        xhci_pci_hc_driver.pci_resume = xhci_pci_resume;
+       xhci_pci_hc_driver.shutdown = xhci_pci_shutdown;
 #endif
        return pci_register_driver(&xhci_pci_driver);
 }
index 014c6c2..bcf41da 100644 (file)
@@ -1633,7 +1633,6 @@ static void handle_port_status(struct xhci_hcd *xhci,
                slot_id = xhci_find_slot_id_by_port(hcd, xhci, hcd_portnum + 1);
                if (slot_id && xhci->devs[slot_id])
                        xhci->devs[slot_id]->flags |= VDEV_PORT_ERROR;
-               bus_state->port_remote_wakeup &= ~(1 << hcd_portnum);
        }
 
        if ((portsc & PORT_PLC) && (portsc & PORT_PLS_MASK) == XDEV_RESUME) {
@@ -1654,6 +1653,7 @@ static void handle_port_status(struct xhci_hcd *xhci,
                        bus_state->port_remote_wakeup |= 1 << hcd_portnum;
                        xhci_test_and_clear_bit(xhci, port, PORT_PLC);
                        xhci_set_link_state(xhci, port, XDEV_U0);
+                       usb_hcd_start_port_resume(&hcd->self, hcd_portnum);
                        /* Need to wait until the next link state change
                         * indicates the device is actually in U0.
                         */
@@ -1693,7 +1693,6 @@ static void handle_port_status(struct xhci_hcd *xhci,
                if (slot_id && xhci->devs[slot_id])
                        xhci_ring_device(xhci, slot_id);
                if (bus_state->port_remote_wakeup & (1 << hcd_portnum)) {
-                       bus_state->port_remote_wakeup &= ~(1 << hcd_portnum);
                        xhci_test_and_clear_bit(xhci, port, PORT_PLC);
                        usb_wakeup_notification(hcd->self.root_hub,
                                        hcd_portnum + 1);
@@ -2354,7 +2353,8 @@ static int handle_tx_event(struct xhci_hcd *xhci,
        case COMP_SUCCESS:
                if (EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)) == 0)
                        break;
-               if (xhci->quirks & XHCI_TRUST_TX_LENGTH)
+               if (xhci->quirks & XHCI_TRUST_TX_LENGTH ||
+                   ep_ring->last_td_was_short)
                        trb_comp_code = COMP_SHORT_PACKET;
                else
                        xhci_warn_ratelimited(xhci,
index b72c33e..5452c80 100644 (file)
@@ -770,7 +770,7 @@ static void xhci_stop(struct usb_hcd *hcd)
  *
  * This will only ever be called with the main usb_hcd (the USB3 roothub).
  */
-static void xhci_shutdown(struct usb_hcd *hcd)
+void xhci_shutdown(struct usb_hcd *hcd)
 {
        struct xhci_hcd *xhci = hcd_to_xhci(hcd);
 
@@ -789,11 +789,8 @@ static void xhci_shutdown(struct usb_hcd *hcd)
        xhci_dbg_trace(xhci, trace_xhci_dbg_init,
                        "xhci_shutdown completed - status = %x",
                        readl(&xhci->op_regs->status));
-
-       /* Yet another workaround for spurious wakeups at shutdown with HSW */
-       if (xhci->quirks & XHCI_SPURIOUS_WAKEUP)
-               pci_set_power_state(to_pci_dev(hcd->self.sysdev), PCI_D3hot);
 }
+EXPORT_SYMBOL_GPL(xhci_shutdown);
 
 #ifdef CONFIG_PM
 static void xhci_save_registers(struct xhci_hcd *xhci)
@@ -964,7 +961,7 @@ static bool xhci_pending_portevent(struct xhci_hcd *xhci)
 int xhci_suspend(struct xhci_hcd *xhci, bool do_wakeup)
 {
        int                     rc = 0;
-       unsigned int            delay = XHCI_MAX_HALT_USEC;
+       unsigned int            delay = XHCI_MAX_HALT_USEC * 2;
        struct usb_hcd          *hcd = xhci_to_hcd(xhci);
        u32                     command;
        u32                     res;
index ec515c5..0878a0f 100644 (file)
@@ -2053,6 +2053,7 @@ int xhci_start(struct xhci_hcd *xhci);
 int xhci_reset(struct xhci_hcd *xhci);
 int xhci_run(struct usb_hcd *hcd);
 int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks);
+void xhci_shutdown(struct usb_hcd *hcd);
 void xhci_init_driver(struct hc_driver *drv,
                      const struct xhci_driver_overrides *over);
 int xhci_disable_slot(struct xhci_hcd *xhci, u32 slot_id);
index 9a51760..b8073f3 100644 (file)
@@ -671,7 +671,7 @@ static int adu_probe(struct usb_interface *interface,
        init_waitqueue_head(&dev->read_wait);
        init_waitqueue_head(&dev->write_wait);
 
-       res = usb_find_common_endpoints_reverse(&interface->altsetting[0],
+       res = usb_find_common_endpoints_reverse(interface->cur_altsetting,
                        NULL, NULL,
                        &dev->interrupt_in_endpoint,
                        &dev->interrupt_out_endpoint);
index 20b0f91..bb24527 100644 (file)
@@ -337,7 +337,7 @@ static int idmouse_probe(struct usb_interface *interface,
        int result;
 
        /* check if we have gotten the data or the hid interface */
-       iface_desc = &interface->altsetting[0];
+       iface_desc = interface->cur_altsetting;
        if (iface_desc->desc.bInterfaceClass != 0x0A)
                return -ENODEV;
 
index ac2b4fc..f48a23a 100644 (file)
@@ -1039,12 +1039,18 @@ static long mon_bin_ioctl(struct file *file, unsigned int cmd, unsigned long arg
 
                mutex_lock(&rp->fetch_lock);
                spin_lock_irqsave(&rp->b_lock, flags);
-               mon_free_buff(rp->b_vec, rp->b_size/CHUNK_SIZE);
-               kfree(rp->b_vec);
-               rp->b_vec  = vec;
-               rp->b_size = size;
-               rp->b_read = rp->b_in = rp->b_out = rp->b_cnt = 0;
-               rp->cnt_lost = 0;
+               if (rp->mmap_active) {
+                       mon_free_buff(vec, size/CHUNK_SIZE);
+                       kfree(vec);
+                       ret = -EBUSY;
+               } else {
+                       mon_free_buff(rp->b_vec, rp->b_size/CHUNK_SIZE);
+                       kfree(rp->b_vec);
+                       rp->b_vec  = vec;
+                       rp->b_size = size;
+                       rp->b_read = rp->b_in = rp->b_out = rp->b_cnt = 0;
+                       rp->cnt_lost = 0;
+               }
                spin_unlock_irqrestore(&rp->b_lock, flags);
                mutex_unlock(&rp->fetch_lock);
                }
@@ -1216,13 +1222,21 @@ mon_bin_poll(struct file *file, struct poll_table_struct *wait)
 static void mon_bin_vma_open(struct vm_area_struct *vma)
 {
        struct mon_reader_bin *rp = vma->vm_private_data;
+       unsigned long flags;
+
+       spin_lock_irqsave(&rp->b_lock, flags);
        rp->mmap_active++;
+       spin_unlock_irqrestore(&rp->b_lock, flags);
 }
 
 static void mon_bin_vma_close(struct vm_area_struct *vma)
 {
+       unsigned long flags;
+
        struct mon_reader_bin *rp = vma->vm_private_data;
+       spin_lock_irqsave(&rp->b_lock, flags);
        rp->mmap_active--;
+       spin_unlock_irqrestore(&rp->b_lock, flags);
 }
 
 /*
@@ -1234,16 +1248,12 @@ static vm_fault_t mon_bin_vma_fault(struct vm_fault *vmf)
        unsigned long offset, chunk_idx;
        struct page *pageptr;
 
-       mutex_lock(&rp->fetch_lock);
        offset = vmf->pgoff << PAGE_SHIFT;
-       if (offset >= rp->b_size) {
-               mutex_unlock(&rp->fetch_lock);
+       if (offset >= rp->b_size)
                return VM_FAULT_SIGBUS;
-       }
        chunk_idx = offset / CHUNK_SIZE;
        pageptr = rp->b_vec[chunk_idx].pg;
        get_page(pageptr);
-       mutex_unlock(&rp->fetch_lock);
        vmf->page = pageptr;
        return 0;
 }
index c47b721..63a75fd 100644 (file)
@@ -157,11 +157,12 @@ struct usbhs_priv;
 #define VBSTS  (1 << 7)        /* VBUS_0 and VBUSIN_0 Input Status */
 #define VALID  (1 << 3)        /* USB Request Receive */
 
-#define DVSQ_MASK              (0x3 << 4)      /* Device State */
+#define DVSQ_MASK              (0x7 << 4)      /* Device State */
 #define  POWER_STATE           (0 << 4)
 #define  DEFAULT_STATE         (1 << 4)
 #define  ADDRESS_STATE         (2 << 4)
 #define  CONFIGURATION_STATE   (3 << 4)
+#define  SUSPENDED_STATE       (4 << 4)
 
 #define CTSQ_MASK              (0x7)   /* Control Transfer Stage */
 #define  IDLE_SETUP_STAGE      0       /* Idle stage or setup stage */
index 7feac41..f36248e 100644 (file)
@@ -456,12 +456,18 @@ static int usbhsg_irq_dev_state(struct usbhs_priv *priv,
 {
        struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv);
        struct device *dev = usbhsg_gpriv_to_dev(gpriv);
+       int state = usbhs_status_get_device_state(irq_state);
 
        gpriv->gadget.speed = usbhs_bus_get_speed(priv);
 
-       dev_dbg(dev, "state = %x : speed : %d\n",
-               usbhs_status_get_device_state(irq_state),
-               gpriv->gadget.speed);
+       dev_dbg(dev, "state = %x : speed : %d\n", state, gpriv->gadget.speed);
+
+       if (gpriv->gadget.speed != USB_SPEED_UNKNOWN &&
+           (state & SUSPENDED_STATE)) {
+               if (gpriv->driver && gpriv->driver->suspend)
+                       gpriv->driver->suspend(&gpriv->gadget);
+               usb_gadget_set_state(&gpriv->gadget, USB_STATE_SUSPENDED);
+       }
 
        return 0;
 }
index 99116af..1dd492e 100644 (file)
@@ -130,8 +130,8 @@ EXPORT_SYMBOL_GPL(usb_role_switch_get);
 void usb_role_switch_put(struct usb_role_switch *sw)
 {
        if (!IS_ERR_OR_NULL(sw)) {
-               put_device(&sw->dev);
                module_put(sw->dev.parent->driver->owner);
+               put_device(&sw->dev);
        }
 }
 EXPORT_SYMBOL_GPL(usb_role_switch_put);
index 97c69d3..97eb738 100644 (file)
@@ -2919,16 +2919,18 @@ static int edge_startup(struct usb_serial *serial)
        response = 0;
 
        if (edge_serial->is_epic) {
+               struct usb_host_interface *alt;
+
+               alt = serial->interface->cur_altsetting;
+
                /* EPIC thing, set up our interrupt polling now and our read
                 * urb, so that the device knows it really is connected. */
                interrupt_in_found = bulk_in_found = bulk_out_found = false;
-               for (i = 0; i < serial->interface->altsetting[0]
-                                               .desc.bNumEndpoints; ++i) {
+               for (i = 0; i < alt->desc.bNumEndpoints; ++i) {
                        struct usb_endpoint_descriptor *endpoint;
                        int buffer_size;
 
-                       endpoint = &serial->interface->altsetting[0].
-                                                       endpoint[i].desc;
+                       endpoint = &alt->endpoint[i].desc;
                        buffer_size = usb_endpoint_maxp(endpoint);
                        if (!interrupt_in_found &&
                            (usb_endpoint_is_int_in(endpoint))) {
index bad391d..1c6eb3a 100644 (file)
@@ -832,6 +832,10 @@ static int uas_slave_configure(struct scsi_device *sdev)
                sdev->wce_default_on = 1;
        }
 
+       /* Some disks cannot handle READ_CAPACITY_16 */
+       if (devinfo->flags & US_FL_NO_READ_CAPACITY_16)
+               sdev->no_read_capacity_16 = 1;
+
        /*
         * Some disks return the total number of blocks in response
         * to READ CAPACITY rather than the highest block number.
@@ -841,6 +845,12 @@ static int uas_slave_configure(struct scsi_device *sdev)
                sdev->fix_capacity = 1;
 
        /*
+        * in some cases we have to guess
+        */
+       if (devinfo->flags & US_FL_CAPACITY_HEURISTICS)
+               sdev->guess_capacity = 1;
+
+       /*
         * Some devices don't like MODE SENSE with page=0x3f,
         * which is the command used for checking if a device
         * is write-protected.  Now that we tell the sd driver
index 00141e0..1916ee1 100644 (file)
@@ -1589,14 +1589,16 @@ struct typec_port *typec_register_port(struct device *parent,
 
        port->sw = typec_switch_get(&port->dev);
        if (IS_ERR(port->sw)) {
+               ret = PTR_ERR(port->sw);
                put_device(&port->dev);
-               return ERR_CAST(port->sw);
+               return ERR_PTR(ret);
        }
 
        port->mux = typec_mux_get(&port->dev, "typec-mux");
        if (IS_ERR(port->mux)) {
+               ret = PTR_ERR(port->mux);
                put_device(&port->dev);
-               return ERR_CAST(port->mux);
+               return ERR_PTR(ret);
        }
 
        ret = device_add(&port->dev);
index d88a5b1..88eaf3c 100644 (file)
@@ -727,6 +727,9 @@ int usbip_recv_xbuff(struct usbip_device *ud, struct urb *urb)
 
                        copy -= recv;
                        ret += recv;
+
+                       if (!copy)
+                               break;
                }
 
                if (ret != size)
index 33f8972..00fc987 100644 (file)
@@ -77,16 +77,21 @@ static void vhci_recv_ret_submit(struct vhci_device *vdev,
        usbip_pack_pdu(pdu, urb, USBIP_RET_SUBMIT, 0);
 
        /* recv transfer buffer */
-       if (usbip_recv_xbuff(ud, urb) < 0)
-               return;
+       if (usbip_recv_xbuff(ud, urb) < 0) {
+               urb->status = -EPROTO;
+               goto error;
+       }
 
        /* recv iso_packet_descriptor */
-       if (usbip_recv_iso(ud, urb) < 0)
-               return;
+       if (usbip_recv_iso(ud, urb) < 0) {
+               urb->status = -EPROTO;
+               goto error;
+       }
 
        /* restore the padding in iso packets */
        usbip_pad_iso(ud, urb);
 
+error:
        if (usbip_dbg_flag_vhci_rx)
                usbip_dump_urb(urb);
 
index 1c46045..94594dc 100644 (file)
@@ -297,8 +297,8 @@ static int vfio_msi_set_vector_signal(struct vfio_pci_device *vdev,
        irq = pci_irq_vector(pdev, vector);
 
        if (vdev->ctx[vector].trigger) {
-               free_irq(irq, vdev->ctx[vector].trigger);
                irq_bypass_unregister_producer(&vdev->ctx[vector].producer);
+               free_irq(irq, vdev->ctx[vector].trigger);
                kfree(vdev->ctx[vector].name);
                eventfd_ctx_put(vdev->ctx[vector].trigger);
                vdev->ctx[vector].trigger = NULL;
index 8dcee4f..5f5c5de 100644 (file)
@@ -436,7 +436,9 @@ static void vhost_vsock_handle_tx_kick(struct vhost_work *work)
                virtio_transport_deliver_tap_pkt(pkt);
 
                /* Only accept correctly addressed packets */
-               if (le64_to_cpu(pkt->hdr.src_cid) == vsock->guest_cid)
+               if (le64_to_cpu(pkt->hdr.src_cid) == vsock->guest_cid &&
+                   le64_to_cpu(pkt->hdr.dst_cid) ==
+                   vhost_transport_get_local_cid())
                        virtio_transport_recv_pkt(pkt);
                else
                        virtio_transport_free_pkt(pkt);
index 8a3e8f6..164564b 100644 (file)
@@ -1039,12 +1039,12 @@ static int hdmi_avi_infoframe_unpack(struct hdmi_avi_infoframe *frame,
        if (ptr[0] & 0x10)
                frame->active_aspect = ptr[1] & 0xf;
        if (ptr[0] & 0x8) {
-               frame->top_bar = (ptr[5] << 8) + ptr[6];
-               frame->bottom_bar = (ptr[7] << 8) + ptr[8];
+               frame->top_bar = (ptr[6] << 8) | ptr[5];
+               frame->bottom_bar = (ptr[8] << 8) | ptr[7];
        }
        if (ptr[0] & 0x4) {
-               frame->left_bar = (ptr[9] << 8) + ptr[10];
-               frame->right_bar = (ptr[11] << 8) + ptr[12];
+               frame->left_bar = (ptr[10] << 8) | ptr[9];
+               frame->right_bar = (ptr[12] << 8) | ptr[11];
        }
        frame->scan_mode = ptr[0] & 0x3;
 
index d1c1f62..14ac36c 100644 (file)
@@ -468,6 +468,17 @@ static int virtballoon_migratepage(struct balloon_dev_info *vb_dev_info,
 
        get_page(newpage); /* balloon reference */
 
+       /*
+         * When we migrate a page to a different zone and adjusted the
+         * managed page count when inflating, we have to fixup the count of
+         * both involved zones.
+         */
+       if (!virtio_has_feature(vb->vdev, VIRTIO_BALLOON_F_DEFLATE_ON_OOM) &&
+           page_zone(page) != page_zone(newpage)) {
+               adjust_managed_page_count(page, 1);
+               adjust_managed_page_count(newpage, -1);
+       }
+
        /* balloon's page migration 1st step  -- inflate "newpage" */
        spin_lock_irqsave(&vb_dev_info->pages_lock, flags);
        balloon_page_insert(vb_dev_info, newpage);
index f6c24b2..4b89333 100644 (file)
@@ -38,7 +38,6 @@
 #include <linux/init.h>                /* For __init/__exit/... */
 #include <linux/hrtimer.h>     /* For hrtimers */
 #include <linux/kernel.h>      /* For printk/panic/... */
-#include <linux/kref.h>                /* For data references */
 #include <linux/kthread.h>     /* For kthread_work */
 #include <linux/miscdevice.h>  /* For handling misc devices */
 #include <linux/module.h>      /* For module stuff/... */
 
 /*
  * struct watchdog_core_data - watchdog core internal data
- * @kref:      Reference count.
+ * @dev:       The watchdog's internal device
  * @cdev:      The watchdog's Character device.
  * @wdd:       Pointer to watchdog device.
  * @lock:      Lock for watchdog core.
  * @status:    Watchdog core internal status bits.
  */
 struct watchdog_core_data {
-       struct kref kref;
+       struct device dev;
        struct cdev cdev;
        struct watchdog_device *wdd;
        struct mutex lock;
@@ -822,7 +821,7 @@ static int watchdog_open(struct inode *inode, struct file *file)
        file->private_data = wd_data;
 
        if (!hw_running)
-               kref_get(&wd_data->kref);
+               get_device(&wd_data->dev);
 
        /* dev/watchdog is a virtual (and thus non-seekable) filesystem */
        return nonseekable_open(inode, file);
@@ -834,11 +833,11 @@ out_clear:
        return err;
 }
 
-static void watchdog_core_data_release(struct kref *kref)
+static void watchdog_core_data_release(struct device *dev)
 {
        struct watchdog_core_data *wd_data;
 
-       wd_data = container_of(kref, struct watchdog_core_data, kref);
+       wd_data = container_of(dev, struct watchdog_core_data, dev);
 
        kfree(wd_data);
 }
@@ -898,7 +897,7 @@ done:
         */
        if (!running) {
                module_put(wd_data->cdev.owner);
-               kref_put(&wd_data->kref, watchdog_core_data_release);
+               put_device(&wd_data->dev);
        }
        return 0;
 }
@@ -917,17 +916,22 @@ static struct miscdevice watchdog_miscdev = {
        .fops           = &watchdog_fops,
 };
 
+static struct class watchdog_class = {
+       .name =         "watchdog",
+       .owner =        THIS_MODULE,
+       .dev_groups =   wdt_groups,
+};
+
 /*
  *     watchdog_cdev_register: register watchdog character device
  *     @wdd: watchdog device
- *     @devno: character device number
  *
  *     Register a watchdog character device including handling the legacy
  *     /dev/watchdog node. /dev/watchdog is actually a miscdevice and
  *     thus we set it up like that.
  */
 
-static int watchdog_cdev_register(struct watchdog_device *wdd, dev_t devno)
+static int watchdog_cdev_register(struct watchdog_device *wdd)
 {
        struct watchdog_core_data *wd_data;
        int err;
@@ -935,7 +939,6 @@ static int watchdog_cdev_register(struct watchdog_device *wdd, dev_t devno)
        wd_data = kzalloc(sizeof(struct watchdog_core_data), GFP_KERNEL);
        if (!wd_data)
                return -ENOMEM;
-       kref_init(&wd_data->kref);
        mutex_init(&wd_data->lock);
 
        wd_data->wdd = wdd;
@@ -964,23 +967,33 @@ static int watchdog_cdev_register(struct watchdog_device *wdd, dev_t devno)
                }
        }
 
+       device_initialize(&wd_data->dev);
+       wd_data->dev.devt = MKDEV(MAJOR(watchdog_devt), wdd->id);
+       wd_data->dev.class = &watchdog_class;
+       wd_data->dev.parent = wdd->parent;
+       wd_data->dev.groups = wdd->groups;
+       wd_data->dev.release = watchdog_core_data_release;
+       dev_set_drvdata(&wd_data->dev, wdd);
+       dev_set_name(&wd_data->dev, "watchdog%d", wdd->id);
+
        /* Fill in the data structures */
        cdev_init(&wd_data->cdev, &watchdog_fops);
-       wd_data->cdev.owner = wdd->ops->owner;
 
        /* Add the device */
-       err = cdev_add(&wd_data->cdev, devno, 1);
+       err = cdev_device_add(&wd_data->cdev, &wd_data->dev);
        if (err) {
                pr_err("watchdog%d unable to add device %d:%d\n",
                        wdd->id,  MAJOR(watchdog_devt), wdd->id);
                if (wdd->id == 0) {
                        misc_deregister(&watchdog_miscdev);
                        old_wd_data = NULL;
-                       kref_put(&wd_data->kref, watchdog_core_data_release);
+                       put_device(&wd_data->dev);
                }
                return err;
        }
 
+       wd_data->cdev.owner = wdd->ops->owner;
+
        /* Record time of most recent heartbeat as 'just before now'. */
        wd_data->last_hw_keepalive = ktime_sub(ktime_get(), 1);
 
@@ -990,7 +1003,7 @@ static int watchdog_cdev_register(struct watchdog_device *wdd, dev_t devno)
         */
        if (watchdog_hw_running(wdd)) {
                __module_get(wdd->ops->owner);
-               kref_get(&wd_data->kref);
+               get_device(&wd_data->dev);
                if (handle_boot_enabled)
                        hrtimer_start(&wd_data->timer, 0, HRTIMER_MODE_REL);
                else
@@ -1013,7 +1026,7 @@ static void watchdog_cdev_unregister(struct watchdog_device *wdd)
 {
        struct watchdog_core_data *wd_data = wdd->wd_data;
 
-       cdev_del(&wd_data->cdev);
+       cdev_device_del(&wd_data->cdev, &wd_data->dev);
        if (wdd->id == 0) {
                misc_deregister(&watchdog_miscdev);
                old_wd_data = NULL;
@@ -1032,15 +1045,9 @@ static void watchdog_cdev_unregister(struct watchdog_device *wdd)
        hrtimer_cancel(&wd_data->timer);
        kthread_cancel_work_sync(&wd_data->work);
 
-       kref_put(&wd_data->kref, watchdog_core_data_release);
+       put_device(&wd_data->dev);
 }
 
-static struct class watchdog_class = {
-       .name =         "watchdog",
-       .owner =        THIS_MODULE,
-       .dev_groups =   wdt_groups,
-};
-
 static int watchdog_reboot_notifier(struct notifier_block *nb,
                                    unsigned long code, void *data)
 {
@@ -1071,27 +1078,14 @@ static int watchdog_reboot_notifier(struct notifier_block *nb,
 
 int watchdog_dev_register(struct watchdog_device *wdd)
 {
-       struct device *dev;
-       dev_t devno;
        int ret;
 
-       devno = MKDEV(MAJOR(watchdog_devt), wdd->id);
-
-       ret = watchdog_cdev_register(wdd, devno);
+       ret = watchdog_cdev_register(wdd);
        if (ret)
                return ret;
 
-       dev = device_create_with_groups(&watchdog_class, wdd->parent,
-                                       devno, wdd, wdd->groups,
-                                       "watchdog%d", wdd->id);
-       if (IS_ERR(dev)) {
-               watchdog_cdev_unregister(wdd);
-               return PTR_ERR(dev);
-       }
-
        ret = watchdog_register_pretimeout(wdd);
        if (ret) {
-               device_destroy(&watchdog_class, devno);
                watchdog_cdev_unregister(wdd);
                return ret;
        }
@@ -1099,7 +1093,8 @@ int watchdog_dev_register(struct watchdog_device *wdd)
        if (test_bit(WDOG_STOP_ON_REBOOT, &wdd->status)) {
                wdd->reboot_nb.notifier_call = watchdog_reboot_notifier;
 
-               ret = devm_register_reboot_notifier(dev, &wdd->reboot_nb);
+               ret = devm_register_reboot_notifier(&wdd->wd_data->dev,
+                                                   &wdd->reboot_nb);
                if (ret) {
                        pr_err("watchdog%d: Cannot register reboot notifier (%d)\n",
                               wdd->id, ret);
@@ -1121,7 +1116,6 @@ int watchdog_dev_register(struct watchdog_device *wdd)
 void watchdog_dev_unregister(struct watchdog_device *wdd)
 {
        watchdog_unregister_pretimeout(wdd);
-       device_destroy(&watchdog_class, wdd->wd_data->cdev.dev);
        watchdog_cdev_unregister(wdd);
 }
 
index 90d387b..0505eeb 100644 (file)
@@ -158,7 +158,8 @@ config XEN_GNTDEV
 
 config XEN_GNTDEV_DMABUF
        bool "Add support for dma-buf grant access device driver extension"
-       depends on XEN_GNTDEV && XEN_GRANT_DMA_ALLOC && DMA_SHARED_BUFFER
+       depends on XEN_GNTDEV && XEN_GRANT_DMA_ALLOC
+       select DMA_SHARED_BUFFER
        help
          Allows userspace processes and kernel modules to use Xen backed
          dma-buf implementation. With this extension grant references to
index 3a144ee..d7438fd 100644 (file)
@@ -504,8 +504,10 @@ static int __write_ring(struct pvcalls_data_intf *intf,
        virt_mb();
 
        size = pvcalls_queued(prod, cons, array_size);
-       if (size >= array_size)
+       if (size > array_size)
                return -EINVAL;
+       if (size == array_size)
+               return 0;
        if (len > array_size - size)
                len = array_size - size;
 
index d522494..02e4e90 100644 (file)
@@ -252,16 +252,17 @@ out:
        }
 }
 
-static void run_ordered_work(struct __btrfs_workqueue *wq)
+static void run_ordered_work(struct __btrfs_workqueue *wq,
+                            struct btrfs_work *self)
 {
        struct list_head *list = &wq->ordered_list;
        struct btrfs_work *work;
        spinlock_t *lock = &wq->list_lock;
        unsigned long flags;
+       void *wtag;
+       bool free_self = false;
 
        while (1) {
-               void *wtag;
-
                spin_lock_irqsave(lock, flags);
                if (list_empty(list))
                        break;
@@ -287,16 +288,47 @@ static void run_ordered_work(struct __btrfs_workqueue *wq)
                list_del(&work->ordered_list);
                spin_unlock_irqrestore(lock, flags);
 
-               /*
-                * We don't want to call the ordered free functions with the
-                * lock held though. Save the work as tag for the trace event,
-                * because the callback could free the structure.
-                */
-               wtag = work;
-               work->ordered_free(work);
-               trace_btrfs_all_work_done(wq->fs_info, wtag);
+               if (work == self) {
+                       /*
+                        * This is the work item that the worker is currently
+                        * executing.
+                        *
+                        * The kernel workqueue code guarantees non-reentrancy
+                        * of work items. I.e., if a work item with the same
+                        * address and work function is queued twice, the second
+                        * execution is blocked until the first one finishes. A
+                        * work item may be freed and recycled with the same
+                        * work function; the workqueue code assumes that the
+                        * original work item cannot depend on the recycled work
+                        * item in that case (see find_worker_executing_work()).
+                        *
+                        * Note that the work of one Btrfs filesystem may depend
+                        * on the work of another Btrfs filesystem via, e.g., a
+                        * loop device. Therefore, we must not allow the current
+                        * work item to be recycled until we are really done,
+                        * otherwise we break the above assumption and can
+                        * deadlock.
+                        */
+                       free_self = true;
+               } else {
+                       /*
+                        * We don't want to call the ordered free functions with
+                        * the lock held though. Save the work as tag for the
+                        * trace event, because the callback could free the
+                        * structure.
+                        */
+                       wtag = work;
+                       work->ordered_free(work);
+                       trace_btrfs_all_work_done(wq->fs_info, wtag);
+               }
        }
        spin_unlock_irqrestore(lock, flags);
+
+       if (free_self) {
+               wtag = self;
+               self->ordered_free(self);
+               trace_btrfs_all_work_done(wq->fs_info, wtag);
+       }
 }
 
 static void normal_work_helper(struct btrfs_work *work)
@@ -324,7 +356,7 @@ static void normal_work_helper(struct btrfs_work *work)
        work->func(work);
        if (need_order) {
                set_bit(WORK_DONE_BIT, &work->flags);
-               run_ordered_work(wq);
+               run_ordered_work(wq, work);
        }
        if (!need_order)
                trace_btrfs_all_work_done(wq->fs_info, wtag);
index fc764f3..84ff398 100644 (file)
@@ -390,7 +390,7 @@ void btrfs_put_tree_mod_seq(struct btrfs_fs_info *fs_info,
        for (node = rb_first(tm_root); node; node = next) {
                next = rb_next(node);
                tm = rb_entry(node, struct tree_mod_elem, node);
-               if (tm->seq > min_seq)
+               if (tm->seq >= min_seq)
                        continue;
                rb_erase(node, tm_root);
                kfree(tm);
index cc2d268..d24ecbf 100644 (file)
@@ -3101,7 +3101,7 @@ int btrfs_find_name_in_ext_backref(struct extent_buffer *leaf, int slot,
 /* file-item.c */
 struct btrfs_dio_private;
 int btrfs_del_csums(struct btrfs_trans_handle *trans,
-                   struct btrfs_fs_info *fs_info, u64 bytenr, u64 len);
+                   struct btrfs_root *root, u64 bytenr, u64 len);
 blk_status_t btrfs_lookup_bio_sums(struct inode *inode, struct bio *bio, u32 *dst);
 blk_status_t btrfs_lookup_bio_sums_dio(struct inode *inode, struct bio *bio,
                              u64 logical_offset);
index f51b509..e9522f2 100644 (file)
@@ -1939,12 +1939,19 @@ void btrfs_kill_all_delayed_nodes(struct btrfs_root *root)
                }
 
                inode_id = delayed_nodes[n - 1]->inode_id + 1;
-
-               for (i = 0; i < n; i++)
-                       refcount_inc(&delayed_nodes[i]->refs);
+               for (i = 0; i < n; i++) {
+                       /*
+                        * Don't increase refs in case the node is dead and
+                        * about to be removed from the tree in the loop below
+                        */
+                       if (!refcount_inc_not_zero(&delayed_nodes[i]->refs))
+                               delayed_nodes[i] = NULL;
+               }
                spin_unlock(&root->inode_lock);
 
                for (i = 0; i < n; i++) {
+                       if (!delayed_nodes[i])
+                               continue;
                        __btrfs_kill_delayed_node(delayed_nodes[i]);
                        btrfs_release_delayed_node(delayed_nodes[i]);
                }
index 96296dc..e12c37f 100644 (file)
@@ -1660,8 +1660,8 @@ static void end_workqueue_fn(struct btrfs_work *work)
        bio->bi_status = end_io_wq->status;
        bio->bi_private = end_io_wq->private;
        bio->bi_end_io = end_io_wq->end_io;
-       kmem_cache_free(btrfs_end_io_wq_cache, end_io_wq);
        bio_endio(bio);
+       kmem_cache_free(btrfs_end_io_wq_cache, end_io_wq);
 }
 
 static int cleaner_kthread(void *arg)
index 4bda5c0..47ca1eb 100644 (file)
@@ -2492,8 +2492,8 @@ static int cleanup_ref_head(struct btrfs_trans_handle *trans,
                btrfs_pin_extent(fs_info, head->bytenr,
                                 head->num_bytes, 1);
                if (head->is_data) {
-                       ret = btrfs_del_csums(trans, fs_info, head->bytenr,
-                                             head->num_bytes);
+                       ret = btrfs_del_csums(trans, fs_info->csum_root,
+                                             head->bytenr, head->num_bytes);
                }
        }
 
@@ -6880,7 +6880,8 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans,
                btrfs_release_path(path);
 
                if (is_data) {
-                       ret = btrfs_del_csums(trans, info, bytenr, num_bytes);
+                       ret = btrfs_del_csums(trans, info->csum_root, bytenr,
+                                             num_bytes);
                        if (ret) {
                                btrfs_abort_transaction(trans, ret);
                                goto out;
index cb598eb..fed4439 100644 (file)
@@ -3956,7 +3956,7 @@ retry:
                for (i = 0; i < nr_pages; i++) {
                        struct page *page = pvec.pages[i];
 
-                       done_index = page->index;
+                       done_index = page->index + 1;
                        /*
                         * At this point we hold neither the i_pages lock nor
                         * the page lock: the page may be truncated or
@@ -3993,16 +3993,6 @@ retry:
                                ret = 0;
                        }
                        if (ret < 0) {
-                               /*
-                                * done_index is set past this page,
-                                * so media errors will not choke
-                                * background writeout for the entire
-                                * file. This has consequences for
-                                * range_cyclic semantics (ie. it may
-                                * not be suitable for data integrity
-                                * writeout).
-                                */
-                               done_index = page->index + 1;
                                done = 1;
                                break;
                        }
@@ -4898,12 +4888,14 @@ struct extent_buffer *alloc_test_extent_buffer(struct btrfs_fs_info *fs_info,
                return eb;
        eb = alloc_dummy_extent_buffer(fs_info, start);
        if (!eb)
-               return NULL;
+               return ERR_PTR(-ENOMEM);
        eb->fs_info = fs_info;
 again:
        ret = radix_tree_preload(GFP_NOFS);
-       if (ret)
+       if (ret) {
+               exists = ERR_PTR(ret);
                goto free_eb;
+       }
        spin_lock(&fs_info->buffer_lock);
        ret = radix_tree_insert(&fs_info->buffer_radix,
                                start >> PAGE_SHIFT, eb);
index ba74827..4cf2817 100644 (file)
@@ -577,9 +577,9 @@ static noinline void truncate_one_csum(struct btrfs_fs_info *fs_info,
  * range of bytes.
  */
 int btrfs_del_csums(struct btrfs_trans_handle *trans,
-                   struct btrfs_fs_info *fs_info, u64 bytenr, u64 len)
+                   struct btrfs_root *root, u64 bytenr, u64 len)
 {
-       struct btrfs_root *root = fs_info->csum_root;
+       struct btrfs_fs_info *fs_info = trans->fs_info;
        struct btrfs_path *path;
        struct btrfs_key key;
        u64 end_byte = bytenr + len;
@@ -589,6 +589,9 @@ int btrfs_del_csums(struct btrfs_trans_handle *trans,
        u16 csum_size = btrfs_super_csum_size(fs_info->super_copy);
        int blocksize_bits = fs_info->sb->s_blocksize_bits;
 
+       ASSERT(root == fs_info->csum_root ||
+              root->root_key.objectid == BTRFS_TREE_LOG_OBJECTID);
+
        path = btrfs_alloc_path();
        if (!path)
                return -ENOMEM;
index a456801..d9d90f0 100644 (file)
@@ -1636,6 +1636,7 @@ static noinline ssize_t btrfs_buffered_write(struct kiocb *iocb,
                        break;
                }
 
+               only_release_metadata = false;
                sector_offset = pos & (fs_info->sectorsize - 1);
                reserve_bytes = round_up(write_bytes + sector_offset,
                                fs_info->sectorsize);
@@ -1791,7 +1792,6 @@ again:
                        set_extent_bit(&BTRFS_I(inode)->io_tree, lockstart,
                                       lockend, EXTENT_NORESERVE, NULL,
                                       NULL, GFP_NOFS);
-                       only_release_metadata = false;
                }
 
                btrfs_drop_pages(pages, num_pages);
index ec01bd3..c9965e8 100644 (file)
@@ -382,6 +382,12 @@ static int io_ctl_prepare_pages(struct btrfs_io_ctl *io_ctl, struct inode *inode
                if (uptodate && !PageUptodate(page)) {
                        btrfs_readpage(NULL, page);
                        lock_page(page);
+                       if (page->mapping != inode->i_mapping) {
+                               btrfs_err(BTRFS_I(inode)->root->fs_info,
+                                         "free space cache page truncated");
+                               io_ctl_drop_pages(io_ctl);
+                               return -EIO;
+                       }
                        if (!PageUptodate(page)) {
                                btrfs_err(BTRFS_I(inode)->root->fs_info,
                                           "error reading free space cache");
index 6f45985..70085e9 100644 (file)
@@ -2161,12 +2161,16 @@ again:
                mapping_set_error(page->mapping, ret);
                end_extent_writepage(page, ret, page_start, page_end);
                ClearPageChecked(page);
-               goto out;
+               goto out_reserved;
        }
 
        ClearPageChecked(page);
        set_page_dirty(page);
+out_reserved:
        btrfs_delalloc_release_extents(BTRFS_I(inode), PAGE_SIZE);
+       if (ret)
+               btrfs_delalloc_release_space(inode, data_reserved, page_start,
+                                            PAGE_SIZE, true);
 out:
        unlock_extent_cached(&BTRFS_I(inode)->io_tree, page_start, page_end,
                             &cached_state);
@@ -5661,7 +5665,6 @@ static void inode_tree_add(struct inode *inode)
 
 static void inode_tree_del(struct inode *inode)
 {
-       struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
        struct btrfs_root *root = BTRFS_I(inode)->root;
        int empty = 0;
 
@@ -5674,7 +5677,6 @@ static void inode_tree_del(struct inode *inode)
        spin_unlock(&root->inode_lock);
 
        if (empty && btrfs_root_refs(&root->root_item) == 0) {
-               synchronize_srcu(&fs_info->subvol_srcu);
                spin_lock(&root->inode_lock);
                empty = RB_EMPTY_ROOT(&root->inode_tree);
                spin_unlock(&root->inode_lock);
@@ -9487,9 +9489,8 @@ static int btrfs_rename_exchange(struct inode *old_dir,
        btrfs_init_log_ctx(&ctx_dest, new_inode);
 
        /* close the race window with snapshot create/destroy ioctl */
-       if (old_ino == BTRFS_FIRST_FREE_OBJECTID)
-               down_read(&fs_info->subvol_sem);
-       if (new_ino == BTRFS_FIRST_FREE_OBJECTID)
+       if (old_ino == BTRFS_FIRST_FREE_OBJECTID ||
+           new_ino == BTRFS_FIRST_FREE_OBJECTID)
                down_read(&fs_info->subvol_sem);
 
        /*
@@ -9506,6 +9507,9 @@ static int btrfs_rename_exchange(struct inode *old_dir,
                goto out_notrans;
        }
 
+       if (dest != root)
+               btrfs_record_root_in_trans(trans, dest);
+
        /*
         * We need to find a free sequence number both in the source and
         * in the destination directory for the exchange.
@@ -9720,9 +9724,8 @@ out_fail:
                ret = ret ? ret : ret2;
        }
 out_notrans:
-       if (new_ino == BTRFS_FIRST_FREE_OBJECTID)
-               up_read(&fs_info->subvol_sem);
-       if (old_ino == BTRFS_FIRST_FREE_OBJECTID)
+       if (new_ino == BTRFS_FIRST_FREE_OBJECTID ||
+           old_ino == BTRFS_FIRST_FREE_OBJECTID)
                up_read(&fs_info->subvol_sem);
 
        ASSERT(list_empty(&ctx_root.list));
index 00ff434..199c70b 100644 (file)
@@ -709,11 +709,17 @@ static noinline int create_subvol(struct inode *dir,
 
        btrfs_i_size_write(BTRFS_I(dir), dir->i_size + namelen * 2);
        ret = btrfs_update_inode(trans, root, dir);
-       BUG_ON(ret);
+       if (ret) {
+               btrfs_abort_transaction(trans, ret);
+               goto fail;
+       }
 
        ret = btrfs_add_root_ref(trans, objectid, root->root_key.objectid,
                                 btrfs_ino(BTRFS_I(dir)), index, name, namelen);
-       BUG_ON(ret);
+       if (ret) {
+               btrfs_abort_transaction(trans, ret);
+               goto fail;
+       }
 
        ret = btrfs_uuid_tree_add(trans, root_item->uuid,
                                  BTRFS_UUID_KEY_SUBVOL, objectid);
index 859274e..4c81ffe 100644 (file)
@@ -720,21 +720,19 @@ static int reada_start_machine_dev(struct btrfs_device *dev)
 static void reada_start_machine_worker(struct btrfs_work *work)
 {
        struct reada_machine_work *rmw;
-       struct btrfs_fs_info *fs_info;
        int old_ioprio;
 
        rmw = container_of(work, struct reada_machine_work, work);
-       fs_info = rmw->fs_info;
-
-       kfree(rmw);
 
        old_ioprio = IOPRIO_PRIO_VALUE(task_nice_ioclass(current),
                                       task_nice_ioprio(current));
        set_task_ioprio(current, BTRFS_IOPRIO_READA);
-       __reada_start_machine(fs_info);
+       __reada_start_machine(rmw->fs_info);
        set_task_ioprio(current, old_ioprio);
 
-       atomic_dec(&fs_info->reada_works_cnt);
+       atomic_dec(&rmw->fs_info->reada_works_cnt);
+
+       kfree(rmw);
 }
 
 static void __reada_start_machine(struct btrfs_fs_info *fs_info)
index b4958f7..f989130 100644 (file)
@@ -4474,6 +4474,7 @@ int btrfs_recover_relocation(struct btrfs_root *root)
                fs_root = read_fs_root(fs_info, reloc_root->root_key.offset);
                if (IS_ERR(fs_root)) {
                        err = PTR_ERR(fs_root);
+                       list_add_tail(&reloc_root->root_list, &reloc_roots);
                        goto out_free;
                }
 
index 916c397..6b6008d 100644 (file)
@@ -2145,14 +2145,13 @@ static void scrub_missing_raid56_worker(struct btrfs_work *work)
                scrub_write_block_to_dev_replace(sblock);
        }
 
-       scrub_block_put(sblock);
-
        if (sctx->is_dev_replace && sctx->flush_all_writes) {
                mutex_lock(&sctx->wr_lock);
                scrub_wr_submit(sctx);
                mutex_unlock(&sctx->wr_lock);
        }
 
+       scrub_block_put(sblock);
        scrub_pending_bio_dec(sctx);
 }
 
index 48ddbc1..931a7d1 100644 (file)
 #include "compression.h"
 
 /*
+ * Maximum number of references an extent can have in order for us to attempt to
+ * issue clone operations instead of write operations. This currently exists to
+ * avoid hitting limitations of the backreference walking code (taking a lot of
+ * time and using too much memory for extents with large number of references).
+ */
+#define SEND_MAX_EXTENT_REFS   64
+
+/*
  * A fs_path is a helper to dynamically build path names with unknown size.
  * It reallocates the internal buffer on demand.
  * It allows fast adding of path elements on the right side (normal path) and
@@ -1303,6 +1311,7 @@ static int find_extent_clone(struct send_ctx *sctx,
        struct clone_root *cur_clone_root;
        struct btrfs_key found_key;
        struct btrfs_path *tmp_path;
+       struct btrfs_extent_item *ei;
        int compressed;
        u32 i;
 
@@ -1352,7 +1361,6 @@ static int find_extent_clone(struct send_ctx *sctx,
        ret = extent_from_logical(fs_info, disk_byte, tmp_path,
                                  &found_key, &flags);
        up_read(&fs_info->commit_root_sem);
-       btrfs_release_path(tmp_path);
 
        if (ret < 0)
                goto out;
@@ -1361,6 +1369,21 @@ static int find_extent_clone(struct send_ctx *sctx,
                goto out;
        }
 
+       ei = btrfs_item_ptr(tmp_path->nodes[0], tmp_path->slots[0],
+                           struct btrfs_extent_item);
+       /*
+        * Backreference walking (iterate_extent_inodes() below) is currently
+        * too expensive when an extent has a large number of references, both
+        * in time spent and used memory. So for now just fallback to write
+        * operations instead of clone operations when an extent has more than
+        * a certain amount of references.
+        */
+       if (btrfs_extent_refs(tmp_path->nodes[0], ei) > SEND_MAX_EXTENT_REFS) {
+               ret = -ENOENT;
+               goto out;
+       }
+       btrfs_release_path(tmp_path);
+
        /*
         * Setup the clone roots.
         */
@@ -6616,12 +6639,6 @@ long btrfs_ioctl_send(struct file *mnt_file, struct btrfs_ioctl_send_args *arg)
        spin_unlock(&send_root->root_item_lock);
 
        /*
-        * This is done when we lookup the root, it should already be complete
-        * by the time we get here.
-        */
-       WARN_ON(send_root->orphan_cleanup_state != ORPHAN_CLEANUP_DONE);
-
-       /*
         * Userspace tools do the checks and warn the user if it's
         * not RO.
         */
index 89346da..de8fef9 100644 (file)
@@ -462,9 +462,9 @@ static int run_test(test_func_t test_func, int bitmaps, u32 sectorsize,
        root->fs_info->tree_root = root;
 
        root->node = alloc_test_extent_buffer(root->fs_info, nodesize);
-       if (!root->node) {
+       if (IS_ERR(root->node)) {
                test_err("couldn't allocate dummy buffer");
-               ret = -ENOMEM;
+               ret = PTR_ERR(root->node);
                goto out;
        }
        btrfs_set_header_level(root->node, 0);
index 412b910..d07dd26 100644 (file)
@@ -484,9 +484,9 @@ int btrfs_test_qgroups(u32 sectorsize, u32 nodesize)
         * *cough*backref walking code*cough*
         */
        root->node = alloc_test_extent_buffer(root->fs_info, nodesize);
-       if (!root->node) {
+       if (IS_ERR(root->node)) {
                test_err("couldn't allocate dummy buffer");
-               ret = -ENOMEM;
+               ret = PTR_ERR(root->node);
                goto out;
        }
        btrfs_set_header_level(root->node, 0);
index 4d4f57f..fe7165c 100644 (file)
@@ -795,7 +795,8 @@ static noinline int replay_one_extent(struct btrfs_trans_handle *trans,
                                                struct btrfs_ordered_sum,
                                                list);
                                if (!ret)
-                                       ret = btrfs_del_csums(trans, fs_info,
+                                       ret = btrfs_del_csums(trans,
+                                                             fs_info->csum_root,
                                                              sums->bytenr,
                                                              sums->len);
                                if (!ret)
@@ -3866,6 +3867,28 @@ static int log_inode_item(struct btrfs_trans_handle *trans,
        return 0;
 }
 
+static int log_csums(struct btrfs_trans_handle *trans,
+                    struct btrfs_root *log_root,
+                    struct btrfs_ordered_sum *sums)
+{
+       int ret;
+
+       /*
+        * Due to extent cloning, we might have logged a csum item that covers a
+        * subrange of a cloned extent, and later we can end up logging a csum
+        * item for a larger subrange of the same extent or the entire range.
+        * This would leave csum items in the log tree that cover the same range
+        * and break the searches for checksums in the log tree, resulting in
+        * some checksums missing in the fs/subvolume tree. So just delete (or
+        * trim and adjust) any existing csum items in the log for this range.
+        */
+       ret = btrfs_del_csums(trans, log_root, sums->bytenr, sums->len);
+       if (ret)
+               return ret;
+
+       return btrfs_csum_file_blocks(trans, log_root, sums);
+}
+
 static noinline int copy_items(struct btrfs_trans_handle *trans,
                               struct btrfs_inode *inode,
                               struct btrfs_path *dst_path,
@@ -4011,7 +4034,7 @@ static noinline int copy_items(struct btrfs_trans_handle *trans,
                                                   struct btrfs_ordered_sum,
                                                   list);
                if (!ret)
-                       ret = btrfs_csum_file_blocks(trans, log, sums);
+                       ret = log_csums(trans, log, sums);
                list_del(&sums->list);
                kfree(sums);
        }
@@ -4231,7 +4254,7 @@ static int log_extent_csums(struct btrfs_trans_handle *trans,
                                                   struct btrfs_ordered_sum,
                                                   list);
                if (!ret)
-                       ret = btrfs_csum_file_blocks(trans, log_root, sums);
+                       ret = log_csums(trans, log_root, sums);
                list_del(&sums->list);
                kfree(sums);
        }
@@ -5997,9 +6020,28 @@ again:
                wc.replay_dest = btrfs_read_fs_root_no_name(fs_info, &tmp_key);
                if (IS_ERR(wc.replay_dest)) {
                        ret = PTR_ERR(wc.replay_dest);
+
+                       /*
+                        * We didn't find the subvol, likely because it was
+                        * deleted.  This is ok, simply skip this log and go to
+                        * the next one.
+                        *
+                        * We need to exclude the root because we can't have
+                        * other log replays overwriting this log as we'll read
+                        * it back in a few more times.  This will keep our
+                        * block from being modified, and we'll just bail for
+                        * each subsequent pass.
+                        */
+                       if (ret == -ENOENT)
+                               ret = btrfs_pin_extent_for_log_replay(fs_info,
+                                                       log->node->start,
+                                                       log->node->len);
                        free_extent_buffer(log->node);
                        free_extent_buffer(log->commit_root);
                        kfree(log);
+
+                       if (!ret)
+                               goto next;
                        btrfs_handle_fs_error(fs_info, ret,
                                "Couldn't read target root for tree log recovery.");
                        goto error;
@@ -6031,7 +6073,6 @@ again:
                                                  &root->highest_objectid);
                }
 
-               key.offset = found_key.offset - 1;
                wc.replay_dest->log_root = NULL;
                free_extent_buffer(log->node);
                free_extent_buffer(log->commit_root);
@@ -6039,9 +6080,10 @@ again:
 
                if (ret)
                        goto error;
-
+next:
                if (found_key.offset == 0)
                        break;
+               key.offset = found_key.offset - 1;
        }
        btrfs_release_path(path);
 
index 3b2ae34..5bbb977 100644 (file)
@@ -324,6 +324,8 @@ again_search_slot:
                                }
                                if (ret < 0 && ret != -ENOENT)
                                        goto out;
+                               key.offset++;
+                               goto again_search_slot;
                        }
                        item_size -= sizeof(subid_le);
                        offset += sizeof(subid_le);
index c0e3015..ac703b1 100644 (file)
@@ -304,7 +304,6 @@ struct btrfs_bio {
        u64 map_type; /* get from map_lookup->type */
        bio_end_io_t *end_io;
        struct bio *orig_bio;
-       unsigned long flags;
        void *private;
        atomic_t error;
        int max_errors;
index 0657679..a85aeff 100644 (file)
@@ -210,6 +210,11 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
                if (!server->rdma)
                        goto skip_rdma;
 
+               if (!server->smbd_conn) {
+                       seq_printf(m, "\nSMBDirect transport not available");
+                       goto skip_rdma;
+               }
+
                seq_printf(m, "\nSMBDirect (in hex) protocol version: %x "
                        "transport status: %x",
                        server->smbd_conn->protocol,
index 455d028..ad93b06 100644 (file)
@@ -726,6 +726,13 @@ cifs_reopen_file(struct cifsFileInfo *cfile, bool can_flush)
        if (backup_cred(cifs_sb))
                create_options |= CREATE_OPEN_BACKUP_INTENT;
 
+       /* O_SYNC also has bit for O_DSYNC so following check picks up either */
+       if (cfile->f_flags & O_SYNC)
+               create_options |= CREATE_WRITE_THROUGH;
+
+       if (cfile->f_flags & O_DIRECT)
+               create_options |= CREATE_NO_BUFFER;
+
        if (server->ops->get_lease_key)
                server->ops->get_lease_key(inode, &cfile->fid);
 
index 449d158..766974f 100644 (file)
@@ -743,36 +743,67 @@ smb2_cancelled_close_fid(struct work_struct *work)
        kfree(cancelled);
 }
 
+/* Caller should already has an extra reference to @tcon */
+static int
+__smb2_handle_cancelled_close(struct cifs_tcon *tcon, __u64 persistent_fid,
+                             __u64 volatile_fid)
+{
+       struct close_cancelled_open *cancelled;
+
+       cancelled = kzalloc(sizeof(*cancelled), GFP_KERNEL);
+       if (!cancelled)
+               return -ENOMEM;
+
+       cancelled->fid.persistent_fid = persistent_fid;
+       cancelled->fid.volatile_fid = volatile_fid;
+       cancelled->tcon = tcon;
+       INIT_WORK(&cancelled->work, smb2_cancelled_close_fid);
+       WARN_ON(queue_work(cifsiod_wq, &cancelled->work) == false);
+
+       return 0;
+}
+
+int
+smb2_handle_cancelled_close(struct cifs_tcon *tcon, __u64 persistent_fid,
+                           __u64 volatile_fid)
+{
+       int rc;
+
+       cifs_dbg(FYI, "%s: tc_count=%d\n", __func__, tcon->tc_count);
+       spin_lock(&cifs_tcp_ses_lock);
+       tcon->tc_count++;
+       spin_unlock(&cifs_tcp_ses_lock);
+
+       rc = __smb2_handle_cancelled_close(tcon, persistent_fid, volatile_fid);
+       if (rc)
+               cifs_put_tcon(tcon);
+
+       return rc;
+}
+
 int
 smb2_handle_cancelled_mid(char *buffer, struct TCP_Server_Info *server)
 {
        struct smb2_sync_hdr *sync_hdr = (struct smb2_sync_hdr *)buffer;
        struct smb2_create_rsp *rsp = (struct smb2_create_rsp *)buffer;
        struct cifs_tcon *tcon;
-       struct close_cancelled_open *cancelled;
+       int rc;
 
        if (sync_hdr->Command != SMB2_CREATE ||
            sync_hdr->Status != STATUS_SUCCESS)
                return 0;
 
-       cancelled = kzalloc(sizeof(*cancelled), GFP_KERNEL);
-       if (!cancelled)
-               return -ENOMEM;
-
        tcon = smb2_find_smb_tcon(server, sync_hdr->SessionId,
                                  sync_hdr->TreeId);
-       if (!tcon) {
-               kfree(cancelled);
+       if (!tcon)
                return -ENOENT;
-       }
 
-       cancelled->fid.persistent_fid = rsp->PersistentFileId;
-       cancelled->fid.volatile_fid = rsp->VolatileFileId;
-       cancelled->tcon = tcon;
-       INIT_WORK(&cancelled->work, smb2_cancelled_close_fid);
-       queue_work(cifsiod_wq, &cancelled->work);
+       rc = __smb2_handle_cancelled_close(tcon, rsp->PersistentFileId,
+                                          rsp->VolatileFileId);
+       if (rc)
+               cifs_put_tcon(tcon);
 
-       return 0;
+       return rc;
 }
 
 /**
index 9194f17..43f2962 100644 (file)
@@ -168,7 +168,7 @@ smb2_reconnect(__le16 smb2_command, struct cifs_tcon *tcon)
        if (tcon == NULL)
                return 0;
 
-       if (smb2_command == SMB2_TREE_CONNECT || smb2_command == SMB2_IOCTL)
+       if (smb2_command == SMB2_TREE_CONNECT)
                return 0;
 
        if (tcon->tidStatus == CifsExiting) {
@@ -335,16 +335,9 @@ fill_small_buf(__le16 smb2_command, struct cifs_tcon *tcon, void *buf,
  * SMB information in the SMB header. If the return code is zero, this
  * function must have filled in request_buf pointer.
  */
-static int
-smb2_plain_req_init(__le16 smb2_command, struct cifs_tcon *tcon,
-                   void **request_buf, unsigned int *total_len)
+static int __smb2_plain_req_init(__le16 smb2_command, struct cifs_tcon *tcon,
+                                 void **request_buf, unsigned int *total_len)
 {
-       int rc;
-
-       rc = smb2_reconnect(smb2_command, tcon);
-       if (rc)
-               return rc;
-
        /* BB eventually switch this to SMB2 specific small buf size */
        if (smb2_command == SMB2_SET_INFO)
                *request_buf = cifs_buf_get();
@@ -365,7 +358,31 @@ smb2_plain_req_init(__le16 smb2_command, struct cifs_tcon *tcon,
                cifs_stats_inc(&tcon->num_smbs_sent);
        }
 
-       return rc;
+       return 0;
+}
+
+static int smb2_plain_req_init(__le16 smb2_command, struct cifs_tcon *tcon,
+                              void **request_buf, unsigned int *total_len)
+{
+       int rc;
+
+       rc = smb2_reconnect(smb2_command, tcon);
+       if (rc)
+               return rc;
+
+       return __smb2_plain_req_init(smb2_command, tcon, request_buf,
+                                    total_len);
+}
+
+static int smb2_ioctl_req_init(u32 opcode, struct cifs_tcon *tcon,
+                              void **request_buf, unsigned int *total_len)
+{
+       /* Skip reconnect only for FSCTL_VALIDATE_NEGOTIATE_INFO IOCTLs */
+       if (opcode == FSCTL_VALIDATE_NEGOTIATE_INFO) {
+               return __smb2_plain_req_init(SMB2_IOCTL, tcon, request_buf,
+                                            total_len);
+       }
+       return smb2_plain_req_init(SMB2_IOCTL, tcon, request_buf, total_len);
 }
 
 
@@ -2386,7 +2403,7 @@ SMB2_ioctl(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid,
        if (!ses || !(ses->server))
                return -EIO;
 
-       rc = smb2_plain_req_init(SMB2_IOCTL, tcon, (void **) &req, &total_len);
+       rc = smb2_ioctl_req_init(opcode, tcon, (void **) &req, &total_len);
        if (rc)
                return rc;
 
@@ -2612,7 +2629,21 @@ int
 SMB2_close(const unsigned int xid, struct cifs_tcon *tcon,
           u64 persistent_fid, u64 volatile_fid)
 {
-       return SMB2_close_flags(xid, tcon, persistent_fid, volatile_fid, 0);
+       int rc;
+       int tmp_rc;
+
+       rc = SMB2_close_flags(xid, tcon, persistent_fid, volatile_fid, 0);
+
+       /* retry close in a worker thread if this one is interrupted */
+       if (rc == -EINTR) {
+               tmp_rc = smb2_handle_cancelled_close(tcon, persistent_fid,
+                                                    volatile_fid);
+               if (tmp_rc)
+                       cifs_dbg(VFS, "handle cancelled close fid 0x%llx returned error %d\n",
+                                persistent_fid, tmp_rc);
+       }
+
+       return rc;
 }
 
 int
index b407657..c66d7da 100644 (file)
@@ -204,6 +204,9 @@ extern int SMB2_set_compression(const unsigned int xid, struct cifs_tcon *tcon,
 extern int SMB2_oplock_break(const unsigned int xid, struct cifs_tcon *tcon,
                             const u64 persistent_fid, const u64 volatile_fid,
                             const __u8 oplock_level);
+extern int smb2_handle_cancelled_close(struct cifs_tcon *tcon,
+                                      __u64 persistent_fid,
+                                      __u64 volatile_fid);
 extern int smb2_handle_cancelled_mid(char *buffer,
                                        struct TCP_Server_Info *server);
 void smb2_cancelled_close_fid(struct work_struct *work);
index 1959931..784628e 100644 (file)
@@ -1164,7 +1164,7 @@ static int smbd_post_send_data(
 
        if (n_vec > SMBDIRECT_MAX_SGE) {
                cifs_dbg(VFS, "Can't fit data to SGL, n_vec=%d\n", n_vec);
-               return -ENOMEM;
+               return -EINVAL;
        }
 
        sg_init_table(sgl, n_vec);
@@ -1491,6 +1491,7 @@ void smbd_destroy(struct smbd_connection *info)
                info->transport_status == SMBD_DESTROYED);
 
        destroy_workqueue(info->workqueue);
+       log_rdma_event(INFO,  "rdma session destroyed\n");
        kfree(info);
 }
 
@@ -1528,8 +1529,9 @@ create_conn:
        log_rdma_event(INFO, "creating rdma session\n");
        server->smbd_conn = smbd_get_connection(
                server, (struct sockaddr *) &server->dstaddr);
-       log_rdma_event(INFO, "created rdma session info=%p\n",
-               server->smbd_conn);
+
+       if (server->smbd_conn)
+               cifs_dbg(VFS, "RDMA transport re-established\n");
 
        return server->smbd_conn ? 0 : -ENOENT;
 }
index fe77f41..0c4df56 100644 (file)
@@ -286,8 +286,11 @@ __smb_send_rqst(struct TCP_Server_Info *server, int num_rqst,
        int val = 1;
        __be32 rfc1002_marker;
 
-       if (cifs_rdma_enabled(server) && server->smbd_conn) {
-               rc = smbd_send(server, num_rqst, rqst);
+       if (cifs_rdma_enabled(server)) {
+               /* return -EAGAIN when connecting or reconnecting */
+               rc = -EAGAIN;
+               if (server->smbd_conn)
+                       rc = smbd_send(server, num_rqst, rqst);
                goto smbd_done;
        }
        if (ssocket == NULL)
index e4bb938..36a2ab6 100644 (file)
@@ -699,10 +699,13 @@ static int ext2_get_blocks(struct inode *inode,
                if (!partial) {
                        count++;
                        mutex_unlock(&ei->truncate_mutex);
-                       if (err)
-                               goto cleanup;
                        goto got_it;
                }
+
+               if (err) {
+                       mutex_unlock(&ei->truncate_mutex);
+                       goto cleanup;
+               }
        }
 
        /*
index 46d5c40..d947c5e 100644 (file)
@@ -77,6 +77,11 @@ int __ext4_check_dir_entry(const char *function, unsigned int line,
                error_msg = "rec_len is too small for name_len";
        else if (unlikely(((char *) de - buf) + rlen > size))
                error_msg = "directory entry overrun";
+       else if (unlikely(((char *) de - buf) + rlen >
+                         size - EXT4_DIR_REC_LEN(1) &&
+                         ((char *) de - buf) + rlen != size)) {
+               error_msg = "directory entry too close to block end";
+       }
        else if (unlikely(le32_to_cpu(de->inode) >
                        le32_to_cpu(EXT4_SB(dir->i_sb)->s_es->s_inodes_count)))
                error_msg = "inode out of bounds";
index f8a0af1..950e3dc 100644 (file)
@@ -196,7 +196,12 @@ void ext4_evict_inode(struct inode *inode)
 {
        handle_t *handle;
        int err;
-       int extra_credits = 3;
+       /*
+        * Credits for final inode cleanup and freeing:
+        * sb + inode (ext4_orphan_del()), block bitmap, group descriptor
+        * (xattr block freeing), bitmap, group descriptor (inode freeing)
+        */
+       int extra_credits = 6;
        struct ext4_xattr_inode_array *ea_inode_array = NULL;
 
        trace_ext4_evict_inode(inode);
@@ -252,8 +257,12 @@ void ext4_evict_inode(struct inode *inode)
        if (!IS_NOQUOTA(inode))
                extra_credits += EXT4_MAXQUOTAS_DEL_BLOCKS(inode->i_sb);
 
+       /*
+        * Block bitmap, group descriptor, and inode are accounted in both
+        * ext4_blocks_for_truncate() and extra_credits. So subtract 3.
+        */
        handle = ext4_journal_start(inode, EXT4_HT_TRUNCATE,
-                                ext4_blocks_for_truncate(inode)+extra_credits);
+                        ext4_blocks_for_truncate(inode) + extra_credits - 3);
        if (IS_ERR(handle)) {
                ext4_std_error(inode->i_sb, PTR_ERR(handle));
                /*
@@ -3535,8 +3544,14 @@ retry:
                        return ret;
        }
 
+       /*
+        * Writes that span EOF might trigger an I/O size update on completion,
+        * so consider them to be dirty for the purposes of O_DSYNC, even if
+        * there is no other metadata changes being made or are pending here.
+        */
        iomap->flags = 0;
-       if (ext4_inode_datasync_dirty(inode))
+       if (ext4_inode_datasync_dirty(inode) ||
+           offset + length > i_size_read(inode))
                iomap->flags |= IOMAP_F_DIRTY;
        iomap->bdev = inode->i_sb->s_bdev;
        iomap->dax_dev = sbi->s_daxdev;
@@ -3839,7 +3854,13 @@ static ssize_t ext4_direct_IO_read(struct kiocb *iocb, struct iov_iter *iter)
         * writes & truncates and since we take care of writing back page cache,
         * we are protected against page writeback as well.
         */
-       inode_lock_shared(inode);
+       if (iocb->ki_flags & IOCB_NOWAIT) {
+               if (!inode_trylock_shared(inode))
+                       return -EAGAIN;
+       } else {
+               inode_lock_shared(inode);
+       }
+
        ret = filemap_write_and_wait_range(mapping, iocb->ki_pos,
                                           iocb->ki_pos + count - 1);
        if (ret)
@@ -5450,11 +5471,15 @@ static void ext4_wait_for_tail_page_commit(struct inode *inode)
 
        offset = inode->i_size & (PAGE_SIZE - 1);
        /*
-        * All buffers in the last page remain valid? Then there's nothing to
-        * do. We do the check mainly to optimize the common PAGE_SIZE ==
-        * blocksize case
+        * If the page is fully truncated, we don't need to wait for any commit
+        * (and we even should not as __ext4_journalled_invalidatepage() may
+        * strip all buffers from the page but keep the page dirty which can then
+        * confuse e.g. concurrent ext4_writepage() seeing dirty page without
+        * buffers). Also we don't need to wait for any commit if all buffers in
+        * the page remain valid. This is most beneficial for the common case of
+        * blocksize == PAGESIZE.
         */
-       if (offset > PAGE_SIZE - i_blocksize(inode))
+       if (!offset || offset > (PAGE_SIZE - i_blocksize(inode)))
                return;
        while (1) {
                page = find_lock_page(inode->i_mapping,
@@ -6014,7 +6039,7 @@ int ext4_expand_extra_isize(struct inode *inode,
        error = ext4_journal_get_write_access(handle, iloc->bh);
        if (error) {
                brelse(iloc->bh);
-               goto out_stop;
+               goto out_unlock;
        }
 
        error = __ext4_expand_extra_isize(inode, new_extra_isize, iloc,
@@ -6024,8 +6049,8 @@ int ext4_expand_extra_isize(struct inode *inode,
        if (!error)
                error = rc;
 
+out_unlock:
        ext4_write_unlock_xattr(inode, &no_expand);
-out_stop:
        ext4_journal_stop(handle);
        return error;
 }
index badbb8b..43dcb91 100644 (file)
@@ -2693,7 +2693,7 @@ bool ext4_empty_dir(struct inode *inode)
 {
        unsigned int offset;
        struct buffer_head *bh;
-       struct ext4_dir_entry_2 *de, *de1;
+       struct ext4_dir_entry_2 *de;
        struct super_block *sb;
 
        if (ext4_has_inline_data(inode)) {
@@ -2718,19 +2718,25 @@ bool ext4_empty_dir(struct inode *inode)
                return true;
 
        de = (struct ext4_dir_entry_2 *) bh->b_data;
-       de1 = ext4_next_entry(de, sb->s_blocksize);
-       if (le32_to_cpu(de->inode) != inode->i_ino ||
-                       le32_to_cpu(de1->inode) == 0 ||
-                       strcmp(".", de->name) || strcmp("..", de1->name)) {
-               ext4_warning_inode(inode, "directory missing '.' and/or '..'");
+       if (ext4_check_dir_entry(inode, NULL, de, bh, bh->b_data, bh->b_size,
+                                0) ||
+           le32_to_cpu(de->inode) != inode->i_ino || strcmp(".", de->name)) {
+               ext4_warning_inode(inode, "directory missing '.'");
+               brelse(bh);
+               return true;
+       }
+       offset = ext4_rec_len_from_disk(de->rec_len, sb->s_blocksize);
+       de = ext4_next_entry(de, sb->s_blocksize);
+       if (ext4_check_dir_entry(inode, NULL, de, bh, bh->b_data, bh->b_size,
+                                offset) ||
+           le32_to_cpu(de->inode) == 0 || strcmp("..", de->name)) {
+               ext4_warning_inode(inode, "directory missing '..'");
                brelse(bh);
                return true;
        }
-       offset = ext4_rec_len_from_disk(de->rec_len, sb->s_blocksize) +
-                ext4_rec_len_from_disk(de1->rec_len, sb->s_blocksize);
-       de = ext4_next_entry(de1, sb->s_blocksize);
+       offset += ext4_rec_len_from_disk(de->rec_len, sb->s_blocksize);
        while (offset < inode->i_size) {
-               if ((void *) de >= (void *) (bh->b_data+sb->s_blocksize)) {
+               if (!(offset & (sb->s_blocksize - 1))) {
                        unsigned int lblock;
                        brelse(bh);
                        lblock = offset >> EXT4_BLOCK_SIZE_BITS(sb);
@@ -2741,12 +2747,11 @@ bool ext4_empty_dir(struct inode *inode)
                        }
                        if (IS_ERR(bh))
                                return true;
-                       de = (struct ext4_dir_entry_2 *) bh->b_data;
                }
+               de = (struct ext4_dir_entry_2 *) (bh->b_data +
+                                       (offset & (sb->s_blocksize - 1)));
                if (ext4_check_dir_entry(inode, NULL, de, bh,
                                         bh->b_data, bh->b_size, offset)) {
-                       de = (struct ext4_dir_entry_2 *)(bh->b_data +
-                                                        sb->s_blocksize);
                        offset = (offset | (sb->s_blocksize - 1)) + 1;
                        continue;
                }
@@ -2755,7 +2760,6 @@ bool ext4_empty_dir(struct inode *inode)
                        return false;
                }
                offset += ext4_rec_len_from_disk(de->rec_len, sb->s_blocksize);
-               de = ext4_next_entry(de, sb->s_blocksize);
        }
        brelse(bh);
        return true;
@@ -3056,18 +3060,17 @@ static int ext4_unlink(struct inode *dir, struct dentry *dentry)
        if (IS_DIRSYNC(dir))
                ext4_handle_sync(handle);
 
-       if (inode->i_nlink == 0) {
-               ext4_warning_inode(inode, "Deleting file '%.*s' with no links",
-                                  dentry->d_name.len, dentry->d_name.name);
-               set_nlink(inode, 1);
-       }
        retval = ext4_delete_entry(handle, dir, de, bh);
        if (retval)
                goto end_unlink;
        dir->i_ctime = dir->i_mtime = current_time(dir);
        ext4_update_dx_flag(dir);
        ext4_mark_inode_dirty(handle, dir);
-       drop_nlink(inode);
+       if (inode->i_nlink == 0)
+               ext4_warning_inode(inode, "Deleting file '%.*s' with no links",
+                                  dentry->d_name.len, dentry->d_name.name);
+       else
+               drop_nlink(inode);
        if (!inode->i_nlink)
                ext4_orphan_add(handle, inode);
        inode->i_ctime = current_time(inode);
index 34e48bc..72d154e 100644 (file)
@@ -2578,6 +2578,20 @@ static inline void clear_file(struct inode *inode, int type)
        f2fs_mark_inode_dirty_sync(inode, true);
 }
 
+static inline bool f2fs_is_time_consistent(struct inode *inode)
+{
+       if (!timespec64_equal(F2FS_I(inode)->i_disk_time, &inode->i_atime))
+               return false;
+       if (!timespec64_equal(F2FS_I(inode)->i_disk_time + 1, &inode->i_ctime))
+               return false;
+       if (!timespec64_equal(F2FS_I(inode)->i_disk_time + 2, &inode->i_mtime))
+               return false;
+       if (!timespec64_equal(F2FS_I(inode)->i_disk_time + 3,
+                                               &F2FS_I(inode)->i_crtime))
+               return false;
+       return true;
+}
+
 static inline bool f2fs_skip_inode_update(struct inode *inode, int dsync)
 {
        bool ret;
@@ -2595,14 +2609,7 @@ static inline bool f2fs_skip_inode_update(struct inode *inode, int dsync)
                        i_size_read(inode) & ~PAGE_MASK)
                return false;
 
-       if (!timespec64_equal(F2FS_I(inode)->i_disk_time, &inode->i_atime))
-               return false;
-       if (!timespec64_equal(F2FS_I(inode)->i_disk_time + 1, &inode->i_ctime))
-               return false;
-       if (!timespec64_equal(F2FS_I(inode)->i_disk_time + 2, &inode->i_mtime))
-               return false;
-       if (!timespec64_equal(F2FS_I(inode)->i_disk_time + 3,
-                                               &F2FS_I(inode)->i_crtime))
+       if (!f2fs_is_time_consistent(inode))
                return false;
 
        down_read(&F2FS_I(inode)->i_sem);
index 540d457..a01be7d 100644 (file)
@@ -614,7 +614,11 @@ int f2fs_write_inode(struct inode *inode, struct writeback_control *wbc)
                        inode->i_ino == F2FS_META_INO(sbi))
                return 0;
 
-       if (!is_inode_flag_set(inode, FI_DIRTY_INODE))
+       /*
+        * atime could be updated without dirtying f2fs inode in lazytime mode
+        */
+       if (f2fs_is_time_consistent(inode) &&
+               !is_inode_flag_set(inode, FI_DIRTY_INODE))
                return 0;
 
        /*
index 6b23dcb..0ace2c2 100644 (file)
@@ -948,7 +948,8 @@ static int f2fs_rename(struct inode *old_dir, struct dentry *old_dentry,
        if (!old_dir_entry || whiteout)
                file_lost_pino(old_inode);
        else
-               F2FS_I(old_inode)->i_pino = new_dir->i_ino;
+               /* adjust dir's i_pino to pass fsck check */
+               f2fs_i_pino_write(old_inode, new_dir->i_ino);
        up_write(&F2FS_I(old_inode)->i_sem);
 
        old_inode->i_ctime = current_time(old_inode);
@@ -1103,7 +1104,11 @@ static int f2fs_cross_rename(struct inode *old_dir, struct dentry *old_dentry,
        f2fs_set_link(old_dir, old_entry, old_page, new_inode);
 
        down_write(&F2FS_I(old_inode)->i_sem);
-       file_lost_pino(old_inode);
+       if (!old_dir_entry)
+               file_lost_pino(old_inode);
+       else
+               /* adjust dir's i_pino to pass fsck check */
+               f2fs_i_pino_write(old_inode, new_dir->i_ino);
        up_write(&F2FS_I(old_inode)->i_sem);
 
        old_dir->i_ctime = current_time(old_dir);
@@ -1118,7 +1123,11 @@ static int f2fs_cross_rename(struct inode *old_dir, struct dentry *old_dentry,
        f2fs_set_link(new_dir, new_entry, new_page, old_inode);
 
        down_write(&F2FS_I(new_inode)->i_sem);
-       file_lost_pino(new_inode);
+       if (!new_dir_entry)
+               file_lost_pino(new_inode);
+       else
+               /* adjust dir's i_pino to pass fsck check */
+               f2fs_i_pino_write(new_inode, old_dir->i_ino);
        up_write(&F2FS_I(new_inode)->i_sem);
 
        new_dir->i_ctime = current_time(new_dir);
index 90b5c8d..d3f0612 100644 (file)
@@ -613,6 +613,14 @@ void gfs2_add_revoke(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd)
        list_add(&bd->bd_list, &sdp->sd_log_le_revoke);
 }
 
+void gfs2_glock_remove_revoke(struct gfs2_glock *gl)
+{
+       if (atomic_dec_return(&gl->gl_revokes) == 0) {
+               clear_bit(GLF_LFLUSH, &gl->gl_flags);
+               gfs2_glock_queue_put(gl);
+       }
+}
+
 void gfs2_write_revokes(struct gfs2_sbd *sdp)
 {
        struct gfs2_trans *tr;
index 2024143..015766c 100644 (file)
@@ -80,6 +80,7 @@ extern void gfs2_ail1_flush(struct gfs2_sbd *sdp, struct writeback_control *wbc)
 extern void gfs2_log_shutdown(struct gfs2_sbd *sdp);
 extern int gfs2_logd(void *data);
 extern void gfs2_add_revoke(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd);
+extern void gfs2_glock_remove_revoke(struct gfs2_glock *gl);
 extern void gfs2_write_revokes(struct gfs2_sbd *sdp);
 
 #endif /* __LOG_DOT_H__ */
index 8f99b39..2b3b755 100644 (file)
@@ -662,10 +662,7 @@ static void revoke_lo_after_commit(struct gfs2_sbd *sdp, struct gfs2_trans *tr)
                bd = list_entry(head->next, struct gfs2_bufdata, bd_list);
                list_del_init(&bd->bd_list);
                gl = bd->bd_gl;
-               if (atomic_dec_return(&gl->gl_revokes) == 0) {
-                       clear_bit(GLF_LFLUSH, &gl->gl_flags);
-                       gfs2_glock_queue_put(gl);
-               }
+               gfs2_glock_remove_revoke(gl);
                kmem_cache_free(gfs2_bufdata_cachep, bd);
        }
 }
index 064c9a0..812b5d5 100644 (file)
@@ -266,6 +266,8 @@ void gfs2_trans_add_unrevoke(struct gfs2_sbd *sdp, u64 blkno, unsigned int len)
                        list_del_init(&bd->bd_list);
                        gfs2_assert_withdraw(sdp, sdp->sd_log_num_revoke);
                        sdp->sd_log_num_revoke--;
+                       if (bd->bd_gl)
+                               gfs2_glock_remove_revoke(bd->bd_gl);
                        kmem_cache_free(gfs2_bufdata_cachep, bd);
                        tr->tr_num_revoke_rm++;
                        if (--n == 0)
index 24f86ff..020bd7a 100644 (file)
@@ -724,7 +724,6 @@ start_journal_io:
                                submit_bh(REQ_OP_WRITE, REQ_SYNC, bh);
                        }
                        cond_resched();
-                       stats.run.rs_blocks_logged += bufs;
 
                        /* Force a new descriptor to be generated next
                            time round the loop. */
@@ -811,6 +810,7 @@ start_journal_io:
                if (unlikely(!buffer_uptodate(bh)))
                        err = -EIO;
                jbd2_unfile_log_bh(bh);
+               stats.run.rs_blocks_logged++;
 
                /*
                 * The list contains temporary buffer heads created by
@@ -856,6 +856,7 @@ start_journal_io:
                BUFFER_TRACE(bh, "ph5: control buffer writeout done: unfile");
                clear_buffer_jwrite(bh);
                jbd2_unfile_log_bh(bh);
+               stats.run.rs_blocks_logged++;
                __brelse(bh);           /* One for getblk */
                /* AKPM: bforget here */
        }
@@ -877,6 +878,7 @@ start_journal_io:
        }
        if (cbh)
                err = journal_wait_on_commit_record(journal, cbh);
+       stats.run.rs_blocks_logged++;
        if (jbd2_has_feature_async_commit(journal) &&
            journal->j_flags & JBD2_BARRIER) {
                blkdev_issue_flush(journal->j_dev, GFP_NOFS, NULL);
index 917fadc..b73b787 100644 (file)
@@ -335,8 +335,8 @@ int ocfs2_acl_chmod(struct inode *inode, struct buffer_head *bh)
        down_read(&OCFS2_I(inode)->ip_xattr_sem);
        acl = ocfs2_get_acl_nolock(inode, ACL_TYPE_ACCESS, bh);
        up_read(&OCFS2_I(inode)->ip_xattr_sem);
-       if (IS_ERR(acl) || !acl)
-               return PTR_ERR(acl);
+       if (IS_ERR_OR_NULL(acl))
+               return PTR_ERR_OR_ZERO(acl);
        ret = __posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode);
        if (ret)
                return ret;
index 7a92219..eda8348 100644 (file)
@@ -728,7 +728,7 @@ static int ocfs2_release_dquot(struct dquot *dquot)
 
        mutex_lock(&dquot->dq_lock);
        /* Check whether we are not racing with some other dqget() */
-       if (atomic_read(&dquot->dq_count) > 1)
+       if (dquot_is_busy(dquot))
                goto out;
        /* Running from downconvert thread? Postpone quota processing to wq */
        if (current == osb->dc_task) {
index 336f04d..800bcad 100644 (file)
@@ -1174,7 +1174,7 @@ static int ovl_rename(struct inode *olddir, struct dentry *old,
        if (newdentry == trap)
                goto out_dput;
 
-       if (WARN_ON(olddentry->d_inode == newdentry->d_inode))
+       if (olddentry->d_inode == newdentry->d_inode)
                goto out_dput;
 
        err = 0;
index 4f4964e..a138bb3 100644 (file)
@@ -203,8 +203,14 @@ int ovl_getattr(const struct path *path, struct kstat *stat,
                        if (ovl_test_flag(OVL_INDEX, d_inode(dentry)) ||
                            (!ovl_verify_lower(dentry->d_sb) &&
                             (is_dir || lowerstat.nlink == 1))) {
-                               stat->ino = lowerstat.ino;
                                lower_layer = ovl_layer_lower(dentry);
+                               /*
+                                * Cannot use origin st_dev;st_ino because
+                                * origin inode content may differ from overlay
+                                * inode content.
+                                */
+                               if (samefs || lower_layer->fsid)
+                                       stat->ino = lowerstat.ino;
                        }
 
                        /*
index 71aba44..efa6273 100644 (file)
@@ -800,6 +800,8 @@ static int show_smap(struct seq_file *m, void *v)
 
        __show_smap(m, &mss);
 
+       seq_printf(m, "THPeligible:    %d\n", transparent_hugepage_enabled(vma));
+
        if (arch_pkeys_enabled())
                seq_printf(m, "ProtectionKey:  %8u\n", vma_pkey(vma));
        show_smap_vma_flags(m, vma);
index dd1783e..154f175 100644 (file)
@@ -491,7 +491,7 @@ int dquot_release(struct dquot *dquot)
 
        mutex_lock(&dquot->dq_lock);
        /* Check whether we are not racing with some other dqget() */
-       if (atomic_read(&dquot->dq_count) > 1)
+       if (dquot_is_busy(dquot))
                goto out_dqlock;
        if (dqopt->ops[dquot->dq_id.type]->release_dqblk) {
                ret = dqopt->ops[dquot->dq_id.type]->release_dqblk(dquot);
@@ -617,7 +617,7 @@ EXPORT_SYMBOL(dquot_scan_active);
 /* Write all dquot structures to quota files */
 int dquot_writeback_dquots(struct super_block *sb, int type)
 {
-       struct list_head *dirty;
+       struct list_head dirty;
        struct dquot *dquot;
        struct quota_info *dqopt = sb_dqopt(sb);
        int cnt;
@@ -631,9 +631,10 @@ int dquot_writeback_dquots(struct super_block *sb, int type)
                if (!sb_has_quota_active(sb, cnt))
                        continue;
                spin_lock(&dq_list_lock);
-               dirty = &dqopt->info[cnt].dqi_dirty_list;
-               while (!list_empty(dirty)) {
-                       dquot = list_first_entry(dirty, struct dquot,
+               /* Move list away to avoid livelock. */
+               list_replace_init(&dqopt->info[cnt].dqi_dirty_list, &dirty);
+               while (!list_empty(&dirty)) {
+                       dquot = list_first_entry(&dirty, struct dquot,
                                                 dq_dirty);
 
                        WARN_ON(!test_bit(DQ_ACTIVE_B, &dquot->dq_flags));
@@ -2852,68 +2853,73 @@ EXPORT_SYMBOL(dquot_quotactl_sysfile_ops);
 static int do_proc_dqstats(struct ctl_table *table, int write,
                     void __user *buffer, size_t *lenp, loff_t *ppos)
 {
-       unsigned int type = (int *)table->data - dqstats.stat;
+       unsigned int type = (unsigned long *)table->data - dqstats.stat;
+       s64 value = percpu_counter_sum(&dqstats.counter[type]);
+
+       /* Filter negative values for non-monotonic counters */
+       if (value < 0 && (type == DQST_ALLOC_DQUOTS ||
+                         type == DQST_FREE_DQUOTS))
+               value = 0;
 
        /* Update global table */
-       dqstats.stat[type] =
-                       percpu_counter_sum_positive(&dqstats.counter[type]);
-       return proc_dointvec(table, write, buffer, lenp, ppos);
+       dqstats.stat[type] = value;
+       return proc_doulongvec_minmax(table, write, buffer, lenp, ppos);
 }
 
 static struct ctl_table fs_dqstats_table[] = {
        {
                .procname       = "lookups",
                .data           = &dqstats.stat[DQST_LOOKUPS],
-               .maxlen         = sizeof(int),
+               .maxlen         = sizeof(unsigned long),
                .mode           = 0444,
                .proc_handler   = do_proc_dqstats,
        },
        {
                .procname       = "drops",
                .data           = &dqstats.stat[DQST_DROPS],
-               .maxlen         = sizeof(int),
+               .maxlen         = sizeof(unsigned long),
                .mode           = 0444,
                .proc_handler   = do_proc_dqstats,
        },
        {
                .procname       = "reads",
                .data           = &dqstats.stat[DQST_READS],
-               .maxlen         = sizeof(int),
+               .maxlen         = sizeof(unsigned long),
                .mode           = 0444,
                .proc_handler   = do_proc_dqstats,
        },
        {
                .procname       = "writes",
                .data           = &dqstats.stat[DQST_WRITES],
-               .maxlen         = sizeof(int),
+               .maxlen         = sizeof(unsigned long),
                .mode           = 0444,
                .proc_handler   = do_proc_dqstats,
        },
        {
                .procname       = "cache_hits",
                .data           = &dqstats.stat[DQST_CACHE_HITS],
-               .maxlen         = sizeof(int),
+               .maxlen         = sizeof(unsigned long),
                .mode           = 0444,
                .proc_handler   = do_proc_dqstats,
        },
        {
                .procname       = "allocated_dquots",
                .data           = &dqstats.stat[DQST_ALLOC_DQUOTS],
-               .maxlen         = sizeof(int),
+               .maxlen         = sizeof(unsigned long),
                .mode           = 0444,
                .proc_handler   = do_proc_dqstats,
        },
        {
                .procname       = "free_dquots",
                .data           = &dqstats.stat[DQST_FREE_DQUOTS],
-               .maxlen         = sizeof(int),
+               .maxlen         = sizeof(unsigned long),
                .mode           = 0444,
                .proc_handler   = do_proc_dqstats,
        },
        {
                .procname       = "syncs",
                .data           = &dqstats.stat[DQST_SYNCS],
-               .maxlen         = sizeof(int),
+               .maxlen         = sizeof(unsigned long),
                .mode           = 0444,
                .proc_handler   = do_proc_dqstats,
        },
index d97f548..443270f 100644 (file)
@@ -65,6 +65,40 @@ out:
 EXPORT_SYMBOL(iterate_dir);
 
 /*
+ * POSIX says that a dirent name cannot contain NULL or a '/'.
+ *
+ * It's not 100% clear what we should really do in this case.
+ * The filesystem is clearly corrupted, but returning a hard
+ * error means that you now don't see any of the other names
+ * either, so that isn't a perfect alternative.
+ *
+ * And if you return an error, what error do you use? Several
+ * filesystems seem to have decided on EUCLEAN being the error
+ * code for EFSCORRUPTED, and that may be the error to use. Or
+ * just EIO, which is perhaps more obvious to users.
+ *
+ * In order to see the other file names in the directory, the
+ * caller might want to make this a "soft" error: skip the
+ * entry, and return the error at the end instead.
+ *
+ * Note that this should likely do a "memchr(name, 0, len)"
+ * check too, since that would be filesystem corruption as
+ * well. However, that case can't actually confuse user space,
+ * which has to do a strlen() on the name anyway to find the
+ * filename length, and the above "soft error" worry means
+ * that it's probably better left alone until we have that
+ * issue clarified.
+ */
+static int verify_dirent_name(const char *name, int len)
+{
+       if (!len)
+               return -EIO;
+       if (memchr(name, '/', len))
+               return -EIO;
+       return 0;
+}
+
+/*
  * Traditional linux readdir() handling..
  *
  * "count=1" is a special case, meaning that the buffer is one
@@ -173,6 +207,9 @@ static int filldir(struct dir_context *ctx, const char *name, int namlen,
        int reclen = ALIGN(offsetof(struct linux_dirent, d_name) + namlen + 2,
                sizeof(long));
 
+       buf->error = verify_dirent_name(name, namlen);
+       if (unlikely(buf->error))
+               return buf->error;
        buf->error = -EINVAL;   /* only used if we fail.. */
        if (reclen > buf->count)
                return -EINVAL;
@@ -259,6 +296,9 @@ static int filldir64(struct dir_context *ctx, const char *name, int namlen,
        int reclen = ALIGN(offsetof(struct linux_dirent64, d_name) + namlen + 1,
                sizeof(u64));
 
+       buf->error = verify_dirent_name(name, namlen);
+       if (unlikely(buf->error))
+               return buf->error;
        buf->error = -EINVAL;   /* only used if we fail.. */
        if (reclen > buf->count)
                return -EINVAL;
index 132ec44..6419e6d 100644 (file)
@@ -2097,6 +2097,15 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th,
                goto out_inserted_sd;
        }
 
+       /*
+        * Mark it private if we're creating the privroot
+        * or something under it.
+        */
+       if (IS_PRIVATE(dir) || dentry == REISERFS_SB(sb)->priv_root) {
+               inode->i_flags |= S_PRIVATE;
+               inode->i_opflags &= ~IOP_XATTR;
+       }
+
        if (reiserfs_posixacl(inode->i_sb)) {
                reiserfs_write_unlock(inode->i_sb);
                retval = reiserfs_inherit_default_acl(th, dir, dentry, inode);
@@ -2111,8 +2120,7 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th,
                reiserfs_warning(inode->i_sb, "jdm-13090",
                                 "ACLs aren't enabled in the fs, "
                                 "but vfs thinks they are!");
-       } else if (IS_PRIVATE(dir))
-               inode->i_flags |= S_PRIVATE;
+       }
 
        if (security->name) {
                reiserfs_write_unlock(inode->i_sb);
index 97f3fc4..959a066 100644 (file)
@@ -377,10 +377,13 @@ static struct dentry *reiserfs_lookup(struct inode *dir, struct dentry *dentry,
 
                /*
                 * Propagate the private flag so we know we're
-                * in the priv tree
+                * in the priv tree.  Also clear IOP_XATTR
+                * since we don't have xattrs on xattr files.
                 */
-               if (IS_PRIVATE(dir))
+               if (IS_PRIVATE(dir)) {
                        inode->i_flags |= S_PRIVATE;
+                       inode->i_opflags &= ~IOP_XATTR;
+               }
        }
        reiserfs_write_unlock(dir->i_sb);
        if (retval == IO_ERROR) {
index e5ca9ed..7265801 100644 (file)
@@ -1168,6 +1168,8 @@ static inline int bmap_would_wrap(unsigned bmap_nr)
        return bmap_nr > ((1LL << 16) - 1);
 }
 
+extern const struct xattr_handler *reiserfs_xattr_handlers[];
+
 /*
  * this says about version of key of all items (but stat data) the
  * object consists of
index 1fc934d..a350749 100644 (file)
@@ -2052,6 +2052,8 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent)
        if (replay_only(s))
                goto error_unlocked;
 
+       s->s_xattr = reiserfs_xattr_handlers;
+
        if (bdev_read_only(s->s_bdev) && !sb_rdonly(s)) {
                SWARN(silent, s, "clm-7000",
                      "Detected readonly device, marking FS readonly");
index 32d8986..2c5c459 100644 (file)
@@ -122,13 +122,13 @@ static struct dentry *open_xa_root(struct super_block *sb, int flags)
        struct dentry *xaroot;
 
        if (d_really_is_negative(privroot))
-               return ERR_PTR(-ENODATA);
+               return ERR_PTR(-EOPNOTSUPP);
 
        inode_lock_nested(d_inode(privroot), I_MUTEX_XATTR);
 
        xaroot = dget(REISERFS_SB(sb)->xattr_root);
        if (!xaroot)
-               xaroot = ERR_PTR(-ENODATA);
+               xaroot = ERR_PTR(-EOPNOTSUPP);
        else if (d_really_is_negative(xaroot)) {
                int err = -ENODATA;
 
@@ -610,6 +610,10 @@ int reiserfs_xattr_set(struct inode *inode, const char *name,
        int error, error2;
        size_t jbegin_count = reiserfs_xattr_nblocks(inode, buffer_size);
 
+       /* Check before we start a transaction and then do nothing. */
+       if (!d_really_is_positive(REISERFS_SB(inode->i_sb)->priv_root))
+               return -EOPNOTSUPP;
+
        if (!(flags & XATTR_REPLACE))
                jbegin_count += reiserfs_xattr_jcreate_nblocks(inode);
 
@@ -832,8 +836,7 @@ ssize_t reiserfs_listxattr(struct dentry * dentry, char *buffer, size_t size)
        if (d_really_is_negative(dentry))
                return -EINVAL;
 
-       if (!dentry->d_sb->s_xattr ||
-           get_inode_sd_version(d_inode(dentry)) == STAT_DATA_V1)
+       if (get_inode_sd_version(d_inode(dentry)) == STAT_DATA_V1)
                return -EOPNOTSUPP;
 
        dir = open_xa_dir(d_inode(dentry), XATTR_REPLACE);
@@ -873,6 +876,7 @@ static int create_privroot(struct dentry *dentry)
        }
 
        d_inode(dentry)->i_flags |= S_PRIVATE;
+       d_inode(dentry)->i_opflags &= ~IOP_XATTR;
        reiserfs_info(dentry->d_sb, "Created %s - reserved for xattr "
                      "storage.\n", PRIVROOT_NAME);
 
@@ -886,7 +890,7 @@ static int create_privroot(struct dentry *dentry) { return 0; }
 #endif
 
 /* Actual operations that are exported to VFS-land */
-static const struct xattr_handler *reiserfs_xattr_handlers[] = {
+const struct xattr_handler *reiserfs_xattr_handlers[] = {
 #ifdef CONFIG_REISERFS_FS_XATTR
        &reiserfs_xattr_user_handler,
        &reiserfs_xattr_trusted_handler,
@@ -957,8 +961,10 @@ int reiserfs_lookup_privroot(struct super_block *s)
        if (!IS_ERR(dentry)) {
                REISERFS_SB(s)->priv_root = dentry;
                d_set_d_op(dentry, &xattr_lookup_poison_ops);
-               if (d_really_is_positive(dentry))
+               if (d_really_is_positive(dentry)) {
                        d_inode(dentry)->i_flags |= S_PRIVATE;
+                       d_inode(dentry)->i_opflags &= ~IOP_XATTR;
+               }
        } else
                err = PTR_ERR(dentry);
        inode_unlock(d_inode(s->s_root));
@@ -987,7 +993,6 @@ int reiserfs_xattr_init(struct super_block *s, int mount_flags)
        }
 
        if (d_really_is_positive(privroot)) {
-               s->s_xattr = reiserfs_xattr_handlers;
                inode_lock(d_inode(privroot));
                if (!REISERFS_SB(s)->xattr_root) {
                        struct dentry *dentry;
index aa9380b..05f6667 100644 (file)
@@ -320,10 +320,8 @@ reiserfs_inherit_default_acl(struct reiserfs_transaction_handle *th,
         * would be useless since permissions are ignored, and a pain because
         * it introduces locking cycles
         */
-       if (IS_PRIVATE(dir)) {
-               inode->i_flags |= S_PRIVATE;
+       if (IS_PRIVATE(inode))
                goto apply_umask;
-       }
 
        err = posix_acl_create(dir, &inode->i_mode, &default_acl, &acl);
        if (err)
index 8af8c31..fd28c7d 100644 (file)
@@ -949,12 +949,13 @@ ssize_t splice_direct_to_actor(struct file *in, struct splice_desc *sd,
        WARN_ON_ONCE(pipe->nrbufs != 0);
 
        while (len) {
+               unsigned int pipe_pages;
                size_t read_len;
                loff_t pos = sd->pos, prev_pos = pos;
 
                /* Don't try to read more the pipe has space for. */
-               read_len = min_t(size_t, len,
-                                (pipe->buffers - pipe->nrbufs) << PAGE_SHIFT);
+               pipe_pages = pipe->buffers - pipe->nrbufs;
+               read_len = min(len, (size_t)pipe_pages << PAGE_SHIFT);
                ret = do_splice_to(in, &pos, pipe, read_len, flags);
                if (unlikely(ret <= 0))
                        goto out_release;
@@ -1175,8 +1176,15 @@ static long do_splice(struct file *in, loff_t __user *off_in,
 
                pipe_lock(opipe);
                ret = wait_for_space(opipe, flags);
-               if (!ret)
+               if (!ret) {
+                       unsigned int pipe_pages;
+
+                       /* Don't try to read more the pipe has space for. */
+                       pipe_pages = opipe->buffers - opipe->nrbufs;
+                       len = min(len, (size_t)pipe_pages << PAGE_SHIFT);
+
                        ret = do_splice_to(in, &offset, opipe, len, flags);
+               }
                pipe_unlock(opipe);
                if (ret > 0)
                        wakeup_pipe_readers(opipe);
index 9c2955f..d269d11 100644 (file)
@@ -1833,13 +1833,12 @@ static int userfaultfd_api(struct userfaultfd_ctx *ctx,
        if (copy_from_user(&uffdio_api, buf, sizeof(uffdio_api)))
                goto out;
        features = uffdio_api.features;
-       if (uffdio_api.api != UFFD_API || (features & ~UFFD_API_FEATURES)) {
-               memset(&uffdio_api, 0, sizeof(uffdio_api));
-               if (copy_to_user(buf, &uffdio_api, sizeof(uffdio_api)))
-                       goto out;
-               ret = -EINVAL;
-               goto out;
-       }
+       ret = -EINVAL;
+       if (uffdio_api.api != UFFD_API || (features & ~UFFD_API_FEATURES))
+               goto err_out;
+       ret = -EPERM;
+       if ((features & UFFD_FEATURE_EVENT_FORK) && !capable(CAP_SYS_PTRACE))
+               goto err_out;
        /* report all available features and ioctls to userland */
        uffdio_api.features = UFFD_API_FEATURES;
        uffdio_api.ioctls = UFFD_API_IOCTLS;
@@ -1852,6 +1851,11 @@ static int userfaultfd_api(struct userfaultfd_ctx *ctx,
        ret = 0;
 out:
        return ret;
+err_out:
+       memset(&uffdio_api, 0, sizeof(uffdio_api));
+       if (copy_to_user(buf, &uffdio_api, sizeof(uffdio_api)))
+               ret = -EFAULT;
+       goto out;
 }
 
 static long userfaultfd_ioctl(struct file *file, unsigned cmd,
index 7f78d26..0f7439f 100644 (file)
@@ -313,7 +313,7 @@ struct drm_dp_resource_status_notify {
 
 struct drm_dp_query_payload_ack_reply {
        u8 port_number;
-       u8 allocated_pbn;
+       u16 allocated_pbn;
 };
 
 struct drm_dp_sideband_msg_req_body {
index 72f59e8..3361663 100644 (file)
@@ -563,17 +563,6 @@ struct governor_attr {
                         size_t count);
 };
 
-static inline bool cpufreq_this_cpu_can_update(struct cpufreq_policy *policy)
-{
-       /*
-        * Allow remote callbacks if:
-        * - dvfs_possible_from_any_cpu flag is set
-        * - the local and remote CPUs share cpufreq policy
-        */
-       return policy->dvfs_possible_from_any_cpu ||
-               cpumask_test_cpu(smp_processor_id(), policy->cpus);
-}
-
 /*********************************************************************
  *                     FREQUENCY TABLE HELPERS                       *
  *********************************************************************/
index 3892e9c..542b4fa 100644 (file)
@@ -430,12 +430,18 @@ extern u64 hrtimer_next_event_without(const struct hrtimer *exclude);
 
 extern bool hrtimer_active(const struct hrtimer *timer);
 
-/*
- * Helper function to check, whether the timer is on one of the queues
+/**
+ * hrtimer_is_queued = check, whether the timer is on one of the queues
+ * @timer:     Timer to check
+ *
+ * Returns: True if the timer is queued, false otherwise
+ *
+ * The function can be used lockless, but it gives only a current snapshot.
  */
-static inline int hrtimer_is_queued(struct hrtimer *timer)
+static inline bool hrtimer_is_queued(struct hrtimer *timer)
 {
-       return timer->state & HRTIMER_STATE_ENQUEUED;
+       /* The READ_ONCE pairs with the update functions of timer->state */
+       return !!(READ_ONCE(timer->state) & HRTIMER_STATE_ENQUEUED);
 }
 
 /*
index 7722722..e375f22 100644 (file)
@@ -91,7 +91,11 @@ extern bool is_vma_temporary_stack(struct vm_area_struct *vma);
 
 extern unsigned long transparent_hugepage_flags;
 
-static inline bool transparent_hugepage_enabled(struct vm_area_struct *vma)
+/*
+ * to be used on vmas which are known to support THP.
+ * Use transparent_hugepage_enabled otherwise
+ */
+static inline bool __transparent_hugepage_enabled(struct vm_area_struct *vma)
 {
        if (vma->vm_flags & VM_NOHUGEPAGE)
                return false;
@@ -115,6 +119,8 @@ static inline bool transparent_hugepage_enabled(struct vm_area_struct *vma)
        return false;
 }
 
+bool transparent_hugepage_enabled(struct vm_area_struct *vma);
+
 #define transparent_hugepage_use_zero_page()                           \
        (transparent_hugepage_flags &                                   \
         (1<<TRANSPARENT_HUGEPAGE_USE_ZERO_PAGE_FLAG))
@@ -255,6 +261,11 @@ static inline bool thp_migration_supported(void)
 
 #define hpage_nr_pages(x) 1
 
+static inline bool __transparent_hugepage_enabled(struct vm_area_struct *vma)
+{
+       return false;
+}
+
 static inline bool transparent_hugepage_enabled(struct vm_area_struct *vma)
 {
        return false;
index 7d5fd38..1995ce1 100644 (file)
@@ -211,10 +211,14 @@ static inline int ipmi_demangle_device_id(uint8_t netfn, uint8_t cmd,
  * is called, and the lower layer must get the interface from that
  * call.
  */
-int ipmi_register_smi(const struct ipmi_smi_handlers *handlers,
-                     void                     *send_info,
-                     struct device            *dev,
-                     unsigned char            slave_addr);
+int ipmi_add_smi(struct module            *owner,
+                const struct ipmi_smi_handlers *handlers,
+                void                     *send_info,
+                struct device            *dev,
+                unsigned char            slave_addr);
+
+#define ipmi_register_smi(handlers, send_info, dev, slave_addr) \
+       ipmi_add_smi(THIS_MODULE, handlers, send_info, dev, slave_addr)
 
 /*
  * Remove a low-level interface from the IPMI driver.  This will
index edb0f0c..1adf54a 100644 (file)
@@ -7,6 +7,9 @@
 
 #include <asm/byteorder.h>
 
+#define INT32_MAX      S32_MAX
+#define UINT32_MAX     U32_MAX
+
 typedef __be16 fdt16_t;
 typedef __be32 fdt32_t;
 typedef __be64 fdt64_t;
index d315659..338e0f6 100644 (file)
@@ -443,7 +443,7 @@ enum {
 enum {
        RK805_ID = 0x8050,
        RK808_ID = 0x0000,
-       RK818_ID = 0x8181,
+       RK818_ID = 0x8180,
 };
 
 struct rk808 {
index 3247a3d..b06b757 100644 (file)
@@ -57,6 +57,7 @@
 #define UHID_MINOR             239
 #define USERIO_MINOR           240
 #define VHOST_VSOCK_MINOR      241
+#define RFKILL_MINOR           242
 #define MISC_DYNAMIC_MINOR     255
 
 struct device;
index 01797cb..867db9b 100644 (file)
@@ -551,9 +551,9 @@ struct platform_device_id {
 #define MDIO_NAME_SIZE         32
 #define MDIO_MODULE_PREFIX     "mdio:"
 
-#define MDIO_ID_FMT "%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d"
+#define MDIO_ID_FMT "%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u"
 #define MDIO_ID_ARGS(_id) \
-       (_id)>>31, ((_id)>>30) & 1, ((_id)>>29) & 1, ((_id)>>28) & 1,   \
+       ((_id)>>31) & 1, ((_id)>>30) & 1, ((_id)>>29) & 1, ((_id)>>28) & 1, \
        ((_id)>>27) & 1, ((_id)>>26) & 1, ((_id)>>25) & 1, ((_id)>>24) & 1, \
        ((_id)>>23) & 1, ((_id)>>22) & 1, ((_id)>>21) & 1, ((_id)>>20) & 1, \
        ((_id)>>19) & 1, ((_id)>>18) & 1, ((_id)>>17) & 1, ((_id)>>16) & 1, \
index 5ada5fd..9dfa0ae 100644 (file)
@@ -1834,6 +1834,11 @@ struct net_device {
        unsigned char           if_port;
        unsigned char           dma;
 
+       /* Note : dev->mtu is often read without holding a lock.
+        * Writers usually hold RTNL.
+        * It is recommended to use READ_ONCE() to annotate the reads,
+        * and to use WRITE_ONCE() to annotate the writes.
+        */
        unsigned int            mtu;
        unsigned int            min_mtu;
        unsigned int            max_mtu;
index 3a3bc71..03cb1f2 100644 (file)
@@ -82,29 +82,32 @@ struct posix_clock_operations {
  *
  * @ops:     Functional interface to the clock
  * @cdev:    Character device instance for this clock
- * @kref:    Reference count.
+ * @dev:     Pointer to the clock's device.
  * @rwsem:   Protects the 'zombie' field from concurrent access.
  * @zombie:  If 'zombie' is true, then the hardware has disappeared.
- * @release: A function to free the structure when the reference count reaches
- *           zero. May be NULL if structure is statically allocated.
  *
  * Drivers should embed their struct posix_clock within a private
  * structure, obtaining a reference to it during callbacks using
  * container_of().
+ *
+ * Drivers should supply an initialized but not exposed struct device
+ * to posix_clock_register(). It is used to manage lifetime of the
+ * driver's private structure. It's 'release' field should be set to
+ * a release function for this private structure.
  */
 struct posix_clock {
        struct posix_clock_operations ops;
        struct cdev cdev;
-       struct kref kref;
+       struct device *dev;
        struct rw_semaphore rwsem;
        bool zombie;
-       void (*release)(struct posix_clock *clk);
 };
 
 /**
  * posix_clock_register() - register a new clock
- * @clk:   Pointer to the clock. Caller must provide 'ops' and 'release'
- * @devid: Allocated device id
+ * @clk:   Pointer to the clock. Caller must provide 'ops' field
+ * @dev:   Pointer to the initialized device. Caller must provide
+ *         'release' field
  *
  * A clock driver calls this function to register itself with the
  * clock device subsystem. If 'clk' points to dynamically allocated
@@ -113,7 +116,7 @@ struct posix_clock {
  *
  * Returns zero on success, non-zero otherwise.
  */
-int posix_clock_register(struct posix_clock *clk, dev_t devid);
+int posix_clock_register(struct posix_clock *clk, struct device *dev);
 
 /**
  * posix_clock_unregister() - unregister a clock
index f32dd27..27aab84 100644 (file)
@@ -263,7 +263,7 @@ enum {
 };
 
 struct dqstats {
-       int stat[_DQST_DQSTAT_LAST];
+       unsigned long stat[_DQST_DQSTAT_LAST];
        struct percpu_counter counter[_DQST_DQSTAT_LAST];
 };
 
index 185d948..91e0b76 100644 (file)
@@ -54,6 +54,16 @@ static inline struct dquot *dqgrab(struct dquot *dquot)
        atomic_inc(&dquot->dq_count);
        return dquot;
 }
+
+static inline bool dquot_is_busy(struct dquot *dquot)
+{
+       if (test_bit(DQ_MOD_B, &dquot->dq_flags))
+               return true;
+       if (atomic_read(&dquot->dq_count) > 1)
+               return true;
+       return false;
+}
+
 void dqput(struct dquot *dquot);
 int dquot_scan_active(struct super_block *sb,
                      int (*fn)(struct dquot *dquot, unsigned long priv),
index bc8206a..61974c4 100644 (file)
@@ -101,6 +101,43 @@ static inline void hlist_nulls_add_head_rcu(struct hlist_nulls_node *n,
 }
 
 /**
+ * hlist_nulls_add_tail_rcu
+ * @n: the element to add to the hash list.
+ * @h: the list to add to.
+ *
+ * Description:
+ * Adds the specified element to the specified hlist_nulls,
+ * while permitting racing traversals.
+ *
+ * The caller must take whatever precautions are necessary
+ * (such as holding appropriate locks) to avoid racing
+ * with another list-mutation primitive, such as hlist_nulls_add_head_rcu()
+ * or hlist_nulls_del_rcu(), running on this same list.
+ * However, it is perfectly legal to run concurrently with
+ * the _rcu list-traversal primitives, such as
+ * hlist_nulls_for_each_entry_rcu(), used to prevent memory-consistency
+ * problems on Alpha CPUs.  Regardless of the type of CPU, the
+ * list-traversal primitive must be guarded by rcu_read_lock().
+ */
+static inline void hlist_nulls_add_tail_rcu(struct hlist_nulls_node *n,
+                                           struct hlist_nulls_head *h)
+{
+       struct hlist_nulls_node *i, *last = NULL;
+
+       /* Note: write side code, so rcu accessors are not needed. */
+       for (i = h->first; !is_a_nulls(i); i = i->next)
+               last = i;
+
+       if (last) {
+               n->next = last->next;
+               n->pprev = &last->next;
+               rcu_assign_pointer(hlist_next_rcu(last), n);
+       } else {
+               hlist_nulls_add_head_rcu(n, h);
+       }
+}
+
+/**
  * hlist_nulls_for_each_entry_rcu - iterate over rcu list of given type
  * @tpos:      the type * to use as a loop cursor.
  * @pos:       the &struct hlist_nulls_node to use as a loop cursor.
index 5966744..a4530d7 100644 (file)
@@ -12,6 +12,8 @@
 #define SCHED_CPUFREQ_MIGRATION        (1U << 1)
 
 #ifdef CONFIG_CPU_FREQ
+struct cpufreq_policy;
+
 struct update_util_data {
        void (*func)(struct update_util_data *data, u64 time, unsigned int flags);
 };
@@ -20,6 +22,7 @@ void cpufreq_add_update_util_hook(int cpu, struct update_util_data *data,
                        void (*func)(struct update_util_data *data, u64 time,
                                    unsigned int flags));
 void cpufreq_remove_update_util_hook(int cpu);
+bool cpufreq_this_cpu_can_update(struct cpufreq_policy *policy);
 #endif /* CONFIG_CPU_FREQ */
 
 #endif /* _LINUX_SCHED_CPUFREQ_H */
index 80c3da1..25407c2 100644 (file)
@@ -1669,7 +1669,7 @@ static inline struct sk_buff *skb_peek_next(struct sk_buff *skb,
  */
 static inline struct sk_buff *skb_peek_tail(const struct sk_buff_head *list_)
 {
-       struct sk_buff *skb = list_->prev;
+       struct sk_buff *skb = READ_ONCE(list_->prev);
 
        if (skb == (struct sk_buff *)list_)
                skb = NULL;
@@ -1737,7 +1737,9 @@ static inline void __skb_insert(struct sk_buff *newsk,
                                struct sk_buff *prev, struct sk_buff *next,
                                struct sk_buff_head *list)
 {
-       /* see skb_queue_empty_lockless() for the opposite READ_ONCE() */
+       /* See skb_queue_empty_lockless() and skb_peek_tail()
+        * for the opposite READ_ONCE()
+        */
        WRITE_ONCE(newsk->next, next);
        WRITE_ONCE(newsk->prev, prev);
        WRITE_ONCE(next->prev, newsk);
index 27d83fd..5f3e499 100644 (file)
@@ -96,4 +96,17 @@ static inline bool itimerspec64_valid(const struct itimerspec64 *its)
  */
 #define time_after32(a, b)     ((s32)((u32)(b) - (u32)(a)) < 0)
 #define time_before32(b, a)    time_after32(a, b)
+
+/**
+ * time_between32 - check if a 32-bit timestamp is within a given time range
+ * @t: the time which may be within [l,h]
+ * @l: the lower bound of the range
+ * @h: the higher bound of the range
+ *
+ * time_before32(t, l, h) returns true if @l <= @t <= @h. All operands are
+ * treated as 32-bit integers.
+ *
+ * Equivalent to !(time_before32(@t, @l) || time_after32(@t, @h)).
+ */
+#define time_between32(t, l, h) ((u32)(h) - (u32)(l) >= (u32)(t) - (u32)(l))
 #endif
index ffc8ee0..35ae45f 100644 (file)
@@ -93,7 +93,7 @@ struct dst_entry {
 struct dst_metrics {
        u32             metrics[RTAX_MAX];
        refcount_t      refcnt;
-};
+} __aligned(4);                /* Low pointer bits contain DST_METRICS_FLAGS */
 extern const struct dst_metrics dst_default_metrics;
 
 u32 *dst_cow_metrics_generic(struct dst_entry *dst, unsigned long old);
@@ -527,7 +527,16 @@ static inline void skb_dst_update_pmtu(struct sk_buff *skb, u32 mtu)
        struct dst_entry *dst = skb_dst(skb);
 
        if (dst && dst->ops->update_pmtu)
-               dst->ops->update_pmtu(dst, NULL, skb, mtu);
+               dst->ops->update_pmtu(dst, NULL, skb, mtu, true);
+}
+
+/* update dst pmtu but not do neighbor confirm */
+static inline void skb_dst_update_pmtu_no_confirm(struct sk_buff *skb, u32 mtu)
+{
+       struct dst_entry *dst = skb_dst(skb);
+
+       if (dst && dst->ops->update_pmtu)
+               dst->ops->update_pmtu(dst, NULL, skb, mtu, false);
 }
 
 static inline void skb_tunnel_check_pmtu(struct sk_buff *skb,
@@ -537,7 +546,7 @@ static inline void skb_tunnel_check_pmtu(struct sk_buff *skb,
        u32 encap_mtu = dst_mtu(encap_dst);
 
        if (skb->len > encap_mtu - headroom)
-               skb_dst_update_pmtu(skb, encap_mtu - headroom);
+               skb_dst_update_pmtu_no_confirm(skb, encap_mtu - headroom);
 }
 
 #endif /* _NET_DST_H */
index 5ec645f..443863c 100644 (file)
@@ -27,7 +27,8 @@ struct dst_ops {
        struct dst_entry *      (*negative_advice)(struct dst_entry *);
        void                    (*link_failure)(struct sk_buff *);
        void                    (*update_pmtu)(struct dst_entry *dst, struct sock *sk,
-                                              struct sk_buff *skb, u32 mtu);
+                                              struct sk_buff *skb, u32 mtu,
+                                              bool confirm_neigh);
        void                    (*redirect)(struct dst_entry *dst, struct sock *sk,
                                            struct sk_buff *skb);
        int                     (*local_out)(struct net *net, struct sock *sk, struct sk_buff *skb);
index 9141e95..b875dce 100644 (file)
@@ -106,13 +106,19 @@ struct inet_bind_hashbucket {
        struct hlist_head       chain;
 };
 
-/*
- * Sockets can be hashed in established or listening table
+/* Sockets can be hashed in established or listening table.
+ * We must use different 'nulls' end-of-chain value for all hash buckets :
+ * A socket might transition from ESTABLISH to LISTEN state without
+ * RCU grace period. A lookup in ehash table needs to handle this case.
  */
+#define LISTENING_NULLS_BASE (1U << 29)
 struct inet_listen_hashbucket {
        spinlock_t              lock;
        unsigned int            count;
-       struct hlist_head       head;
+       union {
+               struct hlist_head       head;
+               struct hlist_nulls_head nulls_head;
+       };
 };
 
 /* This is for listening sockets, thus all sockets which possess wildcards. */
index cfc3dd5..5b29f35 100644 (file)
@@ -692,4 +692,9 @@ int ip_misc_proc_init(void);
 int rtm_getroute_parse_ip_proto(struct nlattr *attr, u8 *ip_proto, u8 family,
                                struct netlink_ext_ack *extack);
 
+static inline bool inetdev_valid_mtu(unsigned int mtu)
+{
+       return likely(mtu >= IPV4_MIN_MTU);
+}
+
 #endif /* _IP_H */
index 4545a9e..f359e5c 100644 (file)
@@ -721,6 +721,11 @@ static inline void __sk_nulls_add_node_rcu(struct sock *sk, struct hlist_nulls_h
        hlist_nulls_add_head_rcu(&sk->sk_nulls_node, list);
 }
 
+static inline void __sk_nulls_add_node_tail_rcu(struct sock *sk, struct hlist_nulls_head *list)
+{
+       hlist_nulls_add_tail_rcu(&sk->sk_nulls_node, list);
+}
+
 static inline void sk_nulls_add_node_rcu(struct sock *sk, struct hlist_nulls_head *list)
 {
        sock_hold(sk);
index 3f4223a..ac4ffe8 100644 (file)
@@ -485,15 +485,16 @@ static inline void tcp_synq_overflow(const struct sock *sk)
                reuse = rcu_dereference(sk->sk_reuseport_cb);
                if (likely(reuse)) {
                        last_overflow = READ_ONCE(reuse->synq_overflow_ts);
-                       if (time_after32(now, last_overflow + HZ))
+                       if (!time_between32(now, last_overflow,
+                                           last_overflow + HZ))
                                WRITE_ONCE(reuse->synq_overflow_ts, now);
                        return;
                }
        }
 
-       last_overflow = tcp_sk(sk)->rx_opt.ts_recent_stamp;
-       if (time_after32(now, last_overflow + HZ))
-               tcp_sk(sk)->rx_opt.ts_recent_stamp = now;
+       last_overflow = READ_ONCE(tcp_sk(sk)->rx_opt.ts_recent_stamp);
+       if (!time_between32(now, last_overflow, last_overflow + HZ))
+               WRITE_ONCE(tcp_sk(sk)->rx_opt.ts_recent_stamp, now);
 }
 
 /* syncookies: no recent synqueue overflow on this listening socket? */
@@ -508,13 +509,23 @@ static inline bool tcp_synq_no_recent_overflow(const struct sock *sk)
                reuse = rcu_dereference(sk->sk_reuseport_cb);
                if (likely(reuse)) {
                        last_overflow = READ_ONCE(reuse->synq_overflow_ts);
-                       return time_after32(now, last_overflow +
-                                           TCP_SYNCOOKIE_VALID);
+                       return !time_between32(now, last_overflow - HZ,
+                                              last_overflow +
+                                              TCP_SYNCOOKIE_VALID);
                }
        }
 
-       last_overflow = tcp_sk(sk)->rx_opt.ts_recent_stamp;
-       return time_after32(now, last_overflow + TCP_SYNCOOKIE_VALID);
+       last_overflow = READ_ONCE(tcp_sk(sk)->rx_opt.ts_recent_stamp);
+
+       /* If last_overflow <= jiffies <= last_overflow + TCP_SYNCOOKIE_VALID,
+        * then we're under synflood. However, we have to use
+        * 'last_overflow - HZ' as lower bound. That's because a concurrent
+        * tcp_synq_overflow() could update .ts_recent_stamp after we read
+        * jiffies but before we store .ts_recent_stamp into last_overflow,
+        * which could lead to rejecting a valid syncookie.
+        */
+       return !time_between32(now, last_overflow - HZ,
+                              last_overflow + TCP_SYNCOOKIE_VALID);
 }
 
 static inline u32 tcp_cookie_time(void)
index df156f1..f0a01a5 100644 (file)
@@ -638,6 +638,7 @@ struct iscsi_reject {
 #define ISCSI_REASON_BOOKMARK_INVALID  9
 #define ISCSI_REASON_BOOKMARK_NO_RESOURCES     10
 #define ISCSI_REASON_NEGOTIATION_RESET 11
+#define ISCSI_REASON_WAITING_FOR_LOGOUT        12
 
 /* Max. number of Key=Value pairs in a text message */
 #define MAX_KEY_VALUE_PAIRS    8192
index b048694..37342a1 100644 (file)
@@ -33,7 +33,8 @@ TRACE_EVENT(wbt_stat,
        ),
 
        TP_fast_assign(
-               strncpy(__entry->name, dev_name(bdi->dev), 32);
+               strlcpy(__entry->name, dev_name(bdi->dev),
+                       ARRAY_SIZE(__entry->name));
                __entry->rmean          = stat[0].mean;
                __entry->rmin           = stat[0].min;
                __entry->rmax           = stat[0].max;
@@ -67,7 +68,8 @@ TRACE_EVENT(wbt_lat,
        ),
 
        TP_fast_assign(
-               strncpy(__entry->name, dev_name(bdi->dev), 32);
+               strlcpy(__entry->name, dev_name(bdi->dev),
+                       ARRAY_SIZE(__entry->name));
                __entry->lat = div_u64(lat, 1000);
        ),
 
@@ -103,7 +105,8 @@ TRACE_EVENT(wbt_step,
        ),
 
        TP_fast_assign(
-               strncpy(__entry->name, dev_name(bdi->dev), 32);
+               strlcpy(__entry->name, dev_name(bdi->dev),
+                       ARRAY_SIZE(__entry->name));
                __entry->msg    = msg;
                __entry->step   = step;
                __entry->window = div_u64(window, 1000);
@@ -138,7 +141,8 @@ TRACE_EVENT(wbt_timer,
        ),
 
        TP_fast_assign(
-               strncpy(__entry->name, dev_name(bdi->dev), 32);
+               strlcpy(__entry->name, dev_name(bdi->dev),
+                       ARRAY_SIZE(__entry->name));
                __entry->status         = status;
                __entry->step           = step;
                __entry->inflight       = inflight;
index 8997d50..4511b85 100644 (file)
@@ -923,7 +923,8 @@ static inline void cec_msg_give_deck_status(struct cec_msg *msg,
        msg->len = 3;
        msg->msg[1] = CEC_MSG_GIVE_DECK_STATUS;
        msg->msg[2] = status_req;
-       msg->reply = reply ? CEC_MSG_DECK_STATUS : 0;
+       msg->reply = (reply && status_req != CEC_OP_STATUS_REQ_OFF) ?
+                               CEC_MSG_DECK_STATUS : 0;
 }
 
 static inline void cec_ops_give_deck_status(const struct cec_msg *msg,
@@ -1027,7 +1028,8 @@ static inline void cec_msg_give_tuner_device_status(struct cec_msg *msg,
        msg->len = 3;
        msg->msg[1] = CEC_MSG_GIVE_TUNER_DEVICE_STATUS;
        msg->msg[2] = status_req;
-       msg->reply = reply ? CEC_MSG_TUNER_DEVICE_STATUS : 0;
+       msg->reply = (reply && status_req != CEC_OP_STATUS_REQ_OFF) ?
+                               CEC_MSG_TUNER_DEVICE_STATUS : 0;
 }
 
 static inline void cec_ops_give_tuner_device_status(const struct cec_msg *msg,
index 3094af6..d6ba688 100644 (file)
@@ -767,8 +767,8 @@ struct cec_event {
 #define CEC_MSG_SELECT_DIGITAL_SERVICE                 0x93
 #define CEC_MSG_TUNER_DEVICE_STATUS                    0x07
 /* Recording Flag Operand (rec_flag) */
-#define CEC_OP_REC_FLAG_USED                           0
-#define CEC_OP_REC_FLAG_NOT_USED                       1
+#define CEC_OP_REC_FLAG_NOT_USED                       0
+#define CEC_OP_REC_FLAG_USED                           1
 /* Tuner Display Info Operand (tuner_display_info) */
 #define CEC_OP_TUNER_DISPLAY_INFO_DIGITAL              0
 #define CEC_OP_TUNER_DISPLAY_INFO_NONE                 1
index 7cb7a7f..55fff5e 100644 (file)
@@ -292,7 +292,7 @@ static void stack_map_get_build_id_offset(struct bpf_stack_build_id *id_offs,
        bool irq_work_busy = false;
        struct stack_map_irq_work *work = NULL;
 
-       if (in_nmi()) {
+       if (irqs_disabled()) {
                work = this_cpu_ptr(&up_read_work);
                if (work->irq_work.flags & IRQ_WORK_BUSY)
                        /* cannot queue more up_read, fallback */
@@ -300,8 +300,9 @@ static void stack_map_get_build_id_offset(struct bpf_stack_build_id *id_offs,
        }
 
        /*
-        * We cannot do up_read() in nmi context. To do build_id lookup
-        * in nmi context, we need to run up_read() in irq_work. We use
+        * We cannot do up_read() when the irq is disabled, because of
+        * risk to deadlock with rq_lock. To do build_id lookup when the
+        * irqs are disabled, we need to run up_read() in irq_work. We use
         * a percpu variable to do the irq_work. If the irq_work is
         * already used by another lookup, we fall back to report ips.
         *
index c9960ba..940d2e8 100644 (file)
@@ -48,7 +48,7 @@ struct pids_cgroup {
         * %PIDS_MAX = (%PID_MAX_LIMIT + 1).
         */
        atomic64_t                      counter;
-       int64_t                         limit;
+       atomic64_t                      limit;
 
        /* Handle for "pids.events" */
        struct cgroup_file              events_file;
@@ -76,8 +76,8 @@ pids_css_alloc(struct cgroup_subsys_state *parent)
        if (!pids)
                return ERR_PTR(-ENOMEM);
 
-       pids->limit = PIDS_MAX;
        atomic64_set(&pids->counter, 0);
+       atomic64_set(&pids->limit, PIDS_MAX);
        atomic64_set(&pids->events_limit, 0);
        return &pids->css;
 }
@@ -149,13 +149,14 @@ static int pids_try_charge(struct pids_cgroup *pids, int num)
 
        for (p = pids; parent_pids(p); p = parent_pids(p)) {
                int64_t new = atomic64_add_return(num, &p->counter);
+               int64_t limit = atomic64_read(&p->limit);
 
                /*
                 * Since new is capped to the maximum number of pid_t, if
                 * p->limit is %PIDS_MAX then we know that this test will never
                 * fail.
                 */
-               if (new > p->limit)
+               if (new > limit)
                        goto revert;
        }
 
@@ -280,7 +281,7 @@ set_limit:
         * Limit updates don't need to be mutex'd, since it isn't
         * critical that any racing fork()s follow the new limit.
         */
-       pids->limit = limit;
+       atomic64_set(&pids->limit, limit);
        return nbytes;
 }
 
@@ -288,7 +289,7 @@ static int pids_max_show(struct seq_file *sf, void *v)
 {
        struct cgroup_subsys_state *css = seq_css(sf);
        struct pids_cgroup *pids = css_pids(css);
-       int64_t limit = pids->limit;
+       int64_t limit = atomic64_read(&pids->limit);
 
        if (limit >= PIDS_MAX)
                seq_printf(sf, "%s\n", PIDS_MAX_STR);
index c007d25..3a23974 100644 (file)
@@ -442,6 +442,7 @@ void debug_dma_dump_mappings(struct device *dev)
                }
 
                spin_unlock_irqrestore(&bucket->lock, flags);
+               cond_resched();
        }
 }
 
index 8257110..d3aaec6 100644 (file)
@@ -1021,6 +1021,8 @@ SYSCALL_DEFINE2(delete_module, const char __user *, name_user,
        strlcpy(last_unloaded_module, mod->name, sizeof(last_unloaded_module));
 
        free_module(mod);
+       /* someone could wait for the module in add_unformed_module() */
+       wake_up_all(&module_wq);
        return 0;
 out:
        mutex_unlock(&module_mutex);
index 5e54cbc..42ce32a 100644 (file)
@@ -8,6 +8,8 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
+#include <linux/cpufreq.h>
+
 #include "sched.h"
 
 DEFINE_PER_CPU(struct update_util_data *, cpufreq_update_util_data);
@@ -60,3 +62,19 @@ void cpufreq_remove_update_util_hook(int cpu)
        rcu_assign_pointer(per_cpu(cpufreq_update_util_data, cpu), NULL);
 }
 EXPORT_SYMBOL_GPL(cpufreq_remove_update_util_hook);
+
+/**
+ * cpufreq_this_cpu_can_update - Check if cpufreq policy can be updated.
+ * @policy: cpufreq policy to check.
+ *
+ * Return 'true' if:
+ * - the local and remote CPUs share @policy,
+ * - dvfs_possible_from_any_cpu is set in @policy and the local CPU is not going
+ *   offline (in which case it is not expected to run cpufreq updates any more).
+ */
+bool cpufreq_this_cpu_can_update(struct cpufreq_policy *policy)
+{
+       return cpumask_test_cpu(smp_processor_id(), policy->cpus) ||
+               (policy->dvfs_possible_from_any_cpu &&
+                rcu_dereference_sched(*this_cpu_ptr(&cpufreq_update_util_data)));
+}
index 54fcff6..1b7ec82 100644 (file)
@@ -83,12 +83,10 @@ static bool sugov_should_update_freq(struct sugov_policy *sg_policy, u64 time)
         * by the hardware, as calculating the frequency is pointless if
         * we cannot in fact act on it.
         *
-        * For the slow switching platforms, the kthread is always scheduled on
-        * the right set of CPUs and any CPU can find the next frequency and
-        * schedule the kthread.
+        * This is needed on the slow switching platforms too to prevent CPUs
+        * going offline from leaving stale IRQ work items behind.
         */
-       if (sg_policy->policy->fast_switch_enabled &&
-           !cpufreq_this_cpu_can_update(sg_policy->policy))
+       if (!cpufreq_this_cpu_can_update(sg_policy->policy))
                return false;
 
        if (unlikely(sg_policy->limits_changed)) {
index f857650..4c4fd43 100644 (file)
@@ -1411,7 +1411,7 @@ static struct ctl_table vm_table[] = {
                .procname       = "drop_caches",
                .data           = &sysctl_drop_caches,
                .maxlen         = sizeof(int),
-               .mode           = 0644,
+               .mode           = 0200,
                .proc_handler   = drop_caches_sysctl_handler,
                .extra1         = &one,
                .extra2         = &four,
index e1a549c..7362554 100644 (file)
@@ -955,7 +955,8 @@ static int enqueue_hrtimer(struct hrtimer *timer,
 
        base->cpu_base->active_bases |= 1 << base->index;
 
-       timer->state = HRTIMER_STATE_ENQUEUED;
+       /* Pairs with the lockless read in hrtimer_is_queued() */
+       WRITE_ONCE(timer->state, HRTIMER_STATE_ENQUEUED);
 
        return timerqueue_add(&base->active, &timer->node);
 }
@@ -977,7 +978,8 @@ static void __remove_hrtimer(struct hrtimer *timer,
        struct hrtimer_cpu_base *cpu_base = base->cpu_base;
        u8 state = timer->state;
 
-       timer->state = newstate;
+       /* Pairs with the lockless read in hrtimer_is_queued() */
+       WRITE_ONCE(timer->state, newstate);
        if (!(state & HRTIMER_STATE_ENQUEUED))
                return;
 
@@ -1002,8 +1004,9 @@ static void __remove_hrtimer(struct hrtimer *timer,
 static inline int
 remove_hrtimer(struct hrtimer *timer, struct hrtimer_clock_base *base, bool restart)
 {
-       if (hrtimer_is_queued(timer)) {
-               u8 state = timer->state;
+       u8 state = timer->state;
+
+       if (state & HRTIMER_STATE_ENQUEUED) {
                int reprogram;
 
                /*
index fe56c4e..c8a8501 100644 (file)
@@ -27,8 +27,6 @@
 
 #include "posix-timers.h"
 
-static void delete_clock(struct kref *kref);
-
 /*
  * Returns NULL if the posix_clock instance attached to 'fp' is old and stale.
  */
@@ -138,7 +136,7 @@ static int posix_clock_open(struct inode *inode, struct file *fp)
                err = 0;
 
        if (!err) {
-               kref_get(&clk->kref);
+               get_device(clk->dev);
                fp->private_data = clk;
        }
 out:
@@ -154,7 +152,7 @@ static int posix_clock_release(struct inode *inode, struct file *fp)
        if (clk->ops.release)
                err = clk->ops.release(clk);
 
-       kref_put(&clk->kref, delete_clock);
+       put_device(clk->dev);
 
        fp->private_data = NULL;
 
@@ -174,38 +172,35 @@ static const struct file_operations posix_clock_file_operations = {
 #endif
 };
 
-int posix_clock_register(struct posix_clock *clk, dev_t devid)
+int posix_clock_register(struct posix_clock *clk, struct device *dev)
 {
        int err;
 
-       kref_init(&clk->kref);
        init_rwsem(&clk->rwsem);
 
        cdev_init(&clk->cdev, &posix_clock_file_operations);
+       err = cdev_device_add(&clk->cdev, dev);
+       if (err) {
+               pr_err("%s unable to add device %d:%d\n",
+                       dev_name(dev), MAJOR(dev->devt), MINOR(dev->devt));
+               return err;
+       }
        clk->cdev.owner = clk->ops.owner;
-       err = cdev_add(&clk->cdev, devid, 1);
+       clk->dev = dev;
 
-       return err;
+       return 0;
 }
 EXPORT_SYMBOL_GPL(posix_clock_register);
 
-static void delete_clock(struct kref *kref)
-{
-       struct posix_clock *clk = container_of(kref, struct posix_clock, kref);
-
-       if (clk->release)
-               clk->release(clk);
-}
-
 void posix_clock_unregister(struct posix_clock *clk)
 {
-       cdev_del(&clk->cdev);
+       cdev_device_del(&clk->cdev, clk->dev);
 
        down_write(&clk->rwsem);
        clk->zombie = true;
        up_write(&clk->rwsem);
 
-       kref_put(&clk->kref, delete_clock);
+       put_device(clk->dev);
 }
 EXPORT_SYMBOL_GPL(posix_clock_unregister);
 
index bdd7f3d..b6ff2f8 100644 (file)
@@ -4389,7 +4389,7 @@ int set_tracer_flag(struct trace_array *tr, unsigned int mask, int enabled)
 
        if (mask == TRACE_ITER_RECORD_TGID) {
                if (!tgid_map)
-                       tgid_map = kcalloc(PID_MAX_DEFAULT + 1,
+                       tgid_map = kvcalloc(PID_MAX_DEFAULT + 1,
                                           sizeof(*tgid_map),
                                           GFP_KERNEL);
                if (!tgid_map) {
index f9a0cd0..c61b2b0 100644 (file)
@@ -519,11 +519,10 @@ disable_trace_kprobe(struct trace_kprobe *tk, struct trace_event_file *file)
 
 #if defined(CONFIG_KPROBES_ON_FTRACE) && \
        !defined(CONFIG_KPROBE_EVENTS_ON_NOTRACE)
-static bool within_notrace_func(struct trace_kprobe *tk)
+static bool __within_notrace_func(unsigned long addr)
 {
-       unsigned long offset, size, addr;
+       unsigned long offset, size;
 
-       addr = trace_kprobe_address(tk);
        if (!addr || !kallsyms_lookup_size_offset(addr, &size, &offset))
                return false;
 
@@ -536,6 +535,28 @@ static bool within_notrace_func(struct trace_kprobe *tk)
         */
        return !ftrace_location_range(addr, addr + size - 1);
 }
+
+static bool within_notrace_func(struct trace_kprobe *tk)
+{
+       unsigned long addr = addr = trace_kprobe_address(tk);
+       char symname[KSYM_NAME_LEN], *p;
+
+       if (!__within_notrace_func(addr))
+               return false;
+
+       /* Check if the address is on a suffixed-symbol */
+       if (!lookup_symbol_name(addr, symname)) {
+               p = strchr(symname, '.');
+               if (!p)
+                       return true;
+               *p = '\0';
+               addr = (unsigned long)kprobe_lookup_name(symname, 0);
+               if (addr)
+                       return __within_notrace_func(addr);
+       }
+
+       return true;
+}
 #else
 #define within_notrace_func(tk)        (false)
 #endif
index cd8b61b..4939084 100644 (file)
@@ -2413,8 +2413,14 @@ repeat:
                         */
                        if (need_to_create_worker(pool)) {
                                spin_lock(&wq_mayday_lock);
-                               get_pwq(pwq);
-                               list_move_tail(&pwq->mayday_node, &wq->maydays);
+                               /*
+                                * Queue iff we aren't racing destruction
+                                * and somebody else hasn't queued it already.
+                                */
+                               if (wq->rescuer && list_empty(&pwq->mayday_node)) {
+                                       get_pwq(pwq);
+                                       list_add_tail(&pwq->mayday_node, &wq->maydays);
+                               }
                                spin_unlock(&wq_mayday_lock);
                        }
                }
@@ -4154,9 +4160,29 @@ void destroy_workqueue(struct workqueue_struct *wq)
        struct pool_workqueue *pwq;
        int node;
 
+       /*
+        * Remove it from sysfs first so that sanity check failure doesn't
+        * lead to sysfs name conflicts.
+        */
+       workqueue_sysfs_unregister(wq);
+
        /* drain it before proceeding with destruction */
        drain_workqueue(wq);
 
+       /* kill rescuer, if sanity checks fail, leave it w/o rescuer */
+       if (wq->rescuer) {
+               struct worker *rescuer = wq->rescuer;
+
+               /* this prevents new queueing */
+               spin_lock_irq(&wq_mayday_lock);
+               wq->rescuer = NULL;
+               spin_unlock_irq(&wq_mayday_lock);
+
+               /* rescuer will empty maydays list before exiting */
+               kthread_stop(rescuer->task);
+               kfree(rescuer);
+       }
+
        /* sanity checks */
        mutex_lock(&wq->mutex);
        for_each_pwq(pwq, wq) {
@@ -4188,11 +4214,6 @@ void destroy_workqueue(struct workqueue_struct *wq)
        list_del_rcu(&wq->list);
        mutex_unlock(&wq_pool_mutex);
 
-       workqueue_sysfs_unregister(wq);
-
-       if (wq->rescuer)
-               kthread_stop(wq->rescuer->task);
-
        if (!(wq->flags & WQ_UNBOUND)) {
                /*
                 * The base ref is never dropped on per-cpu pwqs.  Directly
@@ -4464,7 +4485,8 @@ static void show_pwq(struct pool_workqueue *pwq)
        pr_info("  pwq %d:", pool->id);
        pr_cont_pool_info(pool);
 
-       pr_cont(" active=%d/%d%s\n", pwq->nr_active, pwq->max_active,
+       pr_cont(" active=%d/%d refcnt=%d%s\n",
+               pwq->nr_active, pwq->max_active, pwq->refcnt,
                !list_empty(&pwq->mayday_node) ? " MAYDAY" : "");
 
        hash_for_each(pool->busy_hash, bkt, worker, hentry) {
index 6138356..6ff3b1c 100644 (file)
--- a/lib/idr.c
+++ b/lib/idr.c
@@ -218,7 +218,7 @@ int idr_for_each(const struct idr *idr,
 EXPORT_SYMBOL(idr_for_each);
 
 /**
- * idr_get_next() - Find next populated entry.
+ * idr_get_next_ul() - Find next populated entry.
  * @idr: IDR handle.
  * @nextid: Pointer to an ID.
  *
@@ -227,7 +227,7 @@ EXPORT_SYMBOL(idr_for_each);
  * to the ID of the found value.  To use in a loop, the value pointed to by
  * nextid must be incremented by the user.
  */
-void *idr_get_next(struct idr *idr, int *nextid)
+void *idr_get_next_ul(struct idr *idr, unsigned long *nextid)
 {
        struct radix_tree_iter iter;
        void __rcu **slot;
@@ -249,18 +249,14 @@ void *idr_get_next(struct idr *idr, int *nextid)
        }
        if (!slot)
                return NULL;
-       id = iter.index + base;
-
-       if (WARN_ON_ONCE(id > INT_MAX))
-               return NULL;
 
-       *nextid = id;
+       *nextid = iter.index + base;
        return entry;
 }
-EXPORT_SYMBOL(idr_get_next);
+EXPORT_SYMBOL(idr_get_next_ul);
 
 /**
- * idr_get_next_ul() - Find next populated entry.
+ * idr_get_next() - Find next populated entry.
  * @idr: IDR handle.
  * @nextid: Pointer to an ID.
  *
@@ -269,22 +265,17 @@ EXPORT_SYMBOL(idr_get_next);
  * to the ID of the found value.  To use in a loop, the value pointed to by
  * nextid must be incremented by the user.
  */
-void *idr_get_next_ul(struct idr *idr, unsigned long *nextid)
+void *idr_get_next(struct idr *idr, int *nextid)
 {
-       struct radix_tree_iter iter;
-       void __rcu **slot;
-       unsigned long base = idr->idr_base;
        unsigned long id = *nextid;
+       void *entry = idr_get_next_ul(idr, &id);
 
-       id = (id < base) ? 0 : id - base;
-       slot = radix_tree_iter_find(&idr->idr_rt, &iter, id);
-       if (!slot)
+       if (WARN_ON_ONCE(id > INT_MAX))
                return NULL;
-
-       *nextid = iter.index + base;
-       return rcu_dereference_raw(*slot);
+       *nextid = id;
+       return entry;
 }
-EXPORT_SYMBOL(idr_get_next_ul);
+EXPORT_SYMBOL(idr_get_next);
 
 /**
  * idr_replace() - replace pointer for given ID.
index c6aa036..0809805 100644 (file)
@@ -13,7 +13,7 @@ BEGIN {
        for (i = 0; i < rep; ++i) {
                tmp = $0
                gsub(/\$\$/, i, tmp)
-               gsub(/\$\#/, n, tmp)
+               gsub(/\$#/, n, tmp)
                gsub(/\$\*/, "$", tmp)
                print tmp
        }
index 09ce852..5a1771b 100644 (file)
@@ -63,6 +63,16 @@ static struct shrinker deferred_split_shrinker;
 static atomic_t huge_zero_refcount;
 struct page *huge_zero_page __read_mostly;
 
+bool transparent_hugepage_enabled(struct vm_area_struct *vma)
+{
+       if (vma_is_anonymous(vma))
+               return __transparent_hugepage_enabled(vma);
+       if (vma_is_shmem(vma) && shmem_huge_enabled(vma))
+               return __transparent_hugepage_enabled(vma);
+
+       return false;
+}
+
 static struct page *get_huge_zero_page(void)
 {
        struct page *zero_page;
@@ -1329,7 +1339,7 @@ vm_fault_t do_huge_pmd_wp_page(struct vm_fault *vmf, pmd_t orig_pmd)
        get_page(page);
        spin_unlock(vmf->ptl);
 alloc:
-       if (transparent_hugepage_enabled(vma) &&
+       if (__transparent_hugepage_enabled(vma) &&
            !transparent_hugepage_debug_cow()) {
                huge_gfp = alloc_hugepage_direct_gfpmask(vma);
                new_page = alloc_hugepage_vma(huge_gfp, vma, haddr, HPAGE_PMD_ORDER);
index fb5655b..bbf0cc4 100644 (file)
@@ -4106,7 +4106,7 @@ static vm_fault_t __handle_mm_fault(struct vm_area_struct *vma,
        vmf.pud = pud_alloc(mm, p4d, address);
        if (!vmf.pud)
                return VM_FAULT_OOM;
-       if (pud_none(*vmf.pud) && transparent_hugepage_enabled(vma)) {
+       if (pud_none(*vmf.pud) && __transparent_hugepage_enabled(vma)) {
                ret = create_huge_pud(&vmf);
                if (!(ret & VM_FAULT_FALLBACK))
                        return ret;
@@ -4132,7 +4132,7 @@ static vm_fault_t __handle_mm_fault(struct vm_area_struct *vma,
        vmf.pmd = pmd_alloc(mm, vmf.pud, address);
        if (!vmf.pmd)
                return VM_FAULT_OOM;
-       if (pmd_none(*vmf.pmd) && transparent_hugepage_enabled(vma)) {
+       if (pmd_none(*vmf.pmd) && __transparent_hugepage_enabled(vma)) {
                ret = create_huge_pmd(&vmf);
                if (!(ret & VM_FAULT_FALLBACK))
                        return ret;
index 3c87426..650ef56 100644 (file)
@@ -2692,7 +2692,7 @@ static long shmem_fallocate(struct file *file, int mode, loff_t offset,
                }
 
                shmem_falloc.waitq = &shmem_falloc_waitq;
-               shmem_falloc.start = unmap_start >> PAGE_SHIFT;
+               shmem_falloc.start = (u64)unmap_start >> PAGE_SHIFT;
                shmem_falloc.next = (unmap_end + 1) >> PAGE_SHIFT;
                spin_lock(&inode->i_lock);
                inode->i_private = &shmem_falloc;
index 034a5ec..4ab5e46 100644 (file)
@@ -931,6 +931,14 @@ static void hci_req_directed_advertising(struct hci_request *req,
                        return;
 
                memset(&cp, 0, sizeof(cp));
+
+               /* Some controllers might reject command if intervals are not
+                * within range for undirected advertising.
+                * BCM20702A0 is known to be affected by this.
+                */
+               cp.min_interval = cpu_to_le16(0x0020);
+               cp.max_interval = cpu_to_le16(0x0020);
+
                cp.type = LE_ADV_DIRECT_IND;
                cp.own_address_type = own_addr_type;
                cp.direct_addr_type = conn->dst_type;
index 5afd67e..e03faca 100644 (file)
@@ -841,8 +841,8 @@ static int hci_init4_req(struct hci_request *req, unsigned long opt)
        if (hdev->le_features[0] & HCI_LE_DATA_LEN_EXT) {
                struct hci_cp_le_write_def_data_len cp;
 
-               cp.tx_len = hdev->le_max_tx_len;
-               cp.tx_time = hdev->le_max_tx_time;
+               cp.tx_len = cpu_to_le16(hdev->le_max_tx_len);
+               cp.tx_time = cpu_to_le16(hdev->le_max_tx_time);
                hci_req_add(req, HCI_OP_LE_WRITE_DEF_DATA_LEN, sizeof(cp), &cp);
        }
 
@@ -4330,7 +4330,14 @@ static void hci_rx_work(struct work_struct *work)
                        hci_send_to_sock(hdev, skb);
                }
 
-               if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
+               /* If the device has been opened in HCI_USER_CHANNEL,
+                * the userspace has exclusive access to device.
+                * When device is HCI_INIT, we still need to process
+                * the data packets to the driver in order
+                * to complete its setup().
+                */
+               if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL) &&
+                   !test_bit(HCI_INIT, &hdev->flags)) {
                        kfree_skb(skb);
                        continue;
                }
index 9448ebd..a8ddd21 100644 (file)
@@ -1258,6 +1258,14 @@ static u8 create_instance_adv_data(struct hci_dev *hdev, u8 instance, u8 *ptr)
 
        instance_flags = get_adv_instance_flags(hdev, instance);
 
+       /* If instance already has the flags set skip adding it once
+        * again.
+        */
+       if (adv_instance && eir_get_data(adv_instance->adv_data,
+                                        adv_instance->adv_data_len, EIR_FLAGS,
+                                        NULL))
+               goto skip_flags;
+
        /* The Add Advertising command allows userspace to set both the general
         * and limited discoverable flags.
         */
@@ -1290,6 +1298,7 @@ static u8 create_instance_adv_data(struct hci_dev *hdev, u8 instance, u8 *ptr)
                }
        }
 
+skip_flags:
        if (adv_instance) {
                memcpy(ptr, adv_instance->adv_data,
                       adv_instance->adv_data_len);
index e682a66..9ce661e 100644 (file)
@@ -246,6 +246,12 @@ static int br_set_mac_address(struct net_device *dev, void *p)
        if (!is_valid_ether_addr(addr->sa_data))
                return -EADDRNOTAVAIL;
 
+       /* dev_set_mac_addr() can be called by a master device on bridge's
+        * NETDEV_UNREGISTER, but since it's being destroyed do nothing
+        */
+       if (dev->reg_state != NETREG_REGISTERED)
+               return -EBUSY;
+
        spin_lock_bh(&br->lock);
        if (!ether_addr_equal(dev->dev_addr, addr->sa_data)) {
                /* Mac address will be changed in br_stp_change_bridge_id(). */
index 212c184..ccab290 100644 (file)
@@ -646,6 +646,9 @@ static unsigned int br_nf_forward_arp(void *priv,
                nf_bridge_pull_encap_header(skb);
        }
 
+       if (unlikely(!pskb_may_pull(skb, sizeof(struct arphdr))))
+               return NF_DROP;
+
        if (arp_hdr(skb)->ar_pln != 4) {
                if (IS_VLAN_ARP(skb))
                        nf_bridge_push_encap_header(skb);
index 8e2d7cf..d88e724 100644 (file)
@@ -26,7 +26,8 @@
 #endif
 
 static void fake_update_pmtu(struct dst_entry *dst, struct sock *sk,
-                            struct sk_buff *skb, u32 mtu)
+                            struct sk_buff *skb, u32 mtu,
+                            bool confirm_neigh)
 {
 }
 
index 7d249af..785e19a 100644 (file)
@@ -1876,7 +1876,7 @@ static int ebt_buf_count(struct ebt_entries_buf_state *state, unsigned int sz)
 }
 
 static int ebt_buf_add(struct ebt_entries_buf_state *state,
-                      void *data, unsigned int sz)
+                      const void *data, unsigned int sz)
 {
        if (state->buf_kern_start == NULL)
                goto count_only;
@@ -1910,7 +1910,7 @@ enum compat_mwt {
        EBT_COMPAT_TARGET,
 };
 
-static int compat_mtw_from_user(struct compat_ebt_entry_mwt *mwt,
+static int compat_mtw_from_user(const struct compat_ebt_entry_mwt *mwt,
                                enum compat_mwt compat_mwt,
                                struct ebt_entries_buf_state *state,
                                const unsigned char *base)
@@ -1988,22 +1988,23 @@ static int compat_mtw_from_user(struct compat_ebt_entry_mwt *mwt,
 /* return size of all matches, watchers or target, including necessary
  * alignment and padding.
  */
-static int ebt_size_mwt(struct compat_ebt_entry_mwt *match32,
+static int ebt_size_mwt(const struct compat_ebt_entry_mwt *match32,
                        unsigned int size_left, enum compat_mwt type,
                        struct ebt_entries_buf_state *state, const void *base)
 {
+       const char *buf = (const char *)match32;
        int growth = 0;
-       char *buf;
 
        if (size_left == 0)
                return 0;
 
-       buf = (char *) match32;
-
-       while (size_left >= sizeof(*match32)) {
+       do {
                struct ebt_entry_match *match_kern;
                int ret;
 
+               if (size_left < sizeof(*match32))
+                       return -EINVAL;
+
                match_kern = (struct ebt_entry_match *) state->buf_kern_start;
                if (match_kern) {
                        char *tmp;
@@ -2040,22 +2041,18 @@ static int ebt_size_mwt(struct compat_ebt_entry_mwt *match32,
                if (match_kern)
                        match_kern->match_size = ret;
 
-               /* rule should have no remaining data after target */
-               if (type == EBT_COMPAT_TARGET && size_left)
-                       return -EINVAL;
-
                match32 = (struct compat_ebt_entry_mwt *) buf;
-       }
+       } while (size_left);
 
        return growth;
 }
 
 /* called for all ebt_entry structures. */
-static int size_entry_mwt(struct ebt_entry *entry, const unsigned char *base,
+static int size_entry_mwt(const struct ebt_entry *entry, const unsigned char *base,
                          unsigned int *total,
                          struct ebt_entries_buf_state *state)
 {
-       unsigned int i, j, startoff, new_offset = 0;
+       unsigned int i, j, startoff, next_expected_off, new_offset = 0;
        /* stores match/watchers/targets & offset of next struct ebt_entry: */
        unsigned int offsets[4];
        unsigned int *offsets_update = NULL;
@@ -2141,11 +2138,13 @@ static int size_entry_mwt(struct ebt_entry *entry, const unsigned char *base,
                        return ret;
        }
 
-       startoff = state->buf_user_offset - startoff;
+       next_expected_off = state->buf_user_offset - startoff;
+       if (next_expected_off != entry->next_offset)
+               return -EINVAL;
 
-       if (WARN_ON(*total < startoff))
+       if (*total < entry->next_offset)
                return -EINVAL;
-       *total -= startoff;
+       *total -= entry->next_offset;
        return 0;
 }
 
index 91179fe..8ff21d4 100644 (file)
@@ -7595,7 +7595,8 @@ int __dev_set_mtu(struct net_device *dev, int new_mtu)
        if (ops->ndo_change_mtu)
                return ops->ndo_change_mtu(dev, new_mtu);
 
-       dev->mtu = new_mtu;
+       /* Pairs with all the lockless reads of dev->mtu in the stack */
+       WRITE_ONCE(dev->mtu, new_mtu);
        return 0;
 }
 EXPORT_SYMBOL(__dev_set_mtu);
index 4362ffe..994dd15 100644 (file)
@@ -630,9 +630,10 @@ bool __skb_flow_dissect(const struct sk_buff *skb,
                nhoff = skb_network_offset(skb);
                hlen = skb_headlen(skb);
 #if IS_ENABLED(CONFIG_NET_DSA)
-               if (unlikely(skb->dev && netdev_uses_dsa(skb->dev))) {
+               if (unlikely(skb->dev && netdev_uses_dsa(skb->dev) &&
+                            proto == htons(ETH_P_XDSA))) {
                        const struct dsa_device_ops *ops;
-                       int offset;
+                       int offset = 0;
 
                        ops = skb->dev->dsa_ptr->tag_ops;
                        if (ops->flow_dissect &&
index d67ec17..6cec08c 100644 (file)
@@ -281,6 +281,7 @@ static int proc_dointvec_minmax_bpf_enable(struct ctl_table *table, int write,
        return ret;
 }
 
+# ifdef CONFIG_HAVE_EBPF_JIT
 static int
 proc_dointvec_minmax_bpf_restricted(struct ctl_table *table, int write,
                                    void __user *buffer, size_t *lenp,
@@ -291,6 +292,7 @@ proc_dointvec_minmax_bpf_restricted(struct ctl_table *table, int write,
 
        return proc_dointvec_minmax(table, write, buffer, lenp, ppos);
 }
+# endif /* CONFIG_HAVE_EBPF_JIT */
 
 static int
 proc_dolongvec_minmax_bpf_restricted(struct ctl_table *table, int write,
index 1c002c0..658191f 100644 (file)
@@ -118,7 +118,8 @@ static void dn_dst_ifdown(struct dst_entry *, struct net_device *dev, int how);
 static struct dst_entry *dn_dst_negative_advice(struct dst_entry *);
 static void dn_dst_link_failure(struct sk_buff *);
 static void dn_dst_update_pmtu(struct dst_entry *dst, struct sock *sk,
-                              struct sk_buff *skb , u32 mtu);
+                              struct sk_buff *skb , u32 mtu,
+                              bool confirm_neigh);
 static void dn_dst_redirect(struct dst_entry *dst, struct sock *sk,
                            struct sk_buff *skb);
 static struct neighbour *dn_dst_neigh_lookup(const struct dst_entry *dst,
@@ -259,7 +260,8 @@ static int dn_dst_gc(struct dst_ops *ops)
  * advertise to the other end).
  */
 static void dn_dst_update_pmtu(struct dst_entry *dst, struct sock *sk,
-                              struct sk_buff *skb, u32 mtu)
+                              struct sk_buff *skb, u32 mtu,
+                              bool confirm_neigh)
 {
        struct dn_route *rt = (struct dn_route *) dst;
        struct neighbour *n = rt->n;
index d237461..fabece4 100644 (file)
@@ -1441,11 +1441,6 @@ skip:
        }
 }
 
-static bool inetdev_valid_mtu(unsigned int mtu)
-{
-       return mtu >= IPV4_MIN_MTU;
-}
-
 static void inetdev_send_gratuitous_arp(struct net_device *dev,
                                        struct in_device *in_dev)
 
index 511b32e..0eb4bfa 100644 (file)
@@ -132,7 +132,7 @@ int gre_parse_header(struct sk_buff *skb, struct tnl_ptk_info *tpi,
                if (!pskb_may_pull(skb, nhs + hdr_len + sizeof(*ershdr)))
                        return -EINVAL;
 
-               ershdr = (struct erspan_base_hdr *)options;
+               ershdr = (struct erspan_base_hdr *)(skb->data + nhs + hdr_len);
                tpi->key = cpu_to_be32(get_session_id(ershdr));
        }
 
index 0167e23..4efa5e3 100644 (file)
@@ -254,10 +254,11 @@ bool icmp_global_allow(void)
        bool rc = false;
 
        /* Check if token bucket is empty and cannot be refilled
-        * without taking the spinlock.
+        * without taking the spinlock. The READ_ONCE() are paired
+        * with the following WRITE_ONCE() in this same function.
         */
-       if (!icmp_global.credit) {
-               delta = min_t(u32, now - icmp_global.stamp, HZ);
+       if (!READ_ONCE(icmp_global.credit)) {
+               delta = min_t(u32, now - READ_ONCE(icmp_global.stamp), HZ);
                if (delta < HZ / 50)
                        return false;
        }
@@ -267,14 +268,14 @@ bool icmp_global_allow(void)
        if (delta >= HZ / 50) {
                incr = sysctl_icmp_msgs_per_sec * delta / HZ ;
                if (incr)
-                       icmp_global.stamp = now;
+                       WRITE_ONCE(icmp_global.stamp, now);
        }
        credit = min_t(u32, icmp_global.credit + incr, sysctl_icmp_msgs_burst);
        if (credit) {
                credit--;
                rc = true;
        }
-       icmp_global.credit = credit;
+       WRITE_ONCE(icmp_global.credit, credit);
        spin_unlock(&icmp_global.lock);
        return rc;
 }
index 15e7f79..636a11c 100644 (file)
@@ -1089,7 +1089,7 @@ struct dst_entry *inet_csk_update_pmtu(struct sock *sk, u32 mtu)
                if (!dst)
                        goto out;
        }
-       dst->ops->update_pmtu(dst, sk, NULL, mtu);
+       dst->ops->update_pmtu(dst, sk, NULL, mtu, true);
 
        dst = __sk_dst_check(sk, 0);
        if (!dst)
index 5731670..9742b37 100644 (file)
@@ -918,11 +918,12 @@ void inet_diag_dump_icsk(struct inet_hashinfo *hashinfo, struct sk_buff *skb,
 
                for (i = s_i; i < INET_LHTABLE_SIZE; i++) {
                        struct inet_listen_hashbucket *ilb;
+                       struct hlist_nulls_node *node;
 
                        num = 0;
                        ilb = &hashinfo->listening_hash[i];
                        spin_lock(&ilb->lock);
-                       sk_for_each(sk, &ilb->head) {
+                       sk_nulls_for_each(sk, node, &ilb->nulls_head) {
                                struct inet_sock *inet = inet_sk(sk);
 
                                if (!net_eq(sock_net(sk), net))
index 7be966a..b53da26 100644 (file)
@@ -308,6 +308,7 @@ struct sock *__inet_lookup_listener(struct net *net,
        bool exact_dif = inet_exact_dif_match(net, skb);
        struct inet_listen_hashbucket *ilb2;
        struct sock *sk, *result = NULL;
+       struct hlist_nulls_node *node;
        int score, hiscore = 0;
        unsigned int hash2;
        u32 phash = 0;
@@ -343,7 +344,7 @@ struct sock *__inet_lookup_listener(struct net *net,
        goto done;
 
 port_lookup:
-       sk_for_each_rcu(sk, &ilb->head) {
+       sk_nulls_for_each_rcu(sk, node, &ilb->nulls_head) {
                score = compute_score(sk, net, hnum, daddr,
                                      dif, sdif, exact_dif);
                if (score > hiscore) {
@@ -560,10 +561,11 @@ static int inet_reuseport_add_sock(struct sock *sk,
                                   struct inet_listen_hashbucket *ilb)
 {
        struct inet_bind_bucket *tb = inet_csk(sk)->icsk_bind_hash;
+       const struct hlist_nulls_node *node;
        struct sock *sk2;
        kuid_t uid = sock_i_uid(sk);
 
-       sk_for_each_rcu(sk2, &ilb->head) {
+       sk_nulls_for_each_rcu(sk2, node, &ilb->nulls_head) {
                if (sk2 != sk &&
                    sk2->sk_family == sk->sk_family &&
                    ipv6_only_sock(sk2) == ipv6_only_sock(sk) &&
@@ -599,9 +601,9 @@ int __inet_hash(struct sock *sk, struct sock *osk)
        }
        if (IS_ENABLED(CONFIG_IPV6) && sk->sk_reuseport &&
                sk->sk_family == AF_INET6)
-               hlist_add_tail_rcu(&sk->sk_node, &ilb->head);
+               __sk_nulls_add_node_tail_rcu(sk, &ilb->nulls_head);
        else
-               hlist_add_head_rcu(&sk->sk_node, &ilb->head);
+               __sk_nulls_add_node_rcu(sk, &ilb->nulls_head);
        inet_hash2(hashinfo, sk);
        ilb->count++;
        sock_set_flag(sk, SOCK_RCU_FREE);
@@ -650,11 +652,9 @@ void inet_unhash(struct sock *sk)
                reuseport_detach_sock(sk);
        if (ilb) {
                inet_unhash2(hashinfo, sk);
-                __sk_del_node_init(sk);
-                ilb->count--;
-       } else {
-               __sk_nulls_del_node_init_rcu(sk);
+               ilb->count--;
        }
+       __sk_nulls_del_node_init_rcu(sk);
        sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1);
 unlock:
        spin_unlock_bh(lock);
@@ -790,7 +790,8 @@ void inet_hashinfo_init(struct inet_hashinfo *h)
 
        for (i = 0; i < INET_LHTABLE_SIZE; i++) {
                spin_lock_init(&h->listening_hash[i].lock);
-               INIT_HLIST_HEAD(&h->listening_hash[i].head);
+               INIT_HLIST_NULLS_HEAD(&h->listening_hash[i].nulls_head,
+                                     i + LISTENING_NULLS_BASE);
                h->listening_hash[i].count = 0;
        }
 
index be77859..ff327a6 100644 (file)
@@ -160,7 +160,12 @@ static void inet_peer_gc(struct inet_peer_base *base,
                                        base->total / inet_peer_threshold * HZ;
        for (i = 0; i < gc_cnt; i++) {
                p = gc_stack[i];
-               delta = (__u32)jiffies - p->dtime;
+
+               /* The READ_ONCE() pairs with the WRITE_ONCE()
+                * in inet_putpeer()
+                */
+               delta = (__u32)jiffies - READ_ONCE(p->dtime);
+
                if (delta < ttl || !refcount_dec_if_one(&p->refcnt))
                        gc_stack[i] = NULL;
        }
@@ -237,7 +242,10 @@ EXPORT_SYMBOL_GPL(inet_getpeer);
 
 void inet_putpeer(struct inet_peer *p)
 {
-       p->dtime = (__u32)jiffies;
+       /* The WRITE_ONCE() pairs with itself (we run lockless)
+        * and the READ_ONCE() in inet_peer_gc()
+        */
+       WRITE_ONCE(p->dtime, (__u32)jiffies);
 
        if (refcount_dec_and_test(&p->refcnt))
                call_rcu(&p->rcu, inetpeer_free_rcu);
index 73894ed..d630918 100644 (file)
@@ -1142,15 +1142,18 @@ static int ip_setup_cork(struct sock *sk, struct inet_cork *cork,
                cork->addr = ipc->addr;
        }
 
-       /*
-        * We steal reference to this route, caller should not release it
-        */
-       *rtp = NULL;
        cork->fragsize = ip_sk_use_pmtu(sk) ?
-                        dst_mtu(&rt->dst) : rt->dst.dev->mtu;
+                        dst_mtu(&rt->dst) : READ_ONCE(rt->dst.dev->mtu);
+
+       if (!inetdev_valid_mtu(cork->fragsize))
+               return -ENETUNREACH;
 
        cork->gso_size = ipc->gso_size;
+
        cork->dst = &rt->dst;
+       /* We stole this route, caller should not release it. */
+       *rtp = NULL;
+
        cork->length = 0;
        cork->ttl = ipc->ttl;
        cork->tos = ipc->tos;
index 054d01c..420e891 100644 (file)
@@ -513,7 +513,7 @@ static int tnl_update_pmtu(struct net_device *dev, struct sk_buff *skb,
        else
                mtu = skb_dst(skb) ? dst_mtu(skb_dst(skb)) : dev->mtu;
 
-       skb_dst_update_pmtu(skb, mtu);
+       skb_dst_update_pmtu_no_confirm(skb, mtu);
 
        if (skb->protocol == htons(ETH_P_IP)) {
                if (!skb_is_gso(skb) &&
index 808f8d1..960f4fa 100644 (file)
@@ -235,7 +235,7 @@ static netdev_tx_t vti_xmit(struct sk_buff *skb, struct net_device *dev,
 
        mtu = dst_mtu(dst);
        if (skb->len > mtu) {
-               skb_dst_update_pmtu(skb, mtu);
+               skb_dst_update_pmtu_no_confirm(skb, mtu);
                if (skb->protocol == htons(ETH_P_IP)) {
                        icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED,
                                  htonl(mtu));
index 69127f6..4590af5 100644 (file)
@@ -142,7 +142,8 @@ static unsigned int  ipv4_mtu(const struct dst_entry *dst);
 static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst);
 static void             ipv4_link_failure(struct sk_buff *skb);
 static void             ip_rt_update_pmtu(struct dst_entry *dst, struct sock *sk,
-                                          struct sk_buff *skb, u32 mtu);
+                                          struct sk_buff *skb, u32 mtu,
+                                          bool confirm_neigh);
 static void             ip_do_redirect(struct dst_entry *dst, struct sock *sk,
                                        struct sk_buff *skb);
 static void            ipv4_dst_destroy(struct dst_entry *dst);
@@ -1035,7 +1036,8 @@ static void __ip_rt_update_pmtu(struct rtable *rt, struct flowi4 *fl4, u32 mtu)
 }
 
 static void ip_rt_update_pmtu(struct dst_entry *dst, struct sock *sk,
-                             struct sk_buff *skb, u32 mtu)
+                             struct sk_buff *skb, u32 mtu,
+                             bool confirm_neigh)
 {
        struct rtable *rt = (struct rtable *) dst;
        struct flowi4 fl4;
@@ -2559,7 +2561,8 @@ static unsigned int ipv4_blackhole_mtu(const struct dst_entry *dst)
 }
 
 static void ipv4_rt_blackhole_update_pmtu(struct dst_entry *dst, struct sock *sk,
-                                         struct sk_buff *skb, u32 mtu)
+                                         struct sk_buff *skb, u32 mtu,
+                                         bool confirm_neigh)
 {
 }
 
index bfec488..5553f6a 100644 (file)
@@ -2020,13 +2020,14 @@ static void *listening_get_next(struct seq_file *seq, void *cur)
        struct tcp_iter_state *st = seq->private;
        struct net *net = seq_file_net(seq);
        struct inet_listen_hashbucket *ilb;
+       struct hlist_nulls_node *node;
        struct sock *sk = cur;
 
        if (!sk) {
 get_head:
                ilb = &tcp_hashinfo.listening_hash[st->bucket];
                spin_lock(&ilb->lock);
-               sk = sk_head(&ilb->head);
+               sk = sk_nulls_head(&ilb->nulls_head);
                st->offset = 0;
                goto get_sk;
        }
@@ -2034,9 +2035,9 @@ get_head:
        ++st->num;
        ++st->offset;
 
-       sk = sk_next(sk);
+       sk = sk_nulls_next(sk);
 get_sk:
-       sk_for_each_from(sk) {
+       sk_nulls_for_each_from(sk, node) {
                if (!net_eq(sock_net(sk), net))
                        continue;
                if (sk->sk_family == afinfo->family)
index 8971cc1..1cc20ed 100644 (file)
@@ -60,6 +60,9 @@ static void tcp_event_new_data_sent(struct sock *sk, struct sk_buff *skb)
        __skb_unlink(skb, &sk->sk_write_queue);
        tcp_rbtree_insert(&sk->tcp_rtx_queue, skb);
 
+       if (tp->highest_sack == NULL)
+               tp->highest_sack = skb;
+
        tp->packets_out += tcp_skb_pcount(skb);
        if (!prior_packets || icsk->icsk_pending == ICSK_TIME_LOSS_PROBE)
                tcp_rearm_rto(sk);
@@ -740,8 +743,9 @@ static unsigned int tcp_established_options(struct sock *sk, struct sk_buff *skb
                        min_t(unsigned int, eff_sacks,
                              (remaining - TCPOLEN_SACK_BASE_ALIGNED) /
                              TCPOLEN_SACK_PERBLOCK);
-               size += TCPOLEN_SACK_BASE_ALIGNED +
-                       opts->num_sack_blocks * TCPOLEN_SACK_PERBLOCK;
+               if (likely(opts->num_sack_blocks))
+                       size += TCPOLEN_SACK_BASE_ALIGNED +
+                               opts->num_sack_blocks * TCPOLEN_SACK_PERBLOCK;
        }
 
        return size;
@@ -2372,6 +2376,14 @@ static bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle,
                if (tcp_small_queue_check(sk, skb, 0))
                        break;
 
+               /* Argh, we hit an empty skb(), presumably a thread
+                * is sleeping in sendmsg()/sk_stream_wait_memory().
+                * We do not want to send a pure-ack packet and have
+                * a strange looking rtx queue with empty packet(s).
+                */
+               if (TCP_SKB_CB(skb)->end_seq == TCP_SKB_CB(skb)->seq)
+                       break;
+
                if (unlikely(tcp_transmit_skb(sk, skb, 1, gfp)))
                        break;
 
index 8877bd1..2eeae04 100644 (file)
@@ -1412,7 +1412,7 @@ int __udp_enqueue_schedule_skb(struct sock *sk, struct sk_buff *skb)
         * queue contains some other skb
         */
        rmem = atomic_add_return(size, &sk->sk_rmem_alloc);
-       if (rmem > (size + sk->sk_rcvbuf))
+       if (rmem > (size + (unsigned int)sk->sk_rcvbuf))
                goto uncharge_drop;
 
        spin_lock(&list->lock);
index 2b144b9..1e5e2e4 100644 (file)
@@ -222,12 +222,13 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse)
 }
 
 static void xfrm4_update_pmtu(struct dst_entry *dst, struct sock *sk,
-                             struct sk_buff *skb, u32 mtu)
+                             struct sk_buff *skb, u32 mtu,
+                             bool confirm_neigh)
 {
        struct xfrm_dst *xdst = (struct xfrm_dst *)dst;
        struct dst_entry *path = xdst->route;
 
-       path->ops->update_pmtu(path, sk, skb, mtu);
+       path->ops->update_pmtu(path, sk, skb, mtu, confirm_neigh);
 }
 
 static void xfrm4_redirect(struct dst_entry *dst, struct sock *sk,
index 9a31d13..890adad 100644 (file)
@@ -150,7 +150,7 @@ struct dst_entry *inet6_csk_update_pmtu(struct sock *sk, u32 mtu)
 
        if (IS_ERR(dst))
                return NULL;
-       dst->ops->update_pmtu(dst, sk, NULL, mtu);
+       dst->ops->update_pmtu(dst, sk, NULL, mtu, true);
 
        dst = inet6_csk_route_socket(sk, &fl6);
        return IS_ERR(dst) ? NULL : dst;
index 91d6ea9..d9e2575 100644 (file)
@@ -171,6 +171,7 @@ struct sock *inet6_lookup_listener(struct net *net,
        bool exact_dif = inet6_exact_dif_match(net, skb);
        struct inet_listen_hashbucket *ilb2;
        struct sock *sk, *result = NULL;
+       struct hlist_nulls_node *node;
        int score, hiscore = 0;
        unsigned int hash2;
        u32 phash = 0;
@@ -206,7 +207,7 @@ struct sock *inet6_lookup_listener(struct net *net,
        goto done;
 
 port_lookup:
-       sk_for_each(sk, &ilb->head) {
+       sk_nulls_for_each(sk, node, &ilb->nulls_head) {
                score = compute_score(sk, net, hnum, daddr, dif, sdif, exact_dif);
                if (score > hiscore) {
                        if (sk->sk_reuseport) {
index 8fd28ed..b3515a4 100644 (file)
@@ -1060,7 +1060,7 @@ static netdev_tx_t ip6erspan_tunnel_xmit(struct sk_buff *skb,
 
        /* TooBig packet may have updated dst->dev's mtu */
        if (!t->parms.collect_md && dst && dst_mtu(dst) > dst->dev->mtu)
-               dst->ops->update_pmtu(dst, NULL, skb, dst->dev->mtu);
+               dst->ops->update_pmtu(dst, NULL, skb, dst->dev->mtu, false);
 
        err = ip6_tnl_xmit(skb, dev, dsfield, &fl6, encap_limit, &mtu,
                           NEXTHDR_GRE);
index d0ad85b..e3b4237 100644 (file)
@@ -645,7 +645,7 @@ ip4ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
                if (rel_info > dst_mtu(skb_dst(skb2)))
                        goto out;
 
-               skb_dst_update_pmtu(skb2, rel_info);
+               skb_dst_update_pmtu_no_confirm(skb2, rel_info);
        }
 
        icmp_send(skb2, rel_type, rel_code, htonl(rel_info));
@@ -1137,7 +1137,7 @@ route_lookup:
        mtu = max(mtu, skb->protocol == htons(ETH_P_IPV6) ?
                       IPV6_MIN_MTU : IPV4_MIN_MTU);
 
-       skb_dst_update_pmtu(skb, mtu);
+       skb_dst_update_pmtu_no_confirm(skb, mtu);
        if (skb->len - t->tun_hlen - eth_hlen > mtu && !skb_is_gso(skb)) {
                *pmtu = mtu;
                err = -EMSGSIZE;
index 8b6eeff..bfd39db 100644 (file)
@@ -483,7 +483,7 @@ vti6_xmit(struct sk_buff *skb, struct net_device *dev, struct flowi *fl)
 
        mtu = dst_mtu(dst);
        if (skb->len > mtu) {
-               skb_dst_update_pmtu(skb, mtu);
+               skb_dst_update_pmtu_no_confirm(skb, mtu);
 
                if (skb->protocol == htons(ETH_P_IPV6)) {
                        if (mtu < IPV6_MIN_MTU)
index 076c21f..f8fe4c9 100644 (file)
@@ -99,7 +99,8 @@ static int            ip6_pkt_prohibit(struct sk_buff *skb);
 static int             ip6_pkt_prohibit_out(struct net *net, struct sock *sk, struct sk_buff *skb);
 static void            ip6_link_failure(struct sk_buff *skb);
 static void            ip6_rt_update_pmtu(struct dst_entry *dst, struct sock *sk,
-                                          struct sk_buff *skb, u32 mtu);
+                                          struct sk_buff *skb, u32 mtu,
+                                          bool confirm_neigh);
 static void            rt6_do_redirect(struct dst_entry *dst, struct sock *sk,
                                        struct sk_buff *skb);
 static int rt6_score_route(struct fib6_info *rt, int oif, int strict);
@@ -266,7 +267,8 @@ static unsigned int ip6_blackhole_mtu(const struct dst_entry *dst)
 }
 
 static void ip6_rt_blackhole_update_pmtu(struct dst_entry *dst, struct sock *sk,
-                                        struct sk_buff *skb, u32 mtu)
+                                        struct sk_buff *skb, u32 mtu,
+                                        bool confirm_neigh)
 {
 }
 
@@ -2352,7 +2354,8 @@ static bool rt6_cache_allowed_for_pmtu(const struct rt6_info *rt)
 }
 
 static void __ip6_rt_update_pmtu(struct dst_entry *dst, const struct sock *sk,
-                                const struct ipv6hdr *iph, u32 mtu)
+                                const struct ipv6hdr *iph, u32 mtu,
+                                bool confirm_neigh)
 {
        const struct in6_addr *daddr, *saddr;
        struct rt6_info *rt6 = (struct rt6_info *)dst;
@@ -2370,7 +2373,10 @@ static void __ip6_rt_update_pmtu(struct dst_entry *dst, const struct sock *sk,
                daddr = NULL;
                saddr = NULL;
        }
-       dst_confirm_neigh(dst, daddr);
+
+       if (confirm_neigh)
+               dst_confirm_neigh(dst, daddr);
+
        mtu = max_t(u32, mtu, IPV6_MIN_MTU);
        if (mtu >= dst_mtu(dst))
                return;
@@ -2401,9 +2407,11 @@ static void __ip6_rt_update_pmtu(struct dst_entry *dst, const struct sock *sk,
 }
 
 static void ip6_rt_update_pmtu(struct dst_entry *dst, struct sock *sk,
-                              struct sk_buff *skb, u32 mtu)
+                              struct sk_buff *skb, u32 mtu,
+                              bool confirm_neigh)
 {
-       __ip6_rt_update_pmtu(dst, sk, skb ? ipv6_hdr(skb) : NULL, mtu);
+       __ip6_rt_update_pmtu(dst, sk, skb ? ipv6_hdr(skb) : NULL, mtu,
+                            confirm_neigh);
 }
 
 void ip6_update_pmtu(struct sk_buff *skb, struct net *net, __be32 mtu,
@@ -2423,7 +2431,7 @@ void ip6_update_pmtu(struct sk_buff *skb, struct net *net, __be32 mtu,
 
        dst = ip6_route_output(net, NULL, &fl6);
        if (!dst->error)
-               __ip6_rt_update_pmtu(dst, NULL, iph, ntohl(mtu));
+               __ip6_rt_update_pmtu(dst, NULL, iph, ntohl(mtu), true);
        dst_release(dst);
 }
 EXPORT_SYMBOL_GPL(ip6_update_pmtu);
index 41b3fe8..bfed750 100644 (file)
@@ -943,7 +943,7 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
                }
 
                if (tunnel->parms.iph.daddr)
-                       skb_dst_update_pmtu(skb, mtu);
+                       skb_dst_update_pmtu_no_confirm(skb, mtu);
 
                if (skb->len > mtu && !skb_is_gso(skb)) {
                        icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
index d35bcf9..3023259 100644 (file)
@@ -221,12 +221,13 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl, int reverse)
 }
 
 static void xfrm6_update_pmtu(struct dst_entry *dst, struct sock *sk,
-                             struct sk_buff *skb, u32 mtu)
+                             struct sk_buff *skb, u32 mtu,
+                             bool confirm_neigh)
 {
        struct xfrm_dst *xdst = (struct xfrm_dst *)dst;
        struct dst_entry *path = xdst->route;
 
-       path->ops->update_pmtu(path, sk, skb, mtu);
+       path->ops->update_pmtu(path, sk, skb, mtu, confirm_neigh);
 }
 
 static void xfrm6_redirect(struct dst_entry *dst, struct sock *sk,
index 534a604..f895c65 100644 (file)
@@ -867,7 +867,8 @@ static void __ieee80211_tx_status(struct ieee80211_hw *hw,
                        I802_DEBUG_INC(local->dot11FailedCount);
        }
 
-       if (ieee80211_is_nullfunc(fc) && ieee80211_has_pm(fc) &&
+       if ((ieee80211_is_nullfunc(fc) || ieee80211_is_qos_nullfunc(fc)) &&
+           ieee80211_has_pm(fc) &&
            ieee80211_hw_check(&local->hw, REPORTS_TX_ACK_STATUS) &&
            !(info->flags & IEEE80211_TX_CTL_INJECTED) &&
            local->ps_sdata && !(local->scanning)) {
index 473cce2..3f75cd9 100644 (file)
@@ -209,7 +209,7 @@ static inline void maybe_update_pmtu(int skb_af, struct sk_buff *skb, int mtu)
        struct rtable *ort = skb_rtable(skb);
 
        if (!skb->dev && sk && sk_fullsock(sk))
-               ort->dst.ops->update_pmtu(&ort->dst, sk, NULL, mtu);
+               ort->dst.ops->update_pmtu(&ort->dst, sk, NULL, mtu, true);
 }
 
 static inline bool ensure_mtu_is_adequate(struct netns_ipvs *ipvs, int skb_af,
index a96a8c1..ee6d983 100644 (file)
@@ -174,7 +174,7 @@ static int __nf_queue(struct sk_buff *skb, const struct nf_hook_state *state,
                goto err;
        }
 
-       if (!skb_dst_force(skb) && state->hook != NF_INET_PRE_ROUTING) {
+       if (skb_dst(skb) && !skb_dst_force(skb)) {
                status = -ENETDOWN;
                goto err;
        }
index a66f102..040576d 100644 (file)
@@ -348,7 +348,7 @@ static int nci_uart_default_recv_buf(struct nci_uart *nu, const u8 *data,
                        nu->rx_packet_len = -1;
                        nu->rx_skb = nci_skb_alloc(nu->ndev,
                                                   NCI_MAX_PACKET_SIZE,
-                                                  GFP_KERNEL);
+                                                  GFP_ATOMIC);
                        if (!nu->rx_skb)
                                return -ENOMEM;
                }
index 46aa1aa..6dcb59f 100644 (file)
@@ -897,6 +897,17 @@ static int ovs_ct_nat(struct net *net, struct sw_flow_key *key,
        }
        err = ovs_ct_nat_execute(skb, ct, ctinfo, &info->range, maniptype);
 
+       if (err == NF_ACCEPT &&
+           ct->status & IPS_SRC_NAT && ct->status & IPS_DST_NAT) {
+               if (maniptype == NF_NAT_MANIP_SRC)
+                       maniptype = NF_NAT_MANIP_DST;
+               else
+                       maniptype = NF_NAT_MANIP_SRC;
+
+               err = ovs_ct_nat_execute(skb, ct, ctinfo, &info->range,
+                                        maniptype);
+       }
+
        /* Mark NAT done if successful and update the flow key. */
        if (err == NF_ACCEPT)
                ovs_nat_update_key(key, skb, maniptype);
index 7204e7b..ac65e66 100644 (file)
@@ -552,7 +552,8 @@ static int prb_calc_retire_blk_tmo(struct packet_sock *po,
                        msec = 1;
                        div = ecmd.base.speed / 1000;
                }
-       }
+       } else
+               return DEFAULT_PRB_RETIRE_TOV;
 
        mbits = (blk_size_in_bytes * 8) / (1024 * 1024);
 
index 1355f5c..7fbc831 100644 (file)
@@ -1328,10 +1328,12 @@ static const struct file_operations rfkill_fops = {
        .llseek         = no_llseek,
 };
 
+#define RFKILL_NAME "rfkill"
+
 static struct miscdevice rfkill_miscdev = {
-       .name   = "rfkill",
        .fops   = &rfkill_fops,
-       .minor  = MISC_DYNAMIC_MINOR,
+       .name   = RFKILL_NAME,
+       .minor  = RFKILL_MINOR,
 };
 
 static int __init rfkill_init(void)
@@ -1383,3 +1385,6 @@ static void __exit rfkill_exit(void)
        class_unregister(&rfkill_class);
 }
 module_exit(rfkill_exit);
+
+MODULE_ALIAS_MISCDEV(RFKILL_MINOR);
+MODULE_ALIAS("devname:" RFKILL_NAME);
index 9fd37d9..e4cf72b 100644 (file)
@@ -1666,7 +1666,7 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch,
        if (skb_is_gso(skb) && q->rate_flags & CAKE_FLAG_SPLIT_GSO) {
                struct sk_buff *segs, *nskb;
                netdev_features_t features = netif_skb_features(skb);
-               unsigned int slen = 0;
+               unsigned int slen = 0, numsegs = 0;
 
                segs = skb_gso_segment(skb, features & ~NETIF_F_GSO_MASK);
                if (IS_ERR_OR_NULL(segs))
@@ -1682,6 +1682,7 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch,
                        flow_queue_add(flow, segs);
 
                        sch->q.qlen++;
+                       numsegs++;
                        slen += segs->len;
                        q->buffer_used += segs->truesize;
                        b->packets++;
@@ -1695,7 +1696,7 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch,
                sch->qstats.backlog += slen;
                q->avg_window_bytes += slen;
 
-               qdisc_tree_reduce_backlog(sch, 1len);
+               qdisc_tree_reduce_backlog(sch, 1-numsegs, len-slen);
                consume_skb(skb);
        } else {
                /* not splitting */
index 15c6eb5..c008a31 100644 (file)
@@ -158,6 +158,7 @@ static int mq_dump(struct Qdisc *sch, struct sk_buff *skb)
                        __gnet_stats_copy_queue(&sch->qstats,
                                                qdisc->cpu_qstats,
                                                &qdisc->qstats, qlen);
+                       sch->q.qlen             += qlen;
                } else {
                        sch->q.qlen             += qdisc->q.qlen;
                        sch->bstats.bytes       += qdisc->bstats.bytes;
index 68ce86c..008db8d 100644 (file)
@@ -413,6 +413,7 @@ static int mqprio_dump(struct Qdisc *sch, struct sk_buff *skb)
                        __gnet_stats_copy_queue(&sch->qstats,
                                                qdisc->cpu_qstats,
                                                &qdisc->qstats, qlen);
+                       sch->q.qlen             += qlen;
                } else {
                        sch->q.qlen             += qdisc->q.qlen;
                        sch->bstats.bytes       += qdisc->bstats.bytes;
@@ -435,7 +436,7 @@ static int mqprio_dump(struct Qdisc *sch, struct sk_buff *skb)
                opt.offset[tc] = dev->tc_to_txq[tc].offset;
        }
 
-       if (nla_put(skb, TCA_OPTIONS, NLA_ALIGN(sizeof(opt)), &opt))
+       if (nla_put(skb, TCA_OPTIONS, sizeof(opt), &opt))
                goto nla_put_failure;
 
        if ((priv->flags & TC_MQPRIO_F_MODE) &&
index 6d36f74..269b528 100644 (file)
@@ -242,6 +242,7 @@ static void sctp_v4_from_skb(union sctp_addr *addr, struct sk_buff *skb,
                sa->sin_port = sh->dest;
                sa->sin_addr.s_addr = ip_hdr(skb)->daddr;
        }
+       memset(sa->sin_zero, 0, sizeof(sa->sin_zero));
 }
 
 /* Initialize an sctp_addr from a socket. */
@@ -250,6 +251,7 @@ static void sctp_v4_from_sk(union sctp_addr *addr, struct sock *sk)
        addr->v4.sin_family = AF_INET;
        addr->v4.sin_port = 0;
        addr->v4.sin_addr.s_addr = inet_sk(sk)->inet_rcv_saddr;
+       memset(addr->v4.sin_zero, 0, sizeof(addr->v4.sin_zero));
 }
 
 /* Initialize sk->sk_rcv_saddr from sctp_addr. */
@@ -272,6 +274,7 @@ static void sctp_v4_from_addr_param(union sctp_addr *addr,
        addr->v4.sin_family = AF_INET;
        addr->v4.sin_port = port;
        addr->v4.sin_addr.s_addr = param->v4.addr.s_addr;
+       memset(addr->v4.sin_zero, 0, sizeof(addr->v4.sin_zero));
 }
 
 /* Initialize an address parameter from a sctp_addr and return the length
@@ -296,6 +299,7 @@ static void sctp_v4_dst_saddr(union sctp_addr *saddr, struct flowi4 *fl4,
        saddr->v4.sin_family = AF_INET;
        saddr->v4.sin_port = port;
        saddr->v4.sin_addr.s_addr = fl4->saddr;
+       memset(saddr->v4.sin_zero, 0, sizeof(saddr->v4.sin_zero));
 }
 
 /* Compare two addresses exactly. */
@@ -318,6 +322,7 @@ static void sctp_v4_inaddr_any(union sctp_addr *addr, __be16 port)
        addr->v4.sin_family = AF_INET;
        addr->v4.sin_addr.s_addr = htonl(INADDR_ANY);
        addr->v4.sin_port = port;
+       memset(addr->v4.sin_zero, 0, sizeof(addr->v4.sin_zero));
 }
 
 /* Is this a wildcard address? */
index ad158d3..c0d55ed 100644 (file)
@@ -278,7 +278,7 @@ bool sctp_transport_update_pmtu(struct sctp_transport *t, u32 pmtu)
 
                pf->af->from_sk(&addr, sk);
                pf->to_sk_daddr(&t->ipaddr, sk);
-               dst->ops->update_pmtu(dst, sk, NULL, pmtu);
+               dst->ops->update_pmtu(dst, sk, NULL, pmtu, true);
                pf->to_sk_daddr(&addr, sk);
 
                dst = sctp_transport_dst_check(t);
index 0ecbbdc..62885a2 100644 (file)
@@ -486,25 +486,23 @@ static int smcr_tx_sndbuf_nonempty(struct smc_connection *conn)
        struct smc_wr_buf *wr_buf;
        int rc;
 
-       spin_lock_bh(&conn->send_lock);
        rc = smc_cdc_get_free_slot(conn, &wr_buf, &pend);
        if (rc < 0) {
                if (rc == -EBUSY) {
                        struct smc_sock *smc =
                                container_of(conn, struct smc_sock, conn);
 
-                       if (smc->sk.sk_err == ECONNABORTED) {
-                               rc = sock_error(&smc->sk);
-                               goto out_unlock;
-                       }
+                       if (smc->sk.sk_err == ECONNABORTED)
+                               return sock_error(&smc->sk);
                        rc = 0;
                        if (conn->alert_token_local) /* connection healthy */
                                mod_delayed_work(system_wq, &conn->tx_work,
                                                 SMC_TX_WORK_DELAY);
                }
-               goto out_unlock;
+               return rc;
        }
 
+       spin_lock_bh(&conn->send_lock);
        if (!conn->local_tx_ctrl.prod_flags.urg_data_present) {
                rc = smc_tx_rdma_writes(conn);
                if (rc) {
index 214440c..3a28e15 100644 (file)
@@ -54,9 +54,6 @@ static void cache_init(struct cache_head *h, struct cache_detail *detail)
        h->last_refresh = now;
 }
 
-static inline int cache_is_valid(struct cache_head *h);
-static void cache_fresh_locked(struct cache_head *head, time_t expiry,
-                               struct cache_detail *detail);
 static void cache_fresh_unlocked(struct cache_head *head,
                                struct cache_detail *detail);
 
@@ -101,9 +98,6 @@ struct cache_head *sunrpc_cache_lookup(struct cache_detail *detail,
                        if (cache_is_expired(detail, tmp)) {
                                hlist_del_init(&tmp->cache_list);
                                detail->entries --;
-                               if (cache_is_valid(tmp) == -EAGAIN)
-                                       set_bit(CACHE_NEGATIVE, &tmp->flags);
-                               cache_fresh_locked(tmp, 0, detail);
                                freeme = tmp;
                                break;
                        }
index eb0f701..49bb9fc 100644 (file)
@@ -120,14 +120,6 @@ static int __init tipc_init(void)
        sysctl_tipc_rmem[1] = RCVBUF_DEF;
        sysctl_tipc_rmem[2] = RCVBUF_MAX;
 
-       err = tipc_netlink_start();
-       if (err)
-               goto out_netlink;
-
-       err = tipc_netlink_compat_start();
-       if (err)
-               goto out_netlink_compat;
-
        err = tipc_register_sysctl();
        if (err)
                goto out_sysctl;
@@ -148,8 +140,21 @@ static int __init tipc_init(void)
        if (err)
                goto out_bearer;
 
+       err = tipc_netlink_start();
+       if (err)
+               goto out_netlink;
+
+       err = tipc_netlink_compat_start();
+       if (err)
+               goto out_netlink_compat;
+
        pr_info("Started in single node mode\n");
        return 0;
+
+out_netlink_compat:
+       tipc_netlink_stop();
+out_netlink:
+       tipc_bearer_cleanup();
 out_bearer:
        unregister_pernet_device(&tipc_topsrv_net_ops);
 out_pernet_topsrv:
@@ -159,22 +164,18 @@ out_socket:
 out_pernet:
        tipc_unregister_sysctl();
 out_sysctl:
-       tipc_netlink_compat_stop();
-out_netlink_compat:
-       tipc_netlink_stop();
-out_netlink:
        pr_err("Unable to start in single node mode\n");
        return err;
 }
 
 static void __exit tipc_exit(void)
 {
+       tipc_netlink_compat_stop();
+       tipc_netlink_stop();
        tipc_bearer_cleanup();
        unregister_pernet_device(&tipc_topsrv_net_ops);
        tipc_socket_stop();
        unregister_pernet_device(&tipc_net_ops);
-       tipc_netlink_stop();
-       tipc_netlink_compat_stop();
        tipc_unregister_sysctl();
 
        pr_info("Deactivated\n");
index f8bb3cd..7d92857 100644 (file)
@@ -5,6 +5,8 @@
 # Author: Jesper Dangaaard Brouer
 # License: GPL
 
+set -o errexit
+
 ## -- General shell logging cmds --
 function err() {
     local exitcode=$1
@@ -58,6 +60,7 @@ function pg_set() {
 function proc_cmd() {
     local result
     local proc_file=$1
+    local status=0
     # after shift, the remaining args are contained in $@
     shift
     local proc_ctrl=${PROC_DIR}/$proc_file
@@ -73,13 +76,13 @@ function proc_cmd() {
        echo "cmd: $@ > $proc_ctrl"
     fi
     # Quoting of "$@" is important for space expansion
-    echo "$@" > "$proc_ctrl"
-    local status=$?
+    echo "$@" > "$proc_ctrl" || status=$?
 
-    result=$(grep "Result: OK:" $proc_ctrl)
-    # Due to pgctrl, cannot use exit code $? from grep
-    if [[ "$result" == "" ]]; then
-       grep "Result:" $proc_ctrl >&2
+    if [[ "$proc_file" != "pgctrl" ]]; then
+        result=$(grep "Result: OK:" $proc_ctrl) || true
+        if [[ "$result" == "" ]]; then
+            grep "Result:" $proc_ctrl >&2
+        fi
     fi
     if (( $status != 0 )); then
        err 5 "Write error($status) occurred cmd: \"$@ > $proc_ctrl\""
@@ -105,6 +108,8 @@ function pgset() {
     fi
 }
 
+[[ $EUID -eq 0 ]] && trap 'pg_ctrl "reset"' EXIT
+
 ## -- General shell tricks --
 
 function root_check_run_with_sudo() {
index 31ed7f3..4b2711c 100644 (file)
@@ -491,6 +491,8 @@ static void build_initial_tok_table(void)
                                table[pos] = table[i];
                        learn_symbol(table[pos].sym, table[pos].len);
                        pos++;
+               } else {
+                       free(table[i].sym);
                }
        }
        table_cnt = pos;
index ba11bdf..2469549 100644 (file)
@@ -1462,11 +1462,13 @@ static inline bool use_label_hname(struct aa_ns *ns, struct aa_label *label,
 /* helper macro for snprint routines */
 #define update_for_len(total, len, size, str)  \
 do {                                   \
+       size_t ulen = len;              \
+                                       \
        AA_BUG(len < 0);                \
-       total += len;                   \
-       len = min(len, size);           \
-       size -= len;                    \
-       str += len;                     \
+       total += ulen;                  \
+       ulen = min(ulen, size);         \
+       size -= ulen;                   \
+       str += ulen;                    \
 } while (0)
 
 /**
@@ -1601,7 +1603,7 @@ int aa_label_snxprint(char *str, size_t size, struct aa_ns *ns,
        struct aa_ns *prev_ns = NULL;
        struct label_it i;
        int count = 0, total = 0;
-       size_t len;
+       ssize_t len;
 
        AA_BUG(!str && size != 0);
        AA_BUG(!label);
index e08c6c6..f03ceaf 100644 (file)
@@ -752,6 +752,10 @@ static int snd_pcm_hw_params(struct snd_pcm_substream *substream,
        while (runtime->boundary * 2 <= LONG_MAX - runtime->buffer_size)
                runtime->boundary *= 2;
 
+       /* clear the buffer for avoiding possible kernel info leaks */
+       if (runtime->dma_area && !substream->ops->copy_user)
+               memset(runtime->dma_area, 0, runtime->dma_bytes);
+
        snd_pcm_timer_resolution_change(substream);
        snd_pcm_set_state(substream, SNDRV_PCM_STATE_SETUP);
 
index 86a31e6..b5dc510 100644 (file)
@@ -88,6 +88,9 @@ static LIST_HEAD(snd_timer_slave_list);
 /* lock for slave active lists */
 static DEFINE_SPINLOCK(slave_active_lock);
 
+#define MAX_SLAVE_INSTANCES    1000
+static int num_slaves;
+
 static DEFINE_MUTEX(register_mutex);
 
 static int snd_timer_free(struct snd_timer *timer);
@@ -266,6 +269,10 @@ int snd_timer_open(struct snd_timer_instance **ti,
                        err = -EINVAL;
                        goto unlock;
                }
+               if (num_slaves >= MAX_SLAVE_INSTANCES) {
+                       err = -EBUSY;
+                       goto unlock;
+               }
                timeri = snd_timer_instance_new(owner, NULL);
                if (!timeri) {
                        err = -ENOMEM;
@@ -275,6 +282,7 @@ int snd_timer_open(struct snd_timer_instance **ti,
                timeri->slave_id = tid->device;
                timeri->flags |= SNDRV_TIMER_IFLG_SLAVE;
                list_add_tail(&timeri->open_list, &snd_timer_slave_list);
+               num_slaves++;
                err = snd_timer_check_slave(timeri);
                if (err < 0) {
                        snd_timer_close_locked(timeri, &card_dev_to_put);
@@ -364,6 +372,8 @@ static int snd_timer_close_locked(struct snd_timer_instance *timeri,
        struct snd_timer_instance *slave, *tmp;
 
        list_del(&timeri->open_list);
+       if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE)
+               num_slaves--;
 
        /* force to stop the timer */
        snd_timer_stop(timeri);
index 8fcb421..fa261b2 100644 (file)
@@ -883,7 +883,7 @@ static int azx_rirb_get_response(struct hdac_bus *bus, unsigned int addr,
                return -EAGAIN; /* give a chance to retry */
        }
 
-       dev_WARN(chip->card->dev,
+       dev_err(chip->card->dev,
                "azx_get_response timeout, switching to single_cmd mode: last cmd=0x%08x\n",
                bus->last_cmd[addr]);
        chip->single_cmd = 1;
index 6a9b89e..bc4edc5 100644 (file)
@@ -1683,13 +1683,14 @@ struct scp_msg {
 
 static void dspio_clear_response_queue(struct hda_codec *codec)
 {
+       unsigned long timeout = jiffies + msecs_to_jiffies(1000);
        unsigned int dummy = 0;
-       int status = -1;
+       int status;
 
        /* clear all from the response queue */
        do {
                status = dspio_read(codec, &dummy);
-       } while (status == 0);
+       } while (status == 0 && time_before(jiffies, timeout));
 }
 
 static int dspio_get_response_data(struct hda_codec *codec)
@@ -6754,12 +6755,14 @@ static void ca0132_process_dsp_response(struct hda_codec *codec,
        struct ca0132_spec *spec = codec->spec;
 
        codec_dbg(codec, "ca0132_process_dsp_response\n");
+       snd_hda_power_up_pm(codec);
        if (spec->wait_scp) {
                if (dspio_get_response_data(codec) >= 0)
                        spec->wait_scp = 0;
        }
 
        dspio_clear_response_queue(codec);
+       snd_hda_power_down_pm(codec);
 }
 
 static void hp_callback(struct hda_codec *codec, struct hda_jack_callback *cb)
@@ -6770,11 +6773,10 @@ static void hp_callback(struct hda_codec *codec, struct hda_jack_callback *cb)
        /* Delay enabling the HP amp, to let the mic-detection
         * state machine run.
         */
-       cancel_delayed_work(&spec->unsol_hp_work);
-       schedule_delayed_work(&spec->unsol_hp_work, msecs_to_jiffies(500));
        tbl = snd_hda_jack_tbl_get(codec, cb->nid);
        if (tbl)
                tbl->block_report = 1;
+       schedule_delayed_work(&spec->unsol_hp_work, msecs_to_jiffies(500));
 }
 
 static void amic_callback(struct hda_codec *codec, struct hda_jack_callback *cb)
@@ -7408,12 +7410,25 @@ static void ca0132_reboot_notify(struct hda_codec *codec)
        codec->patch_ops.free(codec);
 }
 
+#ifdef CONFIG_PM
+static int ca0132_suspend(struct hda_codec *codec)
+{
+       struct ca0132_spec *spec = codec->spec;
+
+       cancel_delayed_work_sync(&spec->unsol_hp_work);
+       return 0;
+}
+#endif
+
 static const struct hda_codec_ops ca0132_patch_ops = {
        .build_controls = ca0132_build_controls,
        .build_pcms = ca0132_build_pcms,
        .init = ca0132_init,
        .free = ca0132_free,
        .unsol_event = snd_hda_jack_unsol_event,
+#ifdef CONFIG_PM
+       .suspend = ca0132_suspend,
+#endif
        .reboot_notify = ca0132_reboot_notify,
 };
 
index f842db4..7e3b47e 100644 (file)
@@ -3307,6 +3307,9 @@ static void rt5645_jack_detect_work(struct work_struct *work)
                snd_soc_jack_report(rt5645->mic_jack,
                                    report, SND_JACK_MICROPHONE);
                return;
+       case 4:
+               val = snd_soc_component_read32(rt5645->component, RT5645_A_JD_CTRL1) & 0x0020;
+               break;
        default: /* read rt5645 jd1_1 status */
                val = snd_soc_component_read32(rt5645->component, RT5645_INT_IRQ_ST) & 0x1000;
                break;
@@ -3634,7 +3637,7 @@ static const struct rt5645_platform_data intel_braswell_platform_data = {
 static const struct rt5645_platform_data buddy_platform_data = {
        .dmic1_data_pin = RT5645_DMIC_DATA_GPIO5,
        .dmic2_data_pin = RT5645_DMIC_DATA_IN2P,
-       .jd_mode = 3,
+       .jd_mode = 4,
        .level_trigger_irq = true,
 };
 
@@ -4030,6 +4033,7 @@ static int rt5645_i2c_probe(struct i2c_client *i2c,
                                           RT5645_JD1_MODE_1);
                        break;
                case 3:
+               case 4:
                        regmap_update_bits(rt5645->regmap, RT5645_A_JD_CTRL1,
                                           RT5645_JD1_MODE_MASK,
                                           RT5645_JD1_MODE_2);
index 9b7a183..71b7b88 100644 (file)
@@ -297,6 +297,7 @@ static bool rt5677_volatile_register(struct device *dev, unsigned int reg)
        case RT5677_I2C_MASTER_CTRL7:
        case RT5677_I2C_MASTER_CTRL8:
        case RT5677_HAP_GENE_CTRL2:
+       case RT5677_PWR_ANLG2: /* Modified by DSP firmware */
        case RT5677_PWR_DSP_ST:
        case RT5677_PRIV_DATA:
        case RT5677_ASRC_22:
index deff651..0a3b746 100644 (file)
@@ -2413,6 +2413,8 @@ static int wm2200_i2c_probe(struct i2c_client *i2c,
 
 err_pm_runtime:
        pm_runtime_disable(&i2c->dev);
+       if (i2c->irq)
+               free_irq(i2c->irq, wm2200);
 err_reset:
        if (wm2200->pdata.reset)
                gpio_set_value_cansleep(wm2200->pdata.reset, 0);
@@ -2429,12 +2431,15 @@ static int wm2200_i2c_remove(struct i2c_client *i2c)
 {
        struct wm2200_priv *wm2200 = i2c_get_clientdata(i2c);
 
+       pm_runtime_disable(&i2c->dev);
        if (i2c->irq)
                free_irq(i2c->irq, wm2200);
        if (wm2200->pdata.reset)
                gpio_set_value_cansleep(wm2200->pdata.reset, 0);
        if (wm2200->pdata.ldo_ena)
                gpio_set_value_cansleep(wm2200->pdata.ldo_ena, 0);
+       regulator_bulk_disable(ARRAY_SIZE(wm2200->core_supplies),
+                              wm2200->core_supplies);
 
        return 0;
 }
index ba89d9d..b793701 100644 (file)
@@ -2620,6 +2620,7 @@ static int wm5100_i2c_probe(struct i2c_client *i2c,
        return ret;
 
 err_reset:
+       pm_runtime_disable(&i2c->dev);
        if (i2c->irq)
                free_irq(i2c->irq, wm5100);
        wm5100_free_gpio(i2c);
@@ -2643,6 +2644,7 @@ static int wm5100_i2c_remove(struct i2c_client *i2c)
 {
        struct wm5100_priv *wm5100 = i2c_get_clientdata(i2c);
 
+       pm_runtime_disable(&i2c->dev);
        if (i2c->irq)
                free_irq(i2c->irq, wm5100);
        wm5100_free_gpio(i2c);
index 1965635..d14e851 100644 (file)
@@ -1902,6 +1902,7 @@ static int wm8904_set_bias_level(struct snd_soc_component *component,
                snd_soc_component_update_bits(component, WM8904_BIAS_CONTROL_0,
                                    WM8904_BIAS_ENA, 0);
 
+               snd_soc_component_write(component, WM8904_SW_RESET_AND_ID, 0);
                regcache_cache_only(wm8904->regmap, true);
                regcache_mark_dirty(wm8904->regmap);
 
index b6dc524..6acd5dd 100644 (file)
@@ -414,10 +414,12 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
                        DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
                        DMI_MATCH(DMI_PRODUCT_NAME, "Aspire SW5-012"),
                },
-               .driver_data = (void *)(BYT_RT5640_IN1_MAP |
-                                                BYT_RT5640_MCLK_EN |
-                                                BYT_RT5640_SSP0_AIF1),
-
+               .driver_data = (void *)(BYT_RT5640_DMIC1_MAP |
+                                       BYT_RT5640_JD_SRC_JD2_IN4N |
+                                       BYT_RT5640_OVCD_TH_2000UA |
+                                       BYT_RT5640_OVCD_SF_0P75 |
+                                       BYT_RT5640_SSP0_AIF1 |
+                                       BYT_RT5640_MCLK_EN),
        },
        {
                .matches = {
index b8a03f5..f36e33a 100644 (file)
@@ -423,6 +423,9 @@ static int kabylake_dmic_startup(struct snd_pcm_substream *substream)
        snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
                        dmic_constraints);
 
+       runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE;
+       snd_pcm_hw_constraint_msbits(runtime, 0, 16, 16);
+
        return snd_pcm_hw_constraint_list(substream->runtime, 0,
                        SNDRV_PCM_HW_PARAM_RATE, &constraints_rates);
 }
index c7b990a..2a528e7 100644 (file)
@@ -100,10 +100,9 @@ void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask)
        unsigned int sync = 0;
        int enable;
 
-       trace_snd_soc_jack_report(jack, mask, status);
-
        if (!jack)
                return;
+       trace_snd_soc_jack_report(jack, mask, status);
 
        dapm = &jack->card->dapm;
 
index a62be78..249fa8d 100644 (file)
@@ -1073,16 +1073,22 @@ int bpf_map__reuse_fd(struct bpf_map *map, int fd)
                return -errno;
 
        new_fd = open("/", O_RDONLY | O_CLOEXEC);
-       if (new_fd < 0)
+       if (new_fd < 0) {
+               err = -errno;
                goto err_free_new_name;
+       }
 
        new_fd = dup3(fd, new_fd, O_CLOEXEC);
-       if (new_fd < 0)
+       if (new_fd < 0) {
+               err = -errno;
                goto err_close_new_fd;
+       }
 
        err = zclose(map->fd);
-       if (err)
+       if (err) {
+               err = -errno;
                goto err_close_new_fd;
+       }
        free(map->name);
 
        map->fd = new_fd;
@@ -1101,7 +1107,7 @@ err_close_new_fd:
        close(new_fd);
 err_free_new_name:
        free(new_name);
-       return -errno;
+       return err;
 }
 
 static int
index 5b2cd5e..5dbb0dd 100644 (file)
@@ -28,7 +28,9 @@ ifeq ($(DEBUG),0)
   endif
 endif
 
-ifeq ($(CC_NO_CLANG), 0)
+ifeq ($(DEBUG),1)
+  CFLAGS += -O0
+else ifeq ($(CC_NO_CLANG), 0)
   CFLAGS += -O3
 else
   CFLAGS += -O6
index e76154c..2700f1f 100644 (file)
@@ -1475,8 +1475,10 @@ static int copy_filter_type(struct event_filter *filter,
        if (strcmp(str, "TRUE") == 0 || strcmp(str, "FALSE") == 0) {
                /* Add trivial event */
                arg = allocate_arg();
-               if (arg == NULL)
+               if (arg == NULL) {
+                       free(str);
                        return -1;
+               }
 
                arg->type = FILTER_ARG_BOOLEAN;
                if (strcmp(str, "TRUE") == 0)
@@ -1485,8 +1487,11 @@ static int copy_filter_type(struct event_filter *filter,
                        arg->boolean.value = 0;
 
                filter_type = add_filter_type(filter, event->id);
-               if (filter_type == NULL)
+               if (filter_type == NULL) {
+                       free(str);
+                       free_arg(arg);
                        return -1;
+               }
 
                filter_type->filter = arg;
 
index e0b8593..0a0e911 100644 (file)
@@ -333,7 +333,7 @@ AVXcode: 1
 06: CLTS
 07: SYSRET (o64)
 08: INVD
-09: WBINVD
+09: WBINVD | WBNOINVD (F3)
 0a:
 0b: UD2 (1B)
 0c:
@@ -364,7 +364,7 @@ AVXcode: 1
 # a ModR/M byte.
 1a: BNDCL Gv,Ev (F3) | BNDCU Gv,Ev (F2) | BNDMOV Gv,Ev (66) | BNDLDX Gv,Ev
 1b: BNDCN Gv,Ev (F2) | BNDMOV Ev,Gv (66) | BNDMK Gv,Ev (F3) | BNDSTX Ev,Gv
-1c:
+1c: Grp20 (1A),(1C)
 1d:
 1e:
 1f: NOP Ev
@@ -792,6 +792,8 @@ f3: Grp17 (1A)
 f5: BZHI Gy,Ey,By (v) | PEXT Gy,By,Ey (F3),(v) | PDEP Gy,By,Ey (F2),(v)
 f6: ADCX Gy,Ey (66) | ADOX Gy,Ey (F3) | MULX By,Gy,rDX,Ey (F2),(v)
 f7: BEXTR Gy,Ey,By (v) | SHLX Gy,Ey,By (66),(v) | SARX Gy,Ey,By (F3),(v) | SHRX Gy,Ey,By (F2),(v)
+f8: MOVDIR64B Gv,Mdqq (66) | ENQCMD Gv,Mdqq (F2) | ENQCMDS Gv,Mdqq (F3)
+f9: MOVDIRI My,Gy
 EndTable
 
 Table: 3-byte opcode 2 (0x0f 0x3a)
@@ -943,9 +945,9 @@ GrpTable: Grp6
 EndTable
 
 GrpTable: Grp7
-0: SGDT Ms | VMCALL (001),(11B) | VMLAUNCH (010),(11B) | VMRESUME (011),(11B) | VMXOFF (100),(11B)
-1: SIDT Ms | MONITOR (000),(11B) | MWAIT (001),(11B) | CLAC (010),(11B) | STAC (011),(11B)
-2: LGDT Ms | XGETBV (000),(11B) | XSETBV (001),(11B) | VMFUNC (100),(11B) | XEND (101)(11B) | XTEST (110)(11B)
+0: SGDT Ms | VMCALL (001),(11B) | VMLAUNCH (010),(11B) | VMRESUME (011),(11B) | VMXOFF (100),(11B) | PCONFIG (101),(11B) | ENCLV (000),(11B)
+1: SIDT Ms | MONITOR (000),(11B) | MWAIT (001),(11B) | CLAC (010),(11B) | STAC (011),(11B) | ENCLS (111),(11B)
+2: LGDT Ms | XGETBV (000),(11B) | XSETBV (001),(11B) | VMFUNC (100),(11B) | XEND (101)(11B) | XTEST (110)(11B) | ENCLU (111),(11B)
 3: LIDT Ms
 4: SMSW Mw/Rv
 5: rdpkru (110),(11B) | wrpkru (111),(11B)
@@ -1020,7 +1022,7 @@ GrpTable: Grp15
 3: vstmxcsr Md (v1) | WRGSBASE Ry (F3),(11B)
 4: XSAVE | ptwrite Ey (F3),(11B)
 5: XRSTOR | lfence (11B)
-6: XSAVEOPT | clwb (66) | mfence (11B)
+6: XSAVEOPT | clwb (66) | mfence (11B) | TPAUSE Rd (66),(11B) | UMONITOR Rv (F3),(11B) | UMWAIT Rd (F2),(11B)
 7: clflush | clflushopt (66) | sfence (11B)
 EndTable
 
@@ -1051,6 +1053,10 @@ GrpTable: Grp19
 6: vscatterpf1qps/d Wx (66),(ev)
 EndTable
 
+GrpTable: Grp20
+0: cldemote Mb
+EndTable
+
 # AMD's Prefetch Group
 GrpTable: GrpP
 0: PREFETCH
index b2188e6..2f94f7a 100644 (file)
@@ -383,6 +383,13 @@ static int report__setup_sample_type(struct report *rep)
                                PERF_SAMPLE_BRANCH_ANY))
                rep->nonany_branch_mode = true;
 
+#ifndef HAVE_LIBUNWIND_SUPPORT
+       if (dwarf_callchain_users) {
+               ui__warning("Please install libunwind development packages "
+                           "during the perf build.\n");
+       }
+#endif
+
        return 0;
 }
 
index a4c7849..1200973 100644 (file)
@@ -428,7 +428,7 @@ static int perf_evsel__check_attr(struct perf_evsel *evsel,
                       "selected. Hence, no address to lookup the source line number.\n");
                return -EINVAL;
        }
-       if (PRINT_FIELD(BRSTACKINSN) &&
+       if (PRINT_FIELD(BRSTACKINSN) && !allow_user_set &&
            !(perf_evlist__combined_branch_type(session->evlist) &
              PERF_SAMPLE_BRANCH_ANY)) {
                pr_err("Display of branch stack assembler requested, but non all-branch filter set\n"
index 6cd9623..38b5888 100644 (file)
@@ -754,6 +754,7 @@ static int process_mapfile(FILE *outfp, char *fpath)
        char *line, *p;
        int line_num;
        char *tblname;
+       int ret = 0;
 
        pr_info("%s: Processing mapfile %s\n", prog, fpath);
 
@@ -765,6 +766,7 @@ static int process_mapfile(FILE *outfp, char *fpath)
        if (!mapfp) {
                pr_info("%s: Error %s opening %s\n", prog, strerror(errno),
                                fpath);
+               free(line);
                return -1;
        }
 
@@ -791,7 +793,8 @@ static int process_mapfile(FILE *outfp, char *fpath)
                        /* TODO Deal with lines longer than 16K */
                        pr_info("%s: Mapfile %s: line %d too long, aborting\n",
                                        prog, fpath, line_num);
-                       return -1;
+                       ret = -1;
+                       goto out;
                }
                line[strlen(line)-1] = '\0';
 
@@ -821,7 +824,9 @@ static int process_mapfile(FILE *outfp, char *fpath)
 
 out:
        print_mapping_table_suffix(outfp);
-       return 0;
+       fclose(mapfp);
+       free(line);
+       return ret;
 }
 
 /*
@@ -1118,6 +1123,7 @@ int main(int argc, char *argv[])
                goto empty_map;
        } else if (rc < 0) {
                /* Make build fail */
+               fclose(eventsfp);
                free_arch_std_events();
                return 1;
        } else if (rc) {
@@ -1130,6 +1136,7 @@ int main(int argc, char *argv[])
                goto empty_map;
        } else if (rc < 0) {
                /* Make build fail */
+               fclose(eventsfp);
                free_arch_std_events();
                return 1;
        } else if (rc) {
@@ -1147,6 +1154,8 @@ int main(int argc, char *argv[])
        if (process_mapfile(eventsfp, mapfile)) {
                pr_info("%s: Error processing mapfile %s\n", prog, mapfile);
                /* Make build fail */
+               fclose(eventsfp);
+               free_arch_std_events();
                return 1;
        }
 
index 910e25e..6cf0065 100644 (file)
@@ -48,14 +48,6 @@ asm (
        "__test_function:\n"
        "incq (%rdi)\n"
        "ret\n");
-#elif defined (__aarch64__)
-extern void __test_function(volatile long *ptr);
-asm (
-       ".globl __test_function\n"
-       "__test_function:\n"
-       "str x30, [x0]\n"
-       "ret\n");
-
 #else
 static void __test_function(volatile long *ptr)
 {
@@ -301,10 +293,15 @@ bool test__bp_signal_is_supported(void)
         * stepping into the SIGIO handler and getting stuck on the
         * breakpointed instruction.
         *
+        * Since arm64 has the same issue with arm for the single-step
+        * handling, this case also gets suck on the breakpointed
+        * instruction.
+        *
         * Just disable the test for these architectures until these
         * issues are resolved.
         */
-#if defined(__powerpc__) || defined(__s390x__) || defined(__arm__)
+#if defined(__powerpc__) || defined(__s390x__) || defined(__arm__) || \
+    defined(__aarch64__)
        return false;
 #else
        return true;
index e92fa60..788b080 100644 (file)
@@ -105,6 +105,7 @@ int test__task_exit(struct test *test __maybe_unused, int subtest __maybe_unused
        if (perf_evlist__mmap(evlist, 128) < 0) {
                pr_debug("failed to mmap events: %d (%s)\n", errno,
                         str_error_r(errno, sbuf, sizeof(sbuf)));
+               err = -1;
                goto out_delete_evlist;
        }
 
index 7eb7de5..29e75c0 100644 (file)
@@ -321,20 +321,50 @@ bool die_is_func_def(Dwarf_Die *dw_die)
 }
 
 /**
+ * die_entrypc - Returns entry PC (the lowest address) of a DIE
+ * @dw_die: a DIE
+ * @addr: where to store entry PC
+ *
+ * Since dwarf_entrypc() does not return entry PC if the DIE has only address
+ * range, we have to use this to retrieve the lowest address from the address
+ * range attribute.
+ */
+int die_entrypc(Dwarf_Die *dw_die, Dwarf_Addr *addr)
+{
+       Dwarf_Addr base, end;
+
+       if (!addr)
+               return -EINVAL;
+
+       if (dwarf_entrypc(dw_die, addr) == 0)
+               return 0;
+
+       return dwarf_ranges(dw_die, 0, &base, addr, &end) < 0 ? -ENOENT : 0;
+}
+
+/**
  * die_is_func_instance - Ensure that this DIE is an instance of a subprogram
  * @dw_die: a DIE
  *
  * Ensure that this DIE is an instance (which has an entry address).
- * This returns true if @dw_die is a function instance. If not, you need to
- * call die_walk_instances() to find actual instances.
+ * This returns true if @dw_die is a function instance. If not, the @dw_die
+ * must be a prototype. You can use die_walk_instances() to find actual
+ * instances.
  **/
 bool die_is_func_instance(Dwarf_Die *dw_die)
 {
        Dwarf_Addr tmp;
+       Dwarf_Attribute attr_mem;
+       int tag = dwarf_tag(dw_die);
 
-       /* Actually gcc optimizes non-inline as like as inlined */
-       return !dwarf_func_inline(dw_die) && dwarf_entrypc(dw_die, &tmp) == 0;
+       if (tag != DW_TAG_subprogram &&
+           tag != DW_TAG_inlined_subroutine)
+               return false;
+
+       return dwarf_entrypc(dw_die, &tmp) == 0 ||
+               dwarf_attr(dw_die, DW_AT_ranges, &attr_mem) != NULL;
 }
+
 /**
  * die_get_data_member_location - Get the data-member offset
  * @mb_die: a DIE of a member of a data structure
@@ -611,6 +641,9 @@ static int __die_walk_instances_cb(Dwarf_Die *inst, void *data)
        Dwarf_Die *origin;
        int tmp;
 
+       if (!die_is_func_instance(inst))
+               return DIE_FIND_CB_CONTINUE;
+
        attr = dwarf_attr(inst, DW_AT_abstract_origin, &attr_mem);
        if (attr == NULL)
                return DIE_FIND_CB_CONTINUE;
@@ -682,15 +715,14 @@ static int __die_walk_funclines_cb(Dwarf_Die *in_die, void *data)
        if (dwarf_tag(in_die) == DW_TAG_inlined_subroutine) {
                fname = die_get_call_file(in_die);
                lineno = die_get_call_lineno(in_die);
-               if (fname && lineno > 0 && dwarf_entrypc(in_die, &addr) == 0) {
+               if (fname && lineno > 0 && die_entrypc(in_die, &addr) == 0) {
                        lw->retval = lw->callback(fname, lineno, addr, lw->data);
                        if (lw->retval != 0)
                                return DIE_FIND_CB_END;
                }
+               if (!lw->recursive)
+                       return DIE_FIND_CB_SIBLING;
        }
-       if (!lw->recursive)
-               /* Don't need to search recursively */
-               return DIE_FIND_CB_SIBLING;
 
        if (addr) {
                fname = dwarf_decl_file(in_die);
@@ -723,7 +755,7 @@ static int __die_walk_funclines(Dwarf_Die *sp_die, bool recursive,
        /* Handle function declaration line */
        fname = dwarf_decl_file(sp_die);
        if (fname && dwarf_decl_line(sp_die, &lineno) == 0 &&
-           dwarf_entrypc(sp_die, &addr) == 0) {
+           die_entrypc(sp_die, &addr) == 0) {
                lw.retval = callback(fname, lineno, addr, data);
                if (lw.retval != 0)
                        goto done;
@@ -737,6 +769,10 @@ static int __die_walk_culines_cb(Dwarf_Die *sp_die, void *data)
 {
        struct __line_walk_param *lw = data;
 
+       /*
+        * Since inlined function can include another inlined function in
+        * the same file, we need to walk in it recursively.
+        */
        lw->retval = __die_walk_funclines(sp_die, true, lw->callback, lw->data);
        if (lw->retval != 0)
                return DWARF_CB_ABORT;
@@ -761,11 +797,12 @@ int die_walk_lines(Dwarf_Die *rt_die, line_walk_callback_t callback, void *data)
        Dwarf_Lines *lines;
        Dwarf_Line *line;
        Dwarf_Addr addr;
-       const char *fname, *decf = NULL;
+       const char *fname, *decf = NULL, *inf = NULL;
        int lineno, ret = 0;
        int decl = 0, inl;
        Dwarf_Die die_mem, *cu_die;
        size_t nlines, i;
+       bool flag;
 
        /* Get the CU die */
        if (dwarf_tag(rt_die) != DW_TAG_compile_unit) {
@@ -796,6 +833,12 @@ int die_walk_lines(Dwarf_Die *rt_die, line_walk_callback_t callback, void *data)
                                  "Possible error in debuginfo.\n");
                        continue;
                }
+               /* Skip end-of-sequence */
+               if (dwarf_lineendsequence(line, &flag) != 0 || flag)
+                       continue;
+               /* Skip Non statement line-info */
+               if (dwarf_linebeginstatement(line, &flag) != 0 || !flag)
+                       continue;
                /* Filter lines based on address */
                if (rt_die != cu_die) {
                        /*
@@ -805,13 +848,21 @@ int die_walk_lines(Dwarf_Die *rt_die, line_walk_callback_t callback, void *data)
                         */
                        if (!dwarf_haspc(rt_die, addr))
                                continue;
+
                        if (die_find_inlinefunc(rt_die, addr, &die_mem)) {
+                               /* Call-site check */
+                               inf = die_get_call_file(&die_mem);
+                               if ((inf && !strcmp(inf, decf)) &&
+                                   die_get_call_lineno(&die_mem) == lineno)
+                                       goto found;
+
                                dwarf_decl_line(&die_mem, &inl);
                                if (inl != decl ||
                                    decf != dwarf_decl_file(&die_mem))
                                        continue;
                        }
                }
+found:
                /* Get source line */
                fname = dwarf_linesrc(line, NULL, NULL);
 
@@ -826,8 +877,9 @@ int die_walk_lines(Dwarf_Die *rt_die, line_walk_callback_t callback, void *data)
         */
        if (rt_die != cu_die)
                /*
-                * Don't need walk functions recursively, because nested
-                * inlined functions don't have lines of the specified DIE.
+                * Don't need walk inlined functions recursively, because
+                * inner inlined functions don't have the lines of the
+                * specified function.
                 */
                ret = __die_walk_funclines(rt_die, false, callback, data);
        else {
@@ -1002,7 +1054,7 @@ static int die_get_var_innermost_scope(Dwarf_Die *sp_die, Dwarf_Die *vr_die,
        bool first = true;
        const char *name;
 
-       ret = dwarf_entrypc(sp_die, &entry);
+       ret = die_entrypc(sp_die, &entry);
        if (ret)
                return ret;
 
@@ -1065,7 +1117,7 @@ int die_get_var_range(Dwarf_Die *sp_die, Dwarf_Die *vr_die, struct strbuf *buf)
        bool first = true;
        const char *name;
 
-       ret = dwarf_entrypc(sp_die, &entry);
+       ret = die_entrypc(sp_die, &entry);
        if (ret)
                return ret;
 
index 8ac53bf..ee15fac 100644 (file)
@@ -41,6 +41,9 @@ int cu_walk_functions_at(Dwarf_Die *cu_die, Dwarf_Addr addr,
 /* Get DW_AT_linkage_name (should be NULL for C binary) */
 const char *die_get_linkage_name(Dwarf_Die *dw_die);
 
+/* Get the lowest PC in DIE (including range list) */
+int die_entrypc(Dwarf_Die *dw_die, Dwarf_Addr *addr);
+
 /* Ensure that this DIE is a subprogram and definition (not declaration) */
 bool die_is_func_def(Dwarf_Die *dw_die);
 
index 003b70d..21f867a 100644 (file)
@@ -2276,7 +2276,7 @@ static int thread__resolve_callchain_sample(struct thread *thread,
        }
 
 check_calls:
-       if (callchain_param.order != ORDER_CALLEE) {
+       if (chain && callchain_param.order != ORDER_CALLEE) {
                err = find_prev_cpumode(chain, thread, cursor, parent, root_al,
                                        &cpumode, chain->nr - first_call);
                if (err)
index 1a7c76d..95043ca 100644 (file)
@@ -1282,8 +1282,15 @@ int parse_events_add_pmu(struct parse_events_state *parse_state,
        if (get_config_terms(head_config, &config_terms))
                return -ENOMEM;
 
-       if (perf_pmu__config(pmu, &attr, head_config, parse_state->error))
+       if (perf_pmu__config(pmu, &attr, head_config, parse_state->error)) {
+               struct perf_evsel_config_term *pos, *tmp;
+
+               list_for_each_entry_safe(pos, tmp, &config_terms, list) {
+                       list_del_init(&pos->list);
+                       free(pos);
+               }
                return -EINVAL;
+       }
 
        evsel = __add_event(list, &parse_state->idx, &attr,
                            get_config_name(head_config), pmu,
@@ -1843,15 +1850,20 @@ int parse_events(struct perf_evlist *evlist, const char *str,
 
        ret = parse_events__scanner(str, &parse_state, PE_START_EVENTS);
        perf_pmu__parse_cleanup();
+
+       if (!ret && list_empty(&parse_state.list)) {
+               WARN_ONCE(true, "WARNING: event parser found nothing\n");
+               return -1;
+       }
+
+       /*
+        * Add list to the evlist even with errors to allow callers to clean up.
+        */
+       perf_evlist__splice_list_tail(evlist, &parse_state.list);
+
        if (!ret) {
                struct perf_evsel *last;
 
-               if (list_empty(&parse_state.list)) {
-                       WARN_ONCE(true, "WARNING: event parser found nothing\n");
-                       return -1;
-               }
-
-               perf_evlist__splice_list_tail(evlist, &parse_state.list);
                evlist->nr_groups += parse_state.nr_groups;
                last = perf_evlist__last(evlist);
                last->cmdline_group_boundary = true;
index c9319f8..f732e3a 100644 (file)
@@ -34,7 +34,7 @@ int perf_reg_value(u64 *valp, struct regs_dump *regs, int id);
 
 static inline const char *perf_reg_name(int id __maybe_unused)
 {
-       return NULL;
+       return "unknown";
 }
 
 static inline int perf_reg_value(u64 *valp __maybe_unused,
index c37fbef..7ccabb8 100644 (file)
@@ -764,6 +764,16 @@ static int find_best_scope_cb(Dwarf_Die *fn_die, void *data)
        return 0;
 }
 
+/* Return innermost DIE */
+static int find_inner_scope_cb(Dwarf_Die *fn_die, void *data)
+{
+       struct find_scope_param *fsp = data;
+
+       memcpy(fsp->die_mem, fn_die, sizeof(Dwarf_Die));
+       fsp->found = true;
+       return 1;
+}
+
 /* Find an appropriate scope fits to given conditions */
 static Dwarf_Die *find_best_scope(struct probe_finder *pf, Dwarf_Die *die_mem)
 {
@@ -775,8 +785,13 @@ static Dwarf_Die *find_best_scope(struct probe_finder *pf, Dwarf_Die *die_mem)
                .die_mem = die_mem,
                .found = false,
        };
+       int ret;
 
-       cu_walk_functions_at(&pf->cu_die, pf->addr, find_best_scope_cb, &fsp);
+       ret = cu_walk_functions_at(&pf->cu_die, pf->addr, find_best_scope_cb,
+                                  &fsp);
+       if (!ret && !fsp.found)
+               cu_walk_functions_at(&pf->cu_die, pf->addr,
+                                    find_inner_scope_cb, &fsp);
 
        return fsp.found ? die_mem : NULL;
 }
@@ -950,7 +965,7 @@ static int probe_point_inline_cb(Dwarf_Die *in_die, void *data)
                ret = find_probe_point_lazy(in_die, pf);
        else {
                /* Get probe address */
-               if (dwarf_entrypc(in_die, &addr) != 0) {
+               if (die_entrypc(in_die, &addr) != 0) {
                        pr_warning("Failed to get entry address of %s.\n",
                                   dwarf_diename(in_die));
                        return -ENOENT;
@@ -1002,7 +1017,7 @@ static int probe_point_search_cb(Dwarf_Die *sp_die, void *data)
                param->retval = find_probe_point_by_line(pf);
        } else if (die_is_func_instance(sp_die)) {
                /* Instances always have the entry address */
-               dwarf_entrypc(sp_die, &pf->addr);
+               die_entrypc(sp_die, &pf->addr);
                /* But in some case the entry address is 0 */
                if (pf->addr == 0) {
                        pr_debug("%s has no entry PC. Skipped\n",
@@ -1414,6 +1429,18 @@ error:
        return DIE_FIND_CB_END;
 }
 
+static bool available_var_finder_overlap(struct available_var_finder *af)
+{
+       int i;
+
+       for (i = 0; i < af->nvls; i++) {
+               if (af->pf.addr == af->vls[i].point.address)
+                       return true;
+       }
+       return false;
+
+}
+
 /* Add a found vars into available variables list */
 static int add_available_vars(Dwarf_Die *sc_die, struct probe_finder *pf)
 {
@@ -1424,6 +1451,14 @@ static int add_available_vars(Dwarf_Die *sc_die, struct probe_finder *pf)
        Dwarf_Die die_mem;
        int ret;
 
+       /*
+        * For some reason (e.g. different column assigned to same address),
+        * this callback can be called with the address which already passed.
+        * Ignore it first.
+        */
+       if (available_var_finder_overlap(af))
+               return 0;
+
        /* Check number of tevs */
        if (af->nvls == af->max_vls) {
                pr_warning("Too many( > %d) probe point found.\n", af->max_vls);
@@ -1567,7 +1602,7 @@ int debuginfo__find_probe_point(struct debuginfo *dbg, unsigned long addr,
                /* Get function entry information */
                func = basefunc = dwarf_diename(&spdie);
                if (!func ||
-                   dwarf_entrypc(&spdie, &baseaddr) != 0 ||
+                   die_entrypc(&spdie, &baseaddr) != 0 ||
                    dwarf_decl_line(&spdie, &baseline) != 0) {
                        lineno = 0;
                        goto post;
@@ -1584,7 +1619,7 @@ int debuginfo__find_probe_point(struct debuginfo *dbg, unsigned long addr,
                while (die_find_top_inlinefunc(&spdie, (Dwarf_Addr)addr,
                                                &indie)) {
                        /* There is an inline function */
-                       if (dwarf_entrypc(&indie, &_addr) == 0 &&
+                       if (die_entrypc(&indie, &_addr) == 0 &&
                            _addr == addr) {
                                /*
                                 * addr is at an inline function entry.
index 9005fbe..23092fd 100644 (file)
@@ -109,7 +109,6 @@ static int strbuf_addv(struct strbuf *sb, const char *fmt, va_list ap)
                        return ret;
                }
                len = vsnprintf(sb->buf + sb->len, sb->alloc - sb->len, fmt, ap_saved);
-               va_end(ap_saved);
                if (len > strbuf_avail(sb)) {
                        pr_debug("this should not happen, your vsnprintf is broken");
                        va_end(ap_saved);
index f794d6b..3e4ff4a 100644 (file)
@@ -40,7 +40,6 @@ static cstate_t hsw_ext_cstates[HSW_EXT_CSTATE_COUNT] = {
        {
                .name                   = "PC9",
                .desc                   = N_("Processor Package C9"),
-               .desc                   = N_("Processor Package C2"),
                .id                     = PC9,
                .range                  = RANGE_PACKAGE,
                .get_count_percent      = hsw_ext_get_count_percent,
index cf16948..6af24f9 100644 (file)
@@ -44,7 +44,7 @@
  */
 int setup_cgroup_environment(void)
 {
-       char cgroup_workdir[PATH_MAX + 1];
+       char cgroup_workdir[PATH_MAX - 24];
 
        format_cgroup_path(cgroup_workdir, "");
 
index fef88eb..fa6a88c 100755 (executable)
@@ -36,7 +36,7 @@ h2_destroy()
 {
        ip -6 route del 2001:db8:1::/64 vrf v$h2
        ip -4 route del 192.0.2.0/28 vrf v$h2
-       simple_if_fini $h2 192.0.2.130/28
+       simple_if_fini $h2 192.0.2.130/28 2001:db8:2::2/64
 }
 
 router_create()