]> git.karo-electronics.de Git - linux-beck.git/commitdiff
Merge tag 'iio-for-4.5c' of git://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio...
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 27 Dec 2015 01:05:25 +0000 (17:05 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 27 Dec 2015 01:05:25 +0000 (17:05 -0800)
Jonathan writes:

Third set of new stuff for IIO in the 4.5 cycle.

New driver features
- us5182
  * Add interrupt support and rising / falling threshold events.

Cleanups / fixes to new stuff / minor additions
* Expose the IIO value formatting function for drivers to
  make use of internally.
- ina2xx
   * Fix wrong channel order
   * Fix incorrect reporting of endianness
   * Adding documentation of ABI unique to this device
- mma8452
  * Drop an unused register description
  * Use an enum for the channel index to aid readability
- sca3000
  * Use standard NULL comparison style
- us5182
  * fix an inconsistency in status of enable (a bug with no real effect until
    above patches are applied)
  * refactor the read_raw function to improve maintainability / readability.

1071 files changed:
Documentation/arm/keystone/Overview.txt
Documentation/block/null_blk.txt
Documentation/devicetree/bindings/gpio/gpio-mpc8xxx.txt
Documentation/devicetree/bindings/net/marvell-armada-370-neta.txt
Documentation/devicetree/bindings/staging/ion/hi6220-ion.txt [new file with mode: 0644]
Documentation/devicetree/bindings/thermal/rockchip-thermal.txt
MAINTAINERS
Makefile
arch/arc/configs/axs101_defconfig
arch/arc/configs/axs103_defconfig
arch/arc/configs/axs103_smp_defconfig
arch/arc/configs/nsim_hs_defconfig
arch/arc/configs/nsim_hs_smp_defconfig
arch/arc/configs/nsimosci_hs_defconfig
arch/arc/configs/nsimosci_hs_smp_defconfig
arch/arc/configs/vdk_hs38_defconfig
arch/arc/configs/vdk_hs38_smp_defconfig
arch/arc/include/asm/irqflags-arcv2.h
arch/arc/include/asm/irqflags-compact.h
arch/arc/kernel/ctx_sw.c
arch/arc/kernel/ctx_sw_asm.S
arch/arc/kernel/process.c
arch/arc/kernel/unwind.c
arch/arc/mm/tlb.c
arch/arm/Kconfig
arch/arm/boot/dts/am4372.dtsi
arch/arm/boot/dts/am43xx-clocks.dtsi
arch/arm/boot/dts/am57xx-beagle-x15.dts
arch/arm/boot/dts/animeo_ip.dts
arch/arm/boot/dts/armada-38x.dtsi
arch/arm/boot/dts/at91-foxg20.dts
arch/arm/boot/dts/at91-kizbox.dts
arch/arm/boot/dts/at91-kizbox2.dts
arch/arm/boot/dts/at91-kizboxmini.dts
arch/arm/boot/dts/at91-qil_a9260.dts
arch/arm/boot/dts/at91-sama5d2_xplained.dts
arch/arm/boot/dts/at91-sama5d3_xplained.dts
arch/arm/boot/dts/at91-sama5d4_xplained.dts
arch/arm/boot/dts/at91-sama5d4ek.dts
arch/arm/boot/dts/at91rm9200ek.dts
arch/arm/boot/dts/at91sam9261ek.dts
arch/arm/boot/dts/at91sam9263ek.dts
arch/arm/boot/dts/at91sam9g20ek_common.dtsi
arch/arm/boot/dts/at91sam9m10g45ek.dts
arch/arm/boot/dts/at91sam9n12ek.dts
arch/arm/boot/dts/at91sam9rlek.dts
arch/arm/boot/dts/at91sam9x5cm.dtsi
arch/arm/boot/dts/berlin2q.dtsi
arch/arm/boot/dts/dm816x.dtsi
arch/arm/boot/dts/dra7.dtsi
arch/arm/boot/dts/k2l-netcp.dtsi
arch/arm/boot/dts/kirkwood-ts219.dtsi
arch/arm/boot/dts/rk3288-veyron-minnie.dts
arch/arm/boot/dts/rk3288.dtsi
arch/arm/boot/dts/sama5d35ek.dts
arch/arm/boot/dts/sama5d4.dtsi
arch/arm/boot/dts/usb_a9260_common.dtsi
arch/arm/boot/dts/usb_a9263.dts
arch/arm/boot/dts/vf610-colibri.dtsi
arch/arm/boot/dts/vf610.dtsi
arch/arm/boot/dts/vfxxx.dtsi
arch/arm/configs/at91_dt_defconfig
arch/arm/configs/sama5_defconfig
arch/arm/include/asm/arch_gicv3.h
arch/arm/include/asm/irq.h
arch/arm/include/asm/kvm_emulate.h
arch/arm/include/uapi/asm/unistd.h
arch/arm/kernel/bios32.c
arch/arm/kernel/calls.S
arch/arm/kvm/arm.c
arch/arm/kvm/mmio.c
arch/arm/kvm/mmu.c
arch/arm/kvm/psci.c
arch/arm/mach-at91/Kconfig
arch/arm/mach-at91/pm.c
arch/arm/mach-dove/include/mach/entry-macro.S
arch/arm/mach-exynos/pmu.c
arch/arm/mach-imx/gpc.c
arch/arm/mach-ixp4xx/include/mach/io.h
arch/arm/mach-omap2/Kconfig
arch/arm/mach-omap2/omap-smp.c
arch/arm/mach-omap2/omap_hwmod.c
arch/arm/mach-omap2/omap_hwmod.h
arch/arm/mach-omap2/omap_hwmod_7xx_data.c
arch/arm/mach-omap2/omap_hwmod_81xx_data.c
arch/arm/mach-omap2/pdata-quirks.c
arch/arm/mach-omap2/pm34xx.c
arch/arm/mach-orion5x/include/mach/entry-macro.S
arch/arm/mach-pxa/ezx.c
arch/arm/mach-pxa/palm27x.c
arch/arm/mach-pxa/palmtc.c
arch/arm/mach-s3c24xx/pll-s3c2440-12000000.c
arch/arm/mach-s3c24xx/pll-s3c2440-16934400.c
arch/arm/mach-shmobile/setup-r8a7793.c
arch/arm/mach-zx/Kconfig
arch/arm64/Kconfig
arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi
arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts
arch/arm64/boot/dts/hisilicon/hi6220-ion.dtsi [new file with mode: 0644]
arch/arm64/include/asm/arch_gicv3.h
arch/arm64/include/asm/cpufeature.h
arch/arm64/include/asm/hw_breakpoint.h
arch/arm64/include/asm/irq.h
arch/arm64/include/asm/kvm_emulate.h
arch/arm64/include/asm/pgtable.h
arch/arm64/kernel/cpu_errata.c
arch/arm64/kernel/cpufeature.c
arch/arm64/kernel/efi.c
arch/arm64/kernel/vmlinux.lds.S
arch/arm64/kvm/handle_exit.c
arch/arm64/kvm/hyp.S
arch/arm64/kvm/inject_fault.c
arch/arm64/kvm/sys_regs.c
arch/arm64/kvm/sys_regs.h
arch/arm64/kvm/sys_regs_generic_v8.c
arch/arm64/mm/context.c
arch/arm64/mm/fault.c
arch/arm64/mm/mmu.c
arch/arm64/net/bpf_jit_comp.c
arch/blackfin/kernel/perf_event.c
arch/m68k/coldfire/m54xx.c
arch/m68k/include/asm/unistd.h
arch/m68k/include/uapi/asm/unistd.h
arch/m68k/kernel/setup_no.c
arch/m68k/kernel/syscalltable.S
arch/m68k/mm/motorola.c
arch/m68k/sun3/config.c
arch/mips/kvm/emulate.c
arch/mips/kvm/locore.S
arch/mips/kvm/mips.c
arch/mips/mm/dma-default.c
arch/mips/pci/pci-rt2880.c
arch/mips/pmcs-msp71xx/msp_setup.c
arch/mips/sni/reset.c
arch/mn10300/Kconfig
arch/nios2/mm/cacheflush.c
arch/parisc/include/asm/pgtable.h
arch/parisc/include/uapi/asm/unistd.h
arch/parisc/kernel/pci.c
arch/parisc/kernel/syscall_table.S
arch/powerpc/boot/dts/sbc8641d.dts
arch/powerpc/include/asm/reg.h
arch/powerpc/kernel/eeh_driver.c
arch/powerpc/kernel/process.c
arch/powerpc/kernel/signal_32.c
arch/powerpc/kernel/signal_64.c
arch/powerpc/platforms/powernv/opal-irqchip.c
arch/s390/kvm/interrupt.c
arch/s390/kvm/kvm-s390.c
arch/s390/kvm/priv.c
arch/s390/kvm/sigp.c
arch/sh/include/uapi/asm/unistd_64.h
arch/sh/kernel/perf_event.c
arch/sparc/kernel/perf_event.c
arch/tile/kernel/perf_event.c
arch/um/Makefile
arch/um/drivers/net_user.c
arch/um/kernel/signal.c
arch/x86/boot/boot.h
arch/x86/boot/video-mode.c
arch/x86/boot/video.c
arch/x86/entry/entry_64.S
arch/x86/include/asm/page_types.h
arch/x86/include/asm/pgtable_types.h
arch/x86/include/asm/x86_init.h
arch/x86/kernel/cpu/microcode/core.c
arch/x86/kernel/cpu/perf_event.c
arch/x86/kernel/cpu/perf_event.h
arch/x86/kernel/cpu/perf_event_intel.c
arch/x86/kernel/cpu/perf_event_intel_cqm.c
arch/x86/kernel/cpu/perf_event_intel_lbr.c
arch/x86/kernel/irq_work.c
arch/x86/kernel/pmem.c
arch/x86/kernel/setup.c
arch/x86/kernel/signal.c
arch/x86/kernel/smpboot.c
arch/x86/kvm/vmx.c
arch/x86/kvm/x86.c
arch/x86/mm/mpx.c
arch/x86/pci/bus_numa.c
arch/x86/um/signal.c
block/blk-cgroup.c
block/blk-core.c
block/blk-merge.c
block/blk-mq.c
block/blk-settings.c
block/blk-sysfs.c
block/blk-timeout.c
block/noop-iosched.c
block/partition-generic.c
block/partitions/mac.c
crypto/algif_aead.c
crypto/algif_skcipher.c
drivers/Makefile
drivers/acpi/Kconfig
drivers/acpi/nfit.c
drivers/acpi/nfit.h
drivers/acpi/pci_root.c
drivers/ata/ahci.c
drivers/ata/ahci_mvebu.c
drivers/ata/libahci.c
drivers/ata/libata-eh.c
drivers/ata/sata_fsl.c
drivers/ata/sata_sil.c
drivers/base/memory.c
drivers/base/power/domain.c
drivers/base/power/domain_governor.c
drivers/block/mtip32xx/mtip32xx.c
drivers/block/null_blk.c
drivers/block/rbd.c
drivers/bus/omap-ocp2scp.c
drivers/char/ipmi/ipmi_si_intf.c
drivers/clk/clk-gpio.c
drivers/clk/clk-qoriq.c
drivers/clk/clk-scpi.c
drivers/clk/imx/clk-pllv1.c
drivers/clk/imx/clk-pllv2.c
drivers/clk/imx/clk-vf610.c
drivers/clk/mmp/clk-mmp2.c
drivers/clk/mmp/clk-pxa168.c
drivers/clk/mmp/clk-pxa910.c
drivers/clk/sunxi/clk-a10-pll2.c
drivers/clk/ti/clk-816x.c
drivers/clk/ti/clkt_dpll.c
drivers/clk/ti/divider.c
drivers/clk/ti/fapll.c
drivers/clk/ti/mux.c
drivers/clocksource/mmio.c
drivers/cpufreq/Kconfig.arm
drivers/cpufreq/cppc_cpufreq.c
drivers/cpufreq/cpufreq.c
drivers/cpufreq/intel_pstate.c
drivers/cpufreq/s3c24xx-cpufreq.c
drivers/crypto/nx/nx-aes-ccm.c
drivers/crypto/nx/nx-aes-gcm.c
drivers/crypto/talitos.c
drivers/fpga/fpga-mgr.c
drivers/gpio/gpio-74xx-mmio.c
drivers/gpio/gpio-omap.c
drivers/gpio/gpio-palmas.c
drivers/gpio/gpio-syscon.c
drivers/gpio/gpio-tegra.c
drivers/gpio/gpiolib.c
drivers/gpu/drm/amd/amdgpu/amdgpu.h
drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
drivers/gpu/drm/amd/amdgpu/dce_v8_0.c
drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c
drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
drivers/gpu/drm/amd/amdgpu/vce_v3_0.c
drivers/gpu/drm/amd/scheduler/gpu_scheduler.c
drivers/gpu/drm/amd/scheduler/gpu_scheduler.h
drivers/gpu/drm/amd/scheduler/sched_fence.c
drivers/gpu/drm/drm_drv.c
drivers/gpu/drm/drm_fops.c
drivers/gpu/drm/drm_irq.c
drivers/gpu/drm/i915/i915_debugfs.c
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/i915_gem.c
drivers/gpu/drm/i915/i915_gem_fence.c
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_dp.c
drivers/gpu/drm/i915/intel_drv.h
drivers/gpu/drm/i915/intel_hdmi.c
drivers/gpu/drm/i915/intel_i2c.c
drivers/gpu/drm/i915/intel_runtime_pm.c
drivers/gpu/drm/imx/imx-drm-core.c
drivers/gpu/drm/imx/imx-drm.h
drivers/gpu/drm/imx/imx-tve.c
drivers/gpu/drm/imx/ipuv3-crtc.c
drivers/gpu/drm/imx/ipuv3-plane.c
drivers/gpu/drm/imx/ipuv3-plane.h
drivers/gpu/drm/imx/parallel-display.c
drivers/gpu/drm/nouveau/include/nvkm/core/device.h
drivers/gpu/drm/nouveau/include/nvkm/subdev/instmem.h
drivers/gpu/drm/nouveau/nouveau_acpi.c
drivers/gpu/drm/nouveau/nouveau_display.c
drivers/gpu/drm/nouveau/nouveau_drm.h
drivers/gpu/drm/nouveau/nouveau_usif.c
drivers/gpu/drm/nouveau/nvkm/engine/device/pci.c
drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf117.c
drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpc.fuc
drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgf117.fuc3.h
drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgk104.fuc3.h
drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgk110.fuc3.h
drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgk208.fuc5.h
drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgm107.fuc5.h
drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c
drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h
drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c
drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk104.c
drivers/gpu/drm/nouveau/nvkm/subdev/volt/gk104.c
drivers/gpu/drm/radeon/cik.c
drivers/gpu/drm/radeon/evergreen.c
drivers/gpu/drm/radeon/r100.c
drivers/gpu/drm/radeon/r600.c
drivers/gpu/drm/radeon/radeon.h
drivers/gpu/drm/radeon/radeon_agp.c
drivers/gpu/drm/radeon/radeon_connectors.c
drivers/gpu/drm/radeon/radeon_display.c
drivers/gpu/drm/radeon/radeon_irq_kms.c
drivers/gpu/drm/radeon/radeon_kms.c
drivers/gpu/drm/radeon/radeon_mode.h
drivers/gpu/drm/radeon/radeon_pm.c
drivers/gpu/drm/radeon/radeon_vce.c
drivers/gpu/drm/radeon/rs600.c
drivers/gpu/drm/radeon/rs690.c
drivers/gpu/drm/radeon/rv730_dpm.c
drivers/gpu/drm/radeon/rv770_dpm.c
drivers/gpu/drm/radeon/si.c
drivers/gpu/drm/rockchip/rockchip_drm_gem.c
drivers/gpu/drm/rockchip/rockchip_drm_vop.c
drivers/gpu/drm/ttm/ttm_lock.c
drivers/gpu/drm/virtio/virtgpu_display.c
drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c
drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
drivers/gpu/drm/vmwgfx/vmwgfx_kms.h
drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c
drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c
drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c
drivers/gpu/ipu-v3/ipu-common.c
drivers/gpu/vga/vgaarb.c
drivers/hid/hid-ids.h
drivers/hid/hid-lg.c
drivers/hid/usbhid/hid-quirks.c
drivers/iio/adc/qcom-spmi-vadc.c
drivers/iio/dummy/iio_simple_dummy_events.c
drivers/iio/industrialio-buffer.c
drivers/iio/industrialio-core.c
drivers/iio/light/apds9960.c
drivers/iio/proximity/pulsedlight-lidar-lite-v2.c
drivers/infiniband/core/cma.c
drivers/infiniband/core/mad.c
drivers/infiniband/core/sa_query.c
drivers/infiniband/core/uverbs_cmd.c
drivers/infiniband/core/verbs.c
drivers/infiniband/hw/mlx4/main.c
drivers/infiniband/hw/mlx4/qp.c
drivers/infiniband/hw/mlx4/srq.c
drivers/infiniband/hw/mlx5/mr.c
drivers/infiniband/hw/qib/qib_qsfp.c
drivers/infiniband/hw/qib/qib_verbs.h
drivers/infiniband/ulp/iser/iser_verbs.c
drivers/infiniband/ulp/isert/ib_isert.c
drivers/infiniband/ulp/srp/ib_srp.c
drivers/infiniband/ulp/srp/ib_srp.h
drivers/irqchip/irq-versatile-fpga.c
drivers/isdn/hisax/config.c
drivers/isdn/hisax/hfc_pci.c
drivers/isdn/hisax/hfc_sx.c
drivers/isdn/hisax/q931.c
drivers/lightnvm/Kconfig
drivers/lightnvm/core.c
drivers/lightnvm/gennvm.c
drivers/lightnvm/gennvm.h
drivers/lightnvm/rrpc.c
drivers/md/dm-crypt.c
drivers/md/dm-mpath.c
drivers/md/dm-thin-metadata.c
drivers/md/dm-thin.c
drivers/md/dm.c
drivers/md/persistent-data/dm-btree.c
drivers/md/persistent-data/dm-btree.h
drivers/md/persistent-data/dm-space-map-metadata.c
drivers/misc/cxl/native.c
drivers/net/can/bfin_can.c
drivers/net/can/c_can/c_can.c
drivers/net/can/cc770/cc770.c
drivers/net/can/flexcan.c
drivers/net/can/janz-ican3.c
drivers/net/can/m_can/m_can.c
drivers/net/can/pch_can.c
drivers/net/can/rcar_can.c
drivers/net/can/sja1000/sja1000.c
drivers/net/can/sun4i_can.c
drivers/net/can/ti_hecc.c
drivers/net/can/usb/ems_usb.c
drivers/net/can/usb/esd_usb2.c
drivers/net/can/usb/kvaser_usb.c
drivers/net/can/usb/usb_8dev.c
drivers/net/can/xilinx_can.c
drivers/net/ethernet/Kconfig
drivers/net/ethernet/Makefile
drivers/net/ethernet/apm/xgene/xgene_enet_main.c
drivers/net/ethernet/atheros/alx/main.c
drivers/net/ethernet/atheros/alx/reg.h
drivers/net/ethernet/aurora/Kconfig [new file with mode: 0644]
drivers/net/ethernet/aurora/Makefile [new file with mode: 0644]
drivers/net/ethernet/aurora/nb8800.c [new file with mode: 0644]
drivers/net/ethernet/aurora/nb8800.h [new file with mode: 0644]
drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
drivers/net/ethernet/broadcom/bnxt/bnxt.c
drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c
drivers/net/ethernet/cadence/macb.c
drivers/net/ethernet/cadence/macb.h
drivers/net/ethernet/cavium/thunder/nic.h
drivers/net/ethernet/cavium/thunder/nic_main.c
drivers/net/ethernet/cavium/thunder/nicvf_ethtool.c
drivers/net/ethernet/cavium/thunder/nicvf_main.c
drivers/net/ethernet/cavium/thunder/nicvf_queues.c
drivers/net/ethernet/cavium/thunder/nicvf_queues.h
drivers/net/ethernet/cavium/thunder/thunder_bgx.c
drivers/net/ethernet/cavium/thunder/thunder_bgx.h
drivers/net/ethernet/dec/tulip/tulip_core.c
drivers/net/ethernet/dec/tulip/winbond-840.c
drivers/net/ethernet/freescale/Kconfig
drivers/net/ethernet/freescale/gianfar.c
drivers/net/ethernet/freescale/gianfar_ptp.c
drivers/net/ethernet/intel/fm10k/fm10k_netdev.c
drivers/net/ethernet/marvell/mvneta.c
drivers/net/ethernet/mellanox/mlx4/cmd.c
drivers/net/ethernet/nxp/lpc_eth.c
drivers/net/ethernet/renesas/ravb_main.c
drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
drivers/net/ethernet/ti/cpsw-common.c
drivers/net/macvtap.c
drivers/net/phy/broadcom.c
drivers/net/phy/phy.c
drivers/net/tun.c
drivers/net/usb/cdc_ncm.c
drivers/net/usb/qmi_wwan.c
drivers/net/virtio_net.c
drivers/net/vmxnet3/vmxnet3_drv.c
drivers/net/vrf.c
drivers/net/wan/hdlc_fr.c
drivers/net/wan/x25_asy.c
drivers/net/wireless/ath/ath10k/core.c
drivers/net/wireless/ath/ath10k/core.h
drivers/net/wireless/ath/ath10k/hw.h
drivers/net/wireless/ath/ath10k/mac.c
drivers/net/wireless/ath/ath10k/pci.c
drivers/net/wireless/iwlwifi/iwl-7000.c
drivers/net/wireless/iwlwifi/iwl-8000.c
drivers/net/wireless/iwlwifi/mvm/d3.c
drivers/net/wireless/iwlwifi/mvm/mac80211.c
drivers/net/wireless/iwlwifi/mvm/sta.c
drivers/net/wireless/iwlwifi/mvm/sta.h
drivers/net/wireless/iwlwifi/pcie/drv.c
drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c
drivers/net/wireless/realtek/rtlwifi/rtl8821ae/sw.c
drivers/nvme/host/Makefile
drivers/nvme/host/lightnvm.c
drivers/nvme/host/nvme.h
drivers/nvme/host/pci.c
drivers/of/address.c
drivers/of/fdt.c
drivers/of/irq.c
drivers/of/of_reserved_mem.c
drivers/parisc/iommu-helpers.h
drivers/pci/host/pcie-altera.c
drivers/pci/host/pcie-designware.c
drivers/pci/host/pcie-hisi.c
drivers/pci/msi.c
drivers/pci/pci-driver.c
drivers/pci/pci-sysfs.c
drivers/pci/pci.h
drivers/pinctrl/Kconfig
drivers/pinctrl/freescale/pinctrl-imx1-core.c
drivers/pinctrl/mediatek/pinctrl-mtk-common.c
drivers/pinctrl/qcom/pinctrl-ssbi-gpio.c
drivers/pinctrl/qcom/pinctrl-ssbi-mpp.c
drivers/pinctrl/sh-pfc/pfc-sh7734.c
drivers/remoteproc/remoteproc_core.c
drivers/remoteproc/remoteproc_debugfs.c
drivers/rtc/rtc-ds1307.c
drivers/scsi/Kconfig
drivers/scsi/advansys.c
drivers/scsi/hosts.c
drivers/scsi/hpsa.c
drivers/scsi/mpt3sas/Kconfig
drivers/scsi/mpt3sas/mpt3sas_scsih.c
drivers/scsi/mvsas/mv_init.c
drivers/scsi/qla2xxx/qla_nx.c
drivers/scsi/qla2xxx/tcm_qla2xxx.c
drivers/scsi/scsi_debug.c
drivers/scsi/scsi_scan.c
drivers/scsi/scsi_sysfs.c
drivers/scsi/sd.c
drivers/scsi/sd.h
drivers/scsi/st.c
drivers/soc/mediatek/Kconfig
drivers/soc/ti/knav_qmss_queue.c
drivers/spi/spi-bcm63xx.c
drivers/spi/spi-mt65xx.c
drivers/spi/spi-pl022.c
drivers/spi/spi.c
drivers/staging/android/TODO
drivers/staging/android/ashmem.c
drivers/staging/android/ion/Kconfig
drivers/staging/android/ion/Makefile
drivers/staging/android/ion/hisilicon/Kconfig [new file with mode: 0644]
drivers/staging/android/ion/hisilicon/Makefile [new file with mode: 0644]
drivers/staging/android/ion/hisilicon/hi6220_ion.c [new file with mode: 0644]
drivers/staging/android/sync.c
drivers/staging/android/sync.h
drivers/staging/android/sync_debug.c
drivers/staging/comedi/Kconfig
drivers/staging/comedi/comedi.h
drivers/staging/comedi/comedi_fops.c
drivers/staging/comedi/comedilib.h
drivers/staging/comedi/drivers/Makefile
drivers/staging/comedi/drivers/adv_pci1710.c
drivers/staging/comedi/drivers/adv_pci1760.c [new file with mode: 0644]
drivers/staging/comedi/drivers/adv_pci_dio.c
drivers/staging/comedi/drivers/amplc_pci224.c
drivers/staging/comedi/drivers/cb_pcidda.c
drivers/staging/comedi/drivers/comedi_parport.c
drivers/staging/comedi/drivers/ni_6527.c
drivers/staging/comedi/drivers/ni_65xx.c
drivers/staging/comedi/drivers/ni_670x.c
drivers/staging/comedi/drivers/ni_mio_common.c
drivers/staging/comedi/drivers/plx9080.h
drivers/staging/comedi/drivers/s526.c
drivers/staging/dgnc/dgnc_cls.c
drivers/staging/dgnc/dgnc_neo.c
drivers/staging/dgnc/dgnc_tty.c
drivers/staging/emxx_udc/emxx_udc.c
drivers/staging/iio/adc/mxs-lradc.c
drivers/staging/lustre/include/linux/libcfs/libcfs.h
drivers/staging/lustre/include/linux/libcfs/libcfs_cpu.h
drivers/staging/lustre/include/linux/libcfs/libcfs_hash.h
drivers/staging/lustre/include/linux/libcfs/libcfs_ioctl.h
drivers/staging/lustre/include/linux/lnet/api.h
drivers/staging/lustre/include/linux/lnet/lib-lnet.h
drivers/staging/lustre/include/linux/lnet/lib-types.h
drivers/staging/lustre/include/linux/lnet/nidstr.h
drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c
drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h
drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c
drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c
drivers/staging/lustre/lnet/lnet/acceptor.c
drivers/staging/lustre/lnet/lnet/api-ni.c
drivers/staging/lustre/lnet/lnet/config.c
drivers/staging/lustre/lnet/lnet/lib-eq.c
drivers/staging/lustre/lnet/lnet/lib-move.c
drivers/staging/lustre/lnet/lnet/lib-ptl.c
drivers/staging/lustre/lnet/lnet/lib-socket.c
drivers/staging/lustre/lnet/lnet/module.c
drivers/staging/lustre/lnet/lnet/router.c
drivers/staging/lustre/lnet/selftest/brw_test.c
drivers/staging/lustre/lnet/selftest/conctl.c
drivers/staging/lustre/lnet/selftest/rpc.c
drivers/staging/lustre/lustre/fid/fid_request.c
drivers/staging/lustre/lustre/fid/lproc_fid.c
drivers/staging/lustre/lustre/fld/fld_cache.c
drivers/staging/lustre/lustre/fld/fld_internal.h
drivers/staging/lustre/lustre/fld/fld_request.c
drivers/staging/lustre/lustre/fld/lproc_fld.c
drivers/staging/lustre/lustre/include/cl_object.h
drivers/staging/lustre/lustre/include/lprocfs_status.h
drivers/staging/lustre/lustre/include/lu_object.h
drivers/staging/lustre/lustre/include/lustre/ll_fiemap.h
drivers/staging/lustre/lustre/include/lustre/lustre_idl.h
drivers/staging/lustre/lustre/include/lustre/lustre_user.h
drivers/staging/lustre/lustre/include/lustre_dlm.h
drivers/staging/lustre/lustre/include/lustre_eacl.h
drivers/staging/lustre/lustre/include/lustre_export.h
drivers/staging/lustre/lustre/include/lustre_fid.h
drivers/staging/lustre/lustre/include/lustre_fld.h
drivers/staging/lustre/lustre/include/lustre_ha.h
drivers/staging/lustre/lustre/include/lustre_log.h
drivers/staging/lustre/lustre/include/lustre_mds.h
drivers/staging/lustre/lustre/include/lustre_net.h
drivers/staging/lustre/lustre/include/lustre_param.h
drivers/staging/lustre/lustre/include/lustre_req_layout.h
drivers/staging/lustre/lustre/include/obd.h
drivers/staging/lustre/lustre/include/obd_class.h
drivers/staging/lustre/lustre/include/obd_support.h
drivers/staging/lustre/lustre/lclient/lcommon_cl.c
drivers/staging/lustre/lustre/ldlm/ldlm_internal.h
drivers/staging/lustre/lustre/ldlm/ldlm_lib.c
drivers/staging/lustre/lustre/ldlm/ldlm_lock.c
drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c
drivers/staging/lustre/lustre/ldlm/ldlm_pool.c
drivers/staging/lustre/lustre/ldlm/ldlm_request.c
drivers/staging/lustre/lustre/ldlm/ldlm_resource.c
drivers/staging/lustre/lustre/libcfs/debug.c
drivers/staging/lustre/lustre/libcfs/fail.c
drivers/staging/lustre/lustre/libcfs/hash.c
drivers/staging/lustre/lustre/libcfs/libcfs_lock.c
drivers/staging/lustre/lustre/libcfs/libcfs_string.c
drivers/staging/lustre/lustre/libcfs/linux/linux-cpu.c
drivers/staging/lustre/lustre/libcfs/linux/linux-curproc.c
drivers/staging/lustre/lustre/libcfs/linux/linux-tracefile.h [deleted file]
drivers/staging/lustre/lustre/libcfs/module.c
drivers/staging/lustre/lustre/libcfs/tracefile.h
drivers/staging/lustre/lustre/libcfs/workitem.c
drivers/staging/lustre/lustre/llite/dcache.c
drivers/staging/lustre/lustre/llite/dir.c
drivers/staging/lustre/lustre/llite/file.c
drivers/staging/lustre/lustre/llite/llite_internal.h
drivers/staging/lustre/lustre/llite/llite_lib.c
drivers/staging/lustre/lustre/llite/llite_mmap.c
drivers/staging/lustre/lustre/llite/lproc_llite.c
drivers/staging/lustre/lustre/llite/namei.c
drivers/staging/lustre/lustre/llite/rw.c
drivers/staging/lustre/lustre/llite/rw26.c
drivers/staging/lustre/lustre/llite/statahead.c
drivers/staging/lustre/lustre/llite/symlink.c
drivers/staging/lustre/lustre/llite/vvp_dev.c
drivers/staging/lustre/lustre/llite/vvp_internal.h
drivers/staging/lustre/lustre/llite/vvp_io.c
drivers/staging/lustre/lustre/llite/vvp_lock.c
drivers/staging/lustre/lustre/llite/vvp_object.c
drivers/staging/lustre/lustre/llite/vvp_page.c
drivers/staging/lustre/lustre/llite/xattr.c
drivers/staging/lustre/lustre/llite/xattr_cache.c
drivers/staging/lustre/lustre/lmv/lmv_intent.c
drivers/staging/lustre/lustre/lmv/lmv_internal.h
drivers/staging/lustre/lustre/lmv/lmv_obd.c
drivers/staging/lustre/lustre/lov/lov_cl_internal.h
drivers/staging/lustre/lustre/lov/lov_dev.c
drivers/staging/lustre/lustre/lov/lov_ea.c
drivers/staging/lustre/lustre/lov/lov_internal.h
drivers/staging/lustre/lustre/lov/lov_io.c
drivers/staging/lustre/lustre/lov/lov_merge.c
drivers/staging/lustre/lustre/lov/lov_obd.c
drivers/staging/lustre/lustre/lov/lov_object.c
drivers/staging/lustre/lustre/lov/lov_offset.c
drivers/staging/lustre/lustre/lov/lov_pack.c
drivers/staging/lustre/lustre/lov/lov_page.c
drivers/staging/lustre/lustre/lov/lov_request.c
drivers/staging/lustre/lustre/lov/lovsub_dev.c
drivers/staging/lustre/lustre/lov/lovsub_object.c
drivers/staging/lustre/lustre/lov/lproc_lov.c
drivers/staging/lustre/lustre/mdc/lproc_mdc.c
drivers/staging/lustre/lustre/mdc/mdc_internal.h
drivers/staging/lustre/lustre/mdc/mdc_lib.c
drivers/staging/lustre/lustre/mdc/mdc_locks.c
drivers/staging/lustre/lustre/mdc/mdc_reint.c
drivers/staging/lustre/lustre/mdc/mdc_request.c
drivers/staging/lustre/lustre/mgc/mgc_request.c
drivers/staging/lustre/lustre/obdclass/acl.c
drivers/staging/lustre/lustre/obdclass/cl_io.c
drivers/staging/lustre/lustre/obdclass/cl_object.c
drivers/staging/lustre/lustre/obdclass/cl_page.c
drivers/staging/lustre/lustre/obdclass/class_obd.c
drivers/staging/lustre/lustre/obdclass/genops.c
drivers/staging/lustre/lustre/obdclass/linux/linux-sysctl.c
drivers/staging/lustre/lustre/obdclass/llog.c
drivers/staging/lustre/lustre/obdclass/llog_cat.c
drivers/staging/lustre/lustre/obdclass/llog_internal.h
drivers/staging/lustre/lustre/obdclass/llog_obd.c
drivers/staging/lustre/lustre/obdclass/llog_swab.c
drivers/staging/lustre/lustre/obdclass/lprocfs_status.c
drivers/staging/lustre/lustre/obdclass/lu_object.c
drivers/staging/lustre/lustre/obdclass/obd_config.c
drivers/staging/lustre/lustre/obdclass/obd_mount.c
drivers/staging/lustre/lustre/obdecho/echo_client.c
drivers/staging/lustre/lustre/osc/lproc_osc.c
drivers/staging/lustre/lustre/osc/osc_cache.c
drivers/staging/lustre/lustre/osc/osc_cl_internal.h
drivers/staging/lustre/lustre/osc/osc_dev.c
drivers/staging/lustre/lustre/osc/osc_internal.h
drivers/staging/lustre/lustre/osc/osc_io.c
drivers/staging/lustre/lustre/osc/osc_lock.c
drivers/staging/lustre/lustre/osc/osc_object.c
drivers/staging/lustre/lustre/osc/osc_page.c
drivers/staging/lustre/lustre/osc/osc_quota.c
drivers/staging/lustre/lustre/osc/osc_request.c
drivers/staging/lustre/lustre/ptlrpc/client.c
drivers/staging/lustre/lustre/ptlrpc/events.c
drivers/staging/lustre/lustre/ptlrpc/import.c
drivers/staging/lustre/lustre/ptlrpc/layout.c
drivers/staging/lustre/lustre/ptlrpc/llog_client.c
drivers/staging/lustre/lustre/ptlrpc/lproc_ptlrpc.c
drivers/staging/lustre/lustre/ptlrpc/niobuf.c
drivers/staging/lustre/lustre/ptlrpc/pers.c
drivers/staging/lustre/lustre/ptlrpc/pinger.c
drivers/staging/lustre/lustre/ptlrpc/ptlrpc_internal.h
drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c
drivers/staging/lustre/lustre/ptlrpc/recover.c
drivers/staging/lustre/lustre/ptlrpc/sec_bulk.c
drivers/staging/lustre/lustre/ptlrpc/sec_config.c
drivers/staging/lustre/lustre/ptlrpc/sec_plain.c
drivers/staging/lustre/lustre/ptlrpc/service.c
drivers/staging/lustre/lustre/ptlrpc/wiretest.c
drivers/staging/rdma/ehca/ehca_av.c
drivers/staging/rdma/ehca/ehca_cq.c
drivers/staging/rdma/ehca/ehca_main.c
drivers/staging/rdma/ehca/ehca_mrmw.c
drivers/staging/rdma/ehca/ehca_pd.c
drivers/staging/rdma/ehca/ehca_qp.c
drivers/staging/rdma/hfi1/Makefile
drivers/staging/rdma/hfi1/chip.c
drivers/staging/rdma/hfi1/chip.h
drivers/staging/rdma/hfi1/chip_registers.h
drivers/staging/rdma/hfi1/diag.c
drivers/staging/rdma/hfi1/driver.c
drivers/staging/rdma/hfi1/efivar.c [new file with mode: 0644]
drivers/staging/rdma/hfi1/efivar.h [new file with mode: 0644]
drivers/staging/rdma/hfi1/eprom.c
drivers/staging/rdma/hfi1/file_ops.c
drivers/staging/rdma/hfi1/firmware.c
drivers/staging/rdma/hfi1/hfi.h
drivers/staging/rdma/hfi1/init.c
drivers/staging/rdma/hfi1/mad.c
drivers/staging/rdma/hfi1/mad.h
drivers/staging/rdma/hfi1/pcie.c
drivers/staging/rdma/hfi1/pio.c
drivers/staging/rdma/hfi1/pio.h
drivers/staging/rdma/hfi1/pio_copy.c
drivers/staging/rdma/hfi1/qp.h
drivers/staging/rdma/hfi1/ruc.c
drivers/staging/rdma/hfi1/sdma.c
drivers/staging/rdma/hfi1/sdma.h
drivers/staging/rdma/hfi1/trace.c
drivers/staging/rdma/hfi1/trace.h
drivers/staging/rdma/hfi1/ud.c
drivers/staging/rdma/hfi1/user_pages.c
drivers/staging/rdma/hfi1/user_sdma.c
drivers/staging/rdma/hfi1/user_sdma.h
drivers/staging/rdma/hfi1/verbs.h
drivers/staging/wilc1000/Kconfig
drivers/staging/wilc1000/Makefile
drivers/staging/wilc1000/coreconfigurator.c
drivers/staging/wilc1000/coreconfigurator.h
drivers/staging/wilc1000/host_interface.c
drivers/staging/wilc1000/host_interface.h
drivers/staging/wilc1000/linux_mon.c
drivers/staging/wilc1000/linux_wlan.c
drivers/staging/wilc1000/linux_wlan_common.h
drivers/staging/wilc1000/linux_wlan_sdio.c [deleted file]
drivers/staging/wilc1000/linux_wlan_sdio.h [deleted file]
drivers/staging/wilc1000/linux_wlan_spi.c [deleted file]
drivers/staging/wilc1000/linux_wlan_spi.h [deleted file]
drivers/staging/wilc1000/wilc_debugfs.c
drivers/staging/wilc1000/wilc_msgqueue.c
drivers/staging/wilc1000/wilc_msgqueue.h
drivers/staging/wilc1000/wilc_sdio.c
drivers/staging/wilc1000/wilc_spi.c
drivers/staging/wilc1000/wilc_wfi_cfgoperations.c
drivers/staging/wilc1000/wilc_wfi_cfgoperations.h
drivers/staging/wilc1000/wilc_wfi_netdevice.h
drivers/staging/wilc1000/wilc_wlan.c
drivers/staging/wilc1000/wilc_wlan.h
drivers/staging/wilc1000/wilc_wlan_cfg.c
drivers/staging/wilc1000/wilc_wlan_cfg.h
drivers/staging/wilc1000/wilc_wlan_if.h
drivers/target/iscsi/iscsi_target.c
drivers/target/iscsi/iscsi_target_nego.c
drivers/target/iscsi/iscsi_target_parameters.c
drivers/target/target_core_sbc.c
drivers/target/target_core_stat.c
drivers/target/target_core_tmr.c
drivers/target/target_core_transport.c
drivers/target/target_core_user.c
drivers/thermal/Kconfig
drivers/thermal/imx_thermal.c
drivers/thermal/of-thermal.c
drivers/thermal/power_allocator.c
drivers/thermal/rcar_thermal.c
drivers/thermal/rockchip_thermal.c
drivers/usb/class/cdc-acm.c
drivers/usb/core/config.c
drivers/usb/core/hub.c
drivers/usb/core/port.c
drivers/usb/core/quirks.c
drivers/usb/dwc2/platform.c
drivers/usb/dwc3/gadget.c
drivers/usb/gadget/function/f_fs.c
drivers/usb/gadget/function/f_midi.c
drivers/usb/gadget/function/uvc_configfs.c
drivers/usb/gadget/udc/pxa27x_udc.c
drivers/usb/host/ohci-at91.c
drivers/usb/host/whci/qset.c
drivers/usb/host/xhci-hub.c
drivers/usb/host/xhci-pci.c
drivers/usb/host/xhci-ring.c
drivers/usb/host/xhci.c
drivers/usb/musb/Kconfig
drivers/usb/musb/musb_core.c
drivers/usb/phy/phy-msm-usb.c
drivers/usb/phy/phy-mxs-usb.c
drivers/usb/renesas_usbhs/mod_gadget.c
drivers/usb/serial/cp210x.c
drivers/usb/serial/usb-serial-simple.c
drivers/usb/storage/uas.c
drivers/usb/storage/unusual_devs.h
drivers/usb/storage/unusual_uas.h
drivers/vfio/Kconfig
drivers/vfio/pci/vfio_pci.c
drivers/vfio/platform/vfio_platform.c
drivers/vfio/platform/vfio_platform_common.c
drivers/vfio/vfio.c
drivers/vhost/vhost.c
drivers/virtio/virtio.c
drivers/virtio/virtio_ring.c
drivers/watchdog/Kconfig
drivers/watchdog/mtk_wdt.c
drivers/watchdog/omap_wdt.c
drivers/watchdog/pnx4008_wdt.c
drivers/watchdog/tegra_wdt.c
drivers/watchdog/w83977f_wdt.c
drivers/xen/events/events_base.c
drivers/xen/evtchn.c
drivers/xen/gntdev.c
fs/9p/vfs_inode.c
fs/block_dev.c
fs/btrfs/backref.c
fs/btrfs/ctree.h
fs/btrfs/extent-tree.c
fs/btrfs/file.c
fs/btrfs/inode.c
fs/btrfs/qgroup.c
fs/btrfs/scrub.c
fs/btrfs/tests/free-space-tests.c
fs/btrfs/transaction.c
fs/btrfs/transaction.h
fs/btrfs/volumes.c
fs/btrfs/volumes.h
fs/cifs/inode.c
fs/direct-io.c
fs/dlm/lowcomms.c
fs/exofs/inode.c
fs/ext4/crypto.c
fs/ext4/ext4.h
fs/ext4/symlink.c
fs/ext4/sysfs.c
fs/fuse/cuse.c
fs/fuse/file.c
fs/jbd2/transaction.c
fs/namei.c
fs/nfs/inode.c
fs/nfs/internal.h
fs/nfs/nfs42proc.c
fs/nfs/nfs4client.c
fs/nfs/nfs4file.c
fs/nfs/nfs4proc.c
fs/nfs/nfs4xdr.c
fs/nfs/objlayout/objio_osd.c
fs/nfs/pagelist.c
fs/nfs/pnfs.c
fs/ocfs2/namei.c
fs/overlayfs/copy_up.c
fs/overlayfs/inode.c
fs/overlayfs/overlayfs.h
fs/splice.c
fs/sysv/inode.c
include/asm-generic/tlb.h
include/drm/drmP.h
include/kvm/arm_vgic.h
include/linux/acpi.h
include/linux/bitops.h
include/linux/blkdev.h
include/linux/bpf.h
include/linux/cgroup-defs.h
include/linux/cgroup.h
include/linux/cpufreq.h
include/linux/dns_resolver.h
include/linux/ipv6.h
include/linux/irqchip/arm-gic-v3.h
include/linux/jump_label.h
include/linux/kmemleak.h
include/linux/kref.h
include/linux/kvm_host.h
include/linux/libata.h
include/linux/lightnvm.h
include/linux/lockdep.h
include/linux/mlx4/device.h
include/linux/net.h
include/linux/netdevice.h
include/linux/nfs_xdr.h
include/linux/of_irq.h
include/linux/pci.h
include/linux/perf_event.h
include/linux/proportions.h
include/linux/scpi_protocol.h
include/linux/stop_machine.h
include/linux/syscalls.h
include/linux/thermal.h
include/linux/types.h
include/linux/uprobes.h
include/linux/usb/quirks.h
include/linux/vfio.h
include/linux/wait.h
include/net/af_unix.h
include/net/ip6_route.h
include/net/ipv6.h
include/net/mac80211.h
include/net/ndisc.h
include/net/sch_generic.h
include/net/sctp/structs.h
include/net/sock.h
include/rdma/ib_mad.h
include/rdma/ib_verbs.h
include/scsi/scsi_host.h
include/sound/hda_register.h
include/sound/soc-dapm.h
include/target/target_core_base.h
include/uapi/linux/nfs.h
include/uapi/linux/vfio.h
include/uapi/rdma/hfi/hfi1_user.h
include/video/imx-ipu-v3.h
init/Kconfig
kernel/bpf/arraymap.c
kernel/bpf/hashtab.c
kernel/bpf/inode.c
kernel/bpf/syscall.c
kernel/bpf/verifier.c
kernel/cgroup.c
kernel/cgroup_freezer.c
kernel/cgroup_pids.c
kernel/cpuset.c
kernel/events/callchain.c
kernel/events/core.c
kernel/events/ring_buffer.c
kernel/events/uprobes.c
kernel/fork.c
kernel/irq_work.c
kernel/jump_label.c
kernel/locking/lockdep.c
kernel/locking/lockdep_proc.c
kernel/pid.c
kernel/sched/clock.c
kernel/sched/core.c
kernel/sched/cputime.c
kernel/sched/fair.c
kernel/sched/rt.c
kernel/sched/sched.h
kernel/sched/wait.c
kernel/stop_machine.c
kernel/trace/ring_buffer.c
kernel/trace/trace_event_perf.c
kernel/trace/trace_events.c
lib/btree.c
lib/proportions.c
mm/backing-dev.c
mm/hugetlb.c
mm/memcontrol.c
mm/oom_kill.c
mm/page-writeback.c
mm/page_alloc.c
mm/shmem.c
mm/vmstat.c
net/bluetooth/af_bluetooth.c
net/bluetooth/smp.c
net/caif/caif_socket.c
net/core/datagram.c
net/core/neighbour.c
net/core/netclassid_cgroup.c
net/core/netprio_cgroup.c
net/core/scm.c
net/core/sock.c
net/core/stream.c
net/dccp/ipv6.c
net/dccp/proto.c
net/decnet/af_decnet.c
net/dns_resolver/dns_query.c
net/hsr/hsr_device.c
net/ipv4/igmp.c
net/ipv4/ipmr.c
net/ipv4/tcp.c
net/ipv4/tcp_input.c
net/ipv4/tcp_ipv4.c
net/ipv4/tcp_timer.c
net/ipv4/udp.c
net/ipv6/addrconf.c
net/ipv6/af_inet6.c
net/ipv6/datagram.c
net/ipv6/exthdrs.c
net/ipv6/icmp.c
net/ipv6/inet6_connection_sock.c
net/ipv6/ip6_tunnel.c
net/ipv6/ip6mr.c
net/ipv6/ipv6_sockglue.c
net/ipv6/ndisc.c
net/ipv6/netfilter/nf_conntrack_reasm.c
net/ipv6/raw.c
net/ipv6/reassembly.c
net/ipv6/route.c
net/ipv6/syncookies.c
net/ipv6/tcp_ipv6.c
net/ipv6/udp.c
net/iucv/af_iucv.c
net/l2tp/l2tp_ip6.c
net/mac80211/agg-tx.c
net/mac80211/cfg.c
net/mac80211/iface.c
net/mac80211/main.c
net/mac80211/mesh_pathtbl.c
net/mac80211/scan.c
net/nfc/llcp_sock.c
net/openvswitch/dp_notify.c
net/openvswitch/vport-geneve.c
net/openvswitch/vport-gre.c
net/openvswitch/vport-netdev.c
net/openvswitch/vport.c
net/openvswitch/vport.h
net/packet/af_packet.c
net/rds/connection.c
net/rds/send.c
net/rxrpc/ar-ack.c
net/rxrpc/ar-output.c
net/sched/sch_api.c
net/sched/sch_generic.c
net/sched/sch_mq.c
net/sched/sch_mqprio.c
net/sctp/ipv6.c
net/sctp/socket.c
net/socket.c
net/sunrpc/sched.c
net/sunrpc/svc.c
net/sunrpc/xprtsock.c
net/tipc/link.c
net/tipc/socket.c
net/tipc/udp_media.c
net/unix/af_unix.c
scripts/link-vmlinux.sh
security/keys/encrypted-keys/encrypted.c
security/keys/trusted.c
security/keys/user_defined.c
security/selinux/ss/conditional.c
sound/firewire/dice/dice.c
sound/pci/hda/hda_intel.c
sound/pci/hda/patch_ca0132.c
sound/pci/hda/patch_conexant.c
sound/pci/hda/patch_hdmi.c
sound/pci/hda/patch_realtek.c
sound/pci/hda/patch_sigmatel.c
sound/pci/rme96.c
sound/soc/codecs/arizona.c
sound/soc/codecs/es8328.c
sound/soc/codecs/nau8825.c
sound/soc/codecs/rl6231.c
sound/soc/codecs/rt5645.c
sound/soc/codecs/rt5670.h
sound/soc/codecs/rt5677.c
sound/soc/codecs/wm8960.c
sound/soc/codecs/wm8962.c
sound/soc/davinci/davinci-mcasp.c
sound/soc/fsl/Kconfig
sound/soc/fsl/fsl_sai.c
sound/soc/intel/Kconfig
sound/soc/intel/skylake/skl-topology.c
sound/soc/rockchip/rockchip_spdif.c
sound/soc/rockchip/rockchip_spdif.h
sound/soc/sh/rcar/gen.c
sound/soc/sh/rcar/src.c
sound/soc/soc-core.c
sound/soc/soc-dapm.c
sound/soc/soc-ops.c
sound/soc/soc-topology.c
sound/soc/sti/uniperif_player.c
sound/soc/sti/uniperif_reader.c
sound/soc/sunxi/sun4i-codec.c
sound/usb/midi.c
sound/usb/quirks-table.h
sound/usb/quirks.c
sound/usb/usbaudio.h
tools/testing/nvdimm/test/nfit.c
tools/testing/selftests/futex/README
tools/testing/selftests/seccomp/seccomp_bpf.c
tools/virtio/linux/kernel.h
tools/virtio/linux/virtio.h
tools/virtio/linux/virtio_config.h
virt/kvm/arm/arch_timer.c
virt/kvm/arm/vgic.c

index f17bc4c9dff9fa1334d518e0a6c0ffc8ac270e3a..400c0c270d2e8d935e55fc1396989e75abbad36d 100644 (file)
@@ -49,24 +49,6 @@ specified through DTS. Following are the DTS used:-
 The device tree documentation for the keystone machines are located at
         Documentation/devicetree/bindings/arm/keystone/keystone.txt
 
-Known issues & workaround
--------------------------
-
-Some of the device drivers used on keystone are re-used from that from
-DaVinci and other TI SoCs. These device drivers may use clock APIs directly.
-Some of the keystone specific drivers such as netcp uses run time power
-management API instead to enable clock. As this API has limitations on
-keystone, following workaround is needed to boot Linux.
-
-   Add 'clk_ignore_unused' to the bootargs env variable in u-boot. Otherwise
-   clock frameworks will try to disable clocks that are unused and disable
-   the hardware. This is because netcp related power domain and clock
-   domains are enabled in u-boot as run time power management API currently
-   doesn't enable clocks for netcp due to a limitation. This workaround is
-   expected to be removed in the future when proper API support becomes
-   available. Until then, this work around is needed.
-
-
 Document Author
 ---------------
 Murali Karicheri <m-karicheri2@ti.com>
index 2f6c6ff7161d4e77f3ec8ffee998b19f53b18cf7..d8880ca30af4c35d562c0f77b1b3a56c3ff6e1d7 100644 (file)
@@ -70,3 +70,6 @@ use_per_node_hctx=[0/1]: Default: 0
      parameter.
   1: The multi-queue block layer is instantiated with a hardware dispatch
      queue for each CPU node in the system.
+
+use_lightnvm=[0/1]: Default: 0
+  Register device with LightNVM. Requires blk-mq to be used.
index f2455c50533d6c7388ebfacbe572d164e5d11314..120bc4971cf3ed92cf9590af16643645e5c89234 100644 (file)
@@ -11,6 +11,10 @@ Required properties:
       0 = active high
       1 = active low
 
+Optional properties:
+- little-endian : GPIO registers are used as little endian. If not
+                  present registers are used as big endian by default.
+
 Example:
 
 gpio0: gpio@1100 {
index f5a8ca29aff06e84d49e3c75caf125b35c660055..aeea50c84e921fb301fc7fe9fd2cd6f295c7139c 100644 (file)
@@ -8,6 +8,11 @@ Required properties:
 - phy-mode: See ethernet.txt file in the same directory
 - clocks: a pointer to the reference clock for this device.
 
+Optional properties:
+- tx-csum-limit: maximum mtu supported by port that allow TX checksum.
+  Value is presented in bytes. If not used, by default 1600B is set for
+  "marvell,armada-370-neta" and 9800B for others.
+
 Example:
 
 ethernet@d0070000 {
@@ -15,6 +20,7 @@ ethernet@d0070000 {
        reg = <0xd0070000 0x2500>;
        interrupts = <8>;
        clocks = <&gate_clk 4>;
+       tx-csum-limit = <9800>
        status = "okay";
        phy = <&phy0>;
        phy-mode = "rgmii-id";
diff --git a/Documentation/devicetree/bindings/staging/ion/hi6220-ion.txt b/Documentation/devicetree/bindings/staging/ion/hi6220-ion.txt
new file mode 100644 (file)
index 0000000..c59e27c
--- /dev/null
@@ -0,0 +1,31 @@
+Hi6220 SoC ION
+===================================================================
+Required properties:
+- compatible : "hisilicon,hi6220-ion"
+- list of the ION heaps
+       - heap name : maybe heap_sys_user@0
+       - heap id   : id should be unique in the system.
+       - heap base : base ddr address of the heap,0 means that
+       it is dynamic.
+       - heap size : memory size and 0 means it is dynamic.
+       - heap type : the heap type of the heap, please also
+       see the define in ion.h(drivers/staging/android/uapi/ion.h)
+-------------------------------------------------------------------
+Example:
+       hi6220-ion {
+               compatible = "hisilicon,hi6220-ion";
+               heap_sys_user@0 {
+                       heap-name = "sys_user";
+                       heap-id   = <0x0>;
+                       heap-base = <0x0>;
+                       heap-size = <0x0>;
+                       heap-type = "ion_system";
+               };
+               heap_sys_contig@0 {
+                       heap-name = "sys_contig";
+                       heap-id   = <0x1>;
+                       heap-base = <0x0>;
+                       heap-size = <0x0>;
+                       heap-type = "ion_system_contig";
+               };
+       };
index b38200d2583a5473ebe4c618aa09475128d31100..0dfa60d88dd3b4bb4ce2a42d2c0b3d15f4835e45 100644 (file)
@@ -1,7 +1,9 @@
 * Temperature Sensor ADC (TSADC) on rockchip SoCs
 
 Required properties:
-- compatible : "rockchip,rk3288-tsadc"
+- compatible : should be "rockchip,<name>-tsadc"
+   "rockchip,rk3288-tsadc": found on RK3288 SoCs
+   "rockchip,rk3368-tsadc": found on RK3368 SoCs
 - reg : physical base address of the controller and length of memory mapped
        region.
 - interrupts : The interrupt number to the cpu. The interrupt specifier format
index 050d0e77a2cf00f7d6a33e6d11bccf88c22ad761..9bff63cf326e717a7c7c94c7234fd4a40a407bab 100644 (file)
@@ -318,7 +318,7 @@ M:  Zhang Rui <rui.zhang@intel.com>
 L:     linux-acpi@vger.kernel.org
 W:     https://01.org/linux-acpi
 S:     Supported
-F:     drivers/acpi/video.c
+F:     drivers/acpi/acpi_video.c
 
 ACPI WMI DRIVER
 L:     platform-driver-x86@vger.kernel.org
@@ -1847,7 +1847,7 @@ S:        Supported
 F:     drivers/net/wireless/ath/ath6kl/
 
 WILOCITY WIL6210 WIRELESS DRIVER
-M:     Vladimir Kondratiev <qca_vkondrat@qca.qualcomm.com>
+M:     Maya Erez <qca_merez@qca.qualcomm.com>
 L:     linux-wireless@vger.kernel.org
 L:     wil6210@qca.qualcomm.com
 S:     Supported
@@ -1931,7 +1931,7 @@ S:        Supported
 F:     drivers/i2c/busses/i2c-at91.c
 
 ATMEL ISI DRIVER
-M:     Josh Wu <josh.wu@atmel.com>
+M:     Ludovic Desroches <ludovic.desroches@atmel.com>
 L:     linux-media@vger.kernel.org
 S:     Supported
 F:     drivers/media/platform/soc_camera/atmel-isi.c
@@ -1950,7 +1950,8 @@ S:        Supported
 F:     drivers/net/ethernet/cadence/
 
 ATMEL NAND DRIVER
-M:     Josh Wu <josh.wu@atmel.com>
+M:     Wenyou Yang <wenyou.yang@atmel.com>
+M:     Josh Wu <rainyfeeling@outlook.com>
 L:     linux-mtd@lists.infradead.org
 S:     Supported
 F:     drivers/mtd/nand/atmel_nand*
@@ -2974,6 +2975,7 @@ F:        kernel/cpuset.c
 CONTROL GROUP - MEMORY RESOURCE CONTROLLER (MEMCG)
 M:     Johannes Weiner <hannes@cmpxchg.org>
 M:     Michal Hocko <mhocko@kernel.org>
+M:     Vladimir Davydov <vdavydov@virtuozzo.com>
 L:     cgroups@vger.kernel.org
 L:     linux-mm@kvack.org
 S:     Maintained
@@ -6366,6 +6368,7 @@ F:        arch/*/include/asm/pmem.h
 LIGHTNVM PLATFORM SUPPORT
 M:     Matias Bjorling <mb@lightnvm.io>
 W:     http://github/OpenChannelSSD
+L:     linux-block@vger.kernel.org
 S:     Maintained
 F:     drivers/lightnvm/
 F:     include/linux/lightnvm.h
@@ -8284,7 +8287,7 @@ F:        include/linux/delayacct.h
 F:     kernel/delayacct.c
 
 PERFORMANCE EVENTS SUBSYSTEM
-M:     Peter Zijlstra <a.p.zijlstra@chello.nl>
+M:     Peter Zijlstra <peterz@infradead.org>
 M:     Ingo Molnar <mingo@redhat.com>
 M:     Arnaldo Carvalho de Melo <acme@kernel.org>
 L:     linux-kernel@vger.kernel.org
@@ -9425,8 +9428,10 @@ F:       include/scsi/sg.h
 
 SCSI SUBSYSTEM
 M:     "James E.J. Bottomley" <JBottomley@odin.com>
-L:     linux-scsi@vger.kernel.org
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi.git
+M:     "Martin K. Petersen" <martin.petersen@oracle.com>
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mkp/scsi.git
+L:     linux-scsi@vger.kernel.org
 S:     Maintained
 F:     drivers/scsi/
 F:     include/scsi/
@@ -10901,9 +10906,9 @@ S:      Maintained
 F:     drivers/media/tuners/tua9001*
 
 TULIP NETWORK DRIVERS
-M:     Grant Grundler <grundler@parisc-linux.org>
 L:     netdev@vger.kernel.org
-S:     Maintained
+L:     linux-parisc@vger.kernel.org
+S:     Orphan
 F:     drivers/net/ethernet/dec/tulip/
 
 TUN/TAP driver
index 2ffdf9d6f339f7254f1a08ff979bf424f0c5a33d..bc0165d0f5cf30ea0faa7325fe96fd1b99b428fa 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 4
 PATCHLEVEL = 4
 SUBLEVEL = 0
-EXTRAVERSION = -rc2
+EXTRAVERSION = -rc5
 NAME = Blurry Fish Butt
 
 # *DOCUMENTATION*
index c92c0ef1e9d290b2db437001338cf477c1df9513..f1ac9818b751e1fab854f2c1a4440b9ca8af3e85 100644 (file)
@@ -1,4 +1,4 @@
-CONFIG_CROSS_COMPILE="arc-linux-uclibc-"
+CONFIG_CROSS_COMPILE="arc-linux-"
 CONFIG_DEFAULT_HOSTNAME="ARCLinux"
 # CONFIG_SWAP is not set
 CONFIG_SYSVIPC=y
index cfac24e0e7b6565a48c3a22f6251e8992fbb84bb..323486d6ee83419a9e50d5c53fa042f53e08ebed 100644 (file)
@@ -1,4 +1,4 @@
-CONFIG_CROSS_COMPILE="arc-linux-uclibc-"
+CONFIG_CROSS_COMPILE="arc-linux-"
 CONFIG_DEFAULT_HOSTNAME="ARCLinux"
 # CONFIG_SWAP is not set
 CONFIG_SYSVIPC=y
index 9922a118a15a3d28c99c85f1c67407142e75fb86..66191cd0447eaabc524a36ec497e7047043dc9a4 100644 (file)
@@ -1,4 +1,4 @@
-CONFIG_CROSS_COMPILE="arc-linux-uclibc-"
+CONFIG_CROSS_COMPILE="arc-linux-"
 CONFIG_DEFAULT_HOSTNAME="ARCLinux"
 # CONFIG_SWAP is not set
 CONFIG_SYSVIPC=y
index f761a7c70761862139ffeb7a2f89d2b159ffec71..f68838e8068af53eb2ebb29c83d88cb10dc0bfac 100644 (file)
@@ -1,4 +1,4 @@
-CONFIG_CROSS_COMPILE="arc-linux-uclibc-"
+CONFIG_CROSS_COMPILE="arc-linux-"
 # CONFIG_LOCALVERSION_AUTO is not set
 CONFIG_DEFAULT_HOSTNAME="ARCLinux"
 # CONFIG_SWAP is not set
index dc6f74f412837b51486634851a1e10ddc4341f10..96bd1c20fb0badeb5d3ebf41f2671f6558939c22 100644 (file)
@@ -1,4 +1,4 @@
-CONFIG_CROSS_COMPILE="arc-linux-uclibc-"
+CONFIG_CROSS_COMPILE="arc-linux-"
 # CONFIG_LOCALVERSION_AUTO is not set
 CONFIG_DEFAULT_HOSTNAME="ARCLinux"
 # CONFIG_SWAP is not set
index 3fef0a210c5654bda4e0bc085d3910d2b336a59c..fcae66683ca0bd5865924a88816a388e763604cd 100644 (file)
@@ -1,4 +1,4 @@
-CONFIG_CROSS_COMPILE="arc-linux-uclibc-"
+CONFIG_CROSS_COMPILE="arc-linux-"
 # CONFIG_LOCALVERSION_AUTO is not set
 CONFIG_DEFAULT_HOSTNAME="ARCLinux"
 # CONFIG_SWAP is not set
index 51784837daaec1e0b3fd0434b60e41b5b6e15610..b01b659168ea4a1c36ac85e0ee41c545aa697ec8 100644 (file)
@@ -1,4 +1,4 @@
-CONFIG_CROSS_COMPILE="arc-linux-uclibc-"
+CONFIG_CROSS_COMPILE="arc-linux-"
 CONFIG_DEFAULT_HOSTNAME="ARCLinux"
 # CONFIG_SWAP is not set
 CONFIG_SYSVIPC=y
index ef35ef3923ddca3a6fa84bd121b682681c861fc7..a07f20de221ba1f0b0963ca1f1d44053c6b1b89a 100644 (file)
@@ -1,4 +1,4 @@
-CONFIG_CROSS_COMPILE="arc-linux-uclibc-"
+CONFIG_CROSS_COMPILE="arc-linux-"
 # CONFIG_LOCALVERSION_AUTO is not set
 CONFIG_DEFAULT_HOSTNAME="ARCLinux"
 # CONFIG_CROSS_MEMORY_ATTACH is not set
index 634509e5e572ef02911e1a79906d54faf8523951..f36c047b33cad0c469bd2368bb3e5fa4260535e5 100644 (file)
@@ -1,4 +1,4 @@
-CONFIG_CROSS_COMPILE="arc-linux-uclibc-"
+CONFIG_CROSS_COMPILE="arc-linux-"
 # CONFIG_LOCALVERSION_AUTO is not set
 CONFIG_DEFAULT_HOSTNAME="ARCLinux"
 # CONFIG_CROSS_MEMORY_ATTACH is not set
index ad481c24070dd1f369fefab436160f6d60f9dc2c..258b0e5ad3329a614e59204df55d91873e969623 100644 (file)
@@ -37,6 +37,9 @@
 #define ISA_INIT_STATUS_BITS   (STATUS_IE_MASK | STATUS_AD_MASK | \
                                        (ARCV2_IRQ_DEF_PRIO << 1))
 
+/* SLEEP needs default irq priority (<=) which can interrupt the doze */
+#define ISA_SLEEP_ARG          (0x10 | ARCV2_IRQ_DEF_PRIO)
+
 #ifndef __ASSEMBLY__
 
 /*
index d8c608174617783496b8855bc6ed19de9b6f67cd..c1d36458bfb7aa665acb30a2234660034a19aecd 100644 (file)
@@ -43,6 +43,8 @@
 
 #define ISA_INIT_STATUS_BITS   STATUS_IE_MASK
 
+#define ISA_SLEEP_ARG          0x3
+
 #ifndef __ASSEMBLY__
 
 /******************************************************************
index c14a5bea0c76792ead17b42e1f548e38960cc194..5d446df2c41353a15edfc5a5f7b05abd24b16df3 100644 (file)
@@ -58,8 +58,6 @@ __switch_to(struct task_struct *prev_task, struct task_struct *next_task)
                "st      sp, [r24]       \n\t"
 #endif
 
-               "sync   \n\t"
-
                /*
                 * setup _current_task with incoming tsk.
                 * optionally, set r25 to that as well
index e248594097e7d69c66b2f46044dbfe4782008bd0..e6890b1f8650647774b48678c88e805f6b16de3a 100644 (file)
@@ -44,9 +44,6 @@ __switch_to:
        * don't need to do anything special to return it
        */
 
-       /* hardware memory barrier */
-       sync
-
        /*
         * switch to new task, contained in r1
         * Temp reg r3 is required to get the ptr to store val
index 91d5a0f1f3f79cdd454e99e7781b2e3741caae76..a3f750e76b683dd25a45584b71014532214b20ac 100644 (file)
@@ -44,11 +44,10 @@ SYSCALL_DEFINE0(arc_gettls)
 void arch_cpu_idle(void)
 {
        /* sleep, but enable all interrupts before committing */
-       if (is_isa_arcompact()) {
-               __asm__("sleep 0x3");
-       } else {
-               __asm__("sleep 0x10");
-       }
+       __asm__ __volatile__(
+               "sleep %0       \n"
+               :
+               :"I"(ISA_SLEEP_ARG)); /* can't be "r" has to be embedded const */
 }
 
 asmlinkage void ret_from_fork(void);
index 93c6ea52b6719e4e238d6076fda6c3b981ac48fe..7352475451f6c3798885c97b04c11ddd53146990 100644 (file)
@@ -986,42 +986,13 @@ int arc_unwind(struct unwind_frame_info *frame)
                                                            (const u8 *)(fde +
                                                                         1) +
                                                            *fde, ptrType);
-                               if (pc >= endLoc)
+                               if (pc >= endLoc) {
                                        fde = NULL;
-                       } else
-                               fde = NULL;
-               }
-               if (fde == NULL) {
-                       for (fde = table->address, tableSize = table->size;
-                            cie = NULL, tableSize > sizeof(*fde)
-                            && tableSize - sizeof(*fde) >= *fde;
-                            tableSize -= sizeof(*fde) + *fde,
-                            fde += 1 + *fde / sizeof(*fde)) {
-                               cie = cie_for_fde(fde, table);
-                               if (cie == &bad_cie) {
                                        cie = NULL;
-                                       break;
                                }
-                               if (cie == NULL
-                                   || cie == &not_fde
-                                   || (ptrType = fde_pointer_type(cie)) < 0)
-                                       continue;
-                               ptr = (const u8 *)(fde + 2);
-                               startLoc = read_pointer(&ptr,
-                                                       (const u8 *)(fde + 1) +
-                                                       *fde, ptrType);
-                               if (!startLoc)
-                                       continue;
-                               if (!(ptrType & DW_EH_PE_indirect))
-                                       ptrType &=
-                                           DW_EH_PE_FORM | DW_EH_PE_signed;
-                               endLoc =
-                                   startLoc + read_pointer(&ptr,
-                                                           (const u8 *)(fde +
-                                                                        1) +
-                                                           *fde, ptrType);
-                               if (pc >= startLoc && pc < endLoc)
-                                       break;
+                       } else {
+                               fde = NULL;
+                               cie = NULL;
                        }
                }
        }
index 0ee7398468476f57b301bde2fa7c7e13735bb3fb..daf2bf52b984c6781dbb6831e22f013b04e58d0d 100644 (file)
@@ -619,10 +619,10 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long vaddr_unaligned,
 
                int dirty = !test_and_set_bit(PG_dc_clean, &page->flags);
                if (dirty) {
-                       /* wback + inv dcache lines */
+                       /* wback + inv dcache lines (K-mapping) */
                        __flush_dcache_page(paddr, paddr);
 
-                       /* invalidate any existing icache lines */
+                       /* invalidate any existing icache lines (U-mapping) */
                        if (vma->vm_flags & VM_EXEC)
                                __inv_icache_page(paddr, vaddr);
                }
index 0365cbbc917989853d87b8a84c8409ae268d6e33..34e1569a11ee322a0a020bdfe0c9b801b6b58c12 100644 (file)
@@ -76,6 +76,8 @@ config ARM
        select IRQ_FORCED_THREADING
        select MODULES_USE_ELF_REL
        select NO_BOOTMEM
+       select OF_EARLY_FLATTREE if OF
+       select OF_RESERVED_MEM if OF
        select OLD_SIGACTION
        select OLD_SIGSUSPEND3
        select PERF_USE_VMALLOC
@@ -1822,8 +1824,6 @@ config USE_OF
        bool "Flattened Device Tree support"
        select IRQ_DOMAIN
        select OF
-       select OF_EARLY_FLATTREE
-       select OF_RESERVED_MEM
        help
          Include support for flattened device tree machine descriptions.
 
index d83ff9c9701e36d5d837c87ce292d89c421c4a70..de8791a4d1311883577f51e243769a3c6906a61a 100644 (file)
@@ -74,7 +74,7 @@
                reg = <0x48240200 0x100>;
                interrupts = <GIC_PPI 11 IRQ_TYPE_LEVEL_HIGH>;
                interrupt-parent = <&gic>;
-               clocks = <&dpll_mpu_m2_ck>;
+               clocks = <&mpu_periphclk>;
        };
 
        local_timer: timer@48240600 {
@@ -82,7 +82,7 @@
                reg = <0x48240600 0x100>;
                interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_HIGH>;
                interrupt-parent = <&gic>;
-               clocks = <&dpll_mpu_m2_ck>;
+               clocks = <&mpu_periphclk>;
        };
 
        l2-cache-controller@48242000 {
index cc88728d751de587bcb86abbe179921c493779e9..a38af2bfbfcfbd51f223409e48231d04e73cd7e5 100644 (file)
                ti,invert-autoidle-bit;
        };
 
+       mpu_periphclk: mpu_periphclk {
+               #clock-cells = <0>;
+               compatible = "fixed-factor-clock";
+               clocks = <&dpll_mpu_m2_ck>;
+               clock-mult = <1>;
+               clock-div = <2>;
+       };
+
        dpll_ddr_ck: dpll_ddr_ck {
                #clock-cells = <0>;
                compatible = "ti,am3-dpll-clock";
index d9ba6b879fc1b25e25f8d006c8b57ab722310c7d..00352e761b8c036ce99dbe428ff0ecd7d4d60929 100644 (file)
                reg = <0x6f>;
                interrupts-extended = <&crossbar_mpu GIC_SPI 2 IRQ_TYPE_EDGE_RISING>,
                                      <&dra7_pmx_core 0x424>;
+               interrupt-names = "irq", "wakeup";
 
                pinctrl-names = "default";
                pinctrl-0 = <&mcp79410_pins_default>;
index 4e0ad3b827962831fe7d3e0d5a325d33b420381f..0962f2fa3f6e74d3f253593720689cf934dd56b0 100644 (file)
                        label = "keyswitch_in";
                        gpios = <&pioB 1 GPIO_ACTIVE_HIGH>;
                        linux,code = <28>;
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
 
                error_in {
                        label = "error_in";
                        gpios = <&pioB 2 GPIO_ACTIVE_HIGH>;
                        linux,code = <29>;
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
 
                btn {
                        label = "btn";
                        gpios = <&pioC 23 GPIO_ACTIVE_HIGH>;
                        linux,code = <31>;
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
        };
 };
index c6a0e9d7f1a9bd0409b31bb4272bfbcb68f3b093..e8b7f67267723241730c8279902b82b8340d8118 100644 (file)
                                reg = <0x70000 0x4000>;
                                interrupts-extended = <&mpic 8>;
                                clocks = <&gateclk 4>;
+                               tx-csum-limit = <9800>;
                                status = "disabled";
                        };
 
index f89598af4c2b1ef24b1812b15fca28de2c5b4382..6bf873e7d96c226ac532658c62af2ca1e869046a 100644 (file)
                        label = "Button";
                        gpios = <&pioC 4 GPIO_ACTIVE_LOW>;
                        linux,code = <0x103>;
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
        };
 };
index bf18ece0c02708c4d7b99ac543e2bc9045daf63b..229e989eb60df3305fb6a609e44e919a3696b143 100644 (file)
        };
 
        clocks {
-               #address-cells = <1>;
-               #size-cells = <1>;
-               ranges;
-
-               main_clock: clock@0 {
-                       compatible = "atmel,osc", "fixed-clock";
-                       clock-frequency = <18432000>;
-               };
-
                main_xtal {
                        clock-frequency = <18432000>;
                };
                        label = "PB_RST";
                        gpios = <&pioB 30 GPIO_ACTIVE_HIGH>;
                        linux,code = <0x100>;
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
 
                user {
                        label = "PB_USER";
                        gpios = <&pioB 31 GPIO_ACTIVE_HIGH>;
                        linux,code = <0x101>;
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
        };
 
index f0b1563cb3f164907c63a3ea3d94390a0cd863f9..50a14568f094a64cd5368851e2c39bd250e0cebe 100644 (file)
                        label = "PB_PROG";
                        gpios = <&pioE 27 GPIO_ACTIVE_LOW>;
                        linux,code = <0x102>;
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
 
                reset {
                        label = "PB_RST";
                        gpios = <&pioE 29 GPIO_ACTIVE_LOW>;
                        linux,code = <0x100>;
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
 
                user {
                        label = "PB_USER";
                        gpios = <&pioE 31 GPIO_ACTIVE_HIGH>;
                        linux,code = <0x101>;
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
        };
 
index 9f72b49326344925b55d600a1a5c30173c5f7d48..9682d105d4d8317a4733412fbe4cde6241158e74 100644 (file)
                        label = "PB_PROG";
                        gpios = <&pioC 17 GPIO_ACTIVE_LOW>;
                        linux,code = <0x102>;
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
 
                reset {
                        label = "PB_RST";
                        gpios = <&pioC 16 GPIO_ACTIVE_LOW>;
                        linux,code = <0x100>;
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
        };
 
index a9aef53ab764202df553a058b73cd77a84c55dff..4f2eebf4a5603a5de81043fdefca99d13400c4cf 100644 (file)
                        label = "user_pb";
                        gpios = <&pioB 10 GPIO_ACTIVE_LOW>;
                        linux,code = <28>;
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
        };
 
index e07c2b206beba18c8a139574aa8bc83f74c23545..e74df327cdd3b8d5776cb5d6deb269042f463bdb 100644 (file)
@@ -45,6 +45,7 @@
 /dts-v1/;
 #include "sama5d2.dtsi"
 #include "sama5d2-pinfunc.h"
+#include <dt-bindings/mfd/atmel-flexcom.h>
 
 / {
        model = "Atmel SAMA5D2 Xplained";
        };
 
        clocks {
-               #address-cells = <1>;
-               #size-cells = <1>;
-               ranges;
-
-               main_clock: clock@0 {
-                       compatible = "atmel,osc", "fixed-clock";
-                       clock-frequency = <12000000>;
-               };
-
                slow_xtal {
                        clock-frequency = <32768>;
                };
                        status = "okay";
                };
 
+               sdmmc0: sdio-host@a0000000 {
+                       bus-width = <8>;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&pinctrl_sdmmc0_default>;
+                       non-removable;
+                       mmc-ddr-1_8v;
+                       status = "okay";
+               };
+
+               sdmmc1: sdio-host@b0000000 {
+                       bus-width = <4>;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&pinctrl_sdmmc1_default>;
+                       status = "okay"; /* conflict with qspi0 */
+               };
+
                apb {
                        spi0: spi@f8000000 {
                                pinctrl-names = "default";
                                                        regulator-name = "VDD_SDHC_1V8";
                                                        regulator-min-microvolt = <1800000>;
                                                        regulator-max-microvolt = <1800000>;
+                                                       regulator-always-on;
                                                };
                                        };
                                };
                        };
 
+                       flx0: flexcom@f8034000 {
+                               atmel,flexcom-mode = <ATMEL_FLEXCOM_MODE_USART>;
+                               status = "disabled"; /* conflict with ISC_D2 & ISC_D3 data pins */
+
+                               uart5: serial@200 {
+                                       compatible = "atmel,at91sam9260-usart";
+                                       reg = <0x200 0x200>;
+                                       interrupts = <19 IRQ_TYPE_LEVEL_HIGH 7>;
+                                       clocks = <&flx0_clk>;
+                                       clock-names = "usart";
+                                       pinctrl-names = "default";
+                                       pinctrl-0 = <&pinctrl_flx0_default>;
+                                       atmel,fifo-size = <32>;
+                                       status = "okay";
+                               };
+                       };
+
                        uart3: serial@fc008000 {
                                pinctrl-names = "default";
                                pinctrl-0 = <&pinctrl_uart3_default>;
                                status = "okay";
                        };
 
+                       flx4: flexcom@fc018000 {
+                               atmel,flexcom-mode = <ATMEL_FLEXCOM_MODE_TWI>;
+                               status = "okay";
+
+                               i2c2: i2c@600 {
+                                       compatible = "atmel,sama5d2-i2c";
+                                       reg = <0x600 0x200>;
+                                       interrupts = <23 IRQ_TYPE_LEVEL_HIGH 7>;
+                                       dmas = <0>, <0>;
+                                       dma-names = "tx", "rx";
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+                                       clocks = <&flx4_clk>;
+                                       pinctrl-names = "default";
+                                       pinctrl-0 = <&pinctrl_flx4_default>;
+                                       atmel,fifo-size = <16>;
+                                       status = "okay";
+                               };
+                       };
+
                        i2c1: i2c@fc028000 {
                                dmas = <0>, <0>;
                                pinctrl-names = "default";
                        };
 
                        pinctrl@fc038000 {
+                               pinctrl_flx0_default: flx0_default {
+                                       pinmux = <PIN_PB28__FLEXCOM0_IO0>,
+                                                <PIN_PB29__FLEXCOM0_IO1>;
+                                       bias-disable;
+                               };
+
+                               pinctrl_flx4_default: flx4_default {
+                                       pinmux = <PIN_PD12__FLEXCOM4_IO0>,
+                                                <PIN_PD13__FLEXCOM4_IO1>;
+                                       bias-disable;
+                               };
+
                                pinctrl_i2c0_default: i2c0_default {
                                        pinmux = <PIN_PD21__TWD0>,
                                                 <PIN_PD22__TWCK0>;
                                        bias-disable;
                                };
 
+                               pinctrl_sdmmc0_default: sdmmc0_default {
+                                       cmd_data {
+                                               pinmux = <PIN_PA1__SDMMC0_CMD>,
+                                                        <PIN_PA2__SDMMC0_DAT0>,
+                                                        <PIN_PA3__SDMMC0_DAT1>,
+                                                        <PIN_PA4__SDMMC0_DAT2>,
+                                                        <PIN_PA5__SDMMC0_DAT3>,
+                                                        <PIN_PA6__SDMMC0_DAT4>,
+                                                        <PIN_PA7__SDMMC0_DAT5>,
+                                                        <PIN_PA8__SDMMC0_DAT6>,
+                                                        <PIN_PA9__SDMMC0_DAT7>;
+                                               bias-pull-up;
+                                       };
+
+                                       ck_cd_rstn_vddsel {
+                                               pinmux = <PIN_PA0__SDMMC0_CK>,
+                                                        <PIN_PA10__SDMMC0_RSTN>,
+                                                        <PIN_PA11__SDMMC0_VDDSEL>,
+                                                        <PIN_PA13__SDMMC0_CD>;
+                                               bias-disable;
+                                       };
+                               };
+
+                               pinctrl_sdmmc1_default: sdmmc1_default {
+                                       cmd_data {
+                                               pinmux = <PIN_PA28__SDMMC1_CMD>,
+                                                        <PIN_PA18__SDMMC1_DAT0>,
+                                                        <PIN_PA19__SDMMC1_DAT1>,
+                                                        <PIN_PA20__SDMMC1_DAT2>,
+                                                        <PIN_PA21__SDMMC1_DAT3>;
+                                               bias-pull-up;
+                                       };
+
+                                       conf-ck_cd {
+                                               pinmux = <PIN_PA22__SDMMC1_CK>,
+                                                        <PIN_PA30__SDMMC1_CD>;
+                                               bias-disable;
+                                       };
+                               };
+
                                pinctrl_spi0_default: spi0_default {
                                        pinmux = <PIN_PA14__SPI0_SPCK>,
                                                 <PIN_PA15__SPI0_MOSI>,
index 8488ac53d22d3b4d6f0562ebd9018d3126ce5ee2..ff888d21c786a69b1f56c768ea6a2219056b98dc 100644 (file)
                        label = "PB_USER";
                        gpios = <&pioE 29 GPIO_ACTIVE_LOW>;
                        linux,code = <0x104>;
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
        };
 
index 45371a1b61b398b6b939292649b20d0315cd399b..131614f28e758653e34cc2b993bb6a5a28f20bbb 100644 (file)
@@ -50,7 +50,6 @@
        compatible = "atmel,sama5d4-xplained", "atmel,sama5d4", "atmel,sama5";
 
        chosen {
-               bootargs = "ignore_loglevel earlyprintk";
                stdout-path = "serial0:115200n8";
        };
 
        };
 
        clocks {
-               #address-cells = <1>;
-               #size-cells = <1>;
-               ranges;
-
-               main_clock: clock@0 {
-                       compatible = "atmel,osc", "fixed-clock";
-                       clock-frequency = <12000000>;
-               };
-
                slow_xtal {
                        clock-frequency = <32768>;
                };
                        label = "pb_user1";
                        gpios = <&pioE 8 GPIO_ACTIVE_HIGH>;
                        linux,code = <0x100>;
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
        };
 
index 6d272c0125e365b64aad7dadbeec309c51c60fc6..2d4a33100af6bdc4fcd4a3500467456673f54325 100644 (file)
@@ -50,7 +50,6 @@
        compatible = "atmel,sama5d4ek", "atmel,sama5d4", "atmel,sama5";
 
        chosen {
-               bootargs = "ignore_loglevel earlyprintk";
                stdout-path = "serial0:115200n8";
        };
 
        };
 
        clocks {
-               #address-cells = <1>;
-               #size-cells = <1>;
-               ranges;
-
-               main_clock: clock@0 {
-                       compatible = "atmel,osc", "fixed-clock";
-                       clock-frequency = <12000000>;
-               };
-
                slow_xtal {
                        clock-frequency = <32768>;
                };
                        label = "pb_user1";
                        gpios = <&pioE 13 GPIO_ACTIVE_HIGH>;
                        linux,code = <0x100>;
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
        };
 
index 8dab4b75ca97cfed9beae29bf49224dc71a06bb9..f90e1c2d3caa2fc41485ba330bdcd691a379e6be 100644 (file)
        };
 
        clocks {
-               #address-cells = <1>;
-               #size-cells = <1>;
-               ranges;
-
-               main_clock: clock@0 {
-                       compatible = "atmel,osc", "fixed-clock";
-                       clock-frequency = <18432000>;
-               };
-
                slow_xtal {
                        clock-frequency = <32768>;
                };
index 2e92ac020f2383ef58c25a1836b22954834211be..55bd51f07fa601e709f7fc910e7fa757fe4f32ee 100644 (file)
        };
 
        clocks {
-               #address-cells = <1>;
-               #size-cells = <1>;
-               ranges;
-
-               main_clock: clock@0 {
-                       compatible = "atmel,osc", "fixed-clock";
-                       clock-frequency = <18432000>;
-               };
-
                slow_xtal {
                        clock-frequency = <32768>;
                };
                                        ti,debounce-tol = /bits/ 16 <65535>;
                                        ti,debounce-max = /bits/ 16 <1>;
 
-                                       linux,wakeup;
+                                       wakeup-source;
                                };
                        };
 
                        label = "button_0";
                        gpios = <&pioA 27 GPIO_ACTIVE_LOW>;
                        linux,code = <256>;
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
 
                button_1 {
                        label = "button_1";
                        gpios = <&pioA 26 GPIO_ACTIVE_LOW>;
                        linux,code = <257>;
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
 
                button_2 {
                        label = "button_2";
                        gpios = <&pioA 25 GPIO_ACTIVE_LOW>;
                        linux,code = <258>;
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
 
                button_3 {
                        label = "button_3";
                        gpios = <&pioA 24 GPIO_ACTIVE_LOW>;
                        linux,code = <259>;
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
        };
 };
index 23381276ffb8016b0dafc1237eb990bad1e775b1..59df9d73d27659d507d78d195fe3b1be7c499dd4 100644 (file)
        };
 
        clocks {
-               #address-cells = <1>;
-               #size-cells = <1>;
-               ranges;
-
-               main_clock: clock@0 {
-                       compatible = "atmel,osc", "fixed-clock";
-                       clock-frequency = <16367660>;
-               };
-
                slow_xtal {
                        clock-frequency = <32768>;
                };
                        label = "left_click";
                        gpios = <&pioC 5 GPIO_ACTIVE_LOW>;
                        linux,code = <272>;
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
 
                right_click {
                        label = "right_click";
                        gpios = <&pioC 4 GPIO_ACTIVE_LOW>;
                        linux,code = <273>;
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
        };
 
index 57548a2c5a1eb80b0701129f612bf3a785b65928..e9cc99b6353ad1e464bb0942c29e3cea6dc5d37e 100644 (file)
        };
 
        clocks {
-               #address-cells = <1>;
-               #size-cells = <1>;
-               ranges;
-
-               main_clock: clock@0 {
-                       compatible = "atmel,osc", "fixed-clock";
-                       clock-frequency = <18432000>;
-               };
-
                slow_xtal {
                        clock-frequency = <32768>;
                };
                        label = "Button 3";
                        gpios = <&pioA 30 GPIO_ACTIVE_LOW>;
                        linux,code = <0x103>;
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
 
                btn4 {
                        label = "Button 4";
                        gpios = <&pioA 31 GPIO_ACTIVE_LOW>;
                        linux,code = <0x104>;
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
        };
 
index 9d16ef8453c556f7ad69a21f65d9526a90325115..2400c99134f7f516e97af8234d89b8d3098196bd 100644 (file)
        };
 
        clocks {
-               #address-cells = <1>;
-               #size-cells = <1>;
-               ranges;
-
-               main_clock: clock@0 {
-                       compatible = "atmel,osc", "fixed-clock";
-                       clock-frequency = <12000000>;
-               };
-
                slow_xtal {
                      clock-frequency = <32768>;
                };
                        label = "left_click";
                        gpios = <&pioB 6 GPIO_ACTIVE_LOW>;
                        linux,code = <272>;
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
 
                right_click {
                        label = "right_click";
                        gpios = <&pioB 7 GPIO_ACTIVE_LOW>;
                        linux,code = <273>;
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
 
                left {
index acf3451a332da266f9a4e0ad5903a7ec11767587..ca4ddf86817ab64dc6a8a31193191460bfaf8d4b 100644 (file)
        };
 
        clocks {
-               #address-cells = <1>;
-               #size-cells = <1>;
-               ranges;
-
-               main_clock: clock@0 {
-                       compatible = "atmel,osc", "fixed-clock";
-                       clock-frequency = <16000000>;
-               };
-
                slow_xtal {
                        clock-frequency = <32768>;
                };
                        label = "Enter";
                        gpios = <&pioB 3 GPIO_ACTIVE_LOW>;
                        linux,code = <28>;
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
        };
 
index 558c9f220bedef3c61ac0b78e3dad2eb76017573..f10566f759cdceba2bedb202365a8c30d979c2f5 100644 (file)
        };
 
        clocks {
-               #address-cells = <1>;
-               #size-cells = <1>;
-               ranges;
-
-               main_clock: clock {
-                       compatible = "atmel,osc", "fixed-clock";
-                       clock-frequency = <12000000>;
-               };
-
                slow_xtal {
                        clock-frequency = <32768>;
                };
                        label = "right_click";
                        gpios = <&pioB 0 GPIO_ACTIVE_LOW>;
                        linux,code = <273>;
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
 
                left_click {
                        label = "left_click";
                        gpios = <&pioB 1 GPIO_ACTIVE_LOW>;
                        linux,code = <272>;
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
        };
 
index 26112ebd15fc4e896d576932b330b846fc4cc397..b098ad8cd93a7622b02198ee4bf2b06422af941a 100644 (file)
                reg = <0x20000000 0x8000000>;
        };
 
-       clocks {
-               #address-cells = <1>;
-               #size-cells = <1>;
-               ranges;
-
-               main_clock: clock@0 {
-                       compatible = "atmel,osc", "fixed-clock";
-                       clock-frequency = <12000000>;
-               };
-       };
-
        clocks {
                slow_xtal {
                        clock-frequency = <32768>;
index 8ea177f375ddd652c98339ac2cc8ef8935396442..fb1da99996ea43f9c3492591e9faf800030d5989 100644 (file)
                sdhci0: sdhci@ab0000 {
                        compatible = "mrvl,pxav3-mmc";
                        reg = <0xab0000 0x200>;
-                       clocks = <&chip_clk CLKID_SDIO1XIN>;
+                       clocks = <&chip_clk CLKID_SDIO1XIN>, <&chip_clk CLKID_SDIO>;
+                       clock-names = "io", "core";
                        interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
                        status = "disabled";
                };
                sdhci1: sdhci@ab0800 {
                        compatible = "mrvl,pxav3-mmc";
                        reg = <0xab0800 0x200>;
-                       clocks = <&chip_clk CLKID_SDIO1XIN>;
+                       clocks = <&chip_clk CLKID_SDIO1XIN>, <&chip_clk CLKID_SDIO>;
+                       clock-names = "io", "core";
                        interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
                        status = "disabled";
                };
                        compatible = "mrvl,pxav3-mmc";
                        reg = <0xab1000 0x200>;
                        interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&chip_clk CLKID_NFC_ECC>, <&chip_clk CLKID_NFC>;
+                       clocks = <&chip_clk CLKID_NFC_ECC>, <&chip_clk CLKID_SDIO>;
                        clock-names = "io", "core";
                        status = "disabled";
                };
index 3c99cfa1a8761604a409b9d0525f143c494571b0..eee636de4cd844237f5490b71c5f00d56dd9f06c 100644 (file)
                        reg = <0x480c8000 0x2000>;
                        interrupts = <77>;
                        ti,hwmods = "mailbox";
+                       #mbox-cells = <1>;
                        ti,mbox-num-users = <4>;
                        ti,mbox-num-fifos = <12>;
                        mbox_dsp: mbox_dsp {
                        ti,spi-num-cs = <4>;
                        ti,hwmods = "mcspi1";
                        dmas = <&edma 16 &edma 17
-                               &edma 18 &edma 19>;
-                       dma-names = "tx0", "rx0", "tx1", "rx1";
+                               &edma 18 &edma 19
+                               &edma 20 &edma 21
+                               &edma 22 &edma 23>;
+                       dma-names = "tx0", "rx0", "tx1", "rx1",
+                                   "tx2", "rx2", "tx3", "rx3";
                };
 
                mmc1: mmc@48060000 {
index bc672fb91466a5635a29c0811c202ef5c418aeeb..fe99231cbde5910bae9f768ead874effd33794c1 100644 (file)
                        interrupt-names = "tx", "rx";
                        dmas = <&sdma_xbar 133>, <&sdma_xbar 132>;
                        dma-names = "tx", "rx";
-                       clocks = <&mcasp3_ahclkx_mux>;
-                       clock-names = "fck";
+                       clocks = <&mcasp3_aux_gfclk_mux>, <&mcasp3_ahclkx_mux>;
+                       clock-names = "fck", "ahclkx";
                        status = "disabled";
                };
 
index 01aef230773d4052e19ba13b5c4a95df9ea08787..5acbd0dcc2abd9d3ffd3ac09adeab6f2dc33dfad 100644 (file)
@@ -137,7 +137,7 @@ netcp: netcp@26000000 {
        /* NetCP address range */
        ranges = <0 0x26000000 0x1000000>;
 
-       clocks = <&papllclk>, <&clkcpgmac>, <&chipclk12>;
+       clocks = <&clkosr>, <&papllclk>, <&clkcpgmac>, <&chipclk12>;
        dma-coherent;
 
        ti,navigator-dmas = <&dma_gbe 0>,
index c56ab6bbfe3c3a1fa1b60f481840cbaa3292a7f2..0e46560551f44b5d5dba4a01dcd74d9eb91ec5b2 100644 (file)
@@ -40,7 +40,7 @@
                };
                poweroff@12100 {
                        compatible = "qnap,power-off";
-                       reg = <0x12000 0x100>;
+                       reg = <0x12100 0x100>;
                        clocks = <&gate_clk 7>;
                };
                spi@10600 {
index 8fd8ef2c72dae55de1a1fa6004be38928b6f660f..85f0373df498f07b5b0c54658961bae18b535d7b 100644 (file)
        };
 };
 
+&emmc {
+       /delete-property/mmc-hs200-1_8v;
+};
+
 &gpio_keys {
        pinctrl-0 = <&pwr_key_l &ap_lid_int_l &volum_down_l &volum_up_l>;
 
index 6a79c9c526b8809d9ea201d087d680851653e990..04ea209f1737f9fb052f4efc8589e98aa027836e 100644 (file)
                clock-names = "tsadc", "apb_pclk";
                resets = <&cru SRST_TSADC>;
                reset-names = "tsadc-apb";
-               pinctrl-names = "default";
-               pinctrl-0 = <&otp_out>;
+               pinctrl-names = "init", "default", "sleep";
+               pinctrl-0 = <&otp_gpio>;
+               pinctrl-1 = <&otp_out>;
+               pinctrl-2 = <&otp_gpio>;
                #thermal-sensor-cells = <1>;
                rockchip,hw-tshut-temp = <95000>;
                status = "disabled";
                };
 
                tsadc {
+                       otp_gpio: otp-gpio {
+                               rockchip,pins = <0 10 RK_FUNC_GPIO &pcfg_pull_none>;
+                       };
+
                        otp_out: otp-out {
                                rockchip,pins = <0 10 RK_FUNC_1 &pcfg_pull_none>;
                        };
index d9a9aca1ccfdf6d5514b535241d7c5f2ae379e92..e812f5c1bf709db8edded907516c75e66e20c4b8 100644 (file)
@@ -49,7 +49,7 @@
                        label = "pb_user1";
                        gpios = <&pioE 27 GPIO_ACTIVE_HIGH>;
                        linux,code = <0x100>;
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
        };
 };
index 15bbaf690047dfb9ab0082d31b83142b63228e09..2193637b9cd2bdb4a14a13e8e48218cc04cadf01 100644 (file)
                        };
 
                        watchdog@fc068640 {
-                               compatible = "atmel,at91sam9260-wdt";
+                               compatible = "atmel,sama5d4-wdt";
                                reg = <0xfc068640 0x10>;
                                clocks = <&clk32k>;
                                status = "disabled";
index 12edafefd44a3dfb17a5aae66a3fdeb3b8788679..9beea8976584e5067d68ec895c5b9ab1d8eb7929 100644 (file)
                        label = "user_pb";
                        gpios = <&pioB 10 GPIO_ACTIVE_LOW>;
                        linux,code = <28>;
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
        };
 
index 68c0de36c339f7662b7545e072a60762b82627db..8cc6edb296942762772e5fb4e51cdc99ae219af7 100644 (file)
                        label = "user_pb";
                        gpios = <&pioB 10 GPIO_ACTIVE_LOW>;
                        linux,code = <28>;
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
        };
 
index 19fe045b83342a6ee0f55a02b1490c291b9537dd..2d7eab7552100225efcf2cb5d52a5443459f6a58 100644 (file)
@@ -18,8 +18,3 @@
                reg = <0x80000000 0x10000000>;
        };
 };
-
-&L2 {
-       arm,data-latency = <2 1 2>;
-       arm,tag-latency = <3 2 3>;
-};
index 5f8eb1bd782bf01a6454aa7cb63682835c179650..58bc6e448be5601ed8d04106fbcc193793f040f1 100644 (file)
@@ -19,7 +19,7 @@
                reg = <0x40006000 0x1000>;
                cache-unified;
                cache-level = <2>;
-               arm,data-latency = <1 1 1>;
+               arm,data-latency = <3 3 3>;
                arm,tag-latency = <2 2 2>;
        };
 };
index 6736bae43a5b09280ec824146e6caee85f787cdd..3cd1b27f269780b99d1dbc4af64644bcaa45cce5 100644 (file)
                                interrupts = <67 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks VF610_CLK_DSPI0>;
                                clock-names = "dspi";
-                               spi-num-chipselects = <5>;
+                               spi-num-chipselects = <6>;
                                status = "disabled";
                        };
 
                                interrupts = <68 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks VF610_CLK_DSPI1>;
                                clock-names = "dspi";
-                               spi-num-chipselects = <5>;
+                               spi-num-chipselects = <4>;
                                status = "disabled";
                        };
 
                                compatible = "fsl,vf610-sai";
                                reg = <0x40031000 0x1000>;
                                interrupts = <86 IRQ_TYPE_LEVEL_HIGH>;
-                               clocks = <&clks VF610_CLK_SAI2>;
-                               clock-names = "sai";
+                               clocks = <&clks VF610_CLK_SAI2>,
+                                       <&clks VF610_CLK_SAI2_DIV>,
+                                       <&clks 0>, <&clks 0>;
+                               clock-names = "bus", "mclk1", "mclk2", "mclk3";
                                dma-names = "tx", "rx";
                                dmas = <&edma0 0 21>,
                                        <&edma0 0 20>;
                                clock-names = "adc";
                                #io-channel-cells = <1>;
                                status = "disabled";
+                               fsl,adck-max-frequency = <30000000>, <40000000>,
+                                                       <20000000>;
                        };
 
                        esdhc0: esdhc@400b1000 {
                                        <&clks VF610_CLK_ESDHC0>;
                                clock-names = "ipg", "ahb", "per";
                                status = "disabled";
-                               fsl,adck-max-frequency = <30000000>, <40000000>,
-                                                       <20000000>;
                        };
 
                        esdhc1: esdhc@400b2000 {
index 1b1e5acd76e2ebd8545f5da91397366b264a989f..e4b1be66b3f56a8d0ecb2590559902bb347b539b 100644 (file)
@@ -125,7 +125,6 @@ CONFIG_POWER_RESET=y
 # CONFIG_HWMON is not set
 CONFIG_WATCHDOG=y
 CONFIG_AT91SAM9X_WATCHDOG=y
-CONFIG_SSB=m
 CONFIG_MFD_ATMEL_HLCDC=y
 CONFIG_REGULATOR=y
 CONFIG_REGULATOR_FIXED_VOLTAGE=y
index a0c57ac88b2756c0a4cdf0b9758e4df65d975833..63f7e6ce649a8630e3f5471a7fea60ee483c5496 100644 (file)
@@ -129,7 +129,6 @@ CONFIG_GPIO_SYSFS=y
 CONFIG_POWER_SUPPLY=y
 CONFIG_POWER_RESET=y
 # CONFIG_HWMON is not set
-CONFIG_SSB=m
 CONFIG_MFD_ATMEL_FLEXCOM=y
 CONFIG_REGULATOR=y
 CONFIG_REGULATOR_FIXED_VOLTAGE=y
index 6607d976e07d0998639457745ca364cf1305da85..7da5503c0591411f43df6bc767fb8c4eef314789 100644 (file)
@@ -21,6 +21,7 @@
 #ifndef __ASSEMBLY__
 
 #include <linux/io.h>
+#include <asm/barrier.h>
 
 #define __ACCESS_CP15(CRn, Op1, CRm, Op2)      p15, Op1, %0, CRn, CRm, Op2
 #define __ACCESS_CP15_64(Op1, CRm)             p15, Op1, %Q0, %R0, CRm
index be1d07d59ee9784c7b3dd12a2150a009c7c742ba..1bd9510de1b9ced64b1947f2734ddbf4c8ce4f5d 100644 (file)
@@ -40,6 +40,11 @@ extern void arch_trigger_all_cpu_backtrace(bool);
 #define arch_trigger_all_cpu_backtrace(x) arch_trigger_all_cpu_backtrace(x)
 #endif
 
+static inline int nr_legacy_irqs(void)
+{
+       return NR_IRQS_LEGACY;
+}
+
 #endif
 
 #endif
index a9c80a2ea1a779ffdbcd5d56014b1b2fbbd0381b..3095df091ff8a571cf9b6b074c56beb69ad9243d 100644 (file)
 unsigned long *vcpu_reg(struct kvm_vcpu *vcpu, u8 reg_num);
 unsigned long *vcpu_spsr(struct kvm_vcpu *vcpu);
 
+static inline unsigned long vcpu_get_reg(struct kvm_vcpu *vcpu,
+                                        u8 reg_num)
+{
+       return *vcpu_reg(vcpu, reg_num);
+}
+
+static inline void vcpu_set_reg(struct kvm_vcpu *vcpu, u8 reg_num,
+                               unsigned long val)
+{
+       *vcpu_reg(vcpu, reg_num) = val;
+}
+
 bool kvm_condition_valid(struct kvm_vcpu *vcpu);
 void kvm_skip_instr(struct kvm_vcpu *vcpu, bool is_wide_instr);
 void kvm_inject_undefined(struct kvm_vcpu *vcpu);
index 7a2a32a1d5a8c3fef87e995ac349435de1daeb6f..ede692ffa32ed14958f81eec0d7caac8f7efe853 100644 (file)
 #define __NR_execveat                  (__NR_SYSCALL_BASE+387)
 #define __NR_userfaultfd               (__NR_SYSCALL_BASE+388)
 #define __NR_membarrier                        (__NR_SYSCALL_BASE+389)
+#define __NR_mlock2                    (__NR_SYSCALL_BASE+390)
 
 /*
  * The following SWIs are ARM private.
index 6551d28c27e687068bc69af093a9a97805362d46..066f7f9ba411e09b5e492a84f03034b86305e38f 100644 (file)
 #include <asm/mach/pci.h>
 
 static int debug_pci;
-static resource_size_t (*align_resource)(struct pci_dev *dev,
-                 const struct resource *res,
-                 resource_size_t start,
-                 resource_size_t size,
-                 resource_size_t align) = NULL;
 
 /*
  * We can't use pci_get_device() here since we are
@@ -461,7 +456,6 @@ static void pcibios_init_hw(struct device *parent, struct hw_pci *hw,
                sys->busnr   = busnr;
                sys->swizzle = hw->swizzle;
                sys->map_irq = hw->map_irq;
-               align_resource = hw->align_resource;
                INIT_LIST_HEAD(&sys->resources);
 
                if (hw->private_data)
@@ -470,6 +464,8 @@ static void pcibios_init_hw(struct device *parent, struct hw_pci *hw,
                ret = hw->setup(nr, sys);
 
                if (ret > 0) {
+                       struct pci_host_bridge *host_bridge;
+
                        ret = pcibios_init_resources(nr, sys);
                        if (ret)  {
                                kfree(sys);
@@ -491,6 +487,9 @@ static void pcibios_init_hw(struct device *parent, struct hw_pci *hw,
                        busnr = sys->bus->busn_res.end + 1;
 
                        list_add(&sys->node, head);
+
+                       host_bridge = pci_find_host_bridge(sys->bus);
+                       host_bridge->align_resource = hw->align_resource;
                } else {
                        kfree(sys);
                        if (ret < 0)
@@ -578,14 +577,18 @@ resource_size_t pcibios_align_resource(void *data, const struct resource *res,
 {
        struct pci_dev *dev = data;
        resource_size_t start = res->start;
+       struct pci_host_bridge *host_bridge;
 
        if (res->flags & IORESOURCE_IO && start & 0x300)
                start = (start + 0x3ff) & ~0x3ff;
 
        start = (start + align - 1) & ~(align - 1);
 
-       if (align_resource)
-               return align_resource(dev, res, start, size, align);
+       host_bridge = pci_find_host_bridge(dev->bus);
+
+       if (host_bridge->align_resource)
+               return host_bridge->align_resource(dev, res,
+                               start, size, align);
 
        return start;
 }
index fde6c88d560cffcf8d1433fe486695e763704ca9..ac368bb068d1409af37a8e2585bb837b1ef1f02b 100644 (file)
                CALL(sys_execveat)
                CALL(sys_userfaultfd)
                CALL(sys_membarrier)
+               CALL(sys_mlock2)
 #ifndef syscalls_counted
 .equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls
 #define syscalls_counted
index eab83b2435b8b8ed2abc6342e3a22e19da80d623..e06fd299de0846b44b72cd037eacd05b0b2cb051 100644 (file)
@@ -563,18 +563,13 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
                if (vcpu->arch.power_off || vcpu->arch.pause)
                        vcpu_sleep(vcpu);
 
-               /*
-                * Disarming the background timer must be done in a
-                * preemptible context, as this call may sleep.
-                */
-               kvm_timer_flush_hwstate(vcpu);
-
                /*
                 * Preparing the interrupts to be injected also
                 * involves poking the GIC, which must be done in a
                 * non-preemptible context.
                 */
                preempt_disable();
+               kvm_timer_flush_hwstate(vcpu);
                kvm_vgic_flush_hwstate(vcpu);
 
                local_irq_disable();
index 974b1c606d044c239bfa14ffbdf66f0fc982c4fb..3a10c9f1d0a46b68b42d2e7c311a7dbd6ecd44a0 100644 (file)
@@ -115,7 +115,7 @@ int kvm_handle_mmio_return(struct kvm_vcpu *vcpu, struct kvm_run *run)
                trace_kvm_mmio(KVM_TRACE_MMIO_READ, len, run->mmio.phys_addr,
                               data);
                data = vcpu_data_host_to_guest(vcpu, data, len);
-               *vcpu_reg(vcpu, vcpu->arch.mmio_decode.rt) = data;
+               vcpu_set_reg(vcpu, vcpu->arch.mmio_decode.rt, data);
        }
 
        return 0;
@@ -186,7 +186,8 @@ int io_mem_abort(struct kvm_vcpu *vcpu, struct kvm_run *run,
        rt = vcpu->arch.mmio_decode.rt;
 
        if (is_write) {
-               data = vcpu_data_guest_to_host(vcpu, *vcpu_reg(vcpu, rt), len);
+               data = vcpu_data_guest_to_host(vcpu, vcpu_get_reg(vcpu, rt),
+                                              len);
 
                trace_kvm_mmio(KVM_TRACE_MMIO_WRITE, len, fault_ipa, data);
                mmio_write_buf(data_buf, len, data);
index 6984342da13d09fd0194563f4b598cfb913ec6c1..61d96a645ff38aa6e304eea5a198373958fe69cb 100644 (file)
@@ -98,6 +98,11 @@ static void kvm_flush_dcache_pud(pud_t pud)
        __kvm_flush_dcache_pud(pud);
 }
 
+static bool kvm_is_device_pfn(unsigned long pfn)
+{
+       return !pfn_valid(pfn);
+}
+
 /**
  * stage2_dissolve_pmd() - clear and flush huge PMD entry
  * @kvm:       pointer to kvm structure.
@@ -213,7 +218,7 @@ static void unmap_ptes(struct kvm *kvm, pmd_t *pmd,
                        kvm_tlb_flush_vmid_ipa(kvm, addr);
 
                        /* No need to invalidate the cache for device mappings */
-                       if ((pte_val(old_pte) & PAGE_S2_DEVICE) != PAGE_S2_DEVICE)
+                       if (!kvm_is_device_pfn(pte_pfn(old_pte)))
                                kvm_flush_dcache_pte(old_pte);
 
                        put_page(virt_to_page(pte));
@@ -305,8 +310,7 @@ static void stage2_flush_ptes(struct kvm *kvm, pmd_t *pmd,
 
        pte = pte_offset_kernel(pmd, addr);
        do {
-               if (!pte_none(*pte) &&
-                   (pte_val(*pte) & PAGE_S2_DEVICE) != PAGE_S2_DEVICE)
+               if (!pte_none(*pte) && !kvm_is_device_pfn(pte_pfn(*pte)))
                        kvm_flush_dcache_pte(*pte);
        } while (pte++, addr += PAGE_SIZE, addr != end);
 }
@@ -1037,11 +1041,6 @@ static bool kvm_is_write_fault(struct kvm_vcpu *vcpu)
        return kvm_vcpu_dabt_iswrite(vcpu);
 }
 
-static bool kvm_is_device_pfn(unsigned long pfn)
-{
-       return !pfn_valid(pfn);
-}
-
 /**
  * stage2_wp_ptes - write protect PMD range
  * @pmd:       pointer to pmd entry
index 0b556968a6da1e97e4b6232d1dd8e588a13bfa9e..a9b3b905e661dec55672e459f1119b3eb466b373 100644 (file)
@@ -75,7 +75,7 @@ static unsigned long kvm_psci_vcpu_on(struct kvm_vcpu *source_vcpu)
        unsigned long context_id;
        phys_addr_t target_pc;
 
-       cpu_id = *vcpu_reg(source_vcpu, 1) & MPIDR_HWID_BITMASK;
+       cpu_id = vcpu_get_reg(source_vcpu, 1) & MPIDR_HWID_BITMASK;
        if (vcpu_mode_is_32bit(source_vcpu))
                cpu_id &= ~((u32) 0);
 
@@ -94,8 +94,8 @@ static unsigned long kvm_psci_vcpu_on(struct kvm_vcpu *source_vcpu)
                        return PSCI_RET_INVALID_PARAMS;
        }
 
-       target_pc = *vcpu_reg(source_vcpu, 2);
-       context_id = *vcpu_reg(source_vcpu, 3);
+       target_pc = vcpu_get_reg(source_vcpu, 2);
+       context_id = vcpu_get_reg(source_vcpu, 3);
 
        kvm_reset_vcpu(vcpu);
 
@@ -114,7 +114,7 @@ static unsigned long kvm_psci_vcpu_on(struct kvm_vcpu *source_vcpu)
         * NOTE: We always update r0 (or x0) because for PSCI v0.1
         * the general puspose registers are undefined upon CPU_ON.
         */
-       *vcpu_reg(vcpu, 0) = context_id;
+       vcpu_set_reg(vcpu, 0, context_id);
        vcpu->arch.power_off = false;
        smp_mb();               /* Make sure the above is visible */
 
@@ -134,8 +134,8 @@ static unsigned long kvm_psci_vcpu_affinity_info(struct kvm_vcpu *vcpu)
        struct kvm *kvm = vcpu->kvm;
        struct kvm_vcpu *tmp;
 
-       target_affinity = *vcpu_reg(vcpu, 1);
-       lowest_affinity_level = *vcpu_reg(vcpu, 2);
+       target_affinity = vcpu_get_reg(vcpu, 1);
+       lowest_affinity_level = vcpu_get_reg(vcpu, 2);
 
        /* Determine target affinity mask */
        target_affinity_mask = psci_affinity_mask(lowest_affinity_level);
@@ -209,7 +209,7 @@ int kvm_psci_version(struct kvm_vcpu *vcpu)
 static int kvm_psci_0_2_call(struct kvm_vcpu *vcpu)
 {
        int ret = 1;
-       unsigned long psci_fn = *vcpu_reg(vcpu, 0) & ~((u32) 0);
+       unsigned long psci_fn = vcpu_get_reg(vcpu, 0) & ~((u32) 0);
        unsigned long val;
 
        switch (psci_fn) {
@@ -273,13 +273,13 @@ static int kvm_psci_0_2_call(struct kvm_vcpu *vcpu)
                break;
        }
 
-       *vcpu_reg(vcpu, 0) = val;
+       vcpu_set_reg(vcpu, 0, val);
        return ret;
 }
 
 static int kvm_psci_0_1_call(struct kvm_vcpu *vcpu)
 {
-       unsigned long psci_fn = *vcpu_reg(vcpu, 0) & ~((u32) 0);
+       unsigned long psci_fn = vcpu_get_reg(vcpu, 0) & ~((u32) 0);
        unsigned long val;
 
        switch (psci_fn) {
@@ -295,7 +295,7 @@ static int kvm_psci_0_1_call(struct kvm_vcpu *vcpu)
                break;
        }
 
-       *vcpu_reg(vcpu, 0) = val;
+       vcpu_set_reg(vcpu, 0, val);
        return 1;
 }
 
index 92673006e55c410ad27f60675c8e74bbf1433861..28656c2b54a0baadcc0aeaa6564cd1d91b592259 100644 (file)
@@ -4,7 +4,6 @@ menuconfig ARCH_AT91
        select ARCH_REQUIRE_GPIOLIB
        select COMMON_CLK_AT91
        select PINCTRL
-       select PINCTRL_AT91
        select SOC_BUS
 
 if ARCH_AT91
@@ -17,6 +16,7 @@ config SOC_SAMA5D2
        select HAVE_AT91_USB_CLK
        select HAVE_AT91_H32MX
        select HAVE_AT91_GENERATED_CLK
+       select PINCTRL_AT91PIO4
        help
          Select this if ou are using one of Atmel's SAMA5D2 family SoC.
 
@@ -27,6 +27,7 @@ config SOC_SAMA5D3
        select HAVE_AT91_UTMI
        select HAVE_AT91_SMD
        select HAVE_AT91_USB_CLK
+       select PINCTRL_AT91
        help
          Select this if you are using one of Atmel's SAMA5D3 family SoC.
          This support covers SAMA5D31, SAMA5D33, SAMA5D34, SAMA5D35, SAMA5D36.
@@ -40,6 +41,7 @@ config SOC_SAMA5D4
        select HAVE_AT91_SMD
        select HAVE_AT91_USB_CLK
        select HAVE_AT91_H32MX
+       select PINCTRL_AT91
        help
          Select this if you are using one of Atmel's SAMA5D4 family SoC.
 
@@ -50,6 +52,7 @@ config SOC_AT91RM9200
        select CPU_ARM920T
        select HAVE_AT91_USB_CLK
        select MIGHT_HAVE_PCI
+       select PINCTRL_AT91
        select SOC_SAM_V4_V5
        select SRAM if PM
        help
@@ -65,6 +68,7 @@ config SOC_AT91SAM9
        select HAVE_AT91_UTMI
        select HAVE_FB_ATMEL
        select MEMORY
+       select PINCTRL_AT91
        select SOC_SAM_V4_V5
        select SRAM if PM
        help
index 80e277cfcc8b6965d954473d877b66f91cdec52c..23726fb31741ea1479733ef91e88ac5585f7fe52 100644 (file)
  * implementation should be moved down into the pinctrl driver and get
  * called as part of the generic suspend/resume path.
  */
+#ifdef CONFIG_PINCTRL_AT91
 extern void at91_pinctrl_gpio_suspend(void);
 extern void at91_pinctrl_gpio_resume(void);
+#endif
 
 static struct {
        unsigned long uhp_udp_mask;
@@ -151,8 +153,9 @@ static void at91_pm_suspend(suspend_state_t state)
 
 static int at91_pm_enter(suspend_state_t state)
 {
+#ifdef CONFIG_PINCTRL_AT91
        at91_pinctrl_gpio_suspend();
-
+#endif
        switch (state) {
        /*
         * Suspend-to-RAM is like STANDBY plus slow clock mode, so
@@ -192,7 +195,9 @@ static int at91_pm_enter(suspend_state_t state)
 error:
        target_state = PM_SUSPEND_ON;
 
+#ifdef CONFIG_PINCTRL_AT91
        at91_pinctrl_gpio_resume();
+#endif
        return 0;
 }
 
index 72d622baaad3165ee3e920e6c5fc774e79cf26c5..df1d44bdc375b8c053ca258aa6e6027697e9fc98 100644 (file)
        @ check low interrupts
        ldr     \irqstat, [\base, #IRQ_CAUSE_LOW_OFF]
        ldr     \tmp, [\base, #IRQ_MASK_LOW_OFF]
-       mov     \irqnr, #31
+       mov     \irqnr, #32
        ands    \irqstat, \irqstat, \tmp
 
        @ if no low interrupts set, check high interrupts
        ldreq   \irqstat, [\base, #IRQ_CAUSE_HIGH_OFF]
        ldreq   \tmp, [\base, #IRQ_MASK_HIGH_OFF]
-       moveq   \irqnr, #63
+       moveq   \irqnr, #64
        andeqs  \irqstat, \irqstat, \tmp
 
        @ find first active interrupt source
index de68938ee6aa89a070c910c6de1cf1f5035cf0a4..c21e41dad19c14a66b83bcee65af4b504d8172c7 100644 (file)
@@ -748,8 +748,12 @@ static void exynos5_powerdown_conf(enum sys_powerdown mode)
 void exynos_sys_powerdown_conf(enum sys_powerdown mode)
 {
        unsigned int i;
+       const struct exynos_pmu_data *pmu_data;
+
+       if (!pmu_context)
+               return;
 
-       const struct exynos_pmu_data *pmu_data = pmu_context->pmu_data;
+       pmu_data = pmu_context->pmu_data;
 
        if (pmu_data->powerdown_conf)
                pmu_data->powerdown_conf(mode);
index 8e7976a4c3e723e1b27a08928700bac2b6cb9a09..cfc696b972f323e07b5e9a180755130e63e5e1b2 100644 (file)
@@ -177,6 +177,7 @@ static struct irq_chip imx_gpc_chip = {
        .irq_unmask             = imx_gpc_irq_unmask,
        .irq_retrigger          = irq_chip_retrigger_hierarchy,
        .irq_set_wake           = imx_gpc_irq_set_wake,
+       .irq_set_type           = irq_chip_set_type_parent,
 #ifdef CONFIG_SMP
        .irq_set_affinity       = irq_chip_set_affinity_parent,
 #endif
index b024390199639ca31201730ccdbcfceae577be2b..7a0c13bf42694b724e0fcb35439070eefde0a646 100644 (file)
@@ -143,7 +143,7 @@ static inline void __indirect_writesl(volatile void __iomem *bus_addr,
                writel(*vaddr++, bus_addr);
 }
 
-static inline unsigned char __indirect_readb(const volatile void __iomem *p)
+static inline u8 __indirect_readb(const volatile void __iomem *p)
 {
        u32 addr = (u32)p;
        u32 n, byte_enables, data;
@@ -166,7 +166,7 @@ static inline void __indirect_readsb(const volatile void __iomem *bus_addr,
                *vaddr++ = readb(bus_addr);
 }
 
-static inline unsigned short __indirect_readw(const volatile void __iomem *p)
+static inline u16 __indirect_readw(const volatile void __iomem *p)
 {
        u32 addr = (u32)p;
        u32 n, byte_enables, data;
@@ -189,7 +189,7 @@ static inline void __indirect_readsw(const volatile void __iomem *bus_addr,
                *vaddr++ = readw(bus_addr);
 }
 
-static inline unsigned long __indirect_readl(const volatile void __iomem *p)
+static inline u32 __indirect_readl(const volatile void __iomem *p)
 {
        u32 addr = (__force u32)p;
        u32 data;
@@ -350,7 +350,7 @@ static inline void insl(u32 io_addr, void *p, u32 count)
                                        ((unsigned long)p <= (PIO_MASK + PIO_OFFSET)))
 
 #define        ioread8(p)                      ioread8(p)
-static inline unsigned int ioread8(const void __iomem *addr)
+static inline u8 ioread8(const void __iomem *addr)
 {
        unsigned long port = (unsigned long __force)addr;
        if (__is_io_address(port))
@@ -378,7 +378,7 @@ static inline void ioread8_rep(const void __iomem *addr, void *vaddr, u32 count)
 }
 
 #define        ioread16(p)                     ioread16(p)
-static inline unsigned int ioread16(const void __iomem *addr)
+static inline u16 ioread16(const void __iomem *addr)
 {
        unsigned long port = (unsigned long __force)addr;
        if (__is_io_address(port))
@@ -407,7 +407,7 @@ static inline void ioread16_rep(const void __iomem *addr, void *vaddr,
 }
 
 #define        ioread32(p)                     ioread32(p)
-static inline unsigned int ioread32(const void __iomem *addr)
+static inline u32 ioread32(const void __iomem *addr)
 {
        unsigned long port = (unsigned long __force)addr;
        if (__is_io_address(port))
index 5076d3f334d28753e697b9e801b050c5807cadad..4b4371db5799cc8c5d726281e0834277304404f5 100644 (file)
@@ -121,6 +121,7 @@ config ARCH_OMAP2PLUS_TYPICAL
        select NEON if CPU_V7
        select PM
        select REGULATOR
+       select REGULATOR_FIXED_VOLTAGE
        select TWL4030_CORE if ARCH_OMAP3 || ARCH_OMAP4
        select TWL4030_POWER if ARCH_OMAP3 || ARCH_OMAP4
        select VFP
@@ -201,7 +202,6 @@ config MACH_OMAP3_PANDORA
        depends on ARCH_OMAP3
        default y
        select OMAP_PACKAGE_CBB
-       select REGULATOR_FIXED_VOLTAGE if REGULATOR
 
 config MACH_NOKIA_N810
        bool
index 5305ec7341eca5579398a10b72f263a2fbbe8e0e..79e1f876d1c9b9f28dc862e013e7bc657153fd4f 100644 (file)
@@ -143,9 +143,9 @@ static int omap4_boot_secondary(unsigned int cpu, struct task_struct *idle)
                 * Ensure that CPU power state is set to ON to avoid CPU
                 * powerdomain transition on wfi
                 */
-               clkdm_wakeup(cpu1_clkdm);
-               omap_set_pwrdm_state(cpu1_pwrdm, PWRDM_POWER_ON);
-               clkdm_allow_idle(cpu1_clkdm);
+               clkdm_wakeup_nolock(cpu1_clkdm);
+               pwrdm_set_next_pwrst(cpu1_pwrdm, PWRDM_POWER_ON);
+               clkdm_allow_idle_nolock(cpu1_clkdm);
 
                if (IS_PM44XX_ERRATUM(PM_OMAP4_ROM_SMP_BOOT_ERRATUM_GICD)) {
                        while (gic_dist_disabled()) {
index cc8a987149e2737db4bf255075d5baf3bc2b2bb0..48495ad82aba16775ff2108ead31ceb820a023b5 100644 (file)
@@ -890,6 +890,36 @@ static int _init_opt_clks(struct omap_hwmod *oh)
        return ret;
 }
 
+static void _enable_optional_clocks(struct omap_hwmod *oh)
+{
+       struct omap_hwmod_opt_clk *oc;
+       int i;
+
+       pr_debug("omap_hwmod: %s: enabling optional clocks\n", oh->name);
+
+       for (i = oh->opt_clks_cnt, oc = oh->opt_clks; i > 0; i--, oc++)
+               if (oc->_clk) {
+                       pr_debug("omap_hwmod: enable %s:%s\n", oc->role,
+                                __clk_get_name(oc->_clk));
+                       clk_enable(oc->_clk);
+               }
+}
+
+static void _disable_optional_clocks(struct omap_hwmod *oh)
+{
+       struct omap_hwmod_opt_clk *oc;
+       int i;
+
+       pr_debug("omap_hwmod: %s: disabling optional clocks\n", oh->name);
+
+       for (i = oh->opt_clks_cnt, oc = oh->opt_clks; i > 0; i--, oc++)
+               if (oc->_clk) {
+                       pr_debug("omap_hwmod: disable %s:%s\n", oc->role,
+                                __clk_get_name(oc->_clk));
+                       clk_disable(oc->_clk);
+               }
+}
+
 /**
  * _enable_clocks - enable hwmod main clock and interface clocks
  * @oh: struct omap_hwmod *
@@ -917,6 +947,9 @@ static int _enable_clocks(struct omap_hwmod *oh)
                        clk_enable(os->_clk);
        }
 
+       if (oh->flags & HWMOD_OPT_CLKS_NEEDED)
+               _enable_optional_clocks(oh);
+
        /* The opt clocks are controlled by the device driver. */
 
        return 0;
@@ -948,41 +981,14 @@ static int _disable_clocks(struct omap_hwmod *oh)
                        clk_disable(os->_clk);
        }
 
+       if (oh->flags & HWMOD_OPT_CLKS_NEEDED)
+               _disable_optional_clocks(oh);
+
        /* The opt clocks are controlled by the device driver. */
 
        return 0;
 }
 
-static void _enable_optional_clocks(struct omap_hwmod *oh)
-{
-       struct omap_hwmod_opt_clk *oc;
-       int i;
-
-       pr_debug("omap_hwmod: %s: enabling optional clocks\n", oh->name);
-
-       for (i = oh->opt_clks_cnt, oc = oh->opt_clks; i > 0; i--, oc++)
-               if (oc->_clk) {
-                       pr_debug("omap_hwmod: enable %s:%s\n", oc->role,
-                                __clk_get_name(oc->_clk));
-                       clk_enable(oc->_clk);
-               }
-}
-
-static void _disable_optional_clocks(struct omap_hwmod *oh)
-{
-       struct omap_hwmod_opt_clk *oc;
-       int i;
-
-       pr_debug("omap_hwmod: %s: disabling optional clocks\n", oh->name);
-
-       for (i = oh->opt_clks_cnt, oc = oh->opt_clks; i > 0; i--, oc++)
-               if (oc->_clk) {
-                       pr_debug("omap_hwmod: disable %s:%s\n", oc->role,
-                                __clk_get_name(oc->_clk));
-                       clk_disable(oc->_clk);
-               }
-}
-
 /**
  * _omap4_enable_module - enable CLKCTRL modulemode on OMAP4
  * @oh: struct omap_hwmod *
index ca6df1a734756fa6640067b9158dc1112e37b2a1..76bce11c85a40c477a5b87aab919d5b8dfded5e8 100644 (file)
@@ -523,6 +523,8 @@ struct omap_hwmod_omap4_prcm {
  * HWMOD_RECONFIG_IO_CHAIN: omap_hwmod code needs to reconfigure wake-up 
  *     events by calling _reconfigure_io_chain() when a device is enabled
  *     or idled.
+ * HWMOD_OPT_CLKS_NEEDED: The optional clocks are needed for the module to
+ *     operate and they need to be handled at the same time as the main_clk.
  */
 #define HWMOD_SWSUP_SIDLE                      (1 << 0)
 #define HWMOD_SWSUP_MSTANDBY                   (1 << 1)
@@ -538,6 +540,7 @@ struct omap_hwmod_omap4_prcm {
 #define HWMOD_FORCE_MSTANDBY                   (1 << 11)
 #define HWMOD_SWSUP_SIDLE_ACT                  (1 << 12)
 #define HWMOD_RECONFIG_IO_CHAIN                        (1 << 13)
+#define HWMOD_OPT_CLKS_NEEDED                  (1 << 14)
 
 /*
  * omap_hwmod._int_flags definitions
index 51d1ecb384bdddb95c1996258de93ee9ba9b85ec..ee4e04434a943ea573210fb2468ba29a36232f07 100644 (file)
@@ -1297,6 +1297,44 @@ static struct omap_hwmod dra7xx_mcspi4_hwmod = {
        .dev_attr       = &mcspi4_dev_attr,
 };
 
+/*
+ * 'mcasp' class
+ *
+ */
+static struct omap_hwmod_class_sysconfig dra7xx_mcasp_sysc = {
+       .sysc_offs      = 0x0004,
+       .sysc_flags     = SYSC_HAS_SIDLEMODE,
+       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+       .sysc_fields    = &omap_hwmod_sysc_type3,
+};
+
+static struct omap_hwmod_class dra7xx_mcasp_hwmod_class = {
+       .name   = "mcasp",
+       .sysc   = &dra7xx_mcasp_sysc,
+};
+
+/* mcasp3 */
+static struct omap_hwmod_opt_clk mcasp3_opt_clks[] = {
+       { .role = "ahclkx", .clk = "mcasp3_ahclkx_mux" },
+};
+
+static struct omap_hwmod dra7xx_mcasp3_hwmod = {
+       .name           = "mcasp3",
+       .class          = &dra7xx_mcasp_hwmod_class,
+       .clkdm_name     = "l4per2_clkdm",
+       .main_clk       = "mcasp3_aux_gfclk_mux",
+       .flags          = HWMOD_OPT_CLKS_NEEDED,
+       .prcm = {
+               .omap4 = {
+                       .clkctrl_offs = DRA7XX_CM_L4PER2_MCASP3_CLKCTRL_OFFSET,
+                       .context_offs = DRA7XX_RM_L4PER2_MCASP3_CONTEXT_OFFSET,
+                       .modulemode   = MODULEMODE_SWCTRL,
+               },
+       },
+       .opt_clks       = mcasp3_opt_clks,
+       .opt_clks_cnt   = ARRAY_SIZE(mcasp3_opt_clks),
+};
+
 /*
  * 'mmc' class
  *
@@ -2566,6 +2604,22 @@ static struct omap_hwmod_ocp_if dra7xx_l3_main_1__hdmi = {
        .user           = OCP_USER_MPU | OCP_USER_SDMA,
 };
 
+/* l4_per2 -> mcasp3 */
+static struct omap_hwmod_ocp_if dra7xx_l4_per2__mcasp3 = {
+       .master         = &dra7xx_l4_per2_hwmod,
+       .slave          = &dra7xx_mcasp3_hwmod,
+       .clk            = "l4_root_clk_div",
+       .user           = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l3_main_1 -> mcasp3 */
+static struct omap_hwmod_ocp_if dra7xx_l3_main_1__mcasp3 = {
+       .master         = &dra7xx_l3_main_1_hwmod,
+       .slave          = &dra7xx_mcasp3_hwmod,
+       .clk            = "l3_iclk_div",
+       .user           = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
 /* l4_per1 -> elm */
 static struct omap_hwmod_ocp_if dra7xx_l4_per1__elm = {
        .master         = &dra7xx_l4_per1_hwmod,
@@ -3308,6 +3362,8 @@ static struct omap_hwmod_ocp_if *dra7xx_hwmod_ocp_ifs[] __initdata = {
        &dra7xx_l4_wkup__dcan1,
        &dra7xx_l4_per2__dcan2,
        &dra7xx_l4_per2__cpgmac0,
+       &dra7xx_l4_per2__mcasp3,
+       &dra7xx_l3_main_1__mcasp3,
        &dra7xx_gmac__mdio,
        &dra7xx_l4_cfg__dma_system,
        &dra7xx_l3_main_1__dss,
index b1288f56d5095b4ad782e81b0453c9094ec47ac1..6256052893ec7b1453c3d0afb6e392c321040567 100644 (file)
@@ -144,6 +144,7 @@ static struct omap_hwmod dm81xx_l4_ls_hwmod = {
        .name           = "l4_ls",
        .clkdm_name     = "alwon_l3s_clkdm",
        .class          = &l4_hwmod_class,
+       .flags          = HWMOD_NO_IDLEST,
 };
 
 /*
@@ -155,6 +156,7 @@ static struct omap_hwmod dm81xx_l4_hs_hwmod = {
        .name           = "l4_hs",
        .clkdm_name     = "alwon_l3_med_clkdm",
        .class          = &l4_hwmod_class,
+       .flags          = HWMOD_NO_IDLEST,
 };
 
 /* L3 slow -> L4 ls peripheral interface running at 125MHz */
@@ -850,6 +852,7 @@ static struct omap_hwmod dm816x_emac0_hwmod = {
        .name           = "emac0",
        .clkdm_name     = "alwon_ethernet_clkdm",
        .class          = &dm816x_emac_hwmod_class,
+       .flags          = HWMOD_NO_IDLEST,
 };
 
 static struct omap_hwmod_ocp_if dm81xx_l4_hs__emac0 = {
index 1dfe34654c43a353a34ac2cb9b941ff9f951b275..58144779dec4c118aac35f60cab6f0c33a68929a 100644 (file)
@@ -24,9 +24,6 @@
 #include <linux/platform_data/iommu-omap.h>
 #include <linux/platform_data/wkup_m3.h>
 
-#include <asm/siginfo.h>
-#include <asm/signal.h>
-
 #include "common.h"
 #include "common-board-devices.h"
 #include "dss-common.h"
@@ -385,29 +382,6 @@ static void __init omap3_pandora_legacy_init(void)
 }
 #endif /* CONFIG_ARCH_OMAP3 */
 
-#ifdef CONFIG_SOC_TI81XX
-static int fault_fixed_up;
-
-static int t410_abort_handler(unsigned long addr, unsigned int fsr,
-                             struct pt_regs *regs)
-{
-       if ((fsr == 0x406 || fsr == 0xc06) && !fault_fixed_up) {
-               pr_warn("External imprecise Data abort at addr=%#lx, fsr=%#x ignored.\n",
-                       addr, fsr);
-               fault_fixed_up = 1;
-               return 0;
-       }
-
-       return 1;
-}
-
-static void __init t410_abort_init(void)
-{
-       hook_fault_code(16 + 6, t410_abort_handler, SIGBUS, BUS_OBJERR,
-                       "imprecise external abort");
-}
-#endif
-
 #if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5)
 static struct iommu_platform_data omap4_iommu_pdata = {
        .reset_name = "mmu_cache",
@@ -536,9 +510,6 @@ static struct pdata_init pdata_quirks[] __initdata = {
        { "openpandora,omap3-pandora-600mhz", omap3_pandora_legacy_init, },
        { "openpandora,omap3-pandora-1ghz", omap3_pandora_legacy_init, },
 #endif
-#ifdef CONFIG_SOC_TI81XX
-       { "hp,t410", t410_abort_init, },
-#endif
 #ifdef CONFIG_SOC_OMAP5
        { "ti,omap5-uevm", omap5_uevm_legacy_init, },
 #endif
index 87b98bf92366f4f816ca4f53a32ecae305930016..2dbd3785ee6f0d00b4c3d88bada28d83c0203b2a 100644 (file)
@@ -301,11 +301,11 @@ static void omap3_pm_idle(void)
        if (omap_irq_pending())
                return;
 
-       trace_cpu_idle(1, smp_processor_id());
+       trace_cpu_idle_rcuidle(1, smp_processor_id());
 
        omap_sram_idle();
 
-       trace_cpu_idle(PWR_EVENT_EXIT, smp_processor_id());
+       trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, smp_processor_id());
 }
 
 #ifdef CONFIG_SUSPEND
index 79eb502a1e64a67a7b716d0b31d7db0903aeab9f..73919a36b5775f1facd9cde91be9ef872ab7e18e 100644 (file)
@@ -21,5 +21,5 @@
        @ find cause bits that are unmasked
        ands    \irqstat, \irqstat, \tmp        @ clear Z flag if any
        clzne   \irqnr, \irqstat                @ calc irqnr
-       rsbne   \irqnr, \irqnr, #31
+       rsbne   \irqnr, \irqnr, #32
        .endm
index 9a9c15bfcd3451f02c115238813b2193db266844..7c0d5618be5e8b6f394cec5f4d797ad931675735 100644 (file)
@@ -889,6 +889,7 @@ static void __init e680_init(void)
 
        pxa_set_keypad_info(&e680_keypad_platform_data);
 
+       pwm_add_table(ezx_pwm_lookup, ARRAY_SIZE(ezx_pwm_lookup));
        platform_add_devices(ARRAY_AND_SIZE(ezx_devices));
        platform_add_devices(ARRAY_AND_SIZE(e680_devices));
 }
@@ -956,6 +957,7 @@ static void __init a1200_init(void)
 
        pxa_set_keypad_info(&a1200_keypad_platform_data);
 
+       pwm_add_table(ezx_pwm_lookup, ARRAY_SIZE(ezx_pwm_lookup));
        platform_add_devices(ARRAY_AND_SIZE(ezx_devices));
        platform_add_devices(ARRAY_AND_SIZE(a1200_devices));
 }
@@ -1148,6 +1150,7 @@ static void __init a910_init(void)
                platform_device_register(&a910_camera);
        }
 
+       pwm_add_table(ezx_pwm_lookup, ARRAY_SIZE(ezx_pwm_lookup));
        platform_add_devices(ARRAY_AND_SIZE(ezx_devices));
        platform_add_devices(ARRAY_AND_SIZE(a910_devices));
 }
@@ -1215,6 +1218,7 @@ static void __init e6_init(void)
 
        pxa_set_keypad_info(&e6_keypad_platform_data);
 
+       pwm_add_table(ezx_pwm_lookup, ARRAY_SIZE(ezx_pwm_lookup));
        platform_add_devices(ARRAY_AND_SIZE(ezx_devices));
        platform_add_devices(ARRAY_AND_SIZE(e6_devices));
 }
@@ -1256,6 +1260,7 @@ static void __init e2_init(void)
 
        pxa_set_keypad_info(&e2_keypad_platform_data);
 
+       pwm_add_table(ezx_pwm_lookup, ARRAY_SIZE(ezx_pwm_lookup));
        platform_add_devices(ARRAY_AND_SIZE(ezx_devices));
        platform_add_devices(ARRAY_AND_SIZE(e2_devices));
 }
index 13eba2b26e0aa478e7e26eb541855be091ac68e0..8fbfb10047ec30543b4ccf4c7e6787d9fd5ae5b0 100644 (file)
@@ -344,7 +344,7 @@ void __init palm27x_pwm_init(int bl, int lcd)
 {
        palm_bl_power   = bl;
        palm_lcd_power  = lcd;
-       pwm_add_lookup(palm27x_pwm_lookup, ARRAY_SIZE(palm27x_pwm_lookup));
+       pwm_add_table(palm27x_pwm_lookup, ARRAY_SIZE(palm27x_pwm_lookup));
        platform_device_register(&palm27x_backlight);
 }
 #endif
index aebf6de62468962b9398f6ee299c0539920cbba8..0b5c3876720cc3215949a6cbcf017bdf41f1eec8 100644 (file)
@@ -169,7 +169,7 @@ static inline void palmtc_keys_init(void) {}
 #if defined(CONFIG_BACKLIGHT_PWM) || defined(CONFIG_BACKLIGHT_PWM_MODULE)
 static struct pwm_lookup palmtc_pwm_lookup[] = {
        PWM_LOOKUP("pxa25x-pwm.1", 0, "pwm-backlight.0", NULL, PALMTC_PERIOD_NS,
-                  PWM_PERIOD_NORMAL),
+                  PWM_POLARITY_NORMAL),
 };
 
 static struct platform_pwm_backlight_data palmtc_backlight_data = {
index a19460e6e7b0ec9317e8db98ed9aea2cf6290421..b355fca6cc2efb1a3fccd3763c91430acb66fd69 100644 (file)
@@ -20,7 +20,7 @@
 #include <plat/cpu.h>
 #include <plat/cpu-freq-core.h>
 
-static struct cpufreq_frequency_table s3c2440_plls_12[] __initdata = {
+static struct cpufreq_frequency_table s3c2440_plls_12[] = {
        { .frequency = 75000000,        .driver_data = PLLVAL(0x75, 3, 3),  },  /* FVco 600.000000 */
        { .frequency = 80000000,        .driver_data = PLLVAL(0x98, 4, 3),  },  /* FVco 640.000000 */
        { .frequency = 90000000,        .driver_data = PLLVAL(0x70, 2, 3),  },  /* FVco 720.000000 */
index 1191b29056252e49eee5cc041e0757247dab1bdf..be9a248b5ce901b5eaed665ec4f5d75632775ebc 100644 (file)
@@ -20,7 +20,7 @@
 #include <plat/cpu.h>
 #include <plat/cpu-freq-core.h>
 
-static struct cpufreq_frequency_table s3c2440_plls_169344[] __initdata = {
+static struct cpufreq_frequency_table s3c2440_plls_169344[] = {
        { .frequency = 78019200,        .driver_data = PLLVAL(121, 5, 3),       },      /* FVco 624.153600 */
        { .frequency = 84067200,        .driver_data = PLLVAL(131, 5, 3),       },      /* FVco 672.537600 */
        { .frequency = 90115200,        .driver_data = PLLVAL(141, 5, 3),       },      /* FVco 720.921600 */
index 1d2825cb7a65050bc7b05bed4b200f3e8036349a..5fce87f7f254c2fa4b052c5ab91d11a91e2e3a15 100644 (file)
@@ -19,7 +19,7 @@
 #include "common.h"
 #include "rcar-gen2.h"
 
-static const char *r8a7793_boards_compat_dt[] __initconst = {
+static const char * const r8a7793_boards_compat_dt[] __initconst = {
        "renesas,r8a7793",
        NULL,
 };
index 7fdc5bf24f9b5c05d055f59932b285db4b85d465..446334a25cf5c6f0db61a9c10558e6c1e57b7823 100644 (file)
@@ -13,7 +13,7 @@ config SOC_ZX296702
        select ARM_GLOBAL_TIMER
        select HAVE_ARM_SCU if SMP
        select HAVE_ARM_TWD if SMP
-       select PM_GENERIC_DOMAINS
+       select PM_GENERIC_DOMAINS if PM
        help
          Support for ZTE ZX296702 SoC which is a dual core CortexA9MP
 endif
index 9ac16a482ff1e690b9b6aa66a09225cec831966b..871f21783866d5fdb1557ec56e5f13b602ba331a 100644 (file)
@@ -49,7 +49,7 @@ config ARM64
        select HAVE_ARCH_AUDITSYSCALL
        select HAVE_ARCH_BITREVERSE
        select HAVE_ARCH_JUMP_LABEL
-       select HAVE_ARCH_KASAN if SPARSEMEM_VMEMMAP
+       select HAVE_ARCH_KASAN if SPARSEMEM_VMEMMAP && !(ARM64_16K_PAGES && ARM64_VA_BITS_48)
        select HAVE_ARCH_KGDB
        select HAVE_ARCH_SECCOMP_FILTER
        select HAVE_ARCH_TRACEHOOK
@@ -316,6 +316,27 @@ config ARM64_ERRATUM_832075
 
          If unsure, say Y.
 
+config ARM64_ERRATUM_834220
+       bool "Cortex-A57: 834220: Stage 2 translation fault might be incorrectly reported in presence of a Stage 1 fault"
+       depends on KVM
+       default y
+       help
+         This option adds an alternative code sequence to work around ARM
+         erratum 834220 on Cortex-A57 parts up to r1p2.
+
+         Affected Cortex-A57 parts might report a Stage 2 translation
+         fault as the result of a Stage 1 fault for load crossing a
+         page boundary when there is a permission or device memory
+         alignment fault at Stage 1 and a translation fault at Stage 2.
+
+         The workaround is to verify that the Stage 1 translation
+         doesn't generate a fault before handling the Stage 2 fault.
+         Please note that this does not necessarily enable the workaround,
+         as it depends on the alternative framework, which will only patch
+         the kernel if an affected CPU is detected.
+
+         If unsure, say Y.
+
 config ARM64_ERRATUM_845719
        bool "Cortex-A53: 845719: a load might read incorrect data"
        depends on COMPAT
index e81cd48d6245eace97978c58057a022d105d990d..925552e7b4f3eaf6ce23fc1e8dd2d77f50073121 100644 (file)
                        clock-frequency = <0>;  /* Updated by bootloader */
                        voltage-ranges = <1800 1800 3300 3300>;
                        sdhci,auto-cmd12;
+                       little-endian;
                        bus-width = <4>;
                };
 
                        reg = <0x0 0x2300000 0x0 0x10000>;
                        interrupts = <0 36 0x4>; /* Level high type */
                        gpio-controller;
+                       little-endian;
                        #gpio-cells = <2>;
                        interrupt-controller;
                        #interrupt-cells = <2>;
                        reg = <0x0 0x2310000 0x0 0x10000>;
                        interrupts = <0 36 0x4>; /* Level high type */
                        gpio-controller;
+                       little-endian;
                        #gpio-cells = <2>;
                        interrupt-controller;
                        #interrupt-cells = <2>;
                        reg = <0x0 0x2320000 0x0 0x10000>;
                        interrupts = <0 37 0x4>; /* Level high type */
                        gpio-controller;
+                       little-endian;
                        #gpio-cells = <2>;
                        interrupt-controller;
                        #interrupt-cells = <2>;
                        reg = <0x0 0x2330000 0x0 0x10000>;
                        interrupts = <0 37 0x4>; /* Level high type */
                        gpio-controller;
+                       little-endian;
                        #gpio-cells = <2>;
                        interrupt-controller;
                        #interrupt-cells = <2>;
index 8d43a0fce5226946d78fb416037a7175efaa2e66..496a920eced4adab023499ec3e46d814bf7f259d 100644 (file)
@@ -11,6 +11,7 @@
 /memreserve/ 0x05e00000 0x00100000;
 
 #include "hi6220.dtsi"
+#include "hi6220-ion.dtsi"
 
 / {
        model = "HiKey Development Board";
diff --git a/arch/arm64/boot/dts/hisilicon/hi6220-ion.dtsi b/arch/arm64/boot/dts/hisilicon/hi6220-ion.dtsi
new file mode 100644 (file)
index 0000000..c79f2ce
--- /dev/null
@@ -0,0 +1,20 @@
+/ {
+       hi6220-ion {
+               compatible = "hisilicon,hi6220-ion";
+               heap_sys_user@0 {
+                       heap-name = "sys_user";
+                       heap-id   = <0x0>;
+                       heap-base = <0x0>;
+                       heap-size = <0x0>;
+                       heap-type = "ion_system";
+               };
+               heap_sys_contig@0 {
+                       heap-name = "sys_contig";
+                       heap-id   = <0x1>;
+                       heap-base = <0x0>;
+                       heap-size = <0x0>;
+                       heap-type = "ion_system_contig";
+               };
+       };
+
+};
index 030cdcb46c6bdabd8bb49901ed231fcdbb5c25fd..2731d3b25ed2e338e76966b5efd86658b7e22263 100644 (file)
@@ -77,6 +77,7 @@
 #ifndef __ASSEMBLY__
 
 #include <linux/stringify.h>
+#include <asm/barrier.h>
 
 /*
  * Low-level accessors
index 11d5bb0fdd541052b9cdd49197b2dc90e9ece737..8f271b83f9106c7c9753ce2601d3b59e1ffbdfc5 100644 (file)
@@ -29,8 +29,9 @@
 #define ARM64_HAS_PAN                          4
 #define ARM64_HAS_LSE_ATOMICS                  5
 #define ARM64_WORKAROUND_CAVIUM_23154          6
+#define ARM64_WORKAROUND_834220                        7
 
-#define ARM64_NCAPS                            7
+#define ARM64_NCAPS                            8
 
 #ifndef __ASSEMBLY__
 
@@ -46,8 +47,12 @@ enum ftr_type {
 #define FTR_STRICT     true    /* SANITY check strict matching required */
 #define FTR_NONSTRICT  false   /* SANITY check ignored */
 
+#define FTR_SIGNED     true    /* Value should be treated as signed */
+#define FTR_UNSIGNED   false   /* Value should be treated as unsigned */
+
 struct arm64_ftr_bits {
-       bool            strict;   /* CPU Sanity check: strict matching required ? */
+       bool            sign;   /* Value is signed ? */
+       bool            strict; /* CPU Sanity check: strict matching required ? */
        enum ftr_type   type;
        u8              shift;
        u8              width;
@@ -123,6 +128,18 @@ cpuid_feature_extract_field(u64 features, int field)
        return cpuid_feature_extract_field_width(features, field, 4);
 }
 
+static inline unsigned int __attribute_const__
+cpuid_feature_extract_unsigned_field_width(u64 features, int field, int width)
+{
+       return (u64)(features << (64 - width - field)) >> (64 - width);
+}
+
+static inline unsigned int __attribute_const__
+cpuid_feature_extract_unsigned_field(u64 features, int field)
+{
+       return cpuid_feature_extract_unsigned_field_width(features, field, 4);
+}
+
 static inline u64 arm64_ftr_mask(struct arm64_ftr_bits *ftrp)
 {
        return (u64)GENMASK(ftrp->shift + ftrp->width - 1, ftrp->shift);
@@ -130,7 +147,9 @@ static inline u64 arm64_ftr_mask(struct arm64_ftr_bits *ftrp)
 
 static inline s64 arm64_ftr_value(struct arm64_ftr_bits *ftrp, u64 val)
 {
-       return cpuid_feature_extract_field_width(val, ftrp->shift, ftrp->width);
+       return ftrp->sign ?
+               cpuid_feature_extract_field_width(val, ftrp->shift, ftrp->width) :
+               cpuid_feature_extract_unsigned_field_width(val, ftrp->shift, ftrp->width);
 }
 
 static inline bool id_aa64mmfr0_mixed_endian_el0(u64 mmfr0)
index e54415ec693571d1d4195d57b1928e2e58173353..9732908bfc8a54b546c4cab40802f70a56b36fce 100644 (file)
@@ -138,16 +138,18 @@ extern struct pmu perf_ops_bp;
 /* Determine number of BRP registers available. */
 static inline int get_num_brps(void)
 {
+       u64 dfr0 = read_system_reg(SYS_ID_AA64DFR0_EL1);
        return 1 +
-               cpuid_feature_extract_field(read_system_reg(SYS_ID_AA64DFR0_EL1),
+               cpuid_feature_extract_unsigned_field(dfr0,
                                                ID_AA64DFR0_BRPS_SHIFT);
 }
 
 /* Determine number of WRP registers available. */
 static inline int get_num_wrps(void)
 {
+       u64 dfr0 = read_system_reg(SYS_ID_AA64DFR0_EL1);
        return 1 +
-               cpuid_feature_extract_field(read_system_reg(SYS_ID_AA64DFR0_EL1),
+               cpuid_feature_extract_unsigned_field(dfr0,
                                                ID_AA64DFR0_WRPS_SHIFT);
 }
 
index 23eb450b820ba03ce83b737f308fcd3d6b33f9a8..8e8d30684392b1065b0c5d1f65e7715e4028331c 100644 (file)
@@ -7,4 +7,9 @@ struct pt_regs;
 
 extern void set_handle_irq(void (*handle_irq)(struct pt_regs *));
 
+static inline int nr_legacy_irqs(void)
+{
+       return 0;
+}
+
 #endif
index 17e92f05b1fe597ea1c4e833debf7541be0fde79..25a40213bd9b87cb6802ecfd4204dc66c41e5850 100644 (file)
@@ -99,12 +99,22 @@ static inline void vcpu_set_thumb(struct kvm_vcpu *vcpu)
        *vcpu_cpsr(vcpu) |= COMPAT_PSR_T_BIT;
 }
 
-static inline unsigned long *vcpu_reg(const struct kvm_vcpu *vcpu, u8 reg_num)
+/*
+ * vcpu_get_reg and vcpu_set_reg should always be passed a register number
+ * coming from a read of ESR_EL2. Otherwise, it may give the wrong result on
+ * AArch32 with banked registers.
+ */
+static inline unsigned long vcpu_get_reg(const struct kvm_vcpu *vcpu,
+                                        u8 reg_num)
 {
-       if (vcpu_mode_is_32bit(vcpu))
-               return vcpu_reg32(vcpu, reg_num);
+       return (reg_num == 31) ? 0 : vcpu_gp_regs(vcpu)->regs.regs[reg_num];
+}
 
-       return (unsigned long *)&vcpu_gp_regs(vcpu)->regs.regs[reg_num];
+static inline void vcpu_set_reg(struct kvm_vcpu *vcpu, u8 reg_num,
+                               unsigned long val)
+{
+       if (reg_num != 31)
+               vcpu_gp_regs(vcpu)->regs.regs[reg_num] = val;
 }
 
 /* Get vcpu SPSR for current mode */
index 7e074f93f383fea1891ce79d4048c22f647841a7..63f52b55defe1041a7913217db490528c441c6f3 100644 (file)
@@ -276,10 +276,14 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
         * hardware updates of the pte (ptep_set_access_flags safely changes
         * valid ptes without going through an invalid entry).
         */
-       if (IS_ENABLED(CONFIG_DEBUG_VM) && IS_ENABLED(CONFIG_ARM64_HW_AFDBM) &&
-           pte_valid(*ptep)) {
-               BUG_ON(!pte_young(pte));
-               BUG_ON(pte_write(*ptep) && !pte_dirty(pte));
+       if (IS_ENABLED(CONFIG_ARM64_HW_AFDBM) &&
+           pte_valid(*ptep) && pte_valid(pte)) {
+               VM_WARN_ONCE(!pte_young(pte),
+                            "%s: racy access flag clearing: 0x%016llx -> 0x%016llx",
+                            __func__, pte_val(*ptep), pte_val(pte));
+               VM_WARN_ONCE(pte_write(*ptep) && !pte_dirty(pte),
+                            "%s: racy dirty state clearing: 0x%016llx -> 0x%016llx",
+                            __func__, pte_val(*ptep), pte_val(pte));
        }
 
        set_pte(ptep, pte);
index 24926f2504f7aaf2e37a6f9ecf1692ce3fff422b..feb6b4efa6414846d5598ccb0913a544ba0cf441 100644 (file)
@@ -75,6 +75,15 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
                           (1 << MIDR_VARIANT_SHIFT) | 2),
        },
 #endif
+#ifdef CONFIG_ARM64_ERRATUM_834220
+       {
+       /* Cortex-A57 r0p0 - r1p2 */
+               .desc = "ARM erratum 834220",
+               .capability = ARM64_WORKAROUND_834220,
+               MIDR_RANGE(MIDR_CORTEX_A57, 0x00,
+                          (1 << MIDR_VARIANT_SHIFT) | 2),
+       },
+#endif
 #ifdef CONFIG_ARM64_ERRATUM_845719
        {
        /* Cortex-A53 r0p[01234] */
index c8cf89223b5a8ceb3564e77cc5a6893e5c8eb99d..0669c63281ea01a93ef9794f9731b424b6afd28e 100644 (file)
@@ -44,8 +44,9 @@ unsigned int compat_elf_hwcap2 __read_mostly;
 
 DECLARE_BITMAP(cpu_hwcaps, ARM64_NCAPS);
 
-#define ARM64_FTR_BITS(STRICT, TYPE, SHIFT, WIDTH, SAFE_VAL) \
+#define __ARM64_FTR_BITS(SIGNED, STRICT, TYPE, SHIFT, WIDTH, SAFE_VAL) \
        {                                               \
+               .sign = SIGNED,                         \
                .strict = STRICT,                       \
                .type = TYPE,                           \
                .shift = SHIFT,                         \
@@ -53,6 +54,14 @@ DECLARE_BITMAP(cpu_hwcaps, ARM64_NCAPS);
                .safe_val = SAFE_VAL,                   \
        }
 
+/* Define a feature with signed values */
+#define ARM64_FTR_BITS(STRICT, TYPE, SHIFT, WIDTH, SAFE_VAL) \
+       __ARM64_FTR_BITS(FTR_SIGNED, STRICT, TYPE, SHIFT, WIDTH, SAFE_VAL)
+
+/* Define a feature with unsigned value */
+#define U_ARM64_FTR_BITS(STRICT, TYPE, SHIFT, WIDTH, SAFE_VAL) \
+       __ARM64_FTR_BITS(FTR_UNSIGNED, STRICT, TYPE, SHIFT, WIDTH, SAFE_VAL)
+
 #define ARM64_FTR_END                                  \
        {                                               \
                .width = 0,                             \
@@ -99,7 +108,7 @@ static struct arm64_ftr_bits ftr_id_aa64mmfr0[] = {
         * Differing PARange is fine as long as all peripherals and memory are mapped
         * within the minimum PARange of all CPUs
         */
-       ARM64_FTR_BITS(FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64MMFR0_PARANGE_SHIFT, 4, 0),
+       U_ARM64_FTR_BITS(FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64MMFR0_PARANGE_SHIFT, 4, 0),
        ARM64_FTR_END,
 };
 
@@ -115,18 +124,18 @@ static struct arm64_ftr_bits ftr_id_aa64mmfr1[] = {
 };
 
 static struct arm64_ftr_bits ftr_ctr[] = {
-       ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 31, 1, 1),        /* RAO */
+       U_ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 31, 1, 1),      /* RAO */
        ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 28, 3, 0),
-       ARM64_FTR_BITS(FTR_STRICT, FTR_HIGHER_SAFE, 24, 4, 0),  /* CWG */
-       ARM64_FTR_BITS(FTR_STRICT, FTR_LOWER_SAFE, 20, 4, 0),   /* ERG */
-       ARM64_FTR_BITS(FTR_STRICT, FTR_LOWER_SAFE, 16, 4, 1),   /* DminLine */
+       U_ARM64_FTR_BITS(FTR_STRICT, FTR_HIGHER_SAFE, 24, 4, 0),        /* CWG */
+       U_ARM64_FTR_BITS(FTR_STRICT, FTR_LOWER_SAFE, 20, 4, 0), /* ERG */
+       U_ARM64_FTR_BITS(FTR_STRICT, FTR_LOWER_SAFE, 16, 4, 1), /* DminLine */
        /*
         * Linux can handle differing I-cache policies. Userspace JITs will
         * make use of *minLine
         */
-       ARM64_FTR_BITS(FTR_NONSTRICT, FTR_EXACT, 14, 2, 0),     /* L1Ip */
+       U_ARM64_FTR_BITS(FTR_NONSTRICT, FTR_EXACT, 14, 2, 0),   /* L1Ip */
        ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 4, 10, 0),        /* RAZ */
-       ARM64_FTR_BITS(FTR_STRICT, FTR_LOWER_SAFE, 0, 4, 0),    /* IminLine */
+       U_ARM64_FTR_BITS(FTR_STRICT, FTR_LOWER_SAFE, 0, 4, 0),  /* IminLine */
        ARM64_FTR_END,
 };
 
@@ -144,12 +153,12 @@ static struct arm64_ftr_bits ftr_id_mmfr0[] = {
 
 static struct arm64_ftr_bits ftr_id_aa64dfr0[] = {
        ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 32, 32, 0),
-       ARM64_FTR_BITS(FTR_STRICT, FTR_LOWER_SAFE, ID_AA64DFR0_CTX_CMPS_SHIFT, 4, 0),
-       ARM64_FTR_BITS(FTR_STRICT, FTR_LOWER_SAFE, ID_AA64DFR0_WRPS_SHIFT, 4, 0),
-       ARM64_FTR_BITS(FTR_STRICT, FTR_LOWER_SAFE, ID_AA64DFR0_BRPS_SHIFT, 4, 0),
-       ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, ID_AA64DFR0_PMUVER_SHIFT, 4, 0),
-       ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, ID_AA64DFR0_TRACEVER_SHIFT, 4, 0),
-       ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, ID_AA64DFR0_DEBUGVER_SHIFT, 4, 0x6),
+       U_ARM64_FTR_BITS(FTR_STRICT, FTR_LOWER_SAFE, ID_AA64DFR0_CTX_CMPS_SHIFT, 4, 0),
+       U_ARM64_FTR_BITS(FTR_STRICT, FTR_LOWER_SAFE, ID_AA64DFR0_WRPS_SHIFT, 4, 0),
+       U_ARM64_FTR_BITS(FTR_STRICT, FTR_LOWER_SAFE, ID_AA64DFR0_BRPS_SHIFT, 4, 0),
+       U_ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, ID_AA64DFR0_PMUVER_SHIFT, 4, 0),
+       U_ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, ID_AA64DFR0_TRACEVER_SHIFT, 4, 0),
+       U_ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, ID_AA64DFR0_DEBUGVER_SHIFT, 4, 0x6),
        ARM64_FTR_END,
 };
 
index fc5508e0df57ff8a132894d091c94938d299ee02..4eeb17198cfaf598fd403b1e4040c77f5ee3068a 100644 (file)
@@ -127,7 +127,11 @@ static int __init uefi_init(void)
        table_size = sizeof(efi_config_table_64_t) * efi.systab->nr_tables;
        config_tables = early_memremap(efi_to_phys(efi.systab->tables),
                                       table_size);
-
+       if (config_tables == NULL) {
+               pr_warn("Unable to map EFI config table array.\n");
+               retval = -ENOMEM;
+               goto out;
+       }
        retval = efi_config_parse_tables(config_tables, efi.systab->nr_tables,
                                         sizeof(efi_config_table_64_t), NULL);
 
@@ -209,6 +213,14 @@ void __init efi_init(void)
                         PAGE_ALIGN(params.mmap_size + (params.mmap & ~PAGE_MASK)));
        memmap.phys_map = params.mmap;
        memmap.map = early_memremap(params.mmap, params.mmap_size);
+       if (memmap.map == NULL) {
+               /*
+               * If we are booting via UEFI, the UEFI memory map is the only
+               * description of memory we have, so there is little point in
+               * proceeding if we cannot access it.
+               */
+               panic("Unable to map EFI memory map.\n");
+       }
        memmap.map_end = memmap.map + params.mmap_size;
        memmap.desc_size = params.desc_size;
        memmap.desc_version = params.desc_ver;
@@ -227,7 +239,6 @@ static bool __init efi_virtmap_init(void)
        init_new_context(NULL, &efi_mm);
 
        for_each_efi_memory_desc(&memmap, md) {
-               u64 paddr, npages, size;
                pgprot_t prot;
 
                if (!(md->attribute & EFI_MEMORY_RUNTIME))
@@ -235,11 +246,6 @@ static bool __init efi_virtmap_init(void)
                if (md->virt_addr == 0)
                        return false;
 
-               paddr = md->phys_addr;
-               npages = md->num_pages;
-               memrange_efi_to_native(&paddr, &npages);
-               size = npages << PAGE_SHIFT;
-
                pr_info("  EFI remap 0x%016llx => %p\n",
                        md->phys_addr, (void *)md->virt_addr);
 
@@ -256,7 +262,8 @@ static bool __init efi_virtmap_init(void)
                else
                        prot = PAGE_KERNEL;
 
-               create_pgd_mapping(&efi_mm, paddr, md->virt_addr, size,
+               create_pgd_mapping(&efi_mm, md->phys_addr, md->virt_addr,
+                                  md->num_pages << EFI_PAGE_SHIFT, 
                                   __pgprot(pgprot_val(prot) | PTE_NG));
        }
        return true;
@@ -273,12 +280,12 @@ static int __init arm64_enable_runtime_services(void)
 
        if (!efi_enabled(EFI_BOOT)) {
                pr_info("EFI services will not be available.\n");
-               return -1;
+               return 0;
        }
 
        if (efi_runtime_disabled()) {
                pr_info("EFI runtime services will be disabled.\n");
-               return -1;
+               return 0;
        }
 
        pr_info("Remapping and enabling EFI services.\n");
@@ -288,7 +295,7 @@ static int __init arm64_enable_runtime_services(void)
                                                   mapsize);
        if (!memmap.map) {
                pr_err("Failed to remap EFI memory map\n");
-               return -1;
+               return -ENOMEM;
        }
        memmap.map_end = memmap.map + mapsize;
        efi.memmap = &memmap;
@@ -297,13 +304,13 @@ static int __init arm64_enable_runtime_services(void)
                                                   sizeof(efi_system_table_t));
        if (!efi.systab) {
                pr_err("Failed to remap EFI System Table\n");
-               return -1;
+               return -ENOMEM;
        }
        set_bit(EFI_SYSTEM_TABLES, &efi.flags);
 
        if (!efi_virtmap_init()) {
                pr_err("No UEFI virtual mapping was installed -- runtime services will not be available\n");
-               return -1;
+               return -ENOMEM;
        }
 
        /* Set up runtime services function pointers */
index 1ee2c3937d4e8badf3ccec9a816ad23f9814506f..71426a78db123d13e98acf8659d65155ff342a06 100644 (file)
@@ -5,6 +5,7 @@
  */
 
 #include <asm-generic/vmlinux.lds.h>
+#include <asm/cache.h>
 #include <asm/kernel-pgtable.h>
 #include <asm/thread_info.h>
 #include <asm/memory.h>
@@ -140,7 +141,7 @@ SECTIONS
                ARM_EXIT_KEEP(EXIT_DATA)
        }
 
-       PERCPU_SECTION(64)
+       PERCPU_SECTION(L1_CACHE_BYTES)
 
        . = ALIGN(PAGE_SIZE);
        __init_end = .;
@@ -158,7 +159,7 @@ SECTIONS
        . = ALIGN(PAGE_SIZE);
        _data = .;
        _sdata = .;
-       RW_DATA_SECTION(64, PAGE_SIZE, THREAD_SIZE)
+       RW_DATA_SECTION(L1_CACHE_BYTES, PAGE_SIZE, THREAD_SIZE)
        PECOFF_EDATA_PADDING
        _edata = .;
 
index 68a0759b1375e3d6824b55b0c0548ba21c434ca0..15f0477b0d2adc53d86573b1733d2fa7f368bbd9 100644 (file)
@@ -37,7 +37,7 @@ static int handle_hvc(struct kvm_vcpu *vcpu, struct kvm_run *run)
 {
        int ret;
 
-       trace_kvm_hvc_arm64(*vcpu_pc(vcpu), *vcpu_reg(vcpu, 0),
+       trace_kvm_hvc_arm64(*vcpu_pc(vcpu), vcpu_get_reg(vcpu, 0),
                            kvm_vcpu_hvc_get_imm(vcpu));
 
        ret = kvm_psci_call(vcpu);
index 1599701ef044b28b2534a3766dde1d255dba103a..86c289832272d71ba48786414bb6e4ecb9b9cb14 100644 (file)
@@ -864,6 +864,10 @@ ENTRY(__kvm_flush_vm_context)
 ENDPROC(__kvm_flush_vm_context)
 
 __kvm_hyp_panic:
+       // Stash PAR_EL1 before corrupting it in __restore_sysregs
+       mrs     x0, par_el1
+       push    x0, xzr
+
        // Guess the context by looking at VTTBR:
        // If zero, then we're already a host.
        // Otherwise restore a minimal host context before panicing.
@@ -898,7 +902,7 @@ __kvm_hyp_panic:
        mrs     x3, esr_el2
        mrs     x4, far_el2
        mrs     x5, hpfar_el2
-       mrs     x6, par_el1
+       pop     x6, xzr         // active context PAR_EL1
        mrs     x7, tpidr_el2
 
        mov     lr, #(PSR_F_BIT | PSR_I_BIT | PSR_A_BIT | PSR_D_BIT |\
@@ -914,7 +918,7 @@ __kvm_hyp_panic:
 ENDPROC(__kvm_hyp_panic)
 
 __hyp_panic_str:
-       .ascii  "HYP panic:\nPS:%08x PC:%p ESR:%p\nFAR:%p HPFAR:%p PAR:%p\nVCPU:%p\n\0"
+       .ascii  "HYP panic:\nPS:%08x PC:%016x ESR:%08x\nFAR:%016x HPFAR:%016x PAR:%016x\nVCPU:%p\n\0"
 
        .align  2
 
@@ -1015,9 +1019,15 @@ el1_trap:
        b.ne    1f              // Not an abort we care about
 
        /* This is an abort. Check for permission fault */
+alternative_if_not ARM64_WORKAROUND_834220
        and     x2, x1, #ESR_ELx_FSC_TYPE
        cmp     x2, #FSC_PERM
        b.ne    1f              // Not a permission fault
+alternative_else
+       nop                     // Use the permission fault path to
+       nop                     // check for a valid S1 translation,
+       nop                     // regardless of the ESR value.
+alternative_endif
 
        /*
         * Check for Stage-1 page table walk, which is guaranteed
index 85c57158dcd96a83d80ce99c2c557b371c275984..648112e90ed546d2d052ccf7d9f66866d2390d06 100644 (file)
@@ -48,7 +48,7 @@ static void prepare_fault32(struct kvm_vcpu *vcpu, u32 mode, u32 vect_offset)
 
        /* Note: These now point to the banked copies */
        *vcpu_spsr(vcpu) = new_spsr_value;
-       *vcpu_reg(vcpu, 14) = *vcpu_pc(vcpu) + return_offset;
+       *vcpu_reg32(vcpu, 14) = *vcpu_pc(vcpu) + return_offset;
 
        /* Branch to exception vector */
        if (sctlr & (1 << 13))
index 87a64e8db04c4dac07a5d289ad0c2dd22860f0e2..d2650e84faf2f53f2afbdbd15e1f54d217e3fdb8 100644 (file)
@@ -78,7 +78,7 @@ static u32 get_ccsidr(u32 csselr)
  * See note at ARMv7 ARM B1.14.4 (TL;DR: S/W ops are not easily virtualized).
  */
 static bool access_dcsw(struct kvm_vcpu *vcpu,
-                       const struct sys_reg_params *p,
+                       struct sys_reg_params *p,
                        const struct sys_reg_desc *r)
 {
        if (!p->is_write)
@@ -94,21 +94,19 @@ static bool access_dcsw(struct kvm_vcpu *vcpu,
  * sys_regs and leave it in complete control of the caches.
  */
 static bool access_vm_reg(struct kvm_vcpu *vcpu,
-                         const struct sys_reg_params *p,
+                         struct sys_reg_params *p,
                          const struct sys_reg_desc *r)
 {
-       unsigned long val;
        bool was_enabled = vcpu_has_cache_enabled(vcpu);
 
        BUG_ON(!p->is_write);
 
-       val = *vcpu_reg(vcpu, p->Rt);
        if (!p->is_aarch32) {
-               vcpu_sys_reg(vcpu, r->reg) = val;
+               vcpu_sys_reg(vcpu, r->reg) = p->regval;
        } else {
                if (!p->is_32bit)
-                       vcpu_cp15_64_high(vcpu, r->reg) = val >> 32;
-               vcpu_cp15_64_low(vcpu, r->reg) = val & 0xffffffffUL;
+                       vcpu_cp15_64_high(vcpu, r->reg) = upper_32_bits(p->regval);
+               vcpu_cp15_64_low(vcpu, r->reg) = lower_32_bits(p->regval);
        }
 
        kvm_toggle_cache(vcpu, was_enabled);
@@ -122,22 +120,19 @@ static bool access_vm_reg(struct kvm_vcpu *vcpu,
  * for both AArch64 and AArch32 accesses.
  */
 static bool access_gic_sgi(struct kvm_vcpu *vcpu,
-                          const struct sys_reg_params *p,
+                          struct sys_reg_params *p,
                           const struct sys_reg_desc *r)
 {
-       u64 val;
-
        if (!p->is_write)
                return read_from_write_only(vcpu, p);
 
-       val = *vcpu_reg(vcpu, p->Rt);
-       vgic_v3_dispatch_sgi(vcpu, val);
+       vgic_v3_dispatch_sgi(vcpu, p->regval);
 
        return true;
 }
 
 static bool trap_raz_wi(struct kvm_vcpu *vcpu,
-                       const struct sys_reg_params *p,
+                       struct sys_reg_params *p,
                        const struct sys_reg_desc *r)
 {
        if (p->is_write)
@@ -147,19 +142,19 @@ static bool trap_raz_wi(struct kvm_vcpu *vcpu,
 }
 
 static bool trap_oslsr_el1(struct kvm_vcpu *vcpu,
-                          const struct sys_reg_params *p,
+                          struct sys_reg_params *p,
                           const struct sys_reg_desc *r)
 {
        if (p->is_write) {
                return ignore_write(vcpu, p);
        } else {
-               *vcpu_reg(vcpu, p->Rt) = (1 << 3);
+               p->regval = (1 << 3);
                return true;
        }
 }
 
 static bool trap_dbgauthstatus_el1(struct kvm_vcpu *vcpu,
-                                  const struct sys_reg_params *p,
+                                  struct sys_reg_params *p,
                                   const struct sys_reg_desc *r)
 {
        if (p->is_write) {
@@ -167,7 +162,7 @@ static bool trap_dbgauthstatus_el1(struct kvm_vcpu *vcpu,
        } else {
                u32 val;
                asm volatile("mrs %0, dbgauthstatus_el1" : "=r" (val));
-               *vcpu_reg(vcpu, p->Rt) = val;
+               p->regval = val;
                return true;
        }
 }
@@ -200,17 +195,17 @@ static bool trap_dbgauthstatus_el1(struct kvm_vcpu *vcpu,
  *   now use the debug registers.
  */
 static bool trap_debug_regs(struct kvm_vcpu *vcpu,
-                           const struct sys_reg_params *p,
+                           struct sys_reg_params *p,
                            const struct sys_reg_desc *r)
 {
        if (p->is_write) {
-               vcpu_sys_reg(vcpu, r->reg) = *vcpu_reg(vcpu, p->Rt);
+               vcpu_sys_reg(vcpu, r->reg) = p->regval;
                vcpu->arch.debug_flags |= KVM_ARM64_DEBUG_DIRTY;
        } else {
-               *vcpu_reg(vcpu, p->Rt) = vcpu_sys_reg(vcpu, r->reg);
+               p->regval = vcpu_sys_reg(vcpu, r->reg);
        }
 
-       trace_trap_reg(__func__, r->reg, p->is_write, *vcpu_reg(vcpu, p->Rt));
+       trace_trap_reg(__func__, r->reg, p->is_write, p->regval);
 
        return true;
 }
@@ -225,10 +220,10 @@ static bool trap_debug_regs(struct kvm_vcpu *vcpu,
  * hyp.S code switches between host and guest values in future.
  */
 static inline void reg_to_dbg(struct kvm_vcpu *vcpu,
-                             const struct sys_reg_params *p,
+                             struct sys_reg_params *p,
                              u64 *dbg_reg)
 {
-       u64 val = *vcpu_reg(vcpu, p->Rt);
+       u64 val = p->regval;
 
        if (p->is_32bit) {
                val &= 0xffffffffUL;
@@ -240,19 +235,16 @@ static inline void reg_to_dbg(struct kvm_vcpu *vcpu,
 }
 
 static inline void dbg_to_reg(struct kvm_vcpu *vcpu,
-                             const struct sys_reg_params *p,
+                             struct sys_reg_params *p,
                              u64 *dbg_reg)
 {
-       u64 val = *dbg_reg;
-
+       p->regval = *dbg_reg;
        if (p->is_32bit)
-               val &= 0xffffffffUL;
-
-       *vcpu_reg(vcpu, p->Rt) = val;
+               p->regval &= 0xffffffffUL;
 }
 
 static inline bool trap_bvr(struct kvm_vcpu *vcpu,
-                           const struct sys_reg_params *p,
+                           struct sys_reg_params *p,
                            const struct sys_reg_desc *rd)
 {
        u64 *dbg_reg = &vcpu->arch.vcpu_debug_state.dbg_bvr[rd->reg];
@@ -294,7 +286,7 @@ static inline void reset_bvr(struct kvm_vcpu *vcpu,
 }
 
 static inline bool trap_bcr(struct kvm_vcpu *vcpu,
-                           const struct sys_reg_params *p,
+                           struct sys_reg_params *p,
                            const struct sys_reg_desc *rd)
 {
        u64 *dbg_reg = &vcpu->arch.vcpu_debug_state.dbg_bcr[rd->reg];
@@ -337,7 +329,7 @@ static inline void reset_bcr(struct kvm_vcpu *vcpu,
 }
 
 static inline bool trap_wvr(struct kvm_vcpu *vcpu,
-                           const struct sys_reg_params *p,
+                           struct sys_reg_params *p,
                            const struct sys_reg_desc *rd)
 {
        u64 *dbg_reg = &vcpu->arch.vcpu_debug_state.dbg_wvr[rd->reg];
@@ -380,7 +372,7 @@ static inline void reset_wvr(struct kvm_vcpu *vcpu,
 }
 
 static inline bool trap_wcr(struct kvm_vcpu *vcpu,
-                           const struct sys_reg_params *p,
+                           struct sys_reg_params *p,
                            const struct sys_reg_desc *rd)
 {
        u64 *dbg_reg = &vcpu->arch.vcpu_debug_state.dbg_wcr[rd->reg];
@@ -687,7 +679,7 @@ static const struct sys_reg_desc sys_reg_descs[] = {
 };
 
 static bool trap_dbgidr(struct kvm_vcpu *vcpu,
-                       const struct sys_reg_params *p,
+                       struct sys_reg_params *p,
                        const struct sys_reg_desc *r)
 {
        if (p->is_write) {
@@ -697,23 +689,23 @@ static bool trap_dbgidr(struct kvm_vcpu *vcpu,
                u64 pfr = read_system_reg(SYS_ID_AA64PFR0_EL1);
                u32 el3 = !!cpuid_feature_extract_field(pfr, ID_AA64PFR0_EL3_SHIFT);
 
-               *vcpu_reg(vcpu, p->Rt) = ((((dfr >> ID_AA64DFR0_WRPS_SHIFT) & 0xf) << 28) |
-                                         (((dfr >> ID_AA64DFR0_BRPS_SHIFT) & 0xf) << 24) |
-                                         (((dfr >> ID_AA64DFR0_CTX_CMPS_SHIFT) & 0xf) << 20) |
-                                         (6 << 16) | (el3 << 14) | (el3 << 12));
+               p->regval = ((((dfr >> ID_AA64DFR0_WRPS_SHIFT) & 0xf) << 28) |
+                            (((dfr >> ID_AA64DFR0_BRPS_SHIFT) & 0xf) << 24) |
+                            (((dfr >> ID_AA64DFR0_CTX_CMPS_SHIFT) & 0xf) << 20)
+                            | (6 << 16) | (el3 << 14) | (el3 << 12));
                return true;
        }
 }
 
 static bool trap_debug32(struct kvm_vcpu *vcpu,
-                        const struct sys_reg_params *p,
+                        struct sys_reg_params *p,
                         const struct sys_reg_desc *r)
 {
        if (p->is_write) {
-               vcpu_cp14(vcpu, r->reg) = *vcpu_reg(vcpu, p->Rt);
+               vcpu_cp14(vcpu, r->reg) = p->regval;
                vcpu->arch.debug_flags |= KVM_ARM64_DEBUG_DIRTY;
        } else {
-               *vcpu_reg(vcpu, p->Rt) = vcpu_cp14(vcpu, r->reg);
+               p->regval = vcpu_cp14(vcpu, r->reg);
        }
 
        return true;
@@ -731,7 +723,7 @@ static bool trap_debug32(struct kvm_vcpu *vcpu,
  */
 
 static inline bool trap_xvr(struct kvm_vcpu *vcpu,
-                           const struct sys_reg_params *p,
+                           struct sys_reg_params *p,
                            const struct sys_reg_desc *rd)
 {
        u64 *dbg_reg = &vcpu->arch.vcpu_debug_state.dbg_bvr[rd->reg];
@@ -740,12 +732,12 @@ static inline bool trap_xvr(struct kvm_vcpu *vcpu,
                u64 val = *dbg_reg;
 
                val &= 0xffffffffUL;
-               val |= *vcpu_reg(vcpu, p->Rt) << 32;
+               val |= p->regval << 32;
                *dbg_reg = val;
 
                vcpu->arch.debug_flags |= KVM_ARM64_DEBUG_DIRTY;
        } else {
-               *vcpu_reg(vcpu, p->Rt) = *dbg_reg >> 32;
+               p->regval = *dbg_reg >> 32;
        }
 
        trace_trap_reg(__func__, rd->reg, p->is_write, *dbg_reg);
@@ -991,7 +983,7 @@ int kvm_handle_cp14_load_store(struct kvm_vcpu *vcpu, struct kvm_run *run)
  * Return 0 if the access has been handled, and -1 if not.
  */
 static int emulate_cp(struct kvm_vcpu *vcpu,
-                     const struct sys_reg_params *params,
+                     struct sys_reg_params *params,
                      const struct sys_reg_desc *table,
                      size_t num)
 {
@@ -1062,12 +1054,12 @@ static int kvm_handle_cp_64(struct kvm_vcpu *vcpu,
 {
        struct sys_reg_params params;
        u32 hsr = kvm_vcpu_get_hsr(vcpu);
+       int Rt = (hsr >> 5) & 0xf;
        int Rt2 = (hsr >> 10) & 0xf;
 
        params.is_aarch32 = true;
        params.is_32bit = false;
        params.CRm = (hsr >> 1) & 0xf;
-       params.Rt = (hsr >> 5) & 0xf;
        params.is_write = ((hsr & 1) == 0);
 
        params.Op0 = 0;
@@ -1076,15 +1068,12 @@ static int kvm_handle_cp_64(struct kvm_vcpu *vcpu,
        params.CRn = 0;
 
        /*
-        * Massive hack here. Store Rt2 in the top 32bits so we only
-        * have one register to deal with. As we use the same trap
+        * Make a 64-bit value out of Rt and Rt2. As we use the same trap
         * backends between AArch32 and AArch64, we get away with it.
         */
        if (params.is_write) {
-               u64 val = *vcpu_reg(vcpu, params.Rt);
-               val &= 0xffffffff;
-               val |= *vcpu_reg(vcpu, Rt2) << 32;
-               *vcpu_reg(vcpu, params.Rt) = val;
+               params.regval = vcpu_get_reg(vcpu, Rt) & 0xffffffff;
+               params.regval |= vcpu_get_reg(vcpu, Rt2) << 32;
        }
 
        if (!emulate_cp(vcpu, &params, target_specific, nr_specific))
@@ -1095,11 +1084,10 @@ static int kvm_handle_cp_64(struct kvm_vcpu *vcpu,
        unhandled_cp_access(vcpu, &params);
 
 out:
-       /* Do the opposite hack for the read side */
+       /* Split up the value between registers for the read side */
        if (!params.is_write) {
-               u64 val = *vcpu_reg(vcpu, params.Rt);
-               val >>= 32;
-               *vcpu_reg(vcpu, Rt2) = val;
+               vcpu_set_reg(vcpu, Rt, lower_32_bits(params.regval));
+               vcpu_set_reg(vcpu, Rt2, upper_32_bits(params.regval));
        }
 
        return 1;
@@ -1118,21 +1106,24 @@ static int kvm_handle_cp_32(struct kvm_vcpu *vcpu,
 {
        struct sys_reg_params params;
        u32 hsr = kvm_vcpu_get_hsr(vcpu);
+       int Rt  = (hsr >> 5) & 0xf;
 
        params.is_aarch32 = true;
        params.is_32bit = true;
        params.CRm = (hsr >> 1) & 0xf;
-       params.Rt  = (hsr >> 5) & 0xf;
+       params.regval = vcpu_get_reg(vcpu, Rt);
        params.is_write = ((hsr & 1) == 0);
        params.CRn = (hsr >> 10) & 0xf;
        params.Op0 = 0;
        params.Op1 = (hsr >> 14) & 0x7;
        params.Op2 = (hsr >> 17) & 0x7;
 
-       if (!emulate_cp(vcpu, &params, target_specific, nr_specific))
-               return 1;
-       if (!emulate_cp(vcpu, &params, global, nr_global))
+       if (!emulate_cp(vcpu, &params, target_specific, nr_specific) ||
+           !emulate_cp(vcpu, &params, global, nr_global)) {
+               if (!params.is_write)
+                       vcpu_set_reg(vcpu, Rt, params.regval);
                return 1;
+       }
 
        unhandled_cp_access(vcpu, &params);
        return 1;
@@ -1175,7 +1166,7 @@ int kvm_handle_cp14_32(struct kvm_vcpu *vcpu, struct kvm_run *run)
 }
 
 static int emulate_sys_reg(struct kvm_vcpu *vcpu,
-                          const struct sys_reg_params *params)
+                          struct sys_reg_params *params)
 {
        size_t num;
        const struct sys_reg_desc *table, *r;
@@ -1230,6 +1221,8 @@ int kvm_handle_sys_reg(struct kvm_vcpu *vcpu, struct kvm_run *run)
 {
        struct sys_reg_params params;
        unsigned long esr = kvm_vcpu_get_hsr(vcpu);
+       int Rt = (esr >> 5) & 0x1f;
+       int ret;
 
        trace_kvm_handle_sys_reg(esr);
 
@@ -1240,10 +1233,14 @@ int kvm_handle_sys_reg(struct kvm_vcpu *vcpu, struct kvm_run *run)
        params.CRn = (esr >> 10) & 0xf;
        params.CRm = (esr >> 1) & 0xf;
        params.Op2 = (esr >> 17) & 0x7;
-       params.Rt = (esr >> 5) & 0x1f;
+       params.regval = vcpu_get_reg(vcpu, Rt);
        params.is_write = !(esr & 1);
 
-       return emulate_sys_reg(vcpu, &params);
+       ret = emulate_sys_reg(vcpu, &params);
+
+       if (!params.is_write)
+               vcpu_set_reg(vcpu, Rt, params.regval);
+       return ret;
 }
 
 /******************************************************************************
index eaa324e4db4da1149adfe7ae012b895353f05e91..dbbb01cfbee9c504980943921c841b61118837b8 100644 (file)
@@ -28,7 +28,7 @@ struct sys_reg_params {
        u8      CRn;
        u8      CRm;
        u8      Op2;
-       u8      Rt;
+       u64     regval;
        bool    is_write;
        bool    is_aarch32;
        bool    is_32bit;       /* Only valid if is_aarch32 is true */
@@ -44,7 +44,7 @@ struct sys_reg_desc {
 
        /* Trapped access from guest, if non-NULL. */
        bool (*access)(struct kvm_vcpu *,
-                      const struct sys_reg_params *,
+                      struct sys_reg_params *,
                       const struct sys_reg_desc *);
 
        /* Initialization for vcpu. */
@@ -77,9 +77,9 @@ static inline bool ignore_write(struct kvm_vcpu *vcpu,
 }
 
 static inline bool read_zero(struct kvm_vcpu *vcpu,
-                            const struct sys_reg_params *p)
+                            struct sys_reg_params *p)
 {
-       *vcpu_reg(vcpu, p->Rt) = 0;
+       p->regval = 0;
        return true;
 }
 
index 1e4576824165502d2a6d5a1caee9e0c1da10c3fa..ed90578fa120e50f5685ef51c82dd86efed6f837 100644 (file)
 #include "sys_regs.h"
 
 static bool access_actlr(struct kvm_vcpu *vcpu,
-                        const struct sys_reg_params *p,
+                        struct sys_reg_params *p,
                         const struct sys_reg_desc *r)
 {
        if (p->is_write)
                return ignore_write(vcpu, p);
 
-       *vcpu_reg(vcpu, p->Rt) = vcpu_sys_reg(vcpu, ACTLR_EL1);
+       p->regval = vcpu_sys_reg(vcpu, ACTLR_EL1);
        return true;
 }
 
index f636a2639f031dd03d0b5058ccf378721d67dbf4..e87f53ff5f583aeb47b3ec3187d229df380b2c50 100644 (file)
@@ -76,13 +76,28 @@ static void flush_context(unsigned int cpu)
                __flush_icache_all();
 }
 
-static int is_reserved_asid(u64 asid)
+static bool check_update_reserved_asid(u64 asid, u64 newasid)
 {
        int cpu;
-       for_each_possible_cpu(cpu)
-               if (per_cpu(reserved_asids, cpu) == asid)
-                       return 1;
-       return 0;
+       bool hit = false;
+
+       /*
+        * Iterate over the set of reserved ASIDs looking for a match.
+        * If we find one, then we can update our mm to use newasid
+        * (i.e. the same ASID in the current generation) but we can't
+        * exit the loop early, since we need to ensure that all copies
+        * of the old ASID are updated to reflect the mm. Failure to do
+        * so could result in us missing the reserved ASID in a future
+        * generation.
+        */
+       for_each_possible_cpu(cpu) {
+               if (per_cpu(reserved_asids, cpu) == asid) {
+                       hit = true;
+                       per_cpu(reserved_asids, cpu) = newasid;
+               }
+       }
+
+       return hit;
 }
 
 static u64 new_context(struct mm_struct *mm, unsigned int cpu)
@@ -92,12 +107,14 @@ static u64 new_context(struct mm_struct *mm, unsigned int cpu)
        u64 generation = atomic64_read(&asid_generation);
 
        if (asid != 0) {
+               u64 newasid = generation | (asid & ~ASID_MASK);
+
                /*
                 * If our current ASID was active during a rollover, we
                 * can continue to use it and this was just a false alarm.
                 */
-               if (is_reserved_asid(asid))
-                       return generation | (asid & ~ASID_MASK);
+               if (check_update_reserved_asid(asid, newasid))
+                       return newasid;
 
                /*
                 * We had a valid ASID in a previous life, so try to re-use
@@ -105,7 +122,7 @@ static u64 new_context(struct mm_struct *mm, unsigned int cpu)
                 */
                asid &= ~ASID_MASK;
                if (!__test_and_set_bit(asid, asid_map))
-                       goto bump_gen;
+                       return newasid;
        }
 
        /*
@@ -129,10 +146,7 @@ static u64 new_context(struct mm_struct *mm, unsigned int cpu)
 set_asid:
        __set_bit(asid, asid_map);
        cur_idx = asid;
-
-bump_gen:
-       asid |= generation;
-       return asid;
+       return asid | generation;
 }
 
 void check_and_switch_context(struct mm_struct *mm, unsigned int cpu)
index 19211c4a891111cee301552a234821646f522ea6..92ddac1e8ca2f35b8f24028514bb761aed3591a4 100644 (file)
@@ -393,16 +393,16 @@ static struct fault_info {
        { do_translation_fault, SIGSEGV, SEGV_MAPERR,   "level 1 translation fault"     },
        { do_translation_fault, SIGSEGV, SEGV_MAPERR,   "level 2 translation fault"     },
        { do_page_fault,        SIGSEGV, SEGV_MAPERR,   "level 3 translation fault"     },
-       { do_bad,               SIGBUS,  0,             "reserved access flag fault"    },
+       { do_bad,               SIGBUS,  0,             "unknown 8"                     },
        { do_page_fault,        SIGSEGV, SEGV_ACCERR,   "level 1 access flag fault"     },
        { do_page_fault,        SIGSEGV, SEGV_ACCERR,   "level 2 access flag fault"     },
        { do_page_fault,        SIGSEGV, SEGV_ACCERR,   "level 3 access flag fault"     },
-       { do_bad,               SIGBUS,  0,             "reserved permission fault"     },
+       { do_bad,               SIGBUS,  0,             "unknown 12"                    },
        { do_page_fault,        SIGSEGV, SEGV_ACCERR,   "level 1 permission fault"      },
        { do_page_fault,        SIGSEGV, SEGV_ACCERR,   "level 2 permission fault"      },
        { do_page_fault,        SIGSEGV, SEGV_ACCERR,   "level 3 permission fault"      },
        { do_bad,               SIGBUS,  0,             "synchronous external abort"    },
-       { do_bad,               SIGBUS,  0,             "asynchronous external abort"   },
+       { do_bad,               SIGBUS,  0,             "unknown 17"                    },
        { do_bad,               SIGBUS,  0,             "unknown 18"                    },
        { do_bad,               SIGBUS,  0,             "unknown 19"                    },
        { do_bad,               SIGBUS,  0,             "synchronous abort (translation table walk)" },
@@ -410,16 +410,16 @@ static struct fault_info {
        { do_bad,               SIGBUS,  0,             "synchronous abort (translation table walk)" },
        { do_bad,               SIGBUS,  0,             "synchronous abort (translation table walk)" },
        { do_bad,               SIGBUS,  0,             "synchronous parity error"      },
-       { do_bad,               SIGBUS,  0,             "asynchronous parity error"     },
+       { do_bad,               SIGBUS,  0,             "unknown 25"                    },
        { do_bad,               SIGBUS,  0,             "unknown 26"                    },
        { do_bad,               SIGBUS,  0,             "unknown 27"                    },
-       { do_bad,               SIGBUS,  0,             "synchronous parity error (translation table walk" },
-       { do_bad,               SIGBUS,  0,             "synchronous parity error (translation table walk" },
-       { do_bad,               SIGBUS,  0,             "synchronous parity error (translation table walk" },
-       { do_bad,               SIGBUS,  0,             "synchronous parity error (translation table walk" },
+       { do_bad,               SIGBUS,  0,             "synchronous parity error (translation table walk)" },
+       { do_bad,               SIGBUS,  0,             "synchronous parity error (translation table walk)" },
+       { do_bad,               SIGBUS,  0,             "synchronous parity error (translation table walk)" },
+       { do_bad,               SIGBUS,  0,             "synchronous parity error (translation table walk)" },
        { do_bad,               SIGBUS,  0,             "unknown 32"                    },
        { do_bad,               SIGBUS,  BUS_ADRALN,    "alignment fault"               },
-       { do_bad,               SIGBUS,  0,             "debug event"                   },
+       { do_bad,               SIGBUS,  0,             "unknown 34"                    },
        { do_bad,               SIGBUS,  0,             "unknown 35"                    },
        { do_bad,               SIGBUS,  0,             "unknown 36"                    },
        { do_bad,               SIGBUS,  0,             "unknown 37"                    },
@@ -433,21 +433,21 @@ static struct fault_info {
        { do_bad,               SIGBUS,  0,             "unknown 45"                    },
        { do_bad,               SIGBUS,  0,             "unknown 46"                    },
        { do_bad,               SIGBUS,  0,             "unknown 47"                    },
-       { do_bad,               SIGBUS,  0,             "unknown 48"                    },
+       { do_bad,               SIGBUS,  0,             "TLB conflict abort"            },
        { do_bad,               SIGBUS,  0,             "unknown 49"                    },
        { do_bad,               SIGBUS,  0,             "unknown 50"                    },
        { do_bad,               SIGBUS,  0,             "unknown 51"                    },
        { do_bad,               SIGBUS,  0,             "implementation fault (lockdown abort)" },
-       { do_bad,               SIGBUS,  0,             "unknown 53"                    },
+       { do_bad,               SIGBUS,  0,             "implementation fault (unsupported exclusive)" },
        { do_bad,               SIGBUS,  0,             "unknown 54"                    },
        { do_bad,               SIGBUS,  0,             "unknown 55"                    },
        { do_bad,               SIGBUS,  0,             "unknown 56"                    },
        { do_bad,               SIGBUS,  0,             "unknown 57"                    },
-       { do_bad,               SIGBUS,  0,             "implementation fault (coprocessor abort)" },
+       { do_bad,               SIGBUS,  0,             "unknown 58"                    },
        { do_bad,               SIGBUS,  0,             "unknown 59"                    },
        { do_bad,               SIGBUS,  0,             "unknown 60"                    },
-       { do_bad,               SIGBUS,  0,             "unknown 61"                    },
-       { do_bad,               SIGBUS,  0,             "unknown 62"                    },
+       { do_bad,               SIGBUS,  0,             "section domain fault"          },
+       { do_bad,               SIGBUS,  0,             "page domain fault"             },
        { do_bad,               SIGBUS,  0,             "unknown 63"                    },
 };
 
index abb66f84d4ac896c0978b3c2584470d5db15a8ba..873e363048c6c661eda620bbd4f826ba568c5ba7 100644 (file)
@@ -64,8 +64,12 @@ EXPORT_SYMBOL(phys_mem_access_prot);
 
 static void __init *early_alloc(unsigned long sz)
 {
-       void *ptr = __va(memblock_alloc(sz, sz));
-       BUG_ON(!ptr);
+       phys_addr_t phys;
+       void *ptr;
+
+       phys = memblock_alloc(sz, sz);
+       BUG_ON(!phys);
+       ptr = __va(phys);
        memset(ptr, 0, sz);
        return ptr;
 }
@@ -81,55 +85,19 @@ static void split_pmd(pmd_t *pmd, pte_t *pte)
        do {
                /*
                 * Need to have the least restrictive permissions available
-                * permissions will be fixed up later. Default the new page
-                * range as contiguous ptes.
+                * permissions will be fixed up later
                 */
-               set_pte(pte, pfn_pte(pfn, PAGE_KERNEL_EXEC_CONT));
+               set_pte(pte, pfn_pte(pfn, PAGE_KERNEL_EXEC));
                pfn++;
        } while (pte++, i++, i < PTRS_PER_PTE);
 }
 
-/*
- * Given a PTE with the CONT bit set, determine where the CONT range
- * starts, and clear the entire range of PTE CONT bits.
- */
-static void clear_cont_pte_range(pte_t *pte, unsigned long addr)
-{
-       int i;
-
-       pte -= CONT_RANGE_OFFSET(addr);
-       for (i = 0; i < CONT_PTES; i++) {
-               set_pte(pte, pte_mknoncont(*pte));
-               pte++;
-       }
-       flush_tlb_all();
-}
-
-/*
- * Given a range of PTEs set the pfn and provided page protection flags
- */
-static void __populate_init_pte(pte_t *pte, unsigned long addr,
-                               unsigned long end, phys_addr_t phys,
-                               pgprot_t prot)
-{
-       unsigned long pfn = __phys_to_pfn(phys);
-
-       do {
-               /* clear all the bits except the pfn, then apply the prot */
-               set_pte(pte, pfn_pte(pfn, prot));
-               pte++;
-               pfn++;
-               addr += PAGE_SIZE;
-       } while (addr != end);
-}
-
 static void alloc_init_pte(pmd_t *pmd, unsigned long addr,
-                                 unsigned long end, phys_addr_t phys,
+                                 unsigned long end, unsigned long pfn,
                                  pgprot_t prot,
                                  void *(*alloc)(unsigned long size))
 {
        pte_t *pte;
-       unsigned long next;
 
        if (pmd_none(*pmd) || pmd_sect(*pmd)) {
                pte = alloc(PTRS_PER_PTE * sizeof(pte_t));
@@ -142,27 +110,9 @@ static void alloc_init_pte(pmd_t *pmd, unsigned long addr,
 
        pte = pte_offset_kernel(pmd, addr);
        do {
-               next = min(end, (addr + CONT_SIZE) & CONT_MASK);
-               if (((addr | next | phys) & ~CONT_MASK) == 0) {
-                       /* a block of CONT_PTES  */
-                       __populate_init_pte(pte, addr, next, phys,
-                                           __pgprot(pgprot_val(prot) | PTE_CONT));
-               } else {
-                       /*
-                        * If the range being split is already inside of a
-                        * contiguous range but this PTE isn't going to be
-                        * contiguous, then we want to unmark the adjacent
-                        * ranges, then update the portion of the range we
-                        * are interrested in.
-                        */
-                        clear_cont_pte_range(pte, addr);
-                        __populate_init_pte(pte, addr, next, phys, prot);
-               }
-
-               pte += (next - addr) >> PAGE_SHIFT;
-               phys += next - addr;
-               addr = next;
-       } while (addr != end);
+               set_pte(pte, pfn_pte(pfn, prot));
+               pfn++;
+       } while (pte++, addr += PAGE_SIZE, addr != end);
 }
 
 static void split_pud(pud_t *old_pud, pmd_t *pmd)
@@ -223,7 +173,8 @@ static void alloc_init_pmd(struct mm_struct *mm, pud_t *pud,
                                }
                        }
                } else {
-                       alloc_init_pte(pmd, addr, next, phys, prot, alloc);
+                       alloc_init_pte(pmd, addr, next, __phys_to_pfn(phys),
+                                      prot, alloc);
                }
                phys += next - addr;
        } while (pmd++, addr = next, addr != end);
index d6a53ef2350be81a090c07ab7d6df409d99c6a37..b162ad70effcfeacbc7a304d569b222717f495d7 100644 (file)
@@ -139,6 +139,12 @@ static inline int epilogue_offset(const struct jit_ctx *ctx)
 /* Stack must be multiples of 16B */
 #define STACK_ALIGN(sz) (((sz) + 15) & ~15)
 
+#define _STACK_SIZE \
+       (MAX_BPF_STACK \
+        + 4 /* extra for skb_copy_bits buffer */)
+
+#define STACK_SIZE STACK_ALIGN(_STACK_SIZE)
+
 static void build_prologue(struct jit_ctx *ctx)
 {
        const u8 r6 = bpf2a64[BPF_REG_6];
@@ -150,10 +156,6 @@ static void build_prologue(struct jit_ctx *ctx)
        const u8 rx = bpf2a64[BPF_REG_X];
        const u8 tmp1 = bpf2a64[TMP_REG_1];
        const u8 tmp2 = bpf2a64[TMP_REG_2];
-       int stack_size = MAX_BPF_STACK;
-
-       stack_size += 4; /* extra for skb_copy_bits buffer */
-       stack_size = STACK_ALIGN(stack_size);
 
        /*
         * BPF prog stack layout
@@ -165,12 +167,13 @@ static void build_prologue(struct jit_ctx *ctx)
         *                        | ... | callee saved registers
         *                        +-----+
         *                        |     | x25/x26
-        * BPF fp register => -80:+-----+
+        * BPF fp register => -80:+-----+ <= (BPF_FP)
         *                        |     |
         *                        | ... | BPF prog stack
         *                        |     |
-        *                        |     |
-        * current A64_SP =>      +-----+
+        *                        +-----+ <= (BPF_FP - MAX_BPF_STACK)
+        *                        |RSVD | JIT scratchpad
+        * current A64_SP =>      +-----+ <= (BPF_FP - STACK_SIZE)
         *                        |     |
         *                        | ... | Function call stack
         *                        |     |
@@ -196,7 +199,7 @@ static void build_prologue(struct jit_ctx *ctx)
        emit(A64_MOV(1, fp, A64_SP), ctx);
 
        /* Set up function call stack */
-       emit(A64_SUB_I(1, A64_SP, A64_SP, stack_size), ctx);
+       emit(A64_SUB_I(1, A64_SP, A64_SP, STACK_SIZE), ctx);
 
        /* Clear registers A and X */
        emit_a64_mov_i64(ra, 0, ctx);
@@ -213,13 +216,9 @@ static void build_epilogue(struct jit_ctx *ctx)
        const u8 fp = bpf2a64[BPF_REG_FP];
        const u8 tmp1 = bpf2a64[TMP_REG_1];
        const u8 tmp2 = bpf2a64[TMP_REG_2];
-       int stack_size = MAX_BPF_STACK;
-
-       stack_size += 4; /* extra for skb_copy_bits buffer */
-       stack_size = STACK_ALIGN(stack_size);
 
        /* We're done with BPF stack */
-       emit(A64_ADD_I(1, A64_SP, A64_SP, stack_size), ctx);
+       emit(A64_ADD_I(1, A64_SP, A64_SP, STACK_SIZE), ctx);
 
        /* Restore fs (x25) and x26 */
        emit(A64_POP(fp, A64_R(26), A64_SP), ctx);
@@ -591,7 +590,25 @@ emit_cond_jmp:
        case BPF_ST | BPF_MEM | BPF_H:
        case BPF_ST | BPF_MEM | BPF_B:
        case BPF_ST | BPF_MEM | BPF_DW:
-               goto notyet;
+               /* Load imm to a register then store it */
+               ctx->tmp_used = 1;
+               emit_a64_mov_i(1, tmp2, off, ctx);
+               emit_a64_mov_i(1, tmp, imm, ctx);
+               switch (BPF_SIZE(code)) {
+               case BPF_W:
+                       emit(A64_STR32(tmp, dst, tmp2), ctx);
+                       break;
+               case BPF_H:
+                       emit(A64_STRH(tmp, dst, tmp2), ctx);
+                       break;
+               case BPF_B:
+                       emit(A64_STRB(tmp, dst, tmp2), ctx);
+                       break;
+               case BPF_DW:
+                       emit(A64_STR64(tmp, dst, tmp2), ctx);
+                       break;
+               }
+               break;
 
        /* STX: *(size *)(dst + off) = src */
        case BPF_STX | BPF_MEM | BPF_W:
@@ -658,7 +675,7 @@ emit_cond_jmp:
                        return -EINVAL;
                }
                emit_a64_mov_i64(r3, size, ctx);
-               emit(A64_ADD_I(1, r4, fp, MAX_BPF_STACK), ctx);
+               emit(A64_SUB_I(1, r4, fp, STACK_SIZE), ctx);
                emit_a64_mov_i64(r5, (unsigned long)bpf_load_pointer, ctx);
                emit(A64_PUSH(A64_FP, A64_LR, A64_SP), ctx);
                emit(A64_MOV(1, A64_FP, A64_SP), ctx);
index 1e9c8b0bf48666cfba1ee19d8731eb71cf68a77e..170d786807c460eda342f4383dc379e5279a215d 100644 (file)
@@ -14,7 +14,7 @@
  *  Copyright (C) 2008-2009 Red Hat, Inc., Ingo Molnar
  *  Copyright (C) 2009 Jaswinder Singh Rajput
  *  Copyright (C) 2009 Advanced Micro Devices, Inc., Robert Richter
- *  Copyright (C) 2008-2009 Red Hat, Inc., Peter Zijlstra <pzijlstr@redhat.com>
+ *  Copyright (C) 2008-2009 Red Hat, Inc., Peter Zijlstra
  *  Copyright (C) 2009 Intel Corporation, <markus.t.metzger@intel.com>
  *
  * ppc:
index f7836c6a6b60eb24981a5f9f53207a96bff7a6dc..c32f76791f488ae12e7264960433c70d0fbd4315 100644 (file)
@@ -98,7 +98,7 @@ static void __init mcf54xx_bootmem_alloc(void)
        memstart = PAGE_ALIGN(_ramstart);
        min_low_pfn = PFN_DOWN(_rambase);
        start_pfn = PFN_DOWN(memstart);
-       max_low_pfn = PFN_DOWN(_ramend);
+       max_pfn = max_low_pfn = PFN_DOWN(_ramend);
        high_memory = (void *)_ramend;
 
        m68k_virt_to_node_shift = fls(_ramend - _rambase - 1) - 6;
index 0793a7f174176e6d590ca4d9567a9e3523c42c50..f9d96bf869109c028e5a9f1f12ad3e9fe8b933ba 100644 (file)
@@ -4,7 +4,7 @@
 #include <uapi/asm/unistd.h>
 
 
-#define NR_syscalls            375
+#define NR_syscalls            376
 
 #define __ARCH_WANT_OLD_READDIR
 #define __ARCH_WANT_OLD_STAT
index 5e6fae6c275f9b110464cb80bbb47187c2251dcd..36cf129de663a7ca22f1bf1bba5a6245b7b04c03 100644 (file)
 #define __NR_sendmmsg          372
 #define __NR_userfaultfd       373
 #define __NR_membarrier                374
+#define __NR_mlock2            375
 
 #endif /* _UAPI_ASM_M68K_UNISTD_H_ */
index 88c27d94a7214c959c6d75a3ac992a4c95b13b2e..76b9113f30922df74e8dac0d8dccca9d7c48fd6b 100644 (file)
@@ -238,11 +238,14 @@ void __init setup_arch(char **cmdline_p)
         * Give all the memory to the bootmap allocator, tell it to put the
         * boot mem_map at the start of memory.
         */
+       min_low_pfn = PFN_DOWN(memory_start);
+       max_pfn = max_low_pfn = PFN_DOWN(memory_end);
+
        bootmap_size = init_bootmem_node(
                        NODE_DATA(0),
-                       memory_start >> PAGE_SHIFT, /* map goes here */
-                       PAGE_OFFSET >> PAGE_SHIFT,      /* 0 on coldfire */
-                       memory_end >> PAGE_SHIFT);
+                       min_low_pfn,            /* map goes here */
+                       PFN_DOWN(PAGE_OFFSET),
+                       max_pfn);
        /*
         * Free the usable memory, we have to make sure we do not free
         * the bootmem bitmap so we then reserve it after freeing it :-)
index 5dd0e80042f51107e63e0fcd832f4c46c85b826c..282cd903f4c469197738eb9e840eaa75c77ec11a 100644 (file)
@@ -395,3 +395,4 @@ ENTRY(sys_call_table)
        .long sys_sendmmsg
        .long sys_userfaultfd
        .long sys_membarrier
+       .long sys_mlock2                /* 375 */
index b958916e5eac96b250ef08e556983e059d7d0850..8f37fdd80be9e9ccec99b1d4509f3c97a94f0899 100644 (file)
@@ -250,7 +250,7 @@ void __init paging_init(void)
        high_memory = phys_to_virt(max_addr);
 
        min_low_pfn = availmem >> PAGE_SHIFT;
-       max_low_pfn = max_addr >> PAGE_SHIFT;
+       max_pfn = max_low_pfn = max_addr >> PAGE_SHIFT;
 
        for (i = 0; i < m68k_num_memory; i++) {
                addr = m68k_memory[i].addr;
index a8b942bf71638c9778dd8fff05c63797202edd61..2a5f43a68ae3d73d22dd822a4da4996208543e7c 100644 (file)
@@ -118,13 +118,13 @@ static void __init sun3_bootmem_alloc(unsigned long memory_start,
        memory_end = memory_end & PAGE_MASK;
 
        start_page = __pa(memory_start) >> PAGE_SHIFT;
-       num_pages = __pa(memory_end) >> PAGE_SHIFT;
+       max_pfn = num_pages = __pa(memory_end) >> PAGE_SHIFT;
 
        high_memory = (void *)memory_end;
        availmem = memory_start;
 
        m68k_setup_node(0);
-       availmem += init_bootmem_node(NODE_DATA(0), start_page, 0, num_pages);
+       availmem += init_bootmem(start_page, num_pages);
        availmem = (availmem + (PAGE_SIZE-1)) & PAGE_MASK;
 
        free_bootmem(__pa(availmem), memory_end - (availmem));
index d5fa3eaf39a106546f52d82ec3e5391302ef8dec..41b1b090f56f6b73afc50240318634a4988ef427 100644 (file)
@@ -1581,7 +1581,7 @@ enum emulation_result kvm_mips_emulate_cache(uint32_t inst, uint32_t *opc,
 
        base = (inst >> 21) & 0x1f;
        op_inst = (inst >> 16) & 0x1f;
-       offset = inst & 0xffff;
+       offset = (int16_t)inst;
        cache = (inst >> 16) & 0x3;
        op = (inst >> 18) & 0x7;
 
index 7bab3a4e8f7d90b541b457f4f66138899db6db8a..7e2210846b8b9d1519f679e6a0950fcaf1e6dfd5 100644 (file)
@@ -157,9 +157,11 @@ FEXPORT(__kvm_mips_vcpu_run)
 
 FEXPORT(__kvm_mips_load_asid)
        /* Set the ASID for the Guest Kernel */
-       INT_SLL t0, t0, 1       /* with kseg0 @ 0x40000000, kernel */
-                               /* addresses shift to 0x80000000 */
-       bltz    t0, 1f          /* If kernel */
+       PTR_L   t0, VCPU_COP0(k1)
+       LONG_L  t0, COP0_STATUS(t0)
+       andi    t0, KSU_USER | ST0_ERL | ST0_EXL
+       xori    t0, KSU_USER
+       bnez    t0, 1f          /* If kernel */
         INT_ADDIU t1, k1, VCPU_GUEST_KERNEL_ASID  /* (BD)  */
        INT_ADDIU t1, k1, VCPU_GUEST_USER_ASID    /* else user */
 1:
@@ -474,9 +476,11 @@ __kvm_mips_return_to_guest:
        mtc0    t0, CP0_EPC
 
        /* Set the ASID for the Guest Kernel */
-       INT_SLL t0, t0, 1       /* with kseg0 @ 0x40000000, kernel */
-                               /* addresses shift to 0x80000000 */
-       bltz    t0, 1f          /* If kernel */
+       PTR_L   t0, VCPU_COP0(k1)
+       LONG_L  t0, COP0_STATUS(t0)
+       andi    t0, KSU_USER | ST0_ERL | ST0_EXL
+       xori    t0, KSU_USER
+       bnez    t0, 1f          /* If kernel */
         INT_ADDIU t1, k1, VCPU_GUEST_KERNEL_ASID  /* (BD)  */
        INT_ADDIU t1, k1, VCPU_GUEST_USER_ASID    /* else user */
 1:
index 49ff3bfc007e534529d0f61d21b6fddd6578d145..b9b803facdbf7594dc700ca828a2ced604e617aa 100644 (file)
@@ -279,7 +279,7 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, unsigned int id)
 
        if (!gebase) {
                err = -ENOMEM;
-               goto out_free_cpu;
+               goto out_uninit_cpu;
        }
        kvm_debug("Allocated %d bytes for KVM Exception Handlers @ %p\n",
                  ALIGN(size, PAGE_SIZE), gebase);
@@ -343,6 +343,9 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, unsigned int id)
 out_free_gebase:
        kfree(gebase);
 
+out_uninit_cpu:
+       kvm_vcpu_uninit(vcpu);
+
 out_free_cpu:
        kfree(vcpu);
 
index d8117be729a20ee26d2df8bb42a6f58b9670f513..730d394ce5f017991146084f9df53794242c970d 100644 (file)
@@ -145,7 +145,7 @@ static void *mips_dma_alloc_coherent(struct device *dev, size_t size,
 
        gfp = massage_gfp_flags(dev, gfp);
 
-       if (IS_ENABLED(CONFIG_DMA_CMA) && !(gfp & GFP_ATOMIC))
+       if (IS_ENABLED(CONFIG_DMA_CMA) && gfpflags_allow_blocking(gfp))
                page = dma_alloc_from_contiguous(dev,
                                        count, get_order(size));
        if (!page)
index 8a978022630b252fa0547dd137805d6b3c35ec3b..dbbeccc3d714add203aae3ebb5b3a0cd1522f0ae 100644 (file)
@@ -11,6 +11,7 @@
  *  by the Free Software Foundation.
  */
 
+#include <linux/delay.h>
 #include <linux/types.h>
 #include <linux/pci.h>
 #include <linux/io.h>
@@ -232,8 +233,7 @@ static int rt288x_pci_probe(struct platform_device *pdev)
        ioport_resource.end = RT2880_PCI_IO_BASE + RT2880_PCI_IO_SIZE - 1;
 
        rt2880_pci_reg_write(0, RT2880_PCI_REG_PCICFG_ADDR);
-       for (i = 0; i < 0xfffff; i++)
-               ;
+       udelay(1);
 
        rt2880_pci_reg_write(0x79, RT2880_PCI_REG_ARBCTL);
        rt2880_pci_reg_write(0x07FF0001, RT2880_PCI_REG_BAR0SETUP_ADDR);
index 4f925e06c414663023765630cd84211d62679e16..78b2ef49dbc7a45adc720264f66cc9922453ceb2 100644 (file)
@@ -10,6 +10,8 @@
  * option) any later version.
  */
 
+#include <linux/delay.h>
+
 #include <asm/bootinfo.h>
 #include <asm/cacheflush.h>
 #include <asm/idle.h>
@@ -77,7 +79,7 @@ void msp7120_reset(void)
         */
 
        /* Wait a bit for the DDRC to settle */
-       for (i = 0; i < 100000000; i++);
+       mdelay(125);
 
 #if defined(CONFIG_PMC_MSP7120_GW)
        /*
index 244f9427625b5873003cc92132c96a32d99663eb..db8f88b6a3af9cb52dcb2a2a23df94a49cc0eccd 100644 (file)
@@ -3,6 +3,8 @@
  *
  *  Reset a SNI machine.
  */
+#include <linux/delay.h>
+
 #include <asm/io.h>
 #include <asm/reboot.h>
 #include <asm/sni.h>
@@ -32,9 +34,9 @@ void sni_machine_restart(char *command)
        for (;;) {
                for (i = 0; i < 100; i++) {
                        kb_wait();
-                       for (j = 0; j < 100000 ; j++)
-                               /* nothing */;
+                       udelay(50);
                        outb_p(0xfe, 0x64);      /* pulse reset low */
+                       udelay(50);
                }
        }
 }
index 4434b54e1d87c4e10e705ff5b7641d4f52c9616c..78ae5552fdb89cca3c6a5ff4290a2581fbe95079 100644 (file)
@@ -1,6 +1,7 @@
 config MN10300
        def_bool y
        select HAVE_OPROFILE
+       select HAVE_UID16
        select GENERIC_IRQ_SHOW
        select ARCH_WANT_IPC_PARSE_VERSION
        select HAVE_ARCH_TRACEHOOK
@@ -37,9 +38,6 @@ config HIGHMEM
 config NUMA
        def_bool n
 
-config UID16
-       def_bool y
-
 config RWSEM_GENERIC_SPINLOCK
        def_bool y
 
index 223cdcc8203f566483c15051c1ce5cfdfe608791..87bf88ed04c6c0a13220e2b3588b7fedbb6145f3 100644 (file)
@@ -23,22 +23,6 @@ static void __flush_dcache(unsigned long start, unsigned long end)
        end += (cpuinfo.dcache_line_size - 1);
        end &= ~(cpuinfo.dcache_line_size - 1);
 
-       for (addr = start; addr < end; addr += cpuinfo.dcache_line_size) {
-               __asm__ __volatile__ ("   flushda 0(%0)\n"
-                                       : /* Outputs */
-                                       : /* Inputs  */ "r"(addr)
-                                       /* : No clobber */);
-       }
-}
-
-static void __flush_dcache_all(unsigned long start, unsigned long end)
-{
-       unsigned long addr;
-
-       start &= ~(cpuinfo.dcache_line_size - 1);
-       end += (cpuinfo.dcache_line_size - 1);
-       end &= ~(cpuinfo.dcache_line_size - 1);
-
        if (end > start + cpuinfo.dcache_size)
                end = start + cpuinfo.dcache_size;
 
@@ -112,7 +96,7 @@ static void flush_aliases(struct address_space *mapping, struct page *page)
 
 void flush_cache_all(void)
 {
-       __flush_dcache_all(0, cpuinfo.dcache_size);
+       __flush_dcache(0, cpuinfo.dcache_size);
        __flush_icache(0, cpuinfo.icache_size);
 }
 
@@ -182,7 +166,7 @@ void __flush_dcache_page(struct address_space *mapping, struct page *page)
         */
        unsigned long start = (unsigned long)page_address(page);
 
-       __flush_dcache_all(start, start + PAGE_SIZE);
+       __flush_dcache(start, start + PAGE_SIZE);
 }
 
 void flush_dcache_page(struct page *page)
@@ -268,7 +252,7 @@ void copy_from_user_page(struct vm_area_struct *vma, struct page *page,
 {
        flush_cache_page(vma, user_vaddr, page_to_pfn(page));
        memcpy(dst, src, len);
-       __flush_dcache_all((unsigned long)src, (unsigned long)src + len);
+       __flush_dcache((unsigned long)src, (unsigned long)src + len);
        if (vma->vm_flags & VM_EXEC)
                __flush_icache((unsigned long)src, (unsigned long)src + len);
 }
@@ -279,7 +263,7 @@ void copy_to_user_page(struct vm_area_struct *vma, struct page *page,
 {
        flush_cache_page(vma, user_vaddr, page_to_pfn(page));
        memcpy(dst, src, len);
-       __flush_dcache_all((unsigned long)dst, (unsigned long)dst + len);
+       __flush_dcache((unsigned long)dst, (unsigned long)dst + len);
        if (vma->vm_flags & VM_EXEC)
                __flush_icache((unsigned long)dst, (unsigned long)dst + len);
 }
index d8534f95915a3754c233fd14466aef6cbfba40dc..291cee28ccb60da84576ba1d9e103a0dc6e78ba5 100644 (file)
@@ -372,7 +372,8 @@ static inline pte_t pte_mkspecial(pte_t pte)        { return pte; }
  */
 #ifdef CONFIG_HUGETLB_PAGE
 #define pte_huge(pte)           (pte_val(pte) & _PAGE_HUGE)
-#define pte_mkhuge(pte)         (__pte(pte_val(pte) | _PAGE_HUGE))
+#define pte_mkhuge(pte)         (__pte(pte_val(pte) | \
+                                (parisc_requires_coherency() ? 0 : _PAGE_HUGE)))
 #else
 #define pte_huge(pte)           (0)
 #define pte_mkhuge(pte)         (pte)
index 33170384d3ac1a7fdd835c7b8f04484aaf1f244c..35bdccbb203622e116f288741ac4a9bc173034b0 100644 (file)
 #define __NR_execveat          (__NR_Linux + 342)
 #define __NR_membarrier                (__NR_Linux + 343)
 #define __NR_userfaultfd       (__NR_Linux + 344)
+#define __NR_mlock2            (__NR_Linux + 345)
 
-#define __NR_Linux_syscalls    (__NR_userfaultfd + 1)
+#define __NR_Linux_syscalls    (__NR_mlock2 + 1)
 
 
 #define __IGNORE_select                /* newselect */
index 64f2764a8cef8778a0602262a5c5b10e4d68975d..c99f3dde455ce5979ee4e17830704710ba4683af 100644 (file)
@@ -171,24 +171,6 @@ void pcibios_set_master(struct pci_dev *dev)
 }
 
 
-void __init pcibios_init_bus(struct pci_bus *bus)
-{
-       struct pci_dev *dev = bus->self;
-       unsigned short bridge_ctl;
-
-       /* We deal only with pci controllers and pci-pci bridges. */
-       if (!dev || (dev->class >> 8) != PCI_CLASS_BRIDGE_PCI)
-               return;
-
-       /* PCI-PCI bridge - set the cache line and default latency
-          (32) for primary and secondary buses. */
-       pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER, 32);
-
-       pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &bridge_ctl);
-       bridge_ctl |= PCI_BRIDGE_CTL_PARITY | PCI_BRIDGE_CTL_SERR;
-       pci_write_config_word(dev, PCI_BRIDGE_CONTROL, bridge_ctl);
-}
-
 /*
  * pcibios align resources() is called every time generic PCI code
  * wants to generate a new address. The process of looking for
index 78c3ef8c348d5cfdef2b50670a1da348ee49566e..d4ffcfbc98851e7c3f0707ec9d82470d918bed2e 100644 (file)
        ENTRY_COMP(execveat)
        ENTRY_SAME(membarrier)
        ENTRY_SAME(userfaultfd)
+       ENTRY_SAME(mlock2)              /* 345 */
 
 
 .ifne (. - 90b) - (__NR_Linux_syscalls * (91b - 90b))
index 631ede72e226c31c8d9f610bc583fc9f93802191..68f0ed7626bd96252f768c7dcca12e8e0294ef69 100644 (file)
                                reg = <0x520 0x20>;
 
                                phy0: ethernet-phy@1f {
-                                       interrupt-parent = <&mpic>;
-                                       interrupts = <10 1>;
                                        reg = <0x1f>;
                                };
                                phy1: ethernet-phy@0 {
-                                       interrupt-parent = <&mpic>;
-                                       interrupts = <10 1>;
                                        reg = <0>;
                                };
                                phy2: ethernet-phy@1 {
-                                       interrupt-parent = <&mpic>;
-                                       interrupts = <10 1>;
                                        reg = <1>;
                                };
                                phy3: ethernet-phy@2 {
-                                       interrupt-parent = <&mpic>;
-                                       interrupts = <10 1>;
                                        reg = <2>;
                                };
                                tbi0: tbi-phy@11 {
index a908ada8e0a5353f5fce19af6ad3e59779ce2e0e..2220f7a60def314be5c8f23e18ceb8982061cb18 100644 (file)
 #define MSR_TS_T       __MASK(MSR_TS_T_LG)     /*  Transaction Transactional */
 #define MSR_TS_MASK    (MSR_TS_T | MSR_TS_S)   /* Transaction State bits */
 #define MSR_TM_ACTIVE(x) (((x) & MSR_TS_MASK) != 0) /* Transaction active? */
+#define MSR_TM_RESV(x) (((x) & MSR_TS_MASK) == MSR_TS_MASK) /* Reserved */
 #define MSR_TM_TRANSACTIONAL(x)        (((x) & MSR_TS_MASK) == MSR_TS_T)
 #define MSR_TM_SUSPENDED(x)    (((x) & MSR_TS_MASK) == MSR_TS_S)
 
index 80dfe8965df9f7d49fc57a1f1d6773f0c5ffd736..8d14feb40f121129854a7760818e926f7b5b742c 100644 (file)
@@ -590,16 +590,10 @@ static int eeh_reset_device(struct eeh_pe *pe, struct pci_bus *bus)
        eeh_ops->configure_bridge(pe);
        eeh_pe_restore_bars(pe);
 
-       /*
-        * If it's PHB PE, the frozen state on all available PEs should have
-        * been cleared by the PHB reset. Otherwise, we unfreeze the PE and its
-        * child PEs because they might be in frozen state.
-        */
-       if (!(pe->type & EEH_PE_PHB)) {
-               rc = eeh_clear_pe_frozen_state(pe, false);
-               if (rc)
-                       return rc;
-       }
+       /* Clear frozen state */
+       rc = eeh_clear_pe_frozen_state(pe, false);
+       if (rc)
+               return rc;
 
        /* Give the system 5 seconds to finish running the user-space
         * hotplug shutdown scripts, e.g. ifdown for ethernet.  Yes,
index 75b6676c1a0b911b72b7af5a8dc7761173e638e8..646bf4d222c1caeda5c7851de74fbbe0ad0d65d9 100644 (file)
@@ -551,6 +551,24 @@ static void tm_reclaim_thread(struct thread_struct *thr,
                msr_diff &= MSR_FP | MSR_VEC | MSR_VSX | MSR_FE0 | MSR_FE1;
        }
 
+       /*
+        * Use the current MSR TM suspended bit to track if we have
+        * checkpointed state outstanding.
+        * On signal delivery, we'd normally reclaim the checkpointed
+        * state to obtain stack pointer (see:get_tm_stackpointer()).
+        * This will then directly return to userspace without going
+        * through __switch_to(). However, if the stack frame is bad,
+        * we need to exit this thread which calls __switch_to() which
+        * will again attempt to reclaim the already saved tm state.
+        * Hence we need to check that we've not already reclaimed
+        * this state.
+        * We do this using the current MSR, rather tracking it in
+        * some specific thread_struct bit, as it has the additional
+        * benifit of checking for a potential TM bad thing exception.
+        */
+       if (!MSR_TM_SUSPENDED(mfmsr()))
+               return;
+
        tm_reclaim(thr, thr->regs->msr, cause);
 
        /* Having done the reclaim, we now have the checkpointed
index 0dbee465af7a70e6c1ce0b7f1f667a577a7ebed0..ef7c24e84a623882c8f98dbc93aa7ab318a4ff68 100644 (file)
@@ -875,6 +875,15 @@ static long restore_tm_user_regs(struct pt_regs *regs,
                return 1;
 #endif /* CONFIG_SPE */
 
+       /* Get the top half of the MSR from the user context */
+       if (__get_user(msr_hi, &tm_sr->mc_gregs[PT_MSR]))
+               return 1;
+       msr_hi <<= 32;
+       /* If TM bits are set to the reserved value, it's an invalid context */
+       if (MSR_TM_RESV(msr_hi))
+               return 1;
+       /* Pull in the MSR TM bits from the user context */
+       regs->msr = (regs->msr & ~MSR_TS_MASK) | (msr_hi & MSR_TS_MASK);
        /* Now, recheckpoint.  This loads up all of the checkpointed (older)
         * registers, including FP and V[S]Rs.  After recheckpointing, the
         * transactional versions should be loaded.
@@ -884,11 +893,6 @@ static long restore_tm_user_regs(struct pt_regs *regs,
        current->thread.tm_texasr |= TEXASR_FS;
        /* This loads the checkpointed FP/VEC state, if used */
        tm_recheckpoint(&current->thread, msr);
-       /* Get the top half of the MSR */
-       if (__get_user(msr_hi, &tm_sr->mc_gregs[PT_MSR]))
-               return 1;
-       /* Pull in MSR TM from user context */
-       regs->msr = (regs->msr & ~MSR_TS_MASK) | ((msr_hi<<32) & MSR_TS_MASK);
 
        /* This loads the speculative FP/VEC state, if used */
        if (msr & MSR_FP) {
index 20756dfb9f34620ac254577458ac2aa8ff804835..c676ecec0869b26216e87483f54c2c6906ea6d01 100644 (file)
@@ -438,6 +438,10 @@ static long restore_tm_sigcontexts(struct pt_regs *regs,
 
        /* get MSR separately, transfer the LE bit if doing signal return */
        err |= __get_user(msr, &sc->gp_regs[PT_MSR]);
+       /* Don't allow reserved mode. */
+       if (MSR_TM_RESV(msr))
+               return -EINVAL;
+
        /* pull in MSR TM from user context */
        regs->msr = (regs->msr & ~MSR_TS_MASK) | (msr & MSR_TS_MASK);
 
index 6ccfb6c1c707b40e9fd6ba4cb202d70c1faf57cb..0a00e2aed3935ca48052565d784317bda8edbf1f 100644 (file)
@@ -43,11 +43,34 @@ static unsigned int opal_irq_count;
 static unsigned int *opal_irqs;
 
 static void opal_handle_irq_work(struct irq_work *work);
-static __be64 last_outstanding_events;
+static u64 last_outstanding_events;
 static struct irq_work opal_event_irq_work = {
        .func = opal_handle_irq_work,
 };
 
+void opal_handle_events(uint64_t events)
+{
+       int virq, hwirq = 0;
+       u64 mask = opal_event_irqchip.mask;
+
+       if (!in_irq() && (events & mask)) {
+               last_outstanding_events = events;
+               irq_work_queue(&opal_event_irq_work);
+               return;
+       }
+
+       while (events & mask) {
+               hwirq = fls64(events) - 1;
+               if (BIT_ULL(hwirq) & mask) {
+                       virq = irq_find_mapping(opal_event_irqchip.domain,
+                                               hwirq);
+                       if (virq)
+                               generic_handle_irq(virq);
+               }
+               events &= ~BIT_ULL(hwirq);
+       }
+}
+
 static void opal_event_mask(struct irq_data *d)
 {
        clear_bit(d->hwirq, &opal_event_irqchip.mask);
@@ -55,12 +78,12 @@ static void opal_event_mask(struct irq_data *d)
 
 static void opal_event_unmask(struct irq_data *d)
 {
+       __be64 events;
+
        set_bit(d->hwirq, &opal_event_irqchip.mask);
 
-       opal_poll_events(&last_outstanding_events);
-       if (last_outstanding_events & opal_event_irqchip.mask)
-               /* Need to retrigger the interrupt */
-               irq_work_queue(&opal_event_irq_work);
+       opal_poll_events(&events);
+       opal_handle_events(be64_to_cpu(events));
 }
 
 static int opal_event_set_type(struct irq_data *d, unsigned int flow_type)
@@ -96,29 +119,6 @@ static int opal_event_map(struct irq_domain *d, unsigned int irq,
        return 0;
 }
 
-void opal_handle_events(uint64_t events)
-{
-       int virq, hwirq = 0;
-       u64 mask = opal_event_irqchip.mask;
-
-       if (!in_irq() && (events & mask)) {
-               last_outstanding_events = events;
-               irq_work_queue(&opal_event_irq_work);
-               return;
-       }
-
-       while (events & mask) {
-               hwirq = fls64(events) - 1;
-               if (BIT_ULL(hwirq) & mask) {
-                       virq = irq_find_mapping(opal_event_irqchip.domain,
-                                               hwirq);
-                       if (virq)
-                               generic_handle_irq(virq);
-               }
-               events &= ~BIT_ULL(hwirq);
-       }
-}
-
 static irqreturn_t opal_interrupt(int irq, void *data)
 {
        __be64 events;
@@ -131,7 +131,7 @@ static irqreturn_t opal_interrupt(int irq, void *data)
 
 static void opal_handle_irq_work(struct irq_work *work)
 {
-       opal_handle_events(be64_to_cpu(last_outstanding_events));
+       opal_handle_events(last_outstanding_events);
 }
 
 static int opal_event_match(struct irq_domain *h, struct device_node *node,
index 373e32346d68d6c3ae270ca39b96b09fe66b0a6e..6a75352f453c1a46775112c2749b8cff31d62ed1 100644 (file)
@@ -1030,8 +1030,7 @@ static int __inject_extcall(struct kvm_vcpu *vcpu, struct kvm_s390_irq *irq)
                                   src_id, 0);
 
        /* sending vcpu invalid */
-       if (src_id >= KVM_MAX_VCPUS ||
-           kvm_get_vcpu(vcpu->kvm, src_id) == NULL)
+       if (kvm_get_vcpu_by_id(vcpu->kvm, src_id) == NULL)
                return -EINVAL;
 
        if (sclp.has_sigpif)
@@ -1110,6 +1109,10 @@ static int __inject_sigp_emergency(struct kvm_vcpu *vcpu,
        trace_kvm_s390_inject_vcpu(vcpu->vcpu_id, KVM_S390_INT_EMERGENCY,
                                   irq->u.emerg.code, 0);
 
+       /* sending vcpu invalid */
+       if (kvm_get_vcpu_by_id(vcpu->kvm, irq->u.emerg.code) == NULL)
+               return -EINVAL;
+
        set_bit(irq->u.emerg.code, li->sigp_emerg_pending);
        set_bit(IRQ_PEND_EXT_EMERGENCY, &li->pending_irqs);
        atomic_or(CPUSTAT_EXT_INT, li->cpuflags);
index 8fe2f1c722dcabe22b3b3731bdce5e22092703db..846589281b046f414837cbd3f7ab9f4d0c675a51 100644 (file)
@@ -342,12 +342,16 @@ static int kvm_vm_ioctl_enable_cap(struct kvm *kvm, struct kvm_enable_cap *cap)
                r = 0;
                break;
        case KVM_CAP_S390_VECTOR_REGISTERS:
-               if (MACHINE_HAS_VX) {
+               mutex_lock(&kvm->lock);
+               if (atomic_read(&kvm->online_vcpus)) {
+                       r = -EBUSY;
+               } else if (MACHINE_HAS_VX) {
                        set_kvm_facility(kvm->arch.model.fac->mask, 129);
                        set_kvm_facility(kvm->arch.model.fac->list, 129);
                        r = 0;
                } else
                        r = -EINVAL;
+               mutex_unlock(&kvm->lock);
                VM_EVENT(kvm, 3, "ENABLE: CAP_S390_VECTOR_REGISTERS %s",
                         r ? "(not available)" : "(success)");
                break;
index 77191b85ea7af4dd96dc6a1ae819f27faa25233b..d76b51cb4b6207261e495bad832ec07444ec11a5 100644 (file)
@@ -660,7 +660,7 @@ static int handle_pfmf(struct kvm_vcpu *vcpu)
 
        kvm_s390_get_regs_rre(vcpu, &reg1, &reg2);
 
-       if (!MACHINE_HAS_PFMF)
+       if (!test_kvm_facility(vcpu->kvm, 8))
                return kvm_s390_inject_program_int(vcpu, PGM_OPERATION);
 
        if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE)
index da690b69f9fe17a89c3f1dc3cd1b1119b832bd25..77c22d685c7a150a8ecfdccbfca1ec60f08698af 100644 (file)
@@ -291,12 +291,8 @@ static int handle_sigp_dst(struct kvm_vcpu *vcpu, u8 order_code,
                           u16 cpu_addr, u32 parameter, u64 *status_reg)
 {
        int rc;
-       struct kvm_vcpu *dst_vcpu;
+       struct kvm_vcpu *dst_vcpu = kvm_get_vcpu_by_id(vcpu->kvm, cpu_addr);
 
-       if (cpu_addr >= KVM_MAX_VCPUS)
-               return SIGP_CC_NOT_OPERATIONAL;
-
-       dst_vcpu = kvm_get_vcpu(vcpu->kvm, cpu_addr);
        if (!dst_vcpu)
                return SIGP_CC_NOT_OPERATIONAL;
 
@@ -478,7 +474,7 @@ int kvm_s390_handle_sigp_pei(struct kvm_vcpu *vcpu)
        trace_kvm_s390_handle_sigp_pei(vcpu, order_code, cpu_addr);
 
        if (order_code == SIGP_EXTERNAL_CALL) {
-               dest_vcpu = kvm_get_vcpu(vcpu->kvm, cpu_addr);
+               dest_vcpu = kvm_get_vcpu_by_id(vcpu->kvm, cpu_addr);
                BUG_ON(dest_vcpu == NULL);
 
                kvm_s390_vcpu_wakeup(dest_vcpu);
index e6820c86e8c7bc1c0daf34cd9a891c45b3a5775f..47ebd5b5ed55e018343e0c577eb2ca21e885bc17 100644 (file)
 #define __NR_fsetxattr         256
 #define __NR_getxattr          257
 #define __NR_lgetxattr         258
-#define __NR_fgetxattr         269
+#define __NR_fgetxattr         259
 #define __NR_listxattr         260
 #define __NR_llistxattr                261
 #define __NR_flistxattr                262
index 7cfd7f153966719c9201a66ff6043c3e48a47a93..4dca18347ee9a40949d55af11ae6adf07d05ca4b 100644 (file)
@@ -10,7 +10,7 @@
  *  Copyright (C) 2008-2009 Red Hat, Inc., Ingo Molnar
  *  Copyright (C) 2009 Jaswinder Singh Rajput
  *  Copyright (C) 2009 Advanced Micro Devices, Inc., Robert Richter
- *  Copyright (C) 2008-2009 Red Hat, Inc., Peter Zijlstra <pzijlstr@redhat.com>
+ *  Copyright (C) 2008-2009 Red Hat, Inc., Peter Zijlstra
  *  Copyright (C) 2009 Intel Corporation, <markus.t.metzger@intel.com>
  *
  * ppc:
index b0da5aedb336c643baf9163c010c6c679ce6bbdc..3091267c5cc3d30dba854f152ff8d9bbc06c65a2 100644 (file)
@@ -9,7 +9,7 @@
  *  Copyright (C) 2008-2009 Red Hat, Inc., Ingo Molnar
  *  Copyright (C) 2009 Jaswinder Singh Rajput
  *  Copyright (C) 2009 Advanced Micro Devices, Inc., Robert Richter
- *  Copyright (C) 2008-2009 Red Hat, Inc., Peter Zijlstra <pzijlstr@redhat.com>
+ *  Copyright (C) 2008-2009 Red Hat, Inc., Peter Zijlstra
  */
 
 #include <linux/perf_event.h>
index bb509cee3b598807eeae1aca6056e7adaed59e19..8767060d70fb32eb2dfc0a7da1010233973d78ea 100644 (file)
@@ -21,7 +21,7 @@
  *  Copyright (C) 2008-2009 Red Hat, Inc., Ingo Molnar
  *  Copyright (C) 2009 Jaswinder Singh Rajput
  *  Copyright (C) 2009 Advanced Micro Devices, Inc., Robert Richter
- *  Copyright (C) 2008-2009 Red Hat, Inc., Peter Zijlstra <pzijlstr@redhat.com>
+ *  Copyright (C) 2008-2009 Red Hat, Inc., Peter Zijlstra
  *  Copyright (C) 2009 Intel Corporation, <markus.t.metzger@intel.com>
  *  Copyright (C) 2009 Google, Inc., Stephane Eranian
  */
index 25ed4098640eecf5fc23ae5a8a494b7275badb4a..e3abe6f3156d3fbacca4003c072954619c7e1bb1 100644 (file)
@@ -131,7 +131,7 @@ export LDS_ELF_FORMAT := $(ELF_FORMAT)
 # The wrappers will select whether using "malloc" or the kernel allocator.
 LINK_WRAPS = -Wl,--wrap,malloc -Wl,--wrap,free -Wl,--wrap,calloc
 
-LD_FLAGS_CMDLINE = $(foreach opt,$(LDFLAGS),-Wl,$(opt)) -lrt
+LD_FLAGS_CMDLINE = $(foreach opt,$(LDFLAGS),-Wl,$(opt))
 
 # Used by link-vmlinux.sh which has special support for um link
 export CFLAGS_vmlinux := $(LINK-y) $(LINK_WRAPS) $(LD_FLAGS_CMDLINE)
index e697a4136707e13c609a5e51529f87631896b0c6..e9f8445861dc73639bb32742bb5f6fae327a8b4c 100644 (file)
@@ -249,21 +249,23 @@ void close_addr(unsigned char *addr, unsigned char *netmask, void *arg)
 
 char *split_if_spec(char *str, ...)
 {
-       char **arg, *end;
+       char **arg, *end, *ret = NULL;
        va_list ap;
 
        va_start(ap, str);
        while ((arg = va_arg(ap, char **)) != NULL) {
                if (*str == '\0')
-                       return NULL;
+                       goto out;
                end = strchr(str, ',');
                if (end != str)
                        *arg = str;
                if (end == NULL)
-                       return NULL;
+                       goto out;
                *end++ = '\0';
                str = end;
        }
+       ret = str;
+out:
        va_end(ap);
-       return str;
+       return ret;
 }
index 57acbd67d85dbd4051cd3c534ceff2a300ce9906..fc8be0e3a4ff879a2cf9fddc8e017dfa974ffc95 100644 (file)
@@ -69,7 +69,7 @@ void do_signal(struct pt_regs *regs)
        struct ksignal ksig;
        int handled_sig = 0;
 
-       while (get_signal(&ksig)) {
+       if (get_signal(&ksig)) {
                handled_sig = 1;
                /* Whee!  Actually deliver the signal.  */
                handle_signal(&ksig, regs);
index 0033e96c3f09c165e5745ca410048335de2106d7..9011a88353ded70ece09718a04349464ee8467ec 100644 (file)
@@ -23,7 +23,6 @@
 #include <stdarg.h>
 #include <linux/types.h>
 #include <linux/edd.h>
-#include <asm/boot.h>
 #include <asm/setup.h>
 #include "bitops.h"
 #include "ctype.h"
index aa8a96b052e30263d60afc6b81a60e387fc55773..95c7a818c0ed6929800f72fbb5d507fbc4539195 100644 (file)
@@ -19,6 +19,8 @@
 #include "video.h"
 #include "vesa.h"
 
+#include <uapi/asm/boot.h>
+
 /*
  * Common variables
  */
index 05111bb8d018e38c71ae278ee0a78ccff76e34e2..77780e386e9b224ef8ec5421af644abc65d1eebd 100644 (file)
@@ -13,6 +13,8 @@
  * Select video mode
  */
 
+#include <uapi/asm/boot.h>
+
 #include "boot.h"
 #include "video.h"
 #include "vesa.h"
index 53616ca0324440d6cba482c3855433b5a63b4ef9..a55697d19824727fda8306c566bb99cb4ba6d980 100644 (file)
@@ -509,6 +509,17 @@ END(irq_entries_start)
         * tracking that we're in kernel mode.
         */
        SWAPGS
+
+       /*
+        * We need to tell lockdep that IRQs are off.  We can't do this until
+        * we fix gsbase, and we should do it before enter_from_user_mode
+        * (which can take locks).  Since TRACE_IRQS_OFF idempotent,
+        * the simplest way to handle it is to just call it twice if
+        * we enter from user mode.  There's no reason to optimize this since
+        * TRACE_IRQS_OFF is a no-op if lockdep is off.
+        */
+       TRACE_IRQS_OFF
+
 #ifdef CONFIG_CONTEXT_TRACKING
        call enter_from_user_mode
 #endif
@@ -1049,12 +1060,18 @@ ENTRY(error_entry)
        SWAPGS
 
 .Lerror_entry_from_usermode_after_swapgs:
+       /*
+        * We need to tell lockdep that IRQs are off.  We can't do this until
+        * we fix gsbase, and we should do it before enter_from_user_mode
+        * (which can take locks).
+        */
+       TRACE_IRQS_OFF
 #ifdef CONFIG_CONTEXT_TRACKING
        call enter_from_user_mode
 #endif
+       ret
 
 .Lerror_entry_done:
-
        TRACE_IRQS_OFF
        ret
 
index c5b7fb2774d08e17bad6966933e2d753c6de92ec..cc071c6f7d4da2847b3df2c4cbf7666edde5675b 100644 (file)
@@ -9,19 +9,21 @@
 #define PAGE_SIZE      (_AC(1,UL) << PAGE_SHIFT)
 #define PAGE_MASK      (~(PAGE_SIZE-1))
 
+#define PMD_PAGE_SIZE          (_AC(1, UL) << PMD_SHIFT)
+#define PMD_PAGE_MASK          (~(PMD_PAGE_SIZE-1))
+
+#define PUD_PAGE_SIZE          (_AC(1, UL) << PUD_SHIFT)
+#define PUD_PAGE_MASK          (~(PUD_PAGE_SIZE-1))
+
 #define __PHYSICAL_MASK                ((phys_addr_t)((1ULL << __PHYSICAL_MASK_SHIFT) - 1))
 #define __VIRTUAL_MASK         ((1UL << __VIRTUAL_MASK_SHIFT) - 1)
 
-/* Cast PAGE_MASK to a signed type so that it is sign-extended if
+/* Cast *PAGE_MASK to a signed type so that it is sign-extended if
    virtual addresses are 32-bits but physical addresses are larger
    (ie, 32-bit PAE). */
 #define PHYSICAL_PAGE_MASK     (((signed long)PAGE_MASK) & __PHYSICAL_MASK)
-
-#define PMD_PAGE_SIZE          (_AC(1, UL) << PMD_SHIFT)
-#define PMD_PAGE_MASK          (~(PMD_PAGE_SIZE-1))
-
-#define PUD_PAGE_SIZE          (_AC(1, UL) << PUD_SHIFT)
-#define PUD_PAGE_MASK          (~(PUD_PAGE_SIZE-1))
+#define PHYSICAL_PMD_PAGE_MASK (((signed long)PMD_PAGE_MASK) & __PHYSICAL_MASK)
+#define PHYSICAL_PUD_PAGE_MASK (((signed long)PUD_PAGE_MASK) & __PHYSICAL_MASK)
 
 #define HPAGE_SHIFT            PMD_SHIFT
 #define HPAGE_SIZE             (_AC(1,UL) << HPAGE_SHIFT)
index dd5b0aa9dd2f93a01b554029ebc243aa56ae91d3..a471cadb9630e7b8f46340139efaf4f467a24aff 100644 (file)
@@ -279,17 +279,14 @@ static inline pmdval_t native_pmd_val(pmd_t pmd)
 static inline pudval_t pud_pfn_mask(pud_t pud)
 {
        if (native_pud_val(pud) & _PAGE_PSE)
-               return PUD_PAGE_MASK & PHYSICAL_PAGE_MASK;
+               return PHYSICAL_PUD_PAGE_MASK;
        else
                return PTE_PFN_MASK;
 }
 
 static inline pudval_t pud_flags_mask(pud_t pud)
 {
-       if (native_pud_val(pud) & _PAGE_PSE)
-               return ~(PUD_PAGE_MASK & (pudval_t)PHYSICAL_PAGE_MASK);
-       else
-               return ~PTE_PFN_MASK;
+       return ~pud_pfn_mask(pud);
 }
 
 static inline pudval_t pud_flags(pud_t pud)
@@ -300,17 +297,14 @@ static inline pudval_t pud_flags(pud_t pud)
 static inline pmdval_t pmd_pfn_mask(pmd_t pmd)
 {
        if (native_pmd_val(pmd) & _PAGE_PSE)
-               return PMD_PAGE_MASK & PHYSICAL_PAGE_MASK;
+               return PHYSICAL_PMD_PAGE_MASK;
        else
                return PTE_PFN_MASK;
 }
 
 static inline pmdval_t pmd_flags_mask(pmd_t pmd)
 {
-       if (native_pmd_val(pmd) & _PAGE_PSE)
-               return ~(PMD_PAGE_MASK & (pmdval_t)PHYSICAL_PAGE_MASK);
-       else
-               return ~PTE_PFN_MASK;
+       return ~pmd_pfn_mask(pmd);
 }
 
 static inline pmdval_t pmd_flags(pmd_t pmd)
index 48d34d28f5a60543bc72471e2a1931fcf13dc04e..cd0fc0cc78bc34f1d378c844baf6007ce60c1797 100644 (file)
@@ -1,7 +1,6 @@
 #ifndef _ASM_X86_PLATFORM_H
 #define _ASM_X86_PLATFORM_H
 
-#include <asm/pgtable_types.h>
 #include <asm/bootparam.h>
 
 struct mpc_bus;
index 7fc27f1cca586a1752d95fa73c612db03db78437..b3e94ef461fddcea5c6d5696eb012b6c9c89edc8 100644 (file)
@@ -698,3 +698,4 @@ int __init microcode_init(void)
        return error;
 
 }
+late_initcall(microcode_init);
index 4562cf070c279d5edeb0e18ae94c8bff94166dd8..2bf79d7c97dfb8848b1e7b060a66ddedb4605a1a 100644 (file)
@@ -5,7 +5,7 @@
  *  Copyright (C) 2008-2009 Red Hat, Inc., Ingo Molnar
  *  Copyright (C) 2009 Jaswinder Singh Rajput
  *  Copyright (C) 2009 Advanced Micro Devices, Inc., Robert Richter
- *  Copyright (C) 2008-2009 Red Hat, Inc., Peter Zijlstra <pzijlstr@redhat.com>
+ *  Copyright (C) 2008-2009 Red Hat, Inc., Peter Zijlstra
  *  Copyright (C) 2009 Intel Corporation, <markus.t.metzger@intel.com>
  *  Copyright (C) 2009 Google, Inc., Stephane Eranian
  *
index 499f533dd3ccbd22bb84423649e031f2759080ca..d0e35ebb2adb1d34b526fcb04b2bc192c643fd55 100644 (file)
@@ -5,7 +5,7 @@
  *  Copyright (C) 2008-2009 Red Hat, Inc., Ingo Molnar
  *  Copyright (C) 2009 Jaswinder Singh Rajput
  *  Copyright (C) 2009 Advanced Micro Devices, Inc., Robert Richter
- *  Copyright (C) 2008-2009 Red Hat, Inc., Peter Zijlstra <pzijlstr@redhat.com>
+ *  Copyright (C) 2008-2009 Red Hat, Inc., Peter Zijlstra
  *  Copyright (C) 2009 Intel Corporation, <markus.t.metzger@intel.com>
  *  Copyright (C) 2009 Google, Inc., Stephane Eranian
  *
@@ -387,7 +387,7 @@ struct cpu_hw_events {
 /* Check flags and event code/umask, and set the HSW N/A flag */
 #define INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_NA(code, n) \
        __EVENT_CONSTRAINT(code, n,                     \
-                         INTEL_ARCH_EVENT_MASK|INTEL_ARCH_EVENT_MASK, \
+                         INTEL_ARCH_EVENT_MASK|X86_ALL_EVENT_FLAGS, \
                          HWEIGHT(n), 0, PERF_X86_EVENT_PEBS_NA_HSW)
 
 
@@ -627,6 +627,7 @@ struct x86_perf_task_context {
        u64 lbr_from[MAX_LBR_ENTRIES];
        u64 lbr_to[MAX_LBR_ENTRIES];
        u64 lbr_info[MAX_LBR_ENTRIES];
+       int tos;
        int lbr_callstack_users;
        int lbr_stack_state;
 };
index f63360be22387d4fb4cb30728f1834ee4cbd6228..e2a430021e46e71eb2904af74ae5a7d50653d048 100644 (file)
@@ -232,7 +232,7 @@ static struct event_constraint intel_hsw_event_constraints[] = {
        FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */
        FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */
        FIXED_EVENT_CONSTRAINT(0x0300, 2), /* CPU_CLK_UNHALTED.REF */
-       INTEL_EVENT_CONSTRAINT(0x48, 0x4), /* L1D_PEND_MISS.* */
+       INTEL_UEVENT_CONSTRAINT(0x148, 0x4),    /* L1D_PEND_MISS.PENDING */
        INTEL_UEVENT_CONSTRAINT(0x01c0, 0x2), /* INST_RETIRED.PREC_DIST */
        INTEL_EVENT_CONSTRAINT(0xcd, 0x8), /* MEM_TRANS_RETIRED.LOAD_LATENCY */
        /* CYCLE_ACTIVITY.CYCLES_L1D_PENDING */
index 377e8f8ed39186ad4ef57b33264592ed8459a037..a316ca96f1b639d8a0f58f616c1c62d4da61bfdf 100644 (file)
@@ -298,7 +298,7 @@ static bool __match_event(struct perf_event *a, struct perf_event *b)
 static inline struct perf_cgroup *event_to_cgroup(struct perf_event *event)
 {
        if (event->attach_state & PERF_ATTACH_TASK)
-               return perf_cgroup_from_task(event->hw.target);
+               return perf_cgroup_from_task(event->hw.target, event->ctx);
 
        return event->cgrp;
 }
index bfd0b717e944ce012b7a0abe19c89f5294d284e1..659f01e165d57520f33b09ba68818f72cd206a4d 100644 (file)
@@ -239,7 +239,7 @@ static void __intel_pmu_lbr_restore(struct x86_perf_task_context *task_ctx)
        }
 
        mask = x86_pmu.lbr_nr - 1;
-       tos = intel_pmu_lbr_tos();
+       tos = task_ctx->tos;
        for (i = 0; i < tos; i++) {
                lbr_idx = (tos - i) & mask;
                wrmsrl(x86_pmu.lbr_from + lbr_idx, task_ctx->lbr_from[i]);
@@ -247,6 +247,7 @@ static void __intel_pmu_lbr_restore(struct x86_perf_task_context *task_ctx)
                if (x86_pmu.intel_cap.lbr_format == LBR_FORMAT_INFO)
                        wrmsrl(MSR_LBR_INFO_0 + lbr_idx, task_ctx->lbr_info[i]);
        }
+       wrmsrl(x86_pmu.lbr_tos, tos);
        task_ctx->lbr_stack_state = LBR_NONE;
 }
 
@@ -270,6 +271,7 @@ static void __intel_pmu_lbr_save(struct x86_perf_task_context *task_ctx)
                if (x86_pmu.intel_cap.lbr_format == LBR_FORMAT_INFO)
                        rdmsrl(MSR_LBR_INFO_0 + lbr_idx, task_ctx->lbr_info[i]);
        }
+       task_ctx->tos = tos;
        task_ctx->lbr_stack_state = LBR_VALID;
 }
 
index dc5fa6a1e8d640aa8fc407ee3035feb0a1778451..3512ba607361403e587f417cbce2775cdec428a1 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * x86 specific code for irq_work
  *
- * Copyright (C) 2010 Red Hat, Inc., Peter Zijlstra <pzijlstr@redhat.com>
+ * Copyright (C) 2010 Red Hat, Inc., Peter Zijlstra
  */
 
 #include <linux/kernel.h>
index 4f00b63d7ff33bea8f0016eaa8393d8cb6972fad..14415aff18136524cfa3d4c9b07bdde6ee0d6f54 100644 (file)
@@ -4,10 +4,22 @@
  */
 #include <linux/platform_device.h>
 #include <linux/module.h>
+#include <linux/ioport.h>
+
+static int found(u64 start, u64 end, void *data)
+{
+       return 1;
+}
 
 static __init int register_e820_pmem(void)
 {
+       char *pmem = "Persistent Memory (legacy)";
        struct platform_device *pdev;
+       int rc;
+
+       rc = walk_iomem_res(pmem, IORESOURCE_MEM, 0, -1, NULL, found);
+       if (rc <= 0)
+               return 0;
 
        /*
         * See drivers/nvdimm/e820.c for the implementation, this is
index 29db25f9a745ee11d23867cc974438817a6e5b15..d2bbe343fda74a87307675b3a65704e2cc96769b 100644 (file)
@@ -1250,8 +1250,6 @@ void __init setup_arch(char **cmdline_p)
        if (efi_enabled(EFI_BOOT))
                efi_apply_memmap_quirks();
 #endif
-
-       microcode_init();
 }
 
 #ifdef CONFIG_X86_32
index b7ffb7c00075787532ceec10b6aed0028ea01b5c..cb6282c3638ffbd32bcb33663d8cefc17eac8a8e 100644 (file)
@@ -690,12 +690,15 @@ handle_signal(struct ksignal *ksig, struct pt_regs *regs)
        signal_setup_done(failed, ksig, stepping);
 }
 
-#ifdef CONFIG_X86_32
-#define NR_restart_syscall     __NR_restart_syscall
-#else /* !CONFIG_X86_32 */
-#define NR_restart_syscall     \
-       test_thread_flag(TIF_IA32) ? __NR_ia32_restart_syscall : __NR_restart_syscall
-#endif /* CONFIG_X86_32 */
+static inline unsigned long get_nr_restart_syscall(const struct pt_regs *regs)
+{
+#if defined(CONFIG_X86_32) || !defined(CONFIG_X86_64)
+       return __NR_restart_syscall;
+#else /* !CONFIG_X86_32 && CONFIG_X86_64 */
+       return test_thread_flag(TIF_IA32) ? __NR_ia32_restart_syscall :
+               __NR_restart_syscall | (regs->orig_ax & __X32_SYSCALL_BIT);
+#endif /* CONFIG_X86_32 || !CONFIG_X86_64 */
+}
 
 /*
  * Note that 'init' is a special process: it doesn't get signals it doesn't
@@ -724,7 +727,7 @@ void do_signal(struct pt_regs *regs)
                        break;
 
                case -ERESTART_RESTARTBLOCK:
-                       regs->ax = NR_restart_syscall;
+                       regs->ax = get_nr_restart_syscall(regs);
                        regs->ip -= 2;
                        break;
                }
index 892ee2e5ecbce417df506715f7b28d28c403ef91..fbabe4fcc7fbb71802c756289ac01df9b11599ec 100644 (file)
@@ -509,7 +509,7 @@ void __inquire_remote_apic(int apicid)
  */
 #define UDELAY_10MS_DEFAULT 10000
 
-static unsigned int init_udelay = INT_MAX;
+static unsigned int init_udelay = UINT_MAX;
 
 static int __init cpu_init_udelay(char *str)
 {
@@ -522,14 +522,15 @@ early_param("cpu_init_udelay", cpu_init_udelay);
 static void __init smp_quirk_init_udelay(void)
 {
        /* if cmdline changed it from default, leave it alone */
-       if (init_udelay != INT_MAX)
+       if (init_udelay != UINT_MAX)
                return;
 
        /* if modern processor, use no delay */
        if (((boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) && (boot_cpu_data.x86 == 6)) ||
-           ((boot_cpu_data.x86_vendor == X86_VENDOR_AMD) && (boot_cpu_data.x86 >= 0xF)))
+           ((boot_cpu_data.x86_vendor == X86_VENDOR_AMD) && (boot_cpu_data.x86 >= 0xF))) {
                init_udelay = 0;
-
+               return;
+       }
        /* else, use legacy delay */
        init_udelay = UDELAY_10MS_DEFAULT;
 }
index 87acc5221740a588d256f9f0ed4059d366165872..af823a388c1994ba244e3ef0098f1a578408101e 100644 (file)
@@ -7394,11 +7394,6 @@ static int handle_invvpid(struct kvm_vcpu *vcpu)
 
        switch (type) {
        case VMX_VPID_EXTENT_ALL_CONTEXT:
-               if (get_vmcs12(vcpu)->virtual_processor_id == 0) {
-                       nested_vmx_failValid(vcpu,
-                               VMXERR_INVALID_OPERAND_TO_INVEPT_INVVPID);
-                       return 1;
-               }
                __vmx_flush_tlb(vcpu, to_vmx(vcpu)->nested.vpid02);
                nested_vmx_succeed(vcpu);
                break;
index 00462bd63129cfbde2c6b7e7bdf50eb073cc31b8..eed32283d22cc0cafbff75e8f2a246887d4cbb5f 100644 (file)
@@ -2763,6 +2763,26 @@ static int kvm_vcpu_ioctl_set_lapic(struct kvm_vcpu *vcpu,
        return 0;
 }
 
+static int kvm_cpu_accept_dm_intr(struct kvm_vcpu *vcpu)
+{
+       return (!lapic_in_kernel(vcpu) ||
+               kvm_apic_accept_pic_intr(vcpu));
+}
+
+/*
+ * if userspace requested an interrupt window, check that the
+ * interrupt window is open.
+ *
+ * No need to exit to userspace if we already have an interrupt queued.
+ */
+static int kvm_vcpu_ready_for_interrupt_injection(struct kvm_vcpu *vcpu)
+{
+       return kvm_arch_interrupt_allowed(vcpu) &&
+               !kvm_cpu_has_interrupt(vcpu) &&
+               !kvm_event_needs_reinjection(vcpu) &&
+               kvm_cpu_accept_dm_intr(vcpu);
+}
+
 static int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu,
                                    struct kvm_interrupt *irq)
 {
@@ -2786,6 +2806,7 @@ static int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu,
                return -EEXIST;
 
        vcpu->arch.pending_external_vector = irq->irq;
+       kvm_make_request(KVM_REQ_EVENT, vcpu);
        return 0;
 }
 
@@ -5910,23 +5931,10 @@ static int emulator_fix_hypercall(struct x86_emulate_ctxt *ctxt)
        return emulator_write_emulated(ctxt, rip, instruction, 3, NULL);
 }
 
-/*
- * Check if userspace requested an interrupt window, and that the
- * interrupt window is open.
- *
- * No need to exit to userspace if we already have an interrupt queued.
- */
 static int dm_request_for_irq_injection(struct kvm_vcpu *vcpu)
 {
-       if (!vcpu->run->request_interrupt_window || pic_in_kernel(vcpu->kvm))
-               return false;
-
-       if (kvm_cpu_has_interrupt(vcpu))
-               return false;
-
-       return (irqchip_split(vcpu->kvm)
-               ? kvm_apic_accept_pic_intr(vcpu)
-               : kvm_arch_interrupt_allowed(vcpu));
+       return vcpu->run->request_interrupt_window &&
+               likely(!pic_in_kernel(vcpu->kvm));
 }
 
 static void post_kvm_run_save(struct kvm_vcpu *vcpu)
@@ -5937,17 +5945,9 @@ static void post_kvm_run_save(struct kvm_vcpu *vcpu)
        kvm_run->flags = is_smm(vcpu) ? KVM_RUN_X86_SMM : 0;
        kvm_run->cr8 = kvm_get_cr8(vcpu);
        kvm_run->apic_base = kvm_get_apic_base(vcpu);
-       if (!irqchip_in_kernel(vcpu->kvm))
-               kvm_run->ready_for_interrupt_injection =
-                       kvm_arch_interrupt_allowed(vcpu) &&
-                       !kvm_cpu_has_interrupt(vcpu) &&
-                       !kvm_event_needs_reinjection(vcpu);
-       else if (!pic_in_kernel(vcpu->kvm))
-               kvm_run->ready_for_interrupt_injection =
-                       kvm_apic_accept_pic_intr(vcpu) &&
-                       !kvm_cpu_has_interrupt(vcpu);
-       else
-               kvm_run->ready_for_interrupt_injection = 1;
+       kvm_run->ready_for_interrupt_injection =
+               pic_in_kernel(vcpu->kvm) ||
+               kvm_vcpu_ready_for_interrupt_injection(vcpu);
 }
 
 static void update_cr8_intercept(struct kvm_vcpu *vcpu)
@@ -6360,8 +6360,10 @@ void kvm_arch_mmu_notifier_invalidate_page(struct kvm *kvm,
 static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
 {
        int r;
-       bool req_int_win = !lapic_in_kernel(vcpu) &&
-               vcpu->run->request_interrupt_window;
+       bool req_int_win =
+               dm_request_for_irq_injection(vcpu) &&
+               kvm_cpu_accept_dm_intr(vcpu);
+
        bool req_immediate_exit = false;
 
        if (vcpu->requests) {
@@ -6663,7 +6665,8 @@ static int vcpu_run(struct kvm_vcpu *vcpu)
                if (kvm_cpu_has_pending_timer(vcpu))
                        kvm_inject_pending_timer_irqs(vcpu);
 
-               if (dm_request_for_irq_injection(vcpu)) {
+               if (dm_request_for_irq_injection(vcpu) &&
+                       kvm_vcpu_ready_for_interrupt_injection(vcpu)) {
                        r = 0;
                        vcpu->run->exit_reason = KVM_EXIT_IRQ_WINDOW_OPEN;
                        ++vcpu->stat.request_irq_exits;
index 1202d5ca2fb582d1a71cad1c85f65b61b907c441..b2fd67da1701433d9168ebf1d0a908330544bd7d 100644 (file)
@@ -101,19 +101,19 @@ static int get_reg_offset(struct insn *insn, struct pt_regs *regs,
        switch (type) {
        case REG_TYPE_RM:
                regno = X86_MODRM_RM(insn->modrm.value);
-               if (X86_REX_B(insn->rex_prefix.value) == 1)
+               if (X86_REX_B(insn->rex_prefix.value))
                        regno += 8;
                break;
 
        case REG_TYPE_INDEX:
                regno = X86_SIB_INDEX(insn->sib.value);
-               if (X86_REX_X(insn->rex_prefix.value) == 1)
+               if (X86_REX_X(insn->rex_prefix.value))
                        regno += 8;
                break;
 
        case REG_TYPE_BASE:
                regno = X86_SIB_BASE(insn->sib.value);
-               if (X86_REX_B(insn->rex_prefix.value) == 1)
+               if (X86_REX_B(insn->rex_prefix.value))
                        regno += 8;
                break;
 
index 7bcf06a7cd12069e9e4f5c2f13066e1551ba8a27..6eb3c8af96e23678f16378858d05d435e12199fd 100644 (file)
@@ -50,18 +50,9 @@ void x86_pci_root_bus_resources(int bus, struct list_head *resources)
        if (!found)
                pci_add_resource(resources, &info->busn);
 
-       list_for_each_entry(root_res, &info->resources, list) {
-               struct resource *res;
-               struct resource *root;
+       list_for_each_entry(root_res, &info->resources, list)
+               pci_add_resource(resources, &root_res->res);
 
-               res = &root_res->res;
-               pci_add_resource(resources, res);
-               if (res->flags & IORESOURCE_IO)
-                       root = &ioport_resource;
-               else
-                       root = &iomem_resource;
-               insert_resource(root, res);
-       }
        return;
 
 default_resources:
index 06934a8a48724dc5fc6600b49178e9573e7558c5..e5f854ce2d72404237067031a09297c8f0d3f424 100644 (file)
@@ -211,7 +211,7 @@ static int copy_sc_from_user(struct pt_regs *regs,
                if (err)
                        return 1;
 
-               err = convert_fxsr_from_user(&fpx, sc.fpstate);
+               err = convert_fxsr_from_user(&fpx, (void *)sc.fpstate);
                if (err)
                        return 1;
 
@@ -227,7 +227,7 @@ static int copy_sc_from_user(struct pt_regs *regs,
        {
                struct user_i387_struct fp;
 
-               err = copy_from_user(&fp, sc.fpstate,
+               err = copy_from_user(&fp, (void *)sc.fpstate,
                                     sizeof(struct user_i387_struct));
                if (err)
                        return 1;
@@ -291,7 +291,7 @@ static int copy_sc_to_user(struct sigcontext __user *to,
 #endif
 #undef PUTREG
        sc.oldmask = mask;
-       sc.fpstate = to_fp;
+       sc.fpstate = (unsigned long)to_fp;
 
        err = copy_to_user(to, &sc, sizeof(struct sigcontext));
        if (err)
@@ -468,12 +468,10 @@ long sys_sigreturn(void)
        struct sigframe __user *frame = (struct sigframe __user *)(sp - 8);
        sigset_t set;
        struct sigcontext __user *sc = &frame->sc;
-       unsigned long __user *oldmask = &sc->oldmask;
-       unsigned long __user *extramask = frame->extramask;
        int sig_size = (_NSIG_WORDS - 1) * sizeof(unsigned long);
 
-       if (copy_from_user(&set.sig[0], oldmask, sizeof(set.sig[0])) ||
-           copy_from_user(&set.sig[1], extramask, sig_size))
+       if (copy_from_user(&set.sig[0], (void *)sc->oldmask, sizeof(set.sig[0])) ||
+           copy_from_user(&set.sig[1], frame->extramask, sig_size))
                goto segfault;
 
        set_current_blocked(&set);
@@ -505,6 +503,7 @@ int setup_signal_stack_si(unsigned long stack_top, struct ksignal *ksig,
 {
        struct rt_sigframe __user *frame;
        int err = 0, sig = ksig->sig;
+       unsigned long fp_to;
 
        frame = (struct rt_sigframe __user *)
                round_down(stack_top - sizeof(struct rt_sigframe), 16);
@@ -526,7 +525,10 @@ int setup_signal_stack_si(unsigned long stack_top, struct ksignal *ksig,
        err |= __save_altstack(&frame->uc.uc_stack, PT_REGS_SP(regs));
        err |= copy_sc_to_user(&frame->uc.uc_mcontext, &frame->fpstate, regs,
                               set->sig[0]);
-       err |= __put_user(&frame->fpstate, &frame->uc.uc_mcontext.fpstate);
+
+       fp_to = (unsigned long)&frame->fpstate;
+
+       err |= __put_user(fp_to, &frame->uc.uc_mcontext.fpstate);
        if (sizeof(*set) == 16) {
                err |= __put_user(set->sig[0], &frame->uc.uc_sigmask.sig[0]);
                err |= __put_user(set->sig[1], &frame->uc.uc_sigmask.sig[1]);
index 5bcdfc10c23a6340367c4b9781496a49b5c81efe..5a37188b559fba8feb1da48b00d5290c3a6a09b6 100644 (file)
@@ -1127,15 +1127,15 @@ void blkcg_exit_queue(struct request_queue *q)
  * of the main cic data structures.  For now we allow a task to change
  * its cgroup only if it's the only owner of its ioc.
  */
-static int blkcg_can_attach(struct cgroup_subsys_state *css,
-                           struct cgroup_taskset *tset)
+static int blkcg_can_attach(struct cgroup_taskset *tset)
 {
        struct task_struct *task;
+       struct cgroup_subsys_state *dst_css;
        struct io_context *ioc;
        int ret = 0;
 
        /* task_lock() is needed to avoid races with exit_io_context() */
-       cgroup_taskset_for_each(task, tset) {
+       cgroup_taskset_for_each(task, dst_css, tset) {
                task_lock(task);
                ioc = task->io_context;
                if (ioc && atomic_read(&ioc->nr_tasks) > 1)
index 5131993b23a1a2b35670adcbd4ab7d569a29a3d2..3636be469fa2edfef939985135654a394d639a9b 100644 (file)
@@ -2114,7 +2114,8 @@ blk_qc_t submit_bio(int rw, struct bio *bio)
 EXPORT_SYMBOL(submit_bio);
 
 /**
- * blk_rq_check_limits - Helper function to check a request for the queue limit
+ * blk_cloned_rq_check_limits - Helper function to check a cloned request
+ *                              for new the queue limits
  * @q:  the queue
  * @rq: the request being checked
  *
@@ -2125,20 +2126,13 @@ EXPORT_SYMBOL(submit_bio);
  *    after it is inserted to @q, it should be checked against @q before
  *    the insertion using this generic function.
  *
- *    This function should also be useful for request stacking drivers
- *    in some cases below, so export this function.
  *    Request stacking drivers like request-based dm may change the queue
- *    limits while requests are in the queue (e.g. dm's table swapping).
- *    Such request stacking drivers should check those requests against
- *    the new queue limits again when they dispatch those requests,
- *    although such checkings are also done against the old queue limits
- *    when submitting requests.
+ *    limits when retrying requests on other queues. Those requests need
+ *    to be checked against the new queue limits again during dispatch.
  */
-int blk_rq_check_limits(struct request_queue *q, struct request *rq)
+static int blk_cloned_rq_check_limits(struct request_queue *q,
+                                     struct request *rq)
 {
-       if (!rq_mergeable(rq))
-               return 0;
-
        if (blk_rq_sectors(rq) > blk_queue_get_max_sectors(q, rq->cmd_flags)) {
                printk(KERN_ERR "%s: over max size limit.\n", __func__);
                return -EIO;
@@ -2158,7 +2152,6 @@ int blk_rq_check_limits(struct request_queue *q, struct request *rq)
 
        return 0;
 }
-EXPORT_SYMBOL_GPL(blk_rq_check_limits);
 
 /**
  * blk_insert_cloned_request - Helper for stacking drivers to submit a request
@@ -2170,7 +2163,7 @@ int blk_insert_cloned_request(struct request_queue *q, struct request *rq)
        unsigned long flags;
        int where = ELEVATOR_INSERT_BACK;
 
-       if (blk_rq_check_limits(q, rq))
+       if (blk_cloned_rq_check_limits(q, rq))
                return -EIO;
 
        if (rq->rq_disk &&
@@ -3412,6 +3405,9 @@ int blk_pre_runtime_suspend(struct request_queue *q)
 {
        int ret = 0;
 
+       if (!q->dev)
+               return ret;
+
        spin_lock_irq(q->queue_lock);
        if (q->nr_pending) {
                ret = -EBUSY;
@@ -3439,6 +3435,9 @@ EXPORT_SYMBOL(blk_pre_runtime_suspend);
  */
 void blk_post_runtime_suspend(struct request_queue *q, int err)
 {
+       if (!q->dev)
+               return;
+
        spin_lock_irq(q->queue_lock);
        if (!err) {
                q->rpm_status = RPM_SUSPENDED;
@@ -3463,6 +3462,9 @@ EXPORT_SYMBOL(blk_post_runtime_suspend);
  */
 void blk_pre_runtime_resume(struct request_queue *q)
 {
+       if (!q->dev)
+               return;
+
        spin_lock_irq(q->queue_lock);
        q->rpm_status = RPM_RESUMING;
        spin_unlock_irq(q->queue_lock);
@@ -3485,6 +3487,9 @@ EXPORT_SYMBOL(blk_pre_runtime_resume);
  */
 void blk_post_runtime_resume(struct request_queue *q, int err)
 {
+       if (!q->dev)
+               return;
+
        spin_lock_irq(q->queue_lock);
        if (!err) {
                q->rpm_status = RPM_ACTIVE;
index de5716d8e525969e7849767a775aabec9e4d8b96..e01405a3e8b3f51ce0424a844fadb3304bda5e44 100644 (file)
@@ -76,6 +76,9 @@ static struct bio *blk_bio_segment_split(struct request_queue *q,
        struct bio_vec bv, bvprv, *bvprvp = NULL;
        struct bvec_iter iter;
        unsigned seg_size = 0, nsegs = 0, sectors = 0;
+       unsigned front_seg_size = bio->bi_seg_front_size;
+       bool do_split = true;
+       struct bio *new = NULL;
 
        bio_for_each_segment(bv, bio, iter) {
                if (sectors + (bv.bv_len >> 9) > queue_max_sectors(q))
@@ -98,8 +101,11 @@ static struct bio *blk_bio_segment_split(struct request_queue *q,
 
                        seg_size += bv.bv_len;
                        bvprv = bv;
-                       bvprvp = &bv;
+                       bvprvp = &bvprv;
                        sectors += bv.bv_len >> 9;
+
+                       if (nsegs == 1 && seg_size > front_seg_size)
+                               front_seg_size = seg_size;
                        continue;
                }
 new_segment:
@@ -108,16 +114,29 @@ new_segment:
 
                nsegs++;
                bvprv = bv;
-               bvprvp = &bv;
+               bvprvp = &bvprv;
                seg_size = bv.bv_len;
                sectors += bv.bv_len >> 9;
+
+               if (nsegs == 1 && seg_size > front_seg_size)
+                       front_seg_size = seg_size;
        }
 
-       *segs = nsegs;
-       return NULL;
+       do_split = false;
 split:
        *segs = nsegs;
-       return bio_split(bio, sectors, GFP_NOIO, bs);
+
+       if (do_split) {
+               new = bio_split(bio, sectors, GFP_NOIO, bs);
+               if (new)
+                       bio = new;
+       }
+
+       bio->bi_seg_front_size = front_seg_size;
+       if (seg_size > bio->bi_seg_back_size)
+               bio->bi_seg_back_size = seg_size;
+
+       return do_split ? new : NULL;
 }
 
 void blk_queue_split(struct request_queue *q, struct bio **bio,
@@ -412,6 +431,12 @@ int blk_rq_map_sg(struct request_queue *q, struct request *rq,
        if (sg)
                sg_mark_end(sg);
 
+       /*
+        * Something must have been wrong if the figured number of
+        * segment is bigger than number of req's physical segments
+        */
+       WARN_ON(nsegs > rq->nr_phys_segments);
+
        return nsegs;
 }
 EXPORT_SYMBOL(blk_rq_map_sg);
index 3ae09de62f19ce2ca230a89ae6137a511fc9ae16..6d6f8feb48c08ab875e67c496193a743709b0621 100644 (file)
@@ -1291,15 +1291,16 @@ static blk_qc_t blk_mq_make_request(struct request_queue *q, struct bio *bio)
                blk_mq_bio_to_request(rq, bio);
 
                /*
-                * we do limited pluging. If bio can be merged, do merge.
+                * We do limited pluging. If the bio can be merged, do that.
                 * Otherwise the existing request in the plug list will be
                 * issued. So the plug list will have one request at most
                 */
                if (plug) {
                        /*
                         * The plug list might get flushed before this. If that
-                        * happens, same_queue_rq is invalid and plug list is empty
-                        **/
+                        * happens, same_queue_rq is invalid and plug list is
+                        * empty
+                        */
                        if (same_queue_rq && !list_empty(&plug->mq_list)) {
                                old_rq = same_queue_rq;
                                list_del_init(&old_rq->queuelist);
@@ -1380,12 +1381,15 @@ static blk_qc_t blk_sq_make_request(struct request_queue *q, struct bio *bio)
                blk_mq_bio_to_request(rq, bio);
                if (!request_count)
                        trace_block_plug(q);
-               else if (request_count >= BLK_MAX_REQUEST_COUNT) {
+
+               blk_mq_put_ctx(data.ctx);
+
+               if (request_count >= BLK_MAX_REQUEST_COUNT) {
                        blk_flush_plug_list(plug, false);
                        trace_block_plug(q);
                }
+
                list_add_tail(&rq->queuelist, &plug->mq_list);
-               blk_mq_put_ctx(data.ctx);
                return cookie;
        }
 
index 7d8f129a1516b408d8ebd827e65ffd6d688b2df8..dd49735839789167d427dc8b64da71c6b21f08f5 100644 (file)
@@ -91,7 +91,8 @@ void blk_set_default_limits(struct queue_limits *lim)
        lim->seg_boundary_mask = BLK_SEG_BOUNDARY_MASK;
        lim->virt_boundary_mask = 0;
        lim->max_segment_size = BLK_MAX_SEGMENT_SIZE;
-       lim->max_sectors = lim->max_hw_sectors = BLK_SAFE_MAX_SECTORS;
+       lim->max_sectors = lim->max_dev_sectors = lim->max_hw_sectors =
+               BLK_SAFE_MAX_SECTORS;
        lim->chunk_sectors = 0;
        lim->max_write_same_sectors = 0;
        lim->max_discard_sectors = 0;
@@ -127,6 +128,7 @@ void blk_set_stacking_limits(struct queue_limits *lim)
        lim->max_hw_sectors = UINT_MAX;
        lim->max_segment_size = UINT_MAX;
        lim->max_sectors = UINT_MAX;
+       lim->max_dev_sectors = UINT_MAX;
        lim->max_write_same_sectors = UINT_MAX;
 }
 EXPORT_SYMBOL(blk_set_stacking_limits);
@@ -214,8 +216,8 @@ void blk_queue_bounce_limit(struct request_queue *q, u64 max_addr)
 EXPORT_SYMBOL(blk_queue_bounce_limit);
 
 /**
- * blk_limits_max_hw_sectors - set hard and soft limit of max sectors for request
- * @limits: the queue limits
+ * blk_queue_max_hw_sectors - set max sectors for a request for this queue
+ * @q:  the request queue for the device
  * @max_hw_sectors:  max hardware sectors in the usual 512b unit
  *
  * Description:
@@ -224,13 +226,19 @@ EXPORT_SYMBOL(blk_queue_bounce_limit);
  *    the device driver based upon the capabilities of the I/O
  *    controller.
  *
+ *    max_dev_sectors is a hard limit imposed by the storage device for
+ *    READ/WRITE requests. It is set by the disk driver.
+ *
  *    max_sectors is a soft limit imposed by the block layer for
  *    filesystem type requests.  This value can be overridden on a
  *    per-device basis in /sys/block/<device>/queue/max_sectors_kb.
  *    The soft limit can not exceed max_hw_sectors.
  **/
-void blk_limits_max_hw_sectors(struct queue_limits *limits, unsigned int max_hw_sectors)
+void blk_queue_max_hw_sectors(struct request_queue *q, unsigned int max_hw_sectors)
 {
+       struct queue_limits *limits = &q->limits;
+       unsigned int max_sectors;
+
        if ((max_hw_sectors << 9) < PAGE_CACHE_SIZE) {
                max_hw_sectors = 1 << (PAGE_CACHE_SHIFT - 9);
                printk(KERN_INFO "%s: set to minimum %d\n",
@@ -238,22 +246,9 @@ void blk_limits_max_hw_sectors(struct queue_limits *limits, unsigned int max_hw_
        }
 
        limits->max_hw_sectors = max_hw_sectors;
-       limits->max_sectors = min_t(unsigned int, max_hw_sectors,
-                                   BLK_DEF_MAX_SECTORS);
-}
-EXPORT_SYMBOL(blk_limits_max_hw_sectors);
-
-/**
- * blk_queue_max_hw_sectors - set max sectors for a request for this queue
- * @q:  the request queue for the device
- * @max_hw_sectors:  max hardware sectors in the usual 512b unit
- *
- * Description:
- *    See description for blk_limits_max_hw_sectors().
- **/
-void blk_queue_max_hw_sectors(struct request_queue *q, unsigned int max_hw_sectors)
-{
-       blk_limits_max_hw_sectors(&q->limits, max_hw_sectors);
+       max_sectors = min_not_zero(max_hw_sectors, limits->max_dev_sectors);
+       max_sectors = min_t(unsigned int, max_sectors, BLK_DEF_MAX_SECTORS);
+       limits->max_sectors = max_sectors;
 }
 EXPORT_SYMBOL(blk_queue_max_hw_sectors);
 
@@ -527,6 +522,7 @@ int blk_stack_limits(struct queue_limits *t, struct queue_limits *b,
 
        t->max_sectors = min_not_zero(t->max_sectors, b->max_sectors);
        t->max_hw_sectors = min_not_zero(t->max_hw_sectors, b->max_hw_sectors);
+       t->max_dev_sectors = min_not_zero(t->max_dev_sectors, b->max_dev_sectors);
        t->max_write_same_sectors = min(t->max_write_same_sectors,
                                        b->max_write_same_sectors);
        t->bounce_pfn = min_not_zero(t->bounce_pfn, b->bounce_pfn);
index 565b8dac578297edf327e7451dedfe80a75e5751..e140cc487ce11349ff1917e4e866eccf0a18106c 100644 (file)
@@ -205,6 +205,9 @@ queue_max_sectors_store(struct request_queue *q, const char *page, size_t count)
        if (ret < 0)
                return ret;
 
+       max_hw_sectors_kb = min_not_zero(max_hw_sectors_kb, (unsigned long)
+                                        q->limits.max_dev_sectors >> 1);
+
        if (max_sectors_kb > max_hw_sectors_kb || max_sectors_kb < page_kb)
                return -EINVAL;
 
index 246dfb16c3d988c4f84749065a66977b825c98b5..aa40aa93381b661b73d5aa0f531e247e148c56a0 100644 (file)
@@ -158,11 +158,13 @@ void blk_abort_request(struct request *req)
 {
        if (blk_mark_rq_complete(req))
                return;
-       blk_delete_timer(req);
-       if (req->q->mq_ops)
+
+       if (req->q->mq_ops) {
                blk_mq_rq_timed_out(req, false);
-       else
+       } else {
+               blk_delete_timer(req);
                blk_rq_timed_out(req);
+       }
 }
 EXPORT_SYMBOL_GPL(blk_abort_request);
 
index 3de89d4690f3bf3e0d9abec1976a379b5dc171e5..a163c487cf38c8250ccbf0ec7beac913672796f0 100644 (file)
@@ -21,10 +21,10 @@ static void noop_merged_requests(struct request_queue *q, struct request *rq,
 static int noop_dispatch(struct request_queue *q, int force)
 {
        struct noop_data *nd = q->elevator->elevator_data;
+       struct request *rq;
 
-       if (!list_empty(&nd->queue)) {
-               struct request *rq;
-               rq = list_entry(nd->queue.next, struct request, queuelist);
+       rq = list_first_entry_or_null(&nd->queue, struct request, queuelist);
+       if (rq) {
                list_del_init(&rq->queuelist);
                elv_dispatch_sort(q, rq);
                return 1;
@@ -46,7 +46,7 @@ noop_former_request(struct request_queue *q, struct request *rq)
 
        if (rq->queuelist.prev == &nd->queue)
                return NULL;
-       return list_entry(rq->queuelist.prev, struct request, queuelist);
+       return list_prev_entry(rq, queuelist);
 }
 
 static struct request *
@@ -56,7 +56,7 @@ noop_latter_request(struct request_queue *q, struct request *rq)
 
        if (rq->queuelist.next == &nd->queue)
                return NULL;
-       return list_entry(rq->queuelist.next, struct request, queuelist);
+       return list_next_entry(rq, queuelist);
 }
 
 static int noop_init_queue(struct request_queue *q, struct elevator_type *e)
index 3b030157ec85c45faedd520b6993cd440254d763..746935a5973ca6c76b8f66cfff8d58ce50566994 100644 (file)
@@ -397,7 +397,7 @@ static int drop_partitions(struct gendisk *disk, struct block_device *bdev)
        struct hd_struct *part;
        int res;
 
-       if (bdev->bd_part_count)
+       if (bdev->bd_part_count || bdev->bd_super)
                return -EBUSY;
        res = invalidate_partition(disk, 0);
        if (res)
index c2c48ec64b2709c5f252e164bc3397df0c439210..621317ac4d59f5fd75e433718a194bad7b1c2a56 100644 (file)
@@ -32,7 +32,7 @@ int mac_partition(struct parsed_partitions *state)
        Sector sect;
        unsigned char *data;
        int slot, blocks_in_map;
-       unsigned secsize;
+       unsigned secsize, datasize, partoffset;
 #ifdef CONFIG_PPC_PMAC
        int found_root = 0;
        int found_root_goodness = 0;
@@ -50,10 +50,14 @@ int mac_partition(struct parsed_partitions *state)
        }
        secsize = be16_to_cpu(md->block_size);
        put_dev_sector(sect);
-       data = read_part_sector(state, secsize/512, &sect);
+       datasize = round_down(secsize, 512);
+       data = read_part_sector(state, datasize / 512, &sect);
        if (!data)
                return -1;
-       part = (struct mac_partition *) (data + secsize%512);
+       partoffset = secsize % 512;
+       if (partoffset + sizeof(*part) > datasize)
+               return -1;
+       part = (struct mac_partition *) (data + partoffset);
        if (be16_to_cpu(part->signature) != MAC_PARTITION_MAGIC) {
                put_dev_sector(sect);
                return 0;               /* not a MacOS disk */
index 0aa6fdfb448a8c4081e06aa9dcb041433dc280a5..6d4d4569447ee080ef44eb7c8c17d782bec23103 100644 (file)
@@ -125,7 +125,7 @@ static int aead_wait_for_data(struct sock *sk, unsigned flags)
        if (flags & MSG_DONTWAIT)
                return -EAGAIN;
 
-       set_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
+       sk_set_bit(SOCKWQ_ASYNC_WAITDATA, sk);
 
        for (;;) {
                if (signal_pending(current))
@@ -139,7 +139,7 @@ static int aead_wait_for_data(struct sock *sk, unsigned flags)
        }
        finish_wait(sk_sleep(sk), &wait);
 
-       clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
+       sk_clear_bit(SOCKWQ_ASYNC_WAITDATA, sk);
 
        return err;
 }
index af31a0ee4057370593536cb9f8cc0a4343ab91b8..ca9efe17db1ac4e9e2806528ea28d2d87a954b8f 100644 (file)
@@ -212,7 +212,7 @@ static int skcipher_wait_for_wmem(struct sock *sk, unsigned flags)
        if (flags & MSG_DONTWAIT)
                return -EAGAIN;
 
-       set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags);
+       sk_set_bit(SOCKWQ_ASYNC_NOSPACE, sk);
 
        for (;;) {
                if (signal_pending(current))
@@ -258,7 +258,7 @@ static int skcipher_wait_for_data(struct sock *sk, unsigned flags)
                return -EAGAIN;
        }
 
-       set_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
+       sk_set_bit(SOCKWQ_ASYNC_WAITDATA, sk);
 
        for (;;) {
                if (signal_pending(current))
@@ -272,7 +272,7 @@ static int skcipher_wait_for_data(struct sock *sk, unsigned flags)
        }
        finish_wait(sk_sleep(sk), &wait);
 
-       clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
+       sk_clear_bit(SOCKWQ_ASYNC_WAITDATA, sk);
 
        return err;
 }
index 73d039156ea7694f14a444dea3ccbeda6c45a564..795d0ca714bfe45f25b97d3e6f566088925f5875 100644 (file)
@@ -63,6 +63,7 @@ obj-$(CONFIG_FB_I810)           += video/fbdev/i810/
 obj-$(CONFIG_FB_INTEL)          += video/fbdev/intelfb/
 
 obj-$(CONFIG_PARPORT)          += parport/
+obj-$(CONFIG_NVM)              += lightnvm/
 obj-y                          += base/ block/ misc/ mfd/ nfc/
 obj-$(CONFIG_LIBNVDIMM)                += nvdimm/
 obj-$(CONFIG_DMA_SHARED_BUFFER) += dma-buf/
@@ -70,7 +71,6 @@ obj-$(CONFIG_NUBUS)           += nubus/
 obj-y                          += macintosh/
 obj-$(CONFIG_IDE)              += ide/
 obj-$(CONFIG_SCSI)             += scsi/
-obj-$(CONFIG_NVM)              += lightnvm/
 obj-y                          += nvme/
 obj-$(CONFIG_ATA)              += ata/
 obj-$(CONFIG_TARGET_CORE)      += target/
index 25dbb76c02ccb0fd1d9b56d9956acb115d2e8419..5eef4cb4f70e6995f2d623268d1f8cd2daab63c2 100644 (file)
@@ -58,10 +58,10 @@ config ACPI_CCA_REQUIRED
        bool
 
 config ACPI_DEBUGGER
-       bool "In-kernel debugger (EXPERIMENTAL)"
+       bool "AML debugger interface (EXPERIMENTAL)"
        select ACPI_DEBUG
        help
-         Enable in-kernel debugging facilities: statistics, internal
+         Enable in-kernel debugging of AML facilities: statistics, internal
          object dump, single step control method execution.
          This is still under development, currently enabling this only
          results in the compilation of the ACPICA debugger files.
index f7dab53b352ae0f70838d622ba32da62eb381d83..e7ed39bab97d5d0a97d03919bd615eb5fba4105e 100644 (file)
@@ -233,11 +233,12 @@ static bool add_spa(struct acpi_nfit_desc *acpi_desc,
                struct nfit_table_prev *prev,
                struct acpi_nfit_system_address *spa)
 {
+       size_t length = min_t(size_t, sizeof(*spa), spa->header.length);
        struct device *dev = acpi_desc->dev;
        struct nfit_spa *nfit_spa;
 
        list_for_each_entry(nfit_spa, &prev->spas, list) {
-               if (memcmp(nfit_spa->spa, spa, sizeof(*spa)) == 0) {
+               if (memcmp(nfit_spa->spa, spa, length) == 0) {
                        list_move_tail(&nfit_spa->list, &acpi_desc->spas);
                        return true;
                }
@@ -259,11 +260,12 @@ static bool add_memdev(struct acpi_nfit_desc *acpi_desc,
                struct nfit_table_prev *prev,
                struct acpi_nfit_memory_map *memdev)
 {
+       size_t length = min_t(size_t, sizeof(*memdev), memdev->header.length);
        struct device *dev = acpi_desc->dev;
        struct nfit_memdev *nfit_memdev;
 
        list_for_each_entry(nfit_memdev, &prev->memdevs, list)
-               if (memcmp(nfit_memdev->memdev, memdev, sizeof(*memdev)) == 0) {
+               if (memcmp(nfit_memdev->memdev, memdev, length) == 0) {
                        list_move_tail(&nfit_memdev->list, &acpi_desc->memdevs);
                        return true;
                }
@@ -284,11 +286,12 @@ static bool add_dcr(struct acpi_nfit_desc *acpi_desc,
                struct nfit_table_prev *prev,
                struct acpi_nfit_control_region *dcr)
 {
+       size_t length = min_t(size_t, sizeof(*dcr), dcr->header.length);
        struct device *dev = acpi_desc->dev;
        struct nfit_dcr *nfit_dcr;
 
        list_for_each_entry(nfit_dcr, &prev->dcrs, list)
-               if (memcmp(nfit_dcr->dcr, dcr, sizeof(*dcr)) == 0) {
+               if (memcmp(nfit_dcr->dcr, dcr, length) == 0) {
                        list_move_tail(&nfit_dcr->list, &acpi_desc->dcrs);
                        return true;
                }
@@ -308,11 +311,12 @@ static bool add_bdw(struct acpi_nfit_desc *acpi_desc,
                struct nfit_table_prev *prev,
                struct acpi_nfit_data_region *bdw)
 {
+       size_t length = min_t(size_t, sizeof(*bdw), bdw->header.length);
        struct device *dev = acpi_desc->dev;
        struct nfit_bdw *nfit_bdw;
 
        list_for_each_entry(nfit_bdw, &prev->bdws, list)
-               if (memcmp(nfit_bdw->bdw, bdw, sizeof(*bdw)) == 0) {
+               if (memcmp(nfit_bdw->bdw, bdw, length) == 0) {
                        list_move_tail(&nfit_bdw->list, &acpi_desc->bdws);
                        return true;
                }
@@ -332,11 +336,12 @@ static bool add_idt(struct acpi_nfit_desc *acpi_desc,
                struct nfit_table_prev *prev,
                struct acpi_nfit_interleave *idt)
 {
+       size_t length = min_t(size_t, sizeof(*idt), idt->header.length);
        struct device *dev = acpi_desc->dev;
        struct nfit_idt *nfit_idt;
 
        list_for_each_entry(nfit_idt, &prev->idts, list)
-               if (memcmp(nfit_idt->idt, idt, sizeof(*idt)) == 0) {
+               if (memcmp(nfit_idt->idt, idt, length) == 0) {
                        list_move_tail(&nfit_idt->list, &acpi_desc->idts);
                        return true;
                }
@@ -356,11 +361,12 @@ static bool add_flush(struct acpi_nfit_desc *acpi_desc,
                struct nfit_table_prev *prev,
                struct acpi_nfit_flush_address *flush)
 {
+       size_t length = min_t(size_t, sizeof(*flush), flush->header.length);
        struct device *dev = acpi_desc->dev;
        struct nfit_flush *nfit_flush;
 
        list_for_each_entry(nfit_flush, &prev->flushes, list)
-               if (memcmp(nfit_flush->flush, flush, sizeof(*flush)) == 0) {
+               if (memcmp(nfit_flush->flush, flush, length) == 0) {
                        list_move_tail(&nfit_flush->list, &acpi_desc->flushes);
                        return true;
                }
@@ -655,7 +661,7 @@ static ssize_t revision_show(struct device *dev,
        struct nvdimm_bus_descriptor *nd_desc = to_nd_desc(nvdimm_bus);
        struct acpi_nfit_desc *acpi_desc = to_acpi_desc(nd_desc);
 
-       return sprintf(buf, "%d\n", acpi_desc->nfit->header.revision);
+       return sprintf(buf, "%d\n", acpi_desc->acpi_header.revision);
 }
 static DEVICE_ATTR_RO(revision);
 
@@ -1652,7 +1658,6 @@ int acpi_nfit_init(struct acpi_nfit_desc *acpi_desc, acpi_size sz)
 
        data = (u8 *) acpi_desc->nfit;
        end = data + sz;
-       data += sizeof(struct acpi_table_nfit);
        while (!IS_ERR_OR_NULL(data))
                data = add_table(acpi_desc, &prev, data, end);
 
@@ -1748,13 +1753,29 @@ static int acpi_nfit_add(struct acpi_device *adev)
                return PTR_ERR(acpi_desc);
        }
 
-       acpi_desc->nfit = (struct acpi_table_nfit *) tbl;
+       /*
+        * Save the acpi header for later and then skip it,
+        * making nfit point to the first nfit table header.
+        */
+       acpi_desc->acpi_header = *tbl;
+       acpi_desc->nfit = (void *) tbl + sizeof(struct acpi_table_nfit);
+       sz -= sizeof(struct acpi_table_nfit);
 
        /* Evaluate _FIT and override with that if present */
        status = acpi_evaluate_object(adev->handle, "_FIT", NULL, &buf);
        if (ACPI_SUCCESS(status) && buf.length > 0) {
-               acpi_desc->nfit = (struct acpi_table_nfit *)buf.pointer;
-               sz = buf.length;
+               union acpi_object *obj;
+               /*
+                * Adjust for the acpi_object header of the _FIT
+                */
+               obj = buf.pointer;
+               if (obj->type == ACPI_TYPE_BUFFER) {
+                       acpi_desc->nfit =
+                               (struct acpi_nfit_header *)obj->buffer.pointer;
+                       sz = obj->buffer.length;
+               } else
+                       dev_dbg(dev, "%s invalid type %d, ignoring _FIT\n",
+                                __func__, (int) obj->type);
        }
 
        rc = acpi_nfit_init(acpi_desc, sz);
@@ -1777,7 +1798,8 @@ static void acpi_nfit_notify(struct acpi_device *adev, u32 event)
 {
        struct acpi_nfit_desc *acpi_desc = dev_get_drvdata(&adev->dev);
        struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER, NULL };
-       struct acpi_table_nfit *nfit_saved;
+       struct acpi_nfit_header *nfit_saved;
+       union acpi_object *obj;
        struct device *dev = &adev->dev;
        acpi_status status;
        int ret;
@@ -1808,12 +1830,19 @@ static void acpi_nfit_notify(struct acpi_device *adev, u32 event)
        }
 
        nfit_saved = acpi_desc->nfit;
-       acpi_desc->nfit = (struct acpi_table_nfit *)buf.pointer;
-       ret = acpi_nfit_init(acpi_desc, buf.length);
-       if (!ret) {
-               /* Merge failed, restore old nfit, and exit */
-               acpi_desc->nfit = nfit_saved;
-               dev_err(dev, "failed to merge updated NFIT\n");
+       obj = buf.pointer;
+       if (obj->type == ACPI_TYPE_BUFFER) {
+               acpi_desc->nfit =
+                       (struct acpi_nfit_header *)obj->buffer.pointer;
+               ret = acpi_nfit_init(acpi_desc, obj->buffer.length);
+               if (ret) {
+                       /* Merge failed, restore old nfit, and exit */
+                       acpi_desc->nfit = nfit_saved;
+                       dev_err(dev, "failed to merge updated NFIT\n");
+               }
+       } else {
+               /* Bad _FIT, restore old nfit */
+               dev_err(dev, "Invalid _FIT\n");
        }
        kfree(buf.pointer);
 
index 2ea5c0797c8f4575c090a34352ceba14d9a5af40..3d549a3836590bb9dd55f6dd14dd8619698597ab 100644 (file)
@@ -96,7 +96,8 @@ struct nfit_mem {
 
 struct acpi_nfit_desc {
        struct nvdimm_bus_descriptor nd_desc;
-       struct acpi_table_nfit *nfit;
+       struct acpi_table_header acpi_header;
+       struct acpi_nfit_header *nfit;
        struct mutex spa_map_mutex;
        struct mutex init_mutex;
        struct list_head spa_maps;
index 850d7bf0c873fb64af77ada90e971a733527e2bd..ae3fe4e642035b2d51b2e3f6c4d93e68a6cb1bcc 100644 (file)
@@ -768,6 +768,13 @@ static void pci_acpi_root_add_resources(struct acpi_pci_root_info *info)
                else
                        continue;
 
+               /*
+                * Some legacy x86 host bridge drivers use iomem_resource and
+                * ioport_resource as default resource pool, skip it.
+                */
+               if (res == root)
+                       continue;
+
                conflict = insert_resource_conflict(root, res);
                if (conflict) {
                        dev_info(&info->bridge->dev,
index ff02bb4218fcaae3bbf60821e6d41f81b5a0e40d..cdfbcc54821fd6ea3a5dd6a11c969f12055c7e24 100644 (file)
@@ -314,16 +314,6 @@ static const struct pci_device_id ahci_pci_tbl[] = {
        { PCI_VDEVICE(INTEL, 0x1f37), board_ahci_avn }, /* Avoton RAID */
        { PCI_VDEVICE(INTEL, 0x1f3e), board_ahci_avn }, /* Avoton RAID */
        { PCI_VDEVICE(INTEL, 0x1f3f), board_ahci_avn }, /* Avoton RAID */
-       { PCI_VDEVICE(INTEL, 0xa182), board_ahci }, /* Lewisburg AHCI*/
-       { PCI_VDEVICE(INTEL, 0xa202), board_ahci }, /* Lewisburg AHCI*/
-       { PCI_VDEVICE(INTEL, 0xa184), board_ahci }, /* Lewisburg RAID*/
-       { PCI_VDEVICE(INTEL, 0xa204), board_ahci }, /* Lewisburg RAID*/
-       { PCI_VDEVICE(INTEL, 0xa186), board_ahci }, /* Lewisburg RAID*/
-       { PCI_VDEVICE(INTEL, 0xa206), board_ahci }, /* Lewisburg RAID*/
-       { PCI_VDEVICE(INTEL, 0x2822), board_ahci }, /* Lewisburg RAID*/
-       { PCI_VDEVICE(INTEL, 0x2826), board_ahci }, /* Lewisburg RAID*/
-       { PCI_VDEVICE(INTEL, 0xa18e), board_ahci }, /* Lewisburg RAID*/
-       { PCI_VDEVICE(INTEL, 0xa20e), board_ahci }, /* Lewisburg RAID*/
        { PCI_VDEVICE(INTEL, 0x2823), board_ahci }, /* Wellsburg RAID */
        { PCI_VDEVICE(INTEL, 0x2827), board_ahci }, /* Wellsburg RAID */
        { PCI_VDEVICE(INTEL, 0x8d02), board_ahci }, /* Wellsburg AHCI */
@@ -350,10 +340,22 @@ static const struct pci_device_id ahci_pci_tbl[] = {
        { PCI_VDEVICE(INTEL, 0x9d03), board_ahci }, /* Sunrise Point-LP AHCI */
        { PCI_VDEVICE(INTEL, 0x9d05), board_ahci }, /* Sunrise Point-LP RAID */
        { PCI_VDEVICE(INTEL, 0x9d07), board_ahci }, /* Sunrise Point-LP RAID */
+       { PCI_VDEVICE(INTEL, 0xa102), board_ahci }, /* Sunrise Point-H AHCI */
        { PCI_VDEVICE(INTEL, 0xa103), board_ahci }, /* Sunrise Point-H AHCI */
        { PCI_VDEVICE(INTEL, 0xa105), board_ahci }, /* Sunrise Point-H RAID */
+       { PCI_VDEVICE(INTEL, 0xa106), board_ahci }, /* Sunrise Point-H RAID */
        { PCI_VDEVICE(INTEL, 0xa107), board_ahci }, /* Sunrise Point-H RAID */
        { PCI_VDEVICE(INTEL, 0xa10f), board_ahci }, /* Sunrise Point-H RAID */
+       { PCI_VDEVICE(INTEL, 0x2822), board_ahci }, /* Lewisburg RAID*/
+       { PCI_VDEVICE(INTEL, 0x2826), board_ahci }, /* Lewisburg RAID*/
+       { PCI_VDEVICE(INTEL, 0xa182), board_ahci }, /* Lewisburg AHCI*/
+       { PCI_VDEVICE(INTEL, 0xa184), board_ahci }, /* Lewisburg RAID*/
+       { PCI_VDEVICE(INTEL, 0xa186), board_ahci }, /* Lewisburg RAID*/
+       { PCI_VDEVICE(INTEL, 0xa18e), board_ahci }, /* Lewisburg RAID*/
+       { PCI_VDEVICE(INTEL, 0xa202), board_ahci }, /* Lewisburg AHCI*/
+       { PCI_VDEVICE(INTEL, 0xa204), board_ahci }, /* Lewisburg RAID*/
+       { PCI_VDEVICE(INTEL, 0xa206), board_ahci }, /* Lewisburg RAID*/
+       { PCI_VDEVICE(INTEL, 0xa20e), board_ahci }, /* Lewisburg RAID*/
 
        /* JMicron 360/1/3/5/6, match class to avoid IDE function */
        { PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
index 8490d37aee2a466809c2634e51e8b96386e2eecb..f7a7fa81740e8f7e7f1daa0c6d6e48d344496ceb 100644 (file)
@@ -62,6 +62,7 @@ static void ahci_mvebu_regret_option(struct ahci_host_priv *hpriv)
        writel(0x80, hpriv->mmio + AHCI_VENDOR_SPECIFIC_0_DATA);
 }
 
+#ifdef CONFIG_PM_SLEEP
 static int ahci_mvebu_suspend(struct platform_device *pdev, pm_message_t state)
 {
        return ahci_platform_suspend_host(&pdev->dev);
@@ -81,6 +82,10 @@ static int ahci_mvebu_resume(struct platform_device *pdev)
 
        return ahci_platform_resume_host(&pdev->dev);
 }
+#else
+#define ahci_mvebu_suspend NULL
+#define ahci_mvebu_resume NULL
+#endif
 
 static const struct ata_port_info ahci_mvebu_port_info = {
        .flags     = AHCI_FLAG_COMMON,
index 096064cd6c52b1b0f72bf710d1a56893bd6bff9c..4665512dae44d99e9a5af194812094498d5888cf 100644 (file)
@@ -1273,6 +1273,15 @@ static int ahci_exec_polled_cmd(struct ata_port *ap, int pmp,
        ata_tf_to_fis(tf, pmp, is_cmd, fis);
        ahci_fill_cmd_slot(pp, 0, cmd_fis_len | flags | (pmp << 12));
 
+       /* set port value for softreset of Port Multiplier */
+       if (pp->fbs_enabled && pp->fbs_last_dev != pmp) {
+               tmp = readl(port_mmio + PORT_FBS);
+               tmp &= ~(PORT_FBS_DEV_MASK | PORT_FBS_DEC);
+               tmp |= pmp << PORT_FBS_DEV_OFFSET;
+               writel(tmp, port_mmio + PORT_FBS);
+               pp->fbs_last_dev = pmp;
+       }
+
        /* issue & wait */
        writel(1, port_mmio + PORT_CMD_ISSUE);
 
index cb0508af1459ac43f4aa26f1a16d94134bd9d0bc..961acc788f4490cea48abb4e215cb144d8fc5e93 100644 (file)
@@ -1505,12 +1505,20 @@ static const char *ata_err_string(unsigned int err_mask)
 unsigned int ata_read_log_page(struct ata_device *dev, u8 log,
                               u8 page, void *buf, unsigned int sectors)
 {
+       unsigned long ap_flags = dev->link->ap->flags;
        struct ata_taskfile tf;
        unsigned int err_mask;
        bool dma = false;
 
        DPRINTK("read log page - log 0x%x, page 0x%x\n", log, page);
 
+       /*
+        * Return error without actually issuing the command on controllers
+        * which e.g. lockup on a read log page.
+        */
+       if (ap_flags & ATA_FLAG_NO_LOG_PAGE)
+               return AC_ERR_DEV;
+
 retry:
        ata_tf_init(dev, &tf);
        if (dev->dma_mode && ata_id_has_read_log_dma_ext(dev->id) &&
index 5389579c51204cf336f2689052ccf29c48b8af98..a723ae92978310f64e65eeef44509337a027c8a5 100644 (file)
@@ -45,7 +45,8 @@ enum {
        SATA_FSL_MAX_PRD_DIRECT = 16,   /* Direct PRDT entries */
 
        SATA_FSL_HOST_FLAGS     = (ATA_FLAG_SATA | ATA_FLAG_PIO_DMA |
-                               ATA_FLAG_PMP | ATA_FLAG_NCQ | ATA_FLAG_AN),
+                                  ATA_FLAG_PMP | ATA_FLAG_NCQ |
+                                  ATA_FLAG_AN | ATA_FLAG_NO_LOG_PAGE),
 
        SATA_FSL_MAX_CMDS       = SATA_FSL_QUEUE_DEPTH,
        SATA_FSL_CMD_HDR_SIZE   = 16,   /* 4 DWORDS */
index dea6edcbf145c3d1eaf45d8265ae7f971d6c808c..29bcff086bcedd548f90a15fd67829c7b21a4de9 100644 (file)
@@ -630,6 +630,9 @@ static void sil_dev_config(struct ata_device *dev)
        unsigned int n, quirks = 0;
        unsigned char model_num[ATA_ID_PROD_LEN + 1];
 
+       /* This controller doesn't support trim */
+       dev->horkage |= ATA_HORKAGE_NOTRIM;
+
        ata_id_c_string(dev->id, model_num, ATA_ID_PROD, sizeof(model_num));
 
        for (n = 0; sil_blacklist[n].product; n++)
index 2804aed3f416aea878efde04937937e238ff4e5e..25425d3f257536b291f27aa975bb8f164c0c437c 100644 (file)
@@ -303,6 +303,10 @@ static int memory_subsys_offline(struct device *dev)
        if (mem->state == MEM_OFFLINE)
                return 0;
 
+       /* Can't offline block with non-present sections */
+       if (mem->section_count != sections_per_block)
+               return -EINVAL;
+
        return memory_block_change_state(mem, MEM_OFFLINE, MEM_ONLINE);
 }
 
index e03b1ad25a906334078490786dbd1406ac9ca76b..167418e73445a4f69b372f9205f65ca43f525c9d 100644 (file)
@@ -1775,10 +1775,10 @@ int genpd_dev_pm_attach(struct device *dev)
        }
 
        pd = of_genpd_get_from_provider(&pd_args);
+       of_node_put(pd_args.np);
        if (IS_ERR(pd)) {
                dev_dbg(dev, "%s() failed to find PM domain: %ld\n",
                        __func__, PTR_ERR(pd));
-               of_node_put(dev->of_node);
                return -EPROBE_DEFER;
        }
 
@@ -1796,7 +1796,6 @@ int genpd_dev_pm_attach(struct device *dev)
        if (ret < 0) {
                dev_err(dev, "failed to add to PM domain %s: %d",
                        pd->name, ret);
-               of_node_put(dev->of_node);
                goto out;
        }
 
index e60dd12e23aaee75a2a0d90ba0ba720c28c769e7..1e937ac5f45661b6e2af770e1ab9633e91ad7bd6 100644 (file)
@@ -160,9 +160,6 @@ static bool default_power_down_ok(struct dev_pm_domain *pd)
                struct gpd_timing_data *td;
                s64 constraint_ns;
 
-               if (!pdd->dev->driver)
-                       continue;
-
                /*
                 * Check if the device is allowed to be off long enough for the
                 * domain to turn off and on (that's how much time it will
index a28a562f7b7f245355db7d536e0558c78cc7e374..3457ac8c03e2f3cfe10c8a2ccc26f9a706039831 100644 (file)
@@ -3810,7 +3810,6 @@ static int mtip_block_initialize(struct driver_data *dd)
        sector_t capacity;
        unsigned int index = 0;
        struct kobject *kobj;
-       unsigned char thd_name[16];
 
        if (dd->disk)
                goto skip_create_disk; /* hw init done, before rebuild */
@@ -3958,10 +3957,9 @@ skip_create_disk:
        }
 
 start_service_thread:
-       sprintf(thd_name, "mtip_svc_thd_%02d", index);
        dd->mtip_svc_handler = kthread_create_on_node(mtip_service_thread,
-                                               dd, dd->numa_node, "%s",
-                                               thd_name);
+                                               dd, dd->numa_node,
+                                               "mtip_svc_thd_%02d", index);
 
        if (IS_ERR(dd->mtip_svc_handler)) {
                dev_err(&dd->pdev->dev, "service thread failed to start\n");
index 6255d1c4bba46c802548806ff95ee213ffd3f0e6..8162475d96b55471befacf889acf8dfa28e274ea 100644 (file)
@@ -8,6 +8,7 @@
 #include <linux/slab.h>
 #include <linux/blk-mq.h>
 #include <linux/hrtimer.h>
+#include <linux/lightnvm.h>
 
 struct nullb_cmd {
        struct list_head list;
@@ -17,6 +18,7 @@ struct nullb_cmd {
        struct bio *bio;
        unsigned int tag;
        struct nullb_queue *nq;
+       struct hrtimer timer;
 };
 
 struct nullb_queue {
@@ -39,23 +41,14 @@ struct nullb {
 
        struct nullb_queue *queues;
        unsigned int nr_queues;
+       char disk_name[DISK_NAME_LEN];
 };
 
 static LIST_HEAD(nullb_list);
 static struct mutex lock;
 static int null_major;
 static int nullb_indexes;
-
-struct completion_queue {
-       struct llist_head list;
-       struct hrtimer timer;
-};
-
-/*
- * These are per-cpu for now, they will need to be configured by the
- * complete_queues parameter and appropriately mapped.
- */
-static DEFINE_PER_CPU(struct completion_queue, completion_queues);
+static struct kmem_cache *ppa_cache;
 
 enum {
        NULL_IRQ_NONE           = 0,
@@ -119,6 +112,10 @@ static int nr_devices = 2;
 module_param(nr_devices, int, S_IRUGO);
 MODULE_PARM_DESC(nr_devices, "Number of devices to register");
 
+static bool use_lightnvm;
+module_param(use_lightnvm, bool, S_IRUGO);
+MODULE_PARM_DESC(use_lightnvm, "Register as a LightNVM device");
+
 static int irqmode = NULL_IRQ_SOFTIRQ;
 
 static int null_set_irqmode(const char *str, const struct kernel_param *kp)
@@ -135,8 +132,8 @@ static const struct kernel_param_ops null_irqmode_param_ops = {
 device_param_cb(irqmode, &null_irqmode_param_ops, &irqmode, S_IRUGO);
 MODULE_PARM_DESC(irqmode, "IRQ completion handler. 0-none, 1-softirq, 2-timer");
 
-static int completion_nsec = 10000;
-module_param(completion_nsec, int, S_IRUGO);
+static unsigned long completion_nsec = 10000;
+module_param(completion_nsec, ulong, S_IRUGO);
 MODULE_PARM_DESC(completion_nsec, "Time in ns to complete a request in hardware. Default: 10,000ns");
 
 static int hw_queue_depth = 64;
@@ -173,6 +170,8 @@ static void free_cmd(struct nullb_cmd *cmd)
        put_tag(cmd->nq, cmd->tag);
 }
 
+static enum hrtimer_restart null_cmd_timer_expired(struct hrtimer *timer);
+
 static struct nullb_cmd *__alloc_cmd(struct nullb_queue *nq)
 {
        struct nullb_cmd *cmd;
@@ -183,6 +182,11 @@ static struct nullb_cmd *__alloc_cmd(struct nullb_queue *nq)
                cmd = &nq->cmds[tag];
                cmd->tag = tag;
                cmd->nq = nq;
+               if (irqmode == NULL_IRQ_TIMER) {
+                       hrtimer_init(&cmd->timer, CLOCK_MONOTONIC,
+                                    HRTIMER_MODE_REL);
+                       cmd->timer.function = null_cmd_timer_expired;
+               }
                return cmd;
        }
 
@@ -213,6 +217,8 @@ static struct nullb_cmd *alloc_cmd(struct nullb_queue *nq, int can_wait)
 
 static void end_cmd(struct nullb_cmd *cmd)
 {
+       struct request_queue *q = NULL;
+
        switch (queue_mode)  {
        case NULL_Q_MQ:
                blk_mq_end_request(cmd->rq, 0);
@@ -223,55 +229,37 @@ static void end_cmd(struct nullb_cmd *cmd)
                break;
        case NULL_Q_BIO:
                bio_endio(cmd->bio);
-               break;
+               goto free_cmd;
        }
 
+       if (cmd->rq)
+               q = cmd->rq->q;
+
+       /* Restart queue if needed, as we are freeing a tag */
+       if (q && !q->mq_ops && blk_queue_stopped(q)) {
+               unsigned long flags;
+
+               spin_lock_irqsave(q->queue_lock, flags);
+               if (blk_queue_stopped(q))
+                       blk_start_queue(q);
+               spin_unlock_irqrestore(q->queue_lock, flags);
+       }
+free_cmd:
        free_cmd(cmd);
 }
 
 static enum hrtimer_restart null_cmd_timer_expired(struct hrtimer *timer)
 {
-       struct completion_queue *cq;
-       struct llist_node *entry;
-       struct nullb_cmd *cmd;
-
-       cq = &per_cpu(completion_queues, smp_processor_id());
-
-       while ((entry = llist_del_all(&cq->list)) != NULL) {
-               entry = llist_reverse_order(entry);
-               do {
-                       struct request_queue *q = NULL;
-
-                       cmd = container_of(entry, struct nullb_cmd, ll_list);
-                       entry = entry->next;
-                       if (cmd->rq)
-                               q = cmd->rq->q;
-                       end_cmd(cmd);
-
-                       if (q && !q->mq_ops && blk_queue_stopped(q)) {
-                               spin_lock(q->queue_lock);
-                               if (blk_queue_stopped(q))
-                                       blk_start_queue(q);
-                               spin_unlock(q->queue_lock);
-                       }
-               } while (entry);
-       }
+       end_cmd(container_of(timer, struct nullb_cmd, timer));
 
        return HRTIMER_NORESTART;
 }
 
 static void null_cmd_end_timer(struct nullb_cmd *cmd)
 {
-       struct completion_queue *cq = &per_cpu(completion_queues, get_cpu());
+       ktime_t kt = ktime_set(0, completion_nsec);
 
-       cmd->ll_list.next = NULL;
-       if (llist_add(&cmd->ll_list, &cq->list)) {
-               ktime_t kt = ktime_set(0, completion_nsec);
-
-               hrtimer_start(&cq->timer, kt, HRTIMER_MODE_REL_PINNED);
-       }
-
-       put_cpu();
+       hrtimer_start(&cmd->timer, kt, HRTIMER_MODE_REL);
 }
 
 static void null_softirq_done_fn(struct request *rq)
@@ -369,6 +357,10 @@ static int null_queue_rq(struct blk_mq_hw_ctx *hctx,
 {
        struct nullb_cmd *cmd = blk_mq_rq_to_pdu(bd->rq);
 
+       if (irqmode == NULL_IRQ_TIMER) {
+               hrtimer_init(&cmd->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+               cmd->timer.function = null_cmd_timer_expired;
+       }
        cmd->rq = bd->rq;
        cmd->nq = hctx->driver_data;
 
@@ -427,15 +419,157 @@ static void null_del_dev(struct nullb *nullb)
 {
        list_del_init(&nullb->list);
 
-       del_gendisk(nullb->disk);
+       if (use_lightnvm)
+               nvm_unregister(nullb->disk_name);
+       else
+               del_gendisk(nullb->disk);
        blk_cleanup_queue(nullb->q);
        if (queue_mode == NULL_Q_MQ)
                blk_mq_free_tag_set(&nullb->tag_set);
-       put_disk(nullb->disk);
+       if (!use_lightnvm)
+               put_disk(nullb->disk);
        cleanup_queues(nullb);
        kfree(nullb);
 }
 
+#ifdef CONFIG_NVM
+
+static void null_lnvm_end_io(struct request *rq, int error)
+{
+       struct nvm_rq *rqd = rq->end_io_data;
+       struct nvm_dev *dev = rqd->dev;
+
+       dev->mt->end_io(rqd, error);
+
+       blk_put_request(rq);
+}
+
+static int null_lnvm_submit_io(struct nvm_dev *dev, struct nvm_rq *rqd)
+{
+       struct request_queue *q = dev->q;
+       struct request *rq;
+       struct bio *bio = rqd->bio;
+
+       rq = blk_mq_alloc_request(q, bio_rw(bio), GFP_KERNEL, 0);
+       if (IS_ERR(rq))
+               return -ENOMEM;
+
+       rq->cmd_type = REQ_TYPE_DRV_PRIV;
+       rq->__sector = bio->bi_iter.bi_sector;
+       rq->ioprio = bio_prio(bio);
+
+       if (bio_has_data(bio))
+               rq->nr_phys_segments = bio_phys_segments(q, bio);
+
+       rq->__data_len = bio->bi_iter.bi_size;
+       rq->bio = rq->biotail = bio;
+
+       rq->end_io_data = rqd;
+
+       blk_execute_rq_nowait(q, NULL, rq, 0, null_lnvm_end_io);
+
+       return 0;
+}
+
+static int null_lnvm_id(struct nvm_dev *dev, struct nvm_id *id)
+{
+       sector_t size = gb * 1024 * 1024 * 1024ULL;
+       sector_t blksize;
+       struct nvm_id_group *grp;
+
+       id->ver_id = 0x1;
+       id->vmnt = 0;
+       id->cgrps = 1;
+       id->cap = 0x3;
+       id->dom = 0x1;
+
+       id->ppaf.blk_offset = 0;
+       id->ppaf.blk_len = 16;
+       id->ppaf.pg_offset = 16;
+       id->ppaf.pg_len = 16;
+       id->ppaf.sect_offset = 32;
+       id->ppaf.sect_len = 8;
+       id->ppaf.pln_offset = 40;
+       id->ppaf.pln_len = 8;
+       id->ppaf.lun_offset = 48;
+       id->ppaf.lun_len = 8;
+       id->ppaf.ch_offset = 56;
+       id->ppaf.ch_len = 8;
+
+       do_div(size, bs); /* convert size to pages */
+       do_div(size, 256); /* concert size to pgs pr blk */
+       grp = &id->groups[0];
+       grp->mtype = 0;
+       grp->fmtype = 0;
+       grp->num_ch = 1;
+       grp->num_pg = 256;
+       blksize = size;
+       do_div(size, (1 << 16));
+       grp->num_lun = size + 1;
+       do_div(blksize, grp->num_lun);
+       grp->num_blk = blksize;
+       grp->num_pln = 1;
+
+       grp->fpg_sz = bs;
+       grp->csecs = bs;
+       grp->trdt = 25000;
+       grp->trdm = 25000;
+       grp->tprt = 500000;
+       grp->tprm = 500000;
+       grp->tbet = 1500000;
+       grp->tbem = 1500000;
+       grp->mpos = 0x010101; /* single plane rwe */
+       grp->cpar = hw_queue_depth;
+
+       return 0;
+}
+
+static void *null_lnvm_create_dma_pool(struct nvm_dev *dev, char *name)
+{
+       mempool_t *virtmem_pool;
+
+       virtmem_pool = mempool_create_slab_pool(64, ppa_cache);
+       if (!virtmem_pool) {
+               pr_err("null_blk: Unable to create virtual memory pool\n");
+               return NULL;
+       }
+
+       return virtmem_pool;
+}
+
+static void null_lnvm_destroy_dma_pool(void *pool)
+{
+       mempool_destroy(pool);
+}
+
+static void *null_lnvm_dev_dma_alloc(struct nvm_dev *dev, void *pool,
+                               gfp_t mem_flags, dma_addr_t *dma_handler)
+{
+       return mempool_alloc(pool, mem_flags);
+}
+
+static void null_lnvm_dev_dma_free(void *pool, void *entry,
+                                                       dma_addr_t dma_handler)
+{
+       mempool_free(entry, pool);
+}
+
+static struct nvm_dev_ops null_lnvm_dev_ops = {
+       .identity               = null_lnvm_id,
+       .submit_io              = null_lnvm_submit_io,
+
+       .create_dma_pool        = null_lnvm_create_dma_pool,
+       .destroy_dma_pool       = null_lnvm_destroy_dma_pool,
+       .dev_dma_alloc          = null_lnvm_dev_dma_alloc,
+       .dev_dma_free           = null_lnvm_dev_dma_free,
+
+       /* Simulate nvme protocol restriction */
+       .max_phys_sect          = 64,
+};
+#else
+static struct nvm_dev_ops null_lnvm_dev_ops;
+#endif /* CONFIG_NVM */
+
 static int null_open(struct block_device *bdev, fmode_t mode)
 {
        return 0;
@@ -575,11 +709,6 @@ static int null_add_dev(void)
        queue_flag_set_unlocked(QUEUE_FLAG_NONROT, nullb->q);
        queue_flag_clear_unlocked(QUEUE_FLAG_ADD_RANDOM, nullb->q);
 
-       disk = nullb->disk = alloc_disk_node(1, home_node);
-       if (!disk) {
-               rv = -ENOMEM;
-               goto out_cleanup_blk_queue;
-       }
 
        mutex_lock(&lock);
        list_add_tail(&nullb->list, &nullb_list);
@@ -589,6 +718,21 @@ static int null_add_dev(void)
        blk_queue_logical_block_size(nullb->q, bs);
        blk_queue_physical_block_size(nullb->q, bs);
 
+       sprintf(nullb->disk_name, "nullb%d", nullb->index);
+
+       if (use_lightnvm) {
+               rv = nvm_register(nullb->q, nullb->disk_name,
+                                                       &null_lnvm_dev_ops);
+               if (rv)
+                       goto out_cleanup_blk_queue;
+               goto done;
+       }
+
+       disk = nullb->disk = alloc_disk_node(1, home_node);
+       if (!disk) {
+               rv = -ENOMEM;
+               goto out_cleanup_lightnvm;
+       }
        size = gb * 1024 * 1024 * 1024ULL;
        set_capacity(disk, size >> 9);
 
@@ -598,10 +742,15 @@ static int null_add_dev(void)
        disk->fops              = &null_fops;
        disk->private_data      = nullb;
        disk->queue             = nullb->q;
-       sprintf(disk->disk_name, "nullb%d", nullb->index);
+       strncpy(disk->disk_name, nullb->disk_name, DISK_NAME_LEN);
+
        add_disk(disk);
+done:
        return 0;
 
+out_cleanup_lightnvm:
+       if (use_lightnvm)
+               nvm_unregister(nullb->disk_name);
 out_cleanup_blk_queue:
        blk_cleanup_queue(nullb->q);
 out_cleanup_tags:
@@ -617,7 +766,9 @@ out:
 
 static int __init null_init(void)
 {
+       int ret = 0;
        unsigned int i;
+       struct nullb *nullb;
 
        if (bs > PAGE_SIZE) {
                pr_warn("null_blk: invalid block size\n");
@@ -625,6 +776,18 @@ static int __init null_init(void)
                bs = PAGE_SIZE;
        }
 
+       if (use_lightnvm && bs != 4096) {
+               pr_warn("null_blk: LightNVM only supports 4k block size\n");
+               pr_warn("null_blk: defaults block size to 4k\n");
+               bs = 4096;
+       }
+
+       if (use_lightnvm && queue_mode != NULL_Q_MQ) {
+               pr_warn("null_blk: LightNVM only supported for blk-mq\n");
+               pr_warn("null_blk: defaults queue mode to blk-mq\n");
+               queue_mode = NULL_Q_MQ;
+       }
+
        if (queue_mode == NULL_Q_MQ && use_per_node_hctx) {
                if (submit_queues < nr_online_nodes) {
                        pr_warn("null_blk: submit_queues param is set to %u.",
@@ -638,32 +801,38 @@ static int __init null_init(void)
 
        mutex_init(&lock);
 
-       /* Initialize a separate list for each CPU for issuing softirqs */
-       for_each_possible_cpu(i) {
-               struct completion_queue *cq = &per_cpu(completion_queues, i);
-
-               init_llist_head(&cq->list);
-
-               if (irqmode != NULL_IRQ_TIMER)
-                       continue;
-
-               hrtimer_init(&cq->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
-               cq->timer.function = null_cmd_timer_expired;
-       }
-
        null_major = register_blkdev(0, "nullb");
        if (null_major < 0)
                return null_major;
 
-       for (i = 0; i < nr_devices; i++) {
-               if (null_add_dev()) {
-                       unregister_blkdev(null_major, "nullb");
-                       return -EINVAL;
+       if (use_lightnvm) {
+               ppa_cache = kmem_cache_create("ppa_cache", 64 * sizeof(u64),
+                                                               0, 0, NULL);
+               if (!ppa_cache) {
+                       pr_err("null_blk: unable to create ppa cache\n");
+                       ret = -ENOMEM;
+                       goto err_ppa;
                }
        }
 
+       for (i = 0; i < nr_devices; i++) {
+               ret = null_add_dev();
+               if (ret)
+                       goto err_dev;
+       }
+
        pr_info("null: module loaded\n");
        return 0;
+
+err_dev:
+       while (!list_empty(&nullb_list)) {
+               nullb = list_entry(nullb_list.next, struct nullb, list);
+               null_del_dev(nullb);
+       }
+       kmem_cache_destroy(ppa_cache);
+err_ppa:
+       unregister_blkdev(null_major, "nullb");
+       return ret;
 }
 
 static void __exit null_exit(void)
@@ -678,6 +847,8 @@ static void __exit null_exit(void)
                null_del_dev(nullb);
        }
        mutex_unlock(&lock);
+
+       kmem_cache_destroy(ppa_cache);
 }
 
 module_init(null_init);
index 235708c7c46eee709acb110acb95a28d85ebc946..81ea69fee7ca183313b8e8322833062262279187 100644 (file)
@@ -3442,6 +3442,7 @@ static void rbd_queue_workfn(struct work_struct *work)
                goto err_rq;
        }
        img_request->rq = rq;
+       snapc = NULL; /* img_request consumes a ref */
 
        if (op_type == OBJ_OP_DISCARD)
                result = rbd_img_request_fill(img_request, OBJ_REQUEST_NODATA,
index 9f185694875850427e9613aaf725859c7efbfc63..bf500e0e7362baf72f7a4321e5fda55dc4355f9b 100644 (file)
@@ -117,7 +117,7 @@ static struct platform_driver omap_ocp2scp_driver = {
 
 module_platform_driver(omap_ocp2scp_driver);
 
-MODULE_ALIAS("platform: omap-ocp2scp");
+MODULE_ALIAS("platform:omap-ocp2scp");
 MODULE_AUTHOR("Texas Instruments Inc.");
 MODULE_DESCRIPTION("OMAP OCP2SCP driver");
 MODULE_LICENSE("GPL v2");
index 55fe9020459f2c4bdcec710a90220b2ea32e54db..4cc72fa017c7bbb02c4027e3bf44bc4d102d3849 100644 (file)
@@ -1230,14 +1230,14 @@ static int smi_start_processing(void       *send_info,
 
        new_smi->intf = intf;
 
-       /* Try to claim any interrupts. */
-       if (new_smi->irq_setup)
-               new_smi->irq_setup(new_smi);
-
        /* Set up the timer that drives the interface. */
        setup_timer(&new_smi->si_timer, smi_timeout, (long)new_smi);
        smi_mod_timer(new_smi, jiffies + SI_TIMEOUT_JIFFIES);
 
+       /* Try to claim any interrupts. */
+       if (new_smi->irq_setup)
+               new_smi->irq_setup(new_smi);
+
        /*
         * Check if the user forcefully enabled the daemon.
         */
index 10819e2484145ebae0ef9b1092098d1bbc7848d1..335322dc403f48fcf773028d232e5c772f3cd8b5 100644 (file)
@@ -209,6 +209,8 @@ EXPORT_SYMBOL_GPL(clk_register_gpio_mux);
 
 struct clk_gpio_delayed_register_data {
        const char *gpio_name;
+       int num_parents;
+       const char **parent_names;
        struct device_node *node;
        struct mutex lock;
        struct clk *clk;
@@ -222,8 +224,6 @@ static struct clk *of_clk_gpio_delayed_register_get(
 {
        struct clk_gpio_delayed_register_data *data = _data;
        struct clk *clk;
-       const char **parent_names;
-       int i, num_parents;
        int gpio;
        enum of_gpio_flags of_flags;
 
@@ -248,26 +248,14 @@ static struct clk *of_clk_gpio_delayed_register_get(
                return ERR_PTR(gpio);
        }
 
-       num_parents = of_clk_get_parent_count(data->node);
-
-       parent_names = kcalloc(num_parents, sizeof(char *), GFP_KERNEL);
-       if (!parent_names) {
-               clk = ERR_PTR(-ENOMEM);
-               goto out;
-       }
-
-       for (i = 0; i < num_parents; i++)
-               parent_names[i] = of_clk_get_parent_name(data->node, i);
-
-       clk = data->clk_register_get(data->node->name, parent_names,
-                       num_parents, gpio, of_flags & OF_GPIO_ACTIVE_LOW);
+       clk = data->clk_register_get(data->node->name, data->parent_names,
+                       data->num_parents, gpio, of_flags & OF_GPIO_ACTIVE_LOW);
        if (IS_ERR(clk))
                goto out;
 
        data->clk = clk;
 out:
        mutex_unlock(&data->lock);
-       kfree(parent_names);
 
        return clk;
 }
@@ -296,11 +284,24 @@ static void __init of_gpio_clk_setup(struct device_node *node,
                                unsigned gpio, bool active_low))
 {
        struct clk_gpio_delayed_register_data *data;
+       const char **parent_names;
+       int i, num_parents;
 
        data = kzalloc(sizeof(*data), GFP_KERNEL);
        if (!data)
                return;
 
+       num_parents = of_clk_get_parent_count(node);
+
+       parent_names = kcalloc(num_parents, sizeof(char *), GFP_KERNEL);
+       if (!parent_names)
+               return;
+
+       for (i = 0; i < num_parents; i++)
+               parent_names[i] = of_clk_get_parent_name(node, i);
+
+       data->num_parents = num_parents;
+       data->parent_names = parent_names;
        data->node = node;
        data->gpio_name = gpio_name;
        data->clk_register_get = clk_register_get;
index 1ab0fb81c6a0ef7746d77427c488bdb84235011a..7bc1c4527ae48d0baad2ebb4e141385e695ff8f4 100644 (file)
@@ -778,8 +778,10 @@ static struct clk * __init create_one_cmux(struct clockgen *cg, int idx)
         */
        clksel = (cg_in(cg, hwc->reg) & CLKSEL_MASK) >> CLKSEL_SHIFT;
        div = get_pll_div(cg, hwc, clksel);
-       if (!div)
+       if (!div) {
+               kfree(hwc);
                return NULL;
+       }
 
        pct80_rate = clk_get_rate(div->clk);
        pct80_rate *= 8;
index 0b501a9fef92b96810655b952870c7da58400c2c..cd0f2726f5e0dd0da33b06e4518f02fc231cf1f7 100644 (file)
@@ -292,6 +292,7 @@ static int scpi_clocks_probe(struct platform_device *pdev)
                ret = scpi_clk_add(dev, child, match);
                if (ret) {
                        scpi_clocks_remove(pdev);
+                       of_node_put(child);
                        return ret;
                }
        }
index 8564e4342c7d1fa115c1b5f9043bf6bbb8d6e70d..82fe3662b5f6d43e5bf4d8cc1acb3ea3b29048b9 100644 (file)
@@ -52,7 +52,7 @@ static unsigned long clk_pllv1_recalc_rate(struct clk_hw *hw,
                unsigned long parent_rate)
 {
        struct clk_pllv1 *pll = to_clk_pllv1(hw);
-       long long ll;
+       unsigned long long ull;
        int mfn_abs;
        unsigned int mfi, mfn, mfd, pd;
        u32 reg;
@@ -94,16 +94,16 @@ static unsigned long clk_pllv1_recalc_rate(struct clk_hw *hw,
        rate = parent_rate * 2;
        rate /= pd + 1;
 
-       ll = (unsigned long long)rate * mfn_abs;
+       ull = (unsigned long long)rate * mfn_abs;
 
-       do_div(ll, mfd + 1);
+       do_div(ull, mfd + 1);
 
        if (mfn_is_negative(pll, mfn))
-               ll = -ll;
+               ull = (rate * mfi) - ull;
+       else
+               ull = (rate * mfi) + ull;
 
-       ll = (rate * mfi) + ll;
-
-       return ll;
+       return ull;
 }
 
 static struct clk_ops clk_pllv1_ops = {
index b18f875eac6acadd7e0ae27644fe8af0df240af6..4aeda56ce37279006a5cb8be93f9146d7e3d56d7 100644 (file)
@@ -79,7 +79,7 @@ static unsigned long __clk_pllv2_recalc_rate(unsigned long parent_rate,
 {
        long mfi, mfn, mfd, pdf, ref_clk;
        unsigned long dbl;
-       s64 temp;
+       u64 temp;
 
        dbl = dp_ctl & MXC_PLL_DP_CTL_DPDCK0_2_EN;
 
@@ -98,8 +98,9 @@ static unsigned long __clk_pllv2_recalc_rate(unsigned long parent_rate,
        temp = (u64) ref_clk * abs(mfn);
        do_div(temp, mfd + 1);
        if (mfn < 0)
-               temp = -temp;
-       temp = (ref_clk * mfi) + temp;
+               temp = (ref_clk * mfi) - temp;
+       else
+               temp = (ref_clk * mfi) + temp;
 
        return temp;
 }
@@ -126,7 +127,7 @@ static int __clk_pllv2_set_rate(unsigned long rate, unsigned long parent_rate,
 {
        u32 reg;
        long mfi, pdf, mfn, mfd = 999999;
-       s64 temp64;
+       u64 temp64;
        unsigned long quad_parent_rate;
 
        quad_parent_rate = 4 * parent_rate;
index d1b1c95177bbeb577c88bf06c06121db76477f24..0a94d9661d9123551b5b84cd5764cb9b91a6c176 100644 (file)
@@ -335,22 +335,22 @@ static void __init vf610_clocks_init(struct device_node *ccm_node)
        clk[VF610_CLK_SAI0_SEL] = imx_clk_mux("sai0_sel", CCM_CSCMR1, 0, 2, sai_sels, 4);
        clk[VF610_CLK_SAI0_EN] = imx_clk_gate("sai0_en", "sai0_sel", CCM_CSCDR1, 16);
        clk[VF610_CLK_SAI0_DIV] = imx_clk_divider("sai0_div", "sai0_en", CCM_CSCDR1, 0, 4);
-       clk[VF610_CLK_SAI0] = imx_clk_gate2("sai0", "sai0_div", CCM_CCGR0, CCM_CCGRx_CGn(15));
+       clk[VF610_CLK_SAI0] = imx_clk_gate2("sai0", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(15));
 
        clk[VF610_CLK_SAI1_SEL] = imx_clk_mux("sai1_sel", CCM_CSCMR1, 2, 2, sai_sels, 4);
        clk[VF610_CLK_SAI1_EN] = imx_clk_gate("sai1_en", "sai1_sel", CCM_CSCDR1, 17);
        clk[VF610_CLK_SAI1_DIV] = imx_clk_divider("sai1_div", "sai1_en", CCM_CSCDR1, 4, 4);
-       clk[VF610_CLK_SAI1] = imx_clk_gate2("sai1", "sai1_div", CCM_CCGR1, CCM_CCGRx_CGn(0));
+       clk[VF610_CLK_SAI1] = imx_clk_gate2("sai1", "ipg_bus", CCM_CCGR1, CCM_CCGRx_CGn(0));
 
        clk[VF610_CLK_SAI2_SEL] = imx_clk_mux("sai2_sel", CCM_CSCMR1, 4, 2, sai_sels, 4);
        clk[VF610_CLK_SAI2_EN] = imx_clk_gate("sai2_en", "sai2_sel", CCM_CSCDR1, 18);
        clk[VF610_CLK_SAI2_DIV] = imx_clk_divider("sai2_div", "sai2_en", CCM_CSCDR1, 8, 4);
-       clk[VF610_CLK_SAI2] = imx_clk_gate2("sai2", "sai2_div", CCM_CCGR1, CCM_CCGRx_CGn(1));
+       clk[VF610_CLK_SAI2] = imx_clk_gate2("sai2", "ipg_bus", CCM_CCGR1, CCM_CCGRx_CGn(1));
 
        clk[VF610_CLK_SAI3_SEL] = imx_clk_mux("sai3_sel", CCM_CSCMR1, 6, 2, sai_sels, 4);
        clk[VF610_CLK_SAI3_EN] = imx_clk_gate("sai3_en", "sai3_sel", CCM_CSCDR1, 19);
        clk[VF610_CLK_SAI3_DIV] = imx_clk_divider("sai3_div", "sai3_en", CCM_CSCDR1, 12, 4);
-       clk[VF610_CLK_SAI3] = imx_clk_gate2("sai3", "sai3_div", CCM_CCGR1, CCM_CCGRx_CGn(2));
+       clk[VF610_CLK_SAI3] = imx_clk_gate2("sai3", "ipg_bus", CCM_CCGR1, CCM_CCGRx_CGn(2));
 
        clk[VF610_CLK_NFC_SEL] = imx_clk_mux("nfc_sel", CCM_CSCMR1, 12, 2, nfc_sels, 4);
        clk[VF610_CLK_NFC_EN] = imx_clk_gate("nfc_en", "nfc_sel", CCM_CSCDR2, 9);
index 09d2832fbd7821a56e53fe8dc22ab16548fa3f1c..71fd29348f28b778faacba038cbcc94a887d08ba 100644 (file)
@@ -9,6 +9,7 @@
  * warranty of any kind, whether express or implied.
  */
 
+#include <linux/clk.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/spinlock.h>
index 93e967c0f972f954ef1f7af9bb2f90e0c3241cae..75244915df05f92aad3272887e3f5b55b10ba3be 100644 (file)
@@ -9,6 +9,7 @@
  * warranty of any kind, whether express or implied.
  */
 
+#include <linux/clk.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/spinlock.h>
index 993abcdb32cce825fdb1d2ea835cb69f3ecf94fc..37ba04ba13686c4f986b6559e7175eb005509e67 100644 (file)
@@ -9,6 +9,7 @@
  * warranty of any kind, whether express or implied.
  */
 
+#include <linux/clk.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/spinlock.h>
index 5484c31ec5683c6f92a0c4eeab2ceba1a782e562..0ee1f363e4be154749d4b37a07e215dbd705d76e 100644 (file)
 
 #define SUN4I_PLL2_OUTPUTS             4
 
-struct sun4i_pll2_data {
-       u32     post_div_offset;
-       u32     pre_div_flags;
-};
-
 static DEFINE_SPINLOCK(sun4i_a10_pll2_lock);
 
 static void __init sun4i_pll2_setup(struct device_node *node,
-                                   struct sun4i_pll2_data *data)
+                                   int post_div_offset)
 {
        const char *clk_name = node->name, *parent;
        struct clk **clks, *base_clk, *prediv_clk;
@@ -76,7 +71,7 @@ static void __init sun4i_pll2_setup(struct device_node *node,
                                          parent, 0, reg,
                                          SUN4I_PLL2_PRE_DIV_SHIFT,
                                          SUN4I_PLL2_PRE_DIV_WIDTH,
-                                         data->pre_div_flags,
+                                         CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
                                          &sun4i_a10_pll2_lock);
        if (!prediv_clk) {
                pr_err("Couldn't register the prediv clock\n");
@@ -127,7 +122,7 @@ static void __init sun4i_pll2_setup(struct device_node *node,
         */
        val = readl(reg);
        val &= ~(SUN4I_PLL2_POST_DIV_MASK << SUN4I_PLL2_POST_DIV_SHIFT);
-       val |= (SUN4I_PLL2_POST_DIV_VALUE - data->post_div_offset) << SUN4I_PLL2_POST_DIV_SHIFT;
+       val |= (SUN4I_PLL2_POST_DIV_VALUE - post_div_offset) << SUN4I_PLL2_POST_DIV_SHIFT;
        writel(val, reg);
 
        of_property_read_string_index(node, "clock-output-names",
@@ -191,25 +186,17 @@ err_unmap:
        iounmap(reg);
 }
 
-static struct sun4i_pll2_data sun4i_a10_pll2_data = {
-       .pre_div_flags  = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
-};
-
 static void __init sun4i_a10_pll2_setup(struct device_node *node)
 {
-       sun4i_pll2_setup(node, &sun4i_a10_pll2_data);
+       sun4i_pll2_setup(node, 0);
 }
 
 CLK_OF_DECLARE(sun4i_a10_pll2, "allwinner,sun4i-a10-pll2-clk",
               sun4i_a10_pll2_setup);
 
-static struct sun4i_pll2_data sun5i_a13_pll2_data = {
-       .post_div_offset        = 1,
-};
-
 static void __init sun5i_a13_pll2_setup(struct device_node *node)
 {
-       sun4i_pll2_setup(node, &sun5i_a13_pll2_data);
+       sun4i_pll2_setup(node, 1);
 }
 
 CLK_OF_DECLARE(sun5i_a13_pll2, "allwinner,sun5i-a13-pll2-clk",
index 1dfad0c712cd87c63eb2dabecda3be0e17ba22be..2a5d84fdddc5d56c0f47fe56aa03683569a5e929 100644 (file)
@@ -20,6 +20,8 @@ static struct ti_dt_clk dm816x_clks[] = {
        DT_CLK(NULL, "sys_clkin", "sys_clkin_ck"),
        DT_CLK(NULL, "timer_sys_ck", "sys_clkin_ck"),
        DT_CLK(NULL, "sys_32k_ck", "sys_32k_ck"),
+       DT_CLK(NULL, "timer_32k_ck", "sysclk18_ck"),
+       DT_CLK(NULL, "timer_ext_ck", "tclkin_ck"),
        DT_CLK(NULL, "mpu_ck", "mpu_ck"),
        DT_CLK(NULL, "timer1_fck", "timer1_fck"),
        DT_CLK(NULL, "timer2_fck", "timer2_fck"),
index 9023ca9caf84dde6b02c7ffacdded5244b16795d..b5cc6f66ae5df5e1725dc21ebfd3b18ca5eac1fa 100644 (file)
@@ -240,7 +240,7 @@ u8 omap2_init_dpll_parent(struct clk_hw *hw)
  */
 unsigned long omap2_get_dpll_rate(struct clk_hw_omap *clk)
 {
-       long long dpll_clk;
+       u64 dpll_clk;
        u32 dpll_mult, dpll_div, v;
        struct dpll_data *dd;
 
@@ -262,7 +262,7 @@ unsigned long omap2_get_dpll_rate(struct clk_hw_omap *clk)
        dpll_div = v & dd->div1_mask;
        dpll_div >>= __ffs(dd->div1_mask);
 
-       dpll_clk = (long long)clk_get_rate(dd->clk_ref) * dpll_mult;
+       dpll_clk = (u64)clk_get_rate(dd->clk_ref) * dpll_mult;
        do_div(dpll_clk, dpll_div + 1);
 
        return dpll_clk;
index 5b1726829e6df038de9e8502471cbb6b70414fd5..df2558350fc1d6be681d818c361339acd2afaba3 100644 (file)
@@ -214,7 +214,6 @@ static int ti_clk_divider_set_rate(struct clk_hw *hw, unsigned long rate,
 {
        struct clk_divider *divider;
        unsigned int div, value;
-       unsigned long flags = 0;
        u32 val;
 
        if (!hw || !rate)
@@ -228,9 +227,6 @@ static int ti_clk_divider_set_rate(struct clk_hw *hw, unsigned long rate,
        if (value > div_mask(divider))
                value = div_mask(divider);
 
-       if (divider->lock)
-               spin_lock_irqsave(divider->lock, flags);
-
        if (divider->flags & CLK_DIVIDER_HIWORD_MASK) {
                val = div_mask(divider) << (divider->shift + 16);
        } else {
@@ -240,9 +236,6 @@ static int ti_clk_divider_set_rate(struct clk_hw *hw, unsigned long rate,
        val |= value << divider->shift;
        ti_clk_ll_ops->clk_writel(val, divider->reg);
 
-       if (divider->lock)
-               spin_unlock_irqrestore(divider->lock, flags);
-
        return 0;
 }
 
@@ -256,8 +249,7 @@ static struct clk *_register_divider(struct device *dev, const char *name,
                                     const char *parent_name,
                                     unsigned long flags, void __iomem *reg,
                                     u8 shift, u8 width, u8 clk_divider_flags,
-                                    const struct clk_div_table *table,
-                                    spinlock_t *lock)
+                                    const struct clk_div_table *table)
 {
        struct clk_divider *div;
        struct clk *clk;
@@ -288,7 +280,6 @@ static struct clk *_register_divider(struct device *dev, const char *name,
        div->shift = shift;
        div->width = width;
        div->flags = clk_divider_flags;
-       div->lock = lock;
        div->hw.init = &init;
        div->table = table;
 
@@ -421,7 +412,7 @@ struct clk *ti_clk_register_divider(struct ti_clk *setup)
 
        clk = _register_divider(NULL, setup->name, div->parent,
                                flags, (void __iomem *)reg, div->bit_shift,
-                               width, div_flags, table, NULL);
+                               width, div_flags, table);
 
        if (IS_ERR(clk))
                kfree(table);
@@ -584,8 +575,7 @@ static void __init of_ti_divider_clk_setup(struct device_node *node)
                goto cleanup;
 
        clk = _register_divider(NULL, node->name, parent_name, flags, reg,
-                               shift, width, clk_divider_flags, table,
-                               NULL);
+                               shift, width, clk_divider_flags, table);
 
        if (!IS_ERR(clk)) {
                of_clk_add_provider(node, of_clk_src_simple_get, clk);
index f4b2e9888bdf3c3079b0854b1c04c65a5201c5db..66a0d0ed8b55064ac7a888a1d2e6441d3021ceb1 100644 (file)
@@ -168,7 +168,7 @@ static unsigned long ti_fapll_recalc_rate(struct clk_hw *hw,
 {
        struct fapll_data *fd = to_fapll(hw);
        u32 fapll_n, fapll_p, v;
-       long long rate;
+       u64 rate;
 
        if (ti_fapll_clock_is_bypass(fd))
                return parent_rate;
@@ -314,7 +314,7 @@ static unsigned long ti_fapll_synth_recalc_rate(struct clk_hw *hw,
 {
        struct fapll_synth *synth = to_synth(hw);
        u32 synth_div_m;
-       long long rate;
+       u64 rate;
 
        /* The audio_pll_clk1 is hardwired to produce 32.768KiHz clock */
        if (!synth->div)
index 69f08a1d047d8672a758e441fcd718bbf64bb946..dab9ba88b9d6d2b1b97e2472694bbb588997d8de 100644 (file)
@@ -69,7 +69,6 @@ static int ti_clk_mux_set_parent(struct clk_hw *hw, u8 index)
 {
        struct clk_mux *mux = to_clk_mux(hw);
        u32 val;
-       unsigned long flags = 0;
 
        if (mux->table) {
                index = mux->table[index];
@@ -81,9 +80,6 @@ static int ti_clk_mux_set_parent(struct clk_hw *hw, u8 index)
                        index++;
        }
 
-       if (mux->lock)
-               spin_lock_irqsave(mux->lock, flags);
-
        if (mux->flags & CLK_MUX_HIWORD_MASK) {
                val = mux->mask << (mux->shift + 16);
        } else {
@@ -93,9 +89,6 @@ static int ti_clk_mux_set_parent(struct clk_hw *hw, u8 index)
        val |= index << mux->shift;
        ti_clk_ll_ops->clk_writel(val, mux->reg);
 
-       if (mux->lock)
-               spin_unlock_irqrestore(mux->lock, flags);
-
        return 0;
 }
 
@@ -109,7 +102,7 @@ static struct clk *_register_mux(struct device *dev, const char *name,
                                 const char **parent_names, u8 num_parents,
                                 unsigned long flags, void __iomem *reg,
                                 u8 shift, u32 mask, u8 clk_mux_flags,
-                                u32 *table, spinlock_t *lock)
+                                u32 *table)
 {
        struct clk_mux *mux;
        struct clk *clk;
@@ -133,7 +126,6 @@ static struct clk *_register_mux(struct device *dev, const char *name,
        mux->shift = shift;
        mux->mask = mask;
        mux->flags = clk_mux_flags;
-       mux->lock = lock;
        mux->table = table;
        mux->hw.init = &init;
 
@@ -175,7 +167,7 @@ struct clk *ti_clk_register_mux(struct ti_clk *setup)
 
        return _register_mux(NULL, setup->name, mux->parents, mux->num_parents,
                             flags, (void __iomem *)reg, mux->bit_shift, mask,
-                            mux_flags, NULL, NULL);
+                            mux_flags, NULL);
 }
 
 /**
@@ -227,8 +219,7 @@ static void of_mux_clk_setup(struct device_node *node)
        mask = (1 << fls(mask)) - 1;
 
        clk = _register_mux(NULL, node->name, parent_names, num_parents,
-                           flags, reg, shift, mask, clk_mux_flags, NULL,
-                           NULL);
+                           flags, reg, shift, mask, clk_mux_flags, NULL);
 
        if (!IS_ERR(clk))
                of_clk_add_provider(node, of_clk_src_simple_get, clk);
index 1593ade2a8154da8840236bd9a0debb931ebfa5a..c4f7d7a9b68987e861bb52ea807f919ca785a1c9 100644 (file)
@@ -55,7 +55,7 @@ int __init clocksource_mmio_init(void __iomem *base, const char *name,
 {
        struct clocksource_mmio *cs;
 
-       if (bits > 32 || bits < 16)
+       if (bits > 64 || bits < 16)
                return -EINVAL;
 
        cs = kzalloc(sizeof(struct clocksource_mmio), GFP_KERNEL);
index 8014c2307332cc803a73baec42c297c079d61974..235a1ba73d92d577bbf605f5dab9d737fe246797 100644 (file)
@@ -202,7 +202,7 @@ config ARM_SA1110_CPUFREQ
 
 config ARM_SCPI_CPUFREQ
         tristate "SCPI based CPUfreq driver"
-       depends on ARM_BIG_LITTLE_CPUFREQ && ARM_SCPI_PROTOCOL
+       depends on ARM_BIG_LITTLE_CPUFREQ && ARM_SCPI_PROTOCOL && COMMON_CLK_SCPI
         help
          This adds the CPUfreq driver support for ARM big.LITTLE platforms
          using SCPI protocol for CPU power management.
index e8cb334094b0d5d89df7d8f482515f7901ac28f5..7c0bdfb1a2ca47ea9dcd0b36ef892274edd929b4 100644 (file)
@@ -98,10 +98,11 @@ static int cppc_cpufreq_cpu_init(struct cpufreq_policy *policy)
        policy->max = cpu->perf_caps.highest_perf;
        policy->cpuinfo.min_freq = policy->min;
        policy->cpuinfo.max_freq = policy->max;
+       policy->shared_type = cpu->shared_type;
 
        if (policy->shared_type == CPUFREQ_SHARED_TYPE_ANY)
                cpumask_copy(policy->cpus, cpu->shared_cpu_map);
-       else {
+       else if (policy->shared_type == CPUFREQ_SHARED_TYPE_ALL) {
                /* Support only SW_ANY for now. */
                pr_debug("Unsupported CPU co-ord type\n");
                return -EFAULT;
index 7c48e7316d91e23cd8374852c477375ae65e1ccb..8412ce5f93a712a03bfa81df25bee238a299d242 100644 (file)
@@ -976,10 +976,14 @@ static int cpufreq_init_policy(struct cpufreq_policy *policy)
 
        new_policy.governor = gov;
 
-       /* Use the default policy if its valid. */
-       if (cpufreq_driver->setpolicy)
-               cpufreq_parse_governor(gov->name, &new_policy.policy, NULL);
-
+       /* Use the default policy if there is no last_policy. */
+       if (cpufreq_driver->setpolicy) {
+               if (policy->last_policy)
+                       new_policy.policy = policy->last_policy;
+               else
+                       cpufreq_parse_governor(gov->name, &new_policy.policy,
+                                              NULL);
+       }
        /* set default policy */
        return cpufreq_set_policy(policy, &new_policy);
 }
@@ -1330,6 +1334,8 @@ static void cpufreq_offline_prepare(unsigned int cpu)
                if (has_target())
                        strncpy(policy->last_governor, policy->governor->name,
                                CPUFREQ_NAME_LEN);
+               else
+                       policy->last_policy = policy->policy;
        } else if (cpu == policy->cpu) {
                /* Nominate new CPU */
                policy->cpu = cpumask_any(policy->cpus);
@@ -1401,13 +1407,10 @@ static void cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif)
        }
 
        cpumask_clear_cpu(cpu, policy->real_cpus);
+       remove_cpu_dev_symlink(policy, cpu);
 
-       if (cpumask_empty(policy->real_cpus)) {
+       if (cpumask_empty(policy->real_cpus))
                cpufreq_policy_free(policy, true);
-               return;
-       }
-
-       remove_cpu_dev_symlink(policy, cpu);
 }
 
 static void handle_update(struct work_struct *work)
index 001a532e342e818d6093f50fc2eca3bd15a335b7..4d07cbd2b23cfb80ddc40fc0822ce37464991498 100644 (file)
@@ -1101,6 +1101,8 @@ static int intel_pstate_set_policy(struct cpufreq_policy *policy)
            policy->max >= policy->cpuinfo.max_freq) {
                pr_debug("intel_pstate: set performance\n");
                limits = &performance_limits;
+               if (hwp_active)
+                       intel_pstate_hwp_set();
                return 0;
        }
 
@@ -1108,7 +1110,8 @@ static int intel_pstate_set_policy(struct cpufreq_policy *policy)
        limits = &powersave_limits;
        limits->min_policy_pct = (policy->min * 100) / policy->cpuinfo.max_freq;
        limits->min_policy_pct = clamp_t(int, limits->min_policy_pct, 0 , 100);
-       limits->max_policy_pct = (policy->max * 100) / policy->cpuinfo.max_freq;
+       limits->max_policy_pct = DIV_ROUND_UP(policy->max * 100,
+                                             policy->cpuinfo.max_freq);
        limits->max_policy_pct = clamp_t(int, limits->max_policy_pct, 0 , 100);
 
        /* Normalize user input to [min_policy_pct, max_policy_pct] */
@@ -1120,6 +1123,7 @@ static int intel_pstate_set_policy(struct cpufreq_policy *policy)
                                   limits->max_sysfs_pct);
        limits->max_perf_pct = max(limits->min_policy_pct,
                                   limits->max_perf_pct);
+       limits->max_perf = round_up(limits->max_perf, 8);
 
        /* Make sure min_perf_pct <= max_perf_pct */
        limits->min_perf_pct = min(limits->max_perf_pct, limits->min_perf_pct);
index 733aa5153e7451f645a65e3452ed44d6d488054a..68ef8fd9482fd2532762789973b8d4dfa98cfdd5 100644 (file)
@@ -648,7 +648,7 @@ late_initcall(s3c_cpufreq_initcall);
  *
  * Register the given set of PLLs with the system.
  */
-int __init s3c_plltab_register(struct cpufreq_frequency_table *plls,
+int s3c_plltab_register(struct cpufreq_frequency_table *plls,
                               unsigned int plls_no)
 {
        struct cpufreq_frequency_table *vals;
index 73ef499227881e6fd5c71c65d00f486a1f173dd4..7038f364acb51934f51b5dfd6053b5ec6545ddfa 100644 (file)
@@ -409,7 +409,7 @@ static int ccm_nx_decrypt(struct aead_request   *req,
                processed += to_process;
        } while (processed < nbytes);
 
-       rc = memcmp(csbcpb->cpb.aes_ccm.out_pat_or_mac, priv->oauth_tag,
+       rc = crypto_memneq(csbcpb->cpb.aes_ccm.out_pat_or_mac, priv->oauth_tag,
                    authsize) ? -EBADMSG : 0;
 out:
        spin_unlock_irqrestore(&nx_ctx->lock, irq_flags);
index eee624f589b6545a310d081e772d5924094ed70d..abd465f479c433641f3e5024cfe6442d6b68024d 100644 (file)
@@ -21,6 +21,7 @@
 
 #include <crypto/internal/aead.h>
 #include <crypto/aes.h>
+#include <crypto/algapi.h>
 #include <crypto/scatterwalk.h>
 #include <linux/module.h>
 #include <linux/types.h>
@@ -418,7 +419,7 @@ mac:
                        itag, req->src, req->assoclen + nbytes,
                        crypto_aead_authsize(crypto_aead_reqtfm(req)),
                        SCATTERWALK_FROM_SG);
-               rc = memcmp(itag, otag,
+               rc = crypto_memneq(itag, otag,
                            crypto_aead_authsize(crypto_aead_reqtfm(req))) ?
                     -EBADMSG : 0;
        }
index 46f531e19ccf07e97af05c221a5bfbb0d060d0a7..b6f9f42e2985b476ecc63ac16f648535be0cddc2 100644 (file)
@@ -977,7 +977,7 @@ static void ipsec_esp_decrypt_swauth_done(struct device *dev,
                } else
                        oicv = (char *)&edesc->link_tbl[0];
 
-               err = memcmp(oicv, icv, authsize) ? -EBADMSG : 0;
+               err = crypto_memneq(oicv, icv, authsize) ? -EBADMSG : 0;
        }
 
        kfree(edesc);
index a24f5cb877e0a2b32fcfccc14b80e01f2028a08d..953dc9195937d39bb1def7c7bfaa3f905f8d4032 100644 (file)
@@ -122,12 +122,10 @@ int fpga_mgr_firmware_load(struct fpga_manager *mgr, u32 flags,
        }
 
        ret = fpga_mgr_buf_load(mgr, flags, fw->data, fw->size);
-       if (ret)
-               return ret;
 
        release_firmware(fw);
 
-       return 0;
+       return ret;
 }
 EXPORT_SYMBOL_GPL(fpga_mgr_firmware_load);
 
@@ -256,7 +254,6 @@ int fpga_mgr_register(struct device *dev, const char *name,
                      void *priv)
 {
        struct fpga_manager *mgr;
-       const char *dt_label;
        int id, ret;
 
        if (!mops || !mops->write_init || !mops->write ||
@@ -300,11 +297,9 @@ int fpga_mgr_register(struct device *dev, const char *name,
        mgr->dev.id = id;
        dev_set_drvdata(dev, mgr);
 
-       dt_label = of_get_property(mgr->dev.of_node, "label", NULL);
-       if (dt_label)
-               ret = dev_set_name(&mgr->dev, "%s", dt_label);
-       else
-               ret = dev_set_name(&mgr->dev, "fpga%d", id);
+       ret = dev_set_name(&mgr->dev, "fpga%d", id);
+       if (ret)
+               goto error_device;
 
        ret = device_add(&mgr->dev);
        if (ret)
index 6ed7c0fb3378eac88af03b8c125d0a7c9749f3db..6b186829087c4b3f4746ebebb1e327df58486d15 100644 (file)
@@ -113,13 +113,16 @@ static int mmio_74xx_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
 
 static int mmio_74xx_gpio_probe(struct platform_device *pdev)
 {
-       const struct of_device_id *of_id =
-               of_match_device(mmio_74xx_gpio_ids, &pdev->dev);
+       const struct of_device_id *of_id;
        struct mmio_74xx_gpio_priv *priv;
        struct resource *res;
        void __iomem *dat;
        int err;
 
+       of_id = of_match_device(mmio_74xx_gpio_ids, &pdev->dev);
+       if (!of_id)
+               return -ENODEV;
+
        priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
        if (!priv)
                return -ENOMEM;
index 56d2d026e62e42bf6fec7db5ad2aa25aebd970f3..f7fbb46d5d797a32d9d35c119adb3df2166cc37e 100644 (file)
@@ -1122,8 +1122,6 @@ static int omap_gpio_chip_init(struct gpio_bank *bank, struct irq_chip *irqc)
        /* MPUIO is a bit different, reading IRQ status clears it */
        if (bank->is_mpuio) {
                irqc->irq_ack = dummy_irq_chip.irq_ack;
-               irqc->irq_mask = irq_gc_mask_set_bit;
-               irqc->irq_unmask = irq_gc_mask_clr_bit;
                if (!bank->regs->wkup_en)
                        irqc->irq_set_wake = NULL;
        }
index 171a6389f9ce086ffdf74f6c50523a77e205b473..52b447c071cbaa2e160bf5a67fc511ae26d6a55d 100644 (file)
@@ -167,6 +167,8 @@ static int palmas_gpio_probe(struct platform_device *pdev)
        const struct palmas_device_data *dev_data;
 
        match = of_match_device(of_palmas_gpio_match, &pdev->dev);
+       if (!match)
+               return -ENODEV;
        dev_data = match->data;
        if (!dev_data)
                dev_data = &palmas_dev_data;
index 045a952576c708e253de29438abaec95640989f2..7b25fdf64802339967ab541bb5ecd5bb876779d7 100644 (file)
@@ -187,11 +187,15 @@ MODULE_DEVICE_TABLE(of, syscon_gpio_ids);
 static int syscon_gpio_probe(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
-       const struct of_device_id *of_id = of_match_device(syscon_gpio_ids, dev);
+       const struct of_device_id *of_id;
        struct syscon_gpio_priv *priv;
        struct device_node *np = dev->of_node;
        int ret;
 
+       of_id = of_match_device(syscon_gpio_ids, dev);
+       if (!of_id)
+               return -ENODEV;
+
        priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
        if (!priv)
                return -ENOMEM;
index 027e5f47dd28738f04e6347f1807c6b28b34e618..896bf29776b093ee34efad4d4d29d073fda184b6 100644 (file)
@@ -375,6 +375,60 @@ static int tegra_gpio_irq_set_wake(struct irq_data *d, unsigned int enable)
 }
 #endif
 
+#ifdef CONFIG_DEBUG_FS
+
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+
+static int dbg_gpio_show(struct seq_file *s, void *unused)
+{
+       int i;
+       int j;
+
+       for (i = 0; i < tegra_gpio_bank_count; i++) {
+               for (j = 0; j < 4; j++) {
+                       int gpio = tegra_gpio_compose(i, j, 0);
+                       seq_printf(s,
+                               "%d:%d %02x %02x %02x %02x %02x %02x %06x\n",
+                               i, j,
+                               tegra_gpio_readl(GPIO_CNF(gpio)),
+                               tegra_gpio_readl(GPIO_OE(gpio)),
+                               tegra_gpio_readl(GPIO_OUT(gpio)),
+                               tegra_gpio_readl(GPIO_IN(gpio)),
+                               tegra_gpio_readl(GPIO_INT_STA(gpio)),
+                               tegra_gpio_readl(GPIO_INT_ENB(gpio)),
+                               tegra_gpio_readl(GPIO_INT_LVL(gpio)));
+               }
+       }
+       return 0;
+}
+
+static int dbg_gpio_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, dbg_gpio_show, &inode->i_private);
+}
+
+static const struct file_operations debug_fops = {
+       .open           = dbg_gpio_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
+
+static void tegra_gpio_debuginit(void)
+{
+       (void) debugfs_create_file("tegra_gpio", S_IRUGO,
+                                       NULL, NULL, &debug_fops);
+}
+
+#else
+
+static inline void tegra_gpio_debuginit(void)
+{
+}
+
+#endif
+
 static struct irq_chip tegra_gpio_irq_chip = {
        .name           = "GPIO",
        .irq_ack        = tegra_gpio_irq_ack,
@@ -519,6 +573,8 @@ static int tegra_gpio_probe(struct platform_device *pdev)
                        spin_lock_init(&bank->lvl_lock[j]);
        }
 
+       tegra_gpio_debuginit();
+
        return 0;
 }
 
@@ -536,52 +592,3 @@ static int __init tegra_gpio_init(void)
        return platform_driver_register(&tegra_gpio_driver);
 }
 postcore_initcall(tegra_gpio_init);
-
-#ifdef CONFIG_DEBUG_FS
-
-#include <linux/debugfs.h>
-#include <linux/seq_file.h>
-
-static int dbg_gpio_show(struct seq_file *s, void *unused)
-{
-       int i;
-       int j;
-
-       for (i = 0; i < tegra_gpio_bank_count; i++) {
-               for (j = 0; j < 4; j++) {
-                       int gpio = tegra_gpio_compose(i, j, 0);
-                       seq_printf(s,
-                               "%d:%d %02x %02x %02x %02x %02x %02x %06x\n",
-                               i, j,
-                               tegra_gpio_readl(GPIO_CNF(gpio)),
-                               tegra_gpio_readl(GPIO_OE(gpio)),
-                               tegra_gpio_readl(GPIO_OUT(gpio)),
-                               tegra_gpio_readl(GPIO_IN(gpio)),
-                               tegra_gpio_readl(GPIO_INT_STA(gpio)),
-                               tegra_gpio_readl(GPIO_INT_ENB(gpio)),
-                               tegra_gpio_readl(GPIO_INT_LVL(gpio)));
-               }
-       }
-       return 0;
-}
-
-static int dbg_gpio_open(struct inode *inode, struct file *file)
-{
-       return single_open(file, dbg_gpio_show, &inode->i_private);
-}
-
-static const struct file_operations debug_fops = {
-       .open           = dbg_gpio_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = single_release,
-};
-
-static int __init tegra_gpio_debuginit(void)
-{
-       (void) debugfs_create_file("tegra_gpio", S_IRUGO,
-                                       NULL, NULL, &debug_fops);
-       return 0;
-}
-late_initcall(tegra_gpio_debuginit);
-#endif
index a18f00fc1bb87544cc59182e6f4a5515464a2f29..2a91f3287e3b7e52f2f6e16d108af07d4343be0b 100644 (file)
@@ -233,7 +233,7 @@ static struct gpio_desc *gpio_name_to_desc(const char * const name)
                for (i = 0; i != chip->ngpio; ++i) {
                        struct gpio_desc *gpio = &chip->desc[i];
 
-                       if (!gpio->name)
+                       if (!gpio->name || !name)
                                continue;
 
                        if (!strcmp(gpio->name, name)) {
index 306f75700bf8e1fa5b5c6a7731645ad4a4d86f60..5a5f04d0902d662548ebae9f82525e1363e8457c 100644 (file)
@@ -496,6 +496,7 @@ struct amdgpu_bo_va_mapping {
 
 /* bo virtual addresses in a specific vm */
 struct amdgpu_bo_va {
+       struct mutex                    mutex;
        /* protected by bo being reserved */
        struct list_head                bo_list;
        struct fence                    *last_pt_update;
@@ -538,6 +539,7 @@ struct amdgpu_bo {
        /* Constant after initialization */
        struct amdgpu_device            *adev;
        struct drm_gem_object           gem_base;
+       struct amdgpu_bo                *parent;
 
        struct ttm_bo_kmap_obj          dma_buf_vmap;
        pid_t                           pid;
@@ -928,8 +930,6 @@ struct amdgpu_vm_id {
 };
 
 struct amdgpu_vm {
-       struct mutex            mutex;
-
        struct rb_root          va;
 
        /* protecting invalidated */
@@ -956,6 +956,8 @@ struct amdgpu_vm {
        struct amdgpu_vm_id     ids[AMDGPU_MAX_RINGS];
        /* for interval tree */
        spinlock_t              it_lock;
+       /* protecting freed */
+       spinlock_t              freed_lock;
 };
 
 struct amdgpu_vm_manager {
index 3afcf0237c25474c662f499d4583c7743f6067f9..4f352ec9dec4e2fb7c3bb5bd062e674291fc8d5a 100644 (file)
@@ -222,6 +222,8 @@ int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data)
                                }
 
                                p->uf.bo = gem_to_amdgpu_bo(gobj);
+                               amdgpu_bo_ref(p->uf.bo);
+                               drm_gem_object_unreference_unlocked(gobj);
                                p->uf.offset = fence_data->offset;
                        } else {
                                ret = -EINVAL;
@@ -487,7 +489,7 @@ static void amdgpu_cs_parser_fini(struct amdgpu_cs_parser *parser, int error, bo
                        amdgpu_ib_free(parser->adev, &parser->ibs[i]);
        kfree(parser->ibs);
        if (parser->uf.bo)
-               drm_gem_object_unreference_unlocked(&parser->uf.bo->gem_base);
+               amdgpu_bo_unref(&parser->uf.bo);
 }
 
 static int amdgpu_bo_vm_update_pte(struct amdgpu_cs_parser *p,
@@ -776,7 +778,7 @@ static int amdgpu_cs_free_job(struct amdgpu_job *job)
                        amdgpu_ib_free(job->adev, &job->ibs[i]);
        kfree(job->ibs);
        if (job->uf.bo)
-               drm_gem_object_unreference_unlocked(&job->uf.bo->gem_base);
+               amdgpu_bo_unref(&job->uf.bo);
        return 0;
 }
 
@@ -784,8 +786,6 @@ int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
 {
        struct amdgpu_device *adev = dev->dev_private;
        union drm_amdgpu_cs *cs = data;
-       struct amdgpu_fpriv *fpriv = filp->driver_priv;
-       struct amdgpu_vm *vm = &fpriv->vm;
        struct amdgpu_cs_parser parser = {};
        bool reserved_buffers = false;
        int i, r;
@@ -803,7 +803,6 @@ int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
                r = amdgpu_cs_handle_lockup(adev, r);
                return r;
        }
-       mutex_lock(&vm->mutex);
        r = amdgpu_cs_parser_relocs(&parser);
        if (r == -ENOMEM)
                DRM_ERROR("Not enough memory for command submission!\n");
@@ -888,7 +887,6 @@ int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
 
 out:
        amdgpu_cs_parser_fini(&parser, r, reserved_buffers);
-       mutex_unlock(&vm->mutex);
        r = amdgpu_cs_handle_lockup(adev, r);
        return r;
 }
index e173a5a02f0d8052bb6c76203b188b6cf231d787..5580d3420c3a368815364d8eccce3e1421ce6a12 100644 (file)
@@ -73,6 +73,8 @@ static void amdgpu_flip_work_func(struct work_struct *__work)
        struct drm_crtc *crtc = &amdgpuCrtc->base;
        unsigned long flags;
        unsigned i;
+       int vpos, hpos, stat, min_udelay;
+       struct drm_vblank_crtc *vblank = &crtc->dev->vblank[work->crtc_id];
 
        amdgpu_flip_wait_fence(adev, &work->excl);
        for (i = 0; i < work->shared_count; ++i)
@@ -81,6 +83,41 @@ static void amdgpu_flip_work_func(struct work_struct *__work)
        /* We borrow the event spin lock for protecting flip_status */
        spin_lock_irqsave(&crtc->dev->event_lock, flags);
 
+       /* If this happens to execute within the "virtually extended" vblank
+        * interval before the start of the real vblank interval then it needs
+        * to delay programming the mmio flip until the real vblank is entered.
+        * This prevents completing a flip too early due to the way we fudge
+        * our vblank counter and vblank timestamps in order to work around the
+        * problem that the hw fires vblank interrupts before actual start of
+        * vblank (when line buffer refilling is done for a frame). It
+        * complements the fudging logic in amdgpu_get_crtc_scanoutpos() for
+        * timestamping and amdgpu_get_vblank_counter_kms() for vblank counts.
+        *
+        * In practice this won't execute very often unless on very fast
+        * machines because the time window for this to happen is very small.
+        */
+       for (;;) {
+               /* GET_DISTANCE_TO_VBLANKSTART returns distance to real vblank
+                * start in hpos, and to the "fudged earlier" vblank start in
+                * vpos.
+                */
+               stat = amdgpu_get_crtc_scanoutpos(adev->ddev, work->crtc_id,
+                                                 GET_DISTANCE_TO_VBLANKSTART,
+                                                 &vpos, &hpos, NULL, NULL,
+                                                 &crtc->hwmode);
+
+               if ((stat & (DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_ACCURATE)) !=
+                   (DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_ACCURATE) ||
+                   !(vpos >= 0 && hpos <= 0))
+                       break;
+
+               /* Sleep at least until estimated real start of hw vblank */
+               spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
+               min_udelay = (-hpos + 1) * max(vblank->linedur_ns / 1000, 5);
+               usleep_range(min_udelay, 2 * min_udelay);
+               spin_lock_irqsave(&crtc->dev->event_lock, flags);
+       };
+
        /* do the flip (mmio) */
        adev->mode_info.funcs->page_flip(adev, work->crtc_id, work->base);
        /* set the flip status */
@@ -109,7 +146,7 @@ static void amdgpu_unpin_work_func(struct work_struct *__work)
        } else
                DRM_ERROR("failed to reserve buffer after flip\n");
 
-       drm_gem_object_unreference_unlocked(&work->old_rbo->gem_base);
+       amdgpu_bo_unref(&work->old_rbo);
        kfree(work->shared);
        kfree(work);
 }
@@ -148,8 +185,8 @@ int amdgpu_crtc_page_flip(struct drm_crtc *crtc,
        obj = old_amdgpu_fb->obj;
 
        /* take a reference to the old object */
-       drm_gem_object_reference(obj);
        work->old_rbo = gem_to_amdgpu_bo(obj);
+       amdgpu_bo_ref(work->old_rbo);
 
        new_amdgpu_fb = to_amdgpu_framebuffer(fb);
        obj = new_amdgpu_fb->obj;
@@ -222,7 +259,7 @@ pflip_cleanup:
        amdgpu_bo_unreserve(new_rbo);
 
 cleanup:
-       drm_gem_object_unreference_unlocked(&work->old_rbo->gem_base);
+       amdgpu_bo_unref(&work->old_rbo);
        fence_put(work->excl);
        for (i = 0; i < work->shared_count; ++i)
                fence_put(work->shared[i]);
@@ -712,6 +749,15 @@ bool amdgpu_crtc_scaling_mode_fixup(struct drm_crtc *crtc,
  * \param dev Device to query.
  * \param pipe Crtc to query.
  * \param flags Flags from caller (DRM_CALLED_FROM_VBLIRQ or 0).
+ *              For driver internal use only also supports these flags:
+ *
+ *              USE_REAL_VBLANKSTART to use the real start of vblank instead
+ *              of a fudged earlier start of vblank.
+ *
+ *              GET_DISTANCE_TO_VBLANKSTART to return distance to the
+ *              fudged earlier start of vblank in *vpos and the distance
+ *              to true start of vblank in *hpos.
+ *
  * \param *vpos Location where vertical scanout position should be stored.
  * \param *hpos Location where horizontal scanout position should go.
  * \param *stime Target location for timestamp taken immediately before
@@ -776,10 +822,40 @@ int amdgpu_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe,
                vbl_end = 0;
        }
 
+       /* Called from driver internal vblank counter query code? */
+       if (flags & GET_DISTANCE_TO_VBLANKSTART) {
+           /* Caller wants distance from real vbl_start in *hpos */
+           *hpos = *vpos - vbl_start;
+       }
+
+       /* Fudge vblank to start a few scanlines earlier to handle the
+        * problem that vblank irqs fire a few scanlines before start
+        * of vblank. Some driver internal callers need the true vblank
+        * start to be used and signal this via the USE_REAL_VBLANKSTART flag.
+        *
+        * The cause of the "early" vblank irq is that the irq is triggered
+        * by the line buffer logic when the line buffer read position enters
+        * the vblank, whereas our crtc scanout position naturally lags the
+        * line buffer read position.
+        */
+       if (!(flags & USE_REAL_VBLANKSTART))
+               vbl_start -= adev->mode_info.crtcs[pipe]->lb_vblank_lead_lines;
+
        /* Test scanout position against vblank region. */
        if ((*vpos < vbl_start) && (*vpos >= vbl_end))
                in_vbl = false;
 
+       /* In vblank? */
+       if (in_vbl)
+           ret |= DRM_SCANOUTPOS_IN_VBLANK;
+
+       /* Called from driver internal vblank counter query code? */
+       if (flags & GET_DISTANCE_TO_VBLANKSTART) {
+               /* Caller wants distance from fudged earlier vbl_start */
+               *vpos -= vbl_start;
+               return ret;
+       }
+
        /* Check if inside vblank area and apply corrective offsets:
         * vpos will then be >=0 in video scanout area, but negative
         * within vblank area, counting down the number of lines until
@@ -795,32 +871,6 @@ int amdgpu_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe,
        /* Correct for shifted end of vbl at vbl_end. */
        *vpos = *vpos - vbl_end;
 
-       /* In vblank? */
-       if (in_vbl)
-               ret |= DRM_SCANOUTPOS_IN_VBLANK;
-
-       /* Is vpos outside nominal vblank area, but less than
-        * 1/100 of a frame height away from start of vblank?
-        * If so, assume this isn't a massively delayed vblank
-        * interrupt, but a vblank interrupt that fired a few
-        * microseconds before true start of vblank. Compensate
-        * by adding a full frame duration to the final timestamp.
-        * Happens, e.g., on ATI R500, R600.
-        *
-        * We only do this if DRM_CALLED_FROM_VBLIRQ.
-        */
-       if ((flags & DRM_CALLED_FROM_VBLIRQ) && !in_vbl) {
-               vbl_start = mode->crtc_vdisplay;
-               vtotal = mode->crtc_vtotal;
-
-               if (vbl_start - *vpos < vtotal / 100) {
-                       *vpos -= vtotal;
-
-                       /* Signal this correction as "applied". */
-                       ret |= 0x8;
-               }
-       }
-
        return ret;
 }
 
index 00c5b580f56c6e512a6eaea107130b353c66bc93..9c253c535d26053ae80244a68617675c9b19fc3c 100644 (file)
@@ -115,12 +115,9 @@ int amdgpu_gem_object_open(struct drm_gem_object *obj, struct drm_file *file_pri
        struct amdgpu_vm *vm = &fpriv->vm;
        struct amdgpu_bo_va *bo_va;
        int r;
-       mutex_lock(&vm->mutex);
        r = amdgpu_bo_reserve(rbo, false);
-       if (r) {
-               mutex_unlock(&vm->mutex);
+       if (r)
                return r;
-       }
 
        bo_va = amdgpu_vm_bo_find(vm, rbo);
        if (!bo_va) {
@@ -129,7 +126,6 @@ int amdgpu_gem_object_open(struct drm_gem_object *obj, struct drm_file *file_pri
                ++bo_va->ref_count;
        }
        amdgpu_bo_unreserve(rbo);
-       mutex_unlock(&vm->mutex);
        return 0;
 }
 
@@ -142,10 +138,8 @@ void amdgpu_gem_object_close(struct drm_gem_object *obj,
        struct amdgpu_vm *vm = &fpriv->vm;
        struct amdgpu_bo_va *bo_va;
        int r;
-       mutex_lock(&vm->mutex);
        r = amdgpu_bo_reserve(rbo, true);
        if (r) {
-               mutex_unlock(&vm->mutex);
                dev_err(adev->dev, "leaking bo va because "
                        "we fail to reserve bo (%d)\n", r);
                return;
@@ -157,7 +151,6 @@ void amdgpu_gem_object_close(struct drm_gem_object *obj,
                }
        }
        amdgpu_bo_unreserve(rbo);
-       mutex_unlock(&vm->mutex);
 }
 
 static int amdgpu_gem_handle_lockup(struct amdgpu_device *adev, int r)
@@ -242,8 +235,9 @@ int amdgpu_gem_userptr_ioctl(struct drm_device *dev, void *data,
            AMDGPU_GEM_USERPTR_REGISTER))
                return -EINVAL;
 
-       if (!(args->flags & AMDGPU_GEM_USERPTR_ANONONLY) ||
-                  !(args->flags & AMDGPU_GEM_USERPTR_REGISTER)) {
+       if (!(args->flags & AMDGPU_GEM_USERPTR_READONLY) && (
+            !(args->flags & AMDGPU_GEM_USERPTR_ANONONLY) ||
+            !(args->flags & AMDGPU_GEM_USERPTR_REGISTER))) {
 
                /* if we want to write to it we must require anonymous
                   memory and install a MMU notifier */
@@ -483,6 +477,14 @@ static void amdgpu_gem_va_update_vm(struct amdgpu_device *adev,
                if (domain == AMDGPU_GEM_DOMAIN_CPU)
                        goto error_unreserve;
        }
+       list_for_each_entry(entry, &duplicates, head) {
+               domain = amdgpu_mem_type_to_domain(entry->bo->mem.mem_type);
+               /* if anything is swapped out don't swap it in here,
+                  just abort and wait for the next CS */
+               if (domain == AMDGPU_GEM_DOMAIN_CPU)
+                       goto error_unreserve;
+       }
+
        r = amdgpu_vm_update_page_directory(adev, bo_va->vm);
        if (r)
                goto error_unreserve;
@@ -553,7 +555,6 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data,
        gobj = drm_gem_object_lookup(dev, filp, args->handle);
        if (gobj == NULL)
                return -ENOENT;
-       mutex_lock(&fpriv->vm.mutex);
        rbo = gem_to_amdgpu_bo(gobj);
        INIT_LIST_HEAD(&list);
        INIT_LIST_HEAD(&duplicates);
@@ -568,7 +569,6 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data,
        }
        r = ttm_eu_reserve_buffers(&ticket, &list, true, &duplicates);
        if (r) {
-               mutex_unlock(&fpriv->vm.mutex);
                drm_gem_object_unreference_unlocked(gobj);
                return r;
        }
@@ -577,7 +577,6 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data,
        if (!bo_va) {
                ttm_eu_backoff_reservation(&ticket, &list);
                drm_gem_object_unreference_unlocked(gobj);
-               mutex_unlock(&fpriv->vm.mutex);
                return -ENOENT;
        }
 
@@ -602,7 +601,7 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data,
        ttm_eu_backoff_reservation(&ticket, &list);
        if (!r && !(args->flags & AMDGPU_VM_DELAY_UPDATE))
                amdgpu_gem_va_update_vm(adev, bo_va, args->operation);
-       mutex_unlock(&fpriv->vm.mutex);
+
        drm_gem_object_unreference_unlocked(gobj);
        return r;
 }
index 1618e2294a16056171458998ed65e62a83583774..e23843f4d877be7813a1574db0f855847f9aa591 100644 (file)
@@ -611,13 +611,59 @@ void amdgpu_driver_preclose_kms(struct drm_device *dev,
 u32 amdgpu_get_vblank_counter_kms(struct drm_device *dev, unsigned int pipe)
 {
        struct amdgpu_device *adev = dev->dev_private;
+       int vpos, hpos, stat;
+       u32 count;
 
        if (pipe >= adev->mode_info.num_crtc) {
                DRM_ERROR("Invalid crtc %u\n", pipe);
                return -EINVAL;
        }
 
-       return amdgpu_display_vblank_get_counter(adev, pipe);
+       /* The hw increments its frame counter at start of vsync, not at start
+        * of vblank, as is required by DRM core vblank counter handling.
+        * Cook the hw count here to make it appear to the caller as if it
+        * incremented at start of vblank. We measure distance to start of
+        * vblank in vpos. vpos therefore will be >= 0 between start of vblank
+        * and start of vsync, so vpos >= 0 means to bump the hw frame counter
+        * result by 1 to give the proper appearance to caller.
+        */
+       if (adev->mode_info.crtcs[pipe]) {
+               /* Repeat readout if needed to provide stable result if
+                * we cross start of vsync during the queries.
+                */
+               do {
+                       count = amdgpu_display_vblank_get_counter(adev, pipe);
+                       /* Ask amdgpu_get_crtc_scanoutpos to return vpos as
+                        * distance to start of vblank, instead of regular
+                        * vertical scanout pos.
+                        */
+                       stat = amdgpu_get_crtc_scanoutpos(
+                               dev, pipe, GET_DISTANCE_TO_VBLANKSTART,
+                               &vpos, &hpos, NULL, NULL,
+                               &adev->mode_info.crtcs[pipe]->base.hwmode);
+               } while (count != amdgpu_display_vblank_get_counter(adev, pipe));
+
+               if (((stat & (DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_ACCURATE)) !=
+                   (DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_ACCURATE))) {
+                       DRM_DEBUG_VBL("Query failed! stat %d\n", stat);
+               } else {
+                       DRM_DEBUG_VBL("crtc %d: dist from vblank start %d\n",
+                                     pipe, vpos);
+
+                       /* Bump counter if we are at >= leading edge of vblank,
+                        * but before vsync where vpos would turn negative and
+                        * the hw counter really increments.
+                        */
+                       if (vpos >= 0)
+                               count++;
+               }
+       } else {
+               /* Fallback to use value as is. */
+               count = amdgpu_display_vblank_get_counter(adev, pipe);
+               DRM_DEBUG_VBL("NULL mode info! Returned count may be wrong.\n");
+       }
+
+       return count;
 }
 
 /**
index b62c1710cab6b0fc00e33013ad741c97f9583ed2..064ebb3470748619e0b43ff7bfe2671a58c50bbd 100644 (file)
@@ -407,6 +407,7 @@ struct amdgpu_crtc {
        u32 line_time;
        u32 wm_low;
        u32 wm_high;
+       u32 lb_vblank_lead_lines;
        struct drm_display_mode hw_mode;
 };
 
@@ -528,6 +529,10 @@ struct amdgpu_framebuffer {
 #define ENCODER_MODE_IS_DP(em) (((em) == ATOM_ENCODER_MODE_DP) || \
                                ((em) == ATOM_ENCODER_MODE_DP_MST))
 
+/* Driver internal use only flags of amdgpu_get_crtc_scanoutpos() */
+#define USE_REAL_VBLANKSTART           (1 << 30)
+#define GET_DISTANCE_TO_VBLANKSTART    (1 << 31)
+
 void amdgpu_link_encoder_connector(struct drm_device *dev);
 
 struct drm_connector *
index 0d524384ff79c3b49d2dbaa1489d8cbff231d80a..c3ce103b6a33b2ef3a0a6f7f14877e18150ca405 100644 (file)
@@ -100,6 +100,7 @@ static void amdgpu_ttm_bo_destroy(struct ttm_buffer_object *tbo)
        list_del_init(&bo->list);
        mutex_unlock(&bo->adev->gem.mutex);
        drm_gem_object_release(&bo->gem_base);
+       amdgpu_bo_unref(&bo->parent);
        kfree(bo->metadata);
        kfree(bo);
 }
index d4bac5f49939e1a780e5897754779fde9d1733d6..8a1752ff3d8e55a1d8b8ab3061f5c9c425058d0f 100644 (file)
@@ -587,9 +587,13 @@ static int amdgpu_ttm_backend_bind(struct ttm_tt *ttm,
        uint32_t flags = amdgpu_ttm_tt_pte_flags(gtt->adev, ttm, bo_mem);
        int r;
 
-       if (gtt->userptr)
-               amdgpu_ttm_tt_pin_userptr(ttm);
-
+       if (gtt->userptr) {
+               r = amdgpu_ttm_tt_pin_userptr(ttm);
+               if (r) {
+                       DRM_ERROR("failed to pin userptr\n");
+                       return r;
+               }
+       }
        gtt->offset = (unsigned long)(bo_mem->start << PAGE_SHIFT);
        if (!ttm->num_pages) {
                WARN(1, "nothing to bind %lu pages for mreg %p back %p!\n",
@@ -797,11 +801,12 @@ uint32_t amdgpu_ttm_tt_pte_flags(struct amdgpu_device *adev, struct ttm_tt *ttm,
        if (mem && mem->mem_type != TTM_PL_SYSTEM)
                flags |= AMDGPU_PTE_VALID;
 
-       if (mem && mem->mem_type == TTM_PL_TT)
+       if (mem && mem->mem_type == TTM_PL_TT) {
                flags |= AMDGPU_PTE_SYSTEM;
 
-       if (!ttm || ttm->caching_state == tt_cached)
-               flags |= AMDGPU_PTE_SNOOPED;
+               if (ttm->caching_state == tt_cached)
+                       flags |= AMDGPU_PTE_SNOOPED;
+       }
 
        if (adev->asic_type >= CHIP_TOPAZ)
                flags |= AMDGPU_PTE_EXECUTABLE;
index 03f0c3bae516899aa81ac9b5d4dc6a9c7c1d9660..a745eeeb5d8200f6b92e259c655b10b658c4cad5 100644 (file)
@@ -392,7 +392,10 @@ int amdgpu_vce_get_create_msg(struct amdgpu_ring *ring, uint32_t handle,
        ib->ptr[ib->length_dw++] = 0x00000001; /* session cmd */
        ib->ptr[ib->length_dw++] = handle;
 
-       ib->ptr[ib->length_dw++] = 0x00000030; /* len */
+       if ((ring->adev->vce.fw_version >> 24) >= 52)
+               ib->ptr[ib->length_dw++] = 0x00000040; /* len */
+       else
+               ib->ptr[ib->length_dw++] = 0x00000030; /* len */
        ib->ptr[ib->length_dw++] = 0x01000001; /* create cmd */
        ib->ptr[ib->length_dw++] = 0x00000000;
        ib->ptr[ib->length_dw++] = 0x00000042;
@@ -404,6 +407,12 @@ int amdgpu_vce_get_create_msg(struct amdgpu_ring *ring, uint32_t handle,
        ib->ptr[ib->length_dw++] = 0x00000100;
        ib->ptr[ib->length_dw++] = 0x0000000c;
        ib->ptr[ib->length_dw++] = 0x00000000;
+       if ((ring->adev->vce.fw_version >> 24) >= 52) {
+               ib->ptr[ib->length_dw++] = 0x00000000;
+               ib->ptr[ib->length_dw++] = 0x00000000;
+               ib->ptr[ib->length_dw++] = 0x00000000;
+               ib->ptr[ib->length_dw++] = 0x00000000;
+       }
 
        ib->ptr[ib->length_dw++] = 0x00000014; /* len */
        ib->ptr[ib->length_dw++] = 0x05000005; /* feedback buffer */
index 159ce54bbd8d42137b1b47a4797b88aec3a6fd5e..b53d273eb7a1003a719fff9d1bd32a8b4fa20b78 100644 (file)
@@ -885,17 +885,21 @@ int amdgpu_vm_clear_freed(struct amdgpu_device *adev,
        struct amdgpu_bo_va_mapping *mapping;
        int r;
 
+       spin_lock(&vm->freed_lock);
        while (!list_empty(&vm->freed)) {
                mapping = list_first_entry(&vm->freed,
                        struct amdgpu_bo_va_mapping, list);
                list_del(&mapping->list);
-
+               spin_unlock(&vm->freed_lock);
                r = amdgpu_vm_bo_update_mapping(adev, vm, mapping, 0, 0, NULL);
                kfree(mapping);
                if (r)
                        return r;
 
+               spin_lock(&vm->freed_lock);
        }
+       spin_unlock(&vm->freed_lock);
+
        return 0;
 
 }
@@ -922,8 +926,9 @@ int amdgpu_vm_clear_invalids(struct amdgpu_device *adev,
                bo_va = list_first_entry(&vm->invalidated,
                        struct amdgpu_bo_va, vm_status);
                spin_unlock(&vm->status_lock);
-
+               mutex_lock(&bo_va->mutex);
                r = amdgpu_vm_bo_update(adev, bo_va, NULL);
+               mutex_unlock(&bo_va->mutex);
                if (r)
                        return r;
 
@@ -967,7 +972,7 @@ struct amdgpu_bo_va *amdgpu_vm_bo_add(struct amdgpu_device *adev,
        INIT_LIST_HEAD(&bo_va->valids);
        INIT_LIST_HEAD(&bo_va->invalids);
        INIT_LIST_HEAD(&bo_va->vm_status);
-
+       mutex_init(&bo_va->mutex);
        list_add_tail(&bo_va->bo_list, &bo->va);
 
        return bo_va;
@@ -1045,7 +1050,9 @@ int amdgpu_vm_bo_map(struct amdgpu_device *adev,
        mapping->offset = offset;
        mapping->flags = flags;
 
+       mutex_lock(&bo_va->mutex);
        list_add(&mapping->list, &bo_va->invalids);
+       mutex_unlock(&bo_va->mutex);
        spin_lock(&vm->it_lock);
        interval_tree_insert(&mapping->it, &vm->va);
        spin_unlock(&vm->it_lock);
@@ -1076,6 +1083,11 @@ int amdgpu_vm_bo_map(struct amdgpu_device *adev,
                if (r)
                        goto error_free;
 
+               /* Keep a reference to the page table to avoid freeing
+                * them up in the wrong order.
+                */
+               pt->parent = amdgpu_bo_ref(vm->page_directory);
+
                r = amdgpu_vm_clear_bo(adev, pt);
                if (r) {
                        amdgpu_bo_unref(&pt);
@@ -1121,7 +1133,7 @@ int amdgpu_vm_bo_unmap(struct amdgpu_device *adev,
        bool valid = true;
 
        saddr /= AMDGPU_GPU_PAGE_SIZE;
-
+       mutex_lock(&bo_va->mutex);
        list_for_each_entry(mapping, &bo_va->valids, list) {
                if (mapping->it.start == saddr)
                        break;
@@ -1135,20 +1147,25 @@ int amdgpu_vm_bo_unmap(struct amdgpu_device *adev,
                                break;
                }
 
-               if (&mapping->list == &bo_va->invalids)
+               if (&mapping->list == &bo_va->invalids) {
+                       mutex_unlock(&bo_va->mutex);
                        return -ENOENT;
+               }
        }
-
+       mutex_unlock(&bo_va->mutex);
        list_del(&mapping->list);
        spin_lock(&vm->it_lock);
        interval_tree_remove(&mapping->it, &vm->va);
        spin_unlock(&vm->it_lock);
        trace_amdgpu_vm_bo_unmap(bo_va, mapping);
 
-       if (valid)
+       if (valid) {
+               spin_lock(&vm->freed_lock);
                list_add(&mapping->list, &vm->freed);
-       else
+               spin_unlock(&vm->freed_lock);
+       } else {
                kfree(mapping);
+       }
 
        return 0;
 }
@@ -1181,7 +1198,9 @@ void amdgpu_vm_bo_rmv(struct amdgpu_device *adev,
                interval_tree_remove(&mapping->it, &vm->va);
                spin_unlock(&vm->it_lock);
                trace_amdgpu_vm_bo_unmap(bo_va, mapping);
+               spin_lock(&vm->freed_lock);
                list_add(&mapping->list, &vm->freed);
+               spin_unlock(&vm->freed_lock);
        }
        list_for_each_entry_safe(mapping, next, &bo_va->invalids, list) {
                list_del(&mapping->list);
@@ -1190,8 +1209,8 @@ void amdgpu_vm_bo_rmv(struct amdgpu_device *adev,
                spin_unlock(&vm->it_lock);
                kfree(mapping);
        }
-
        fence_put(bo_va->last_pt_update);
+       mutex_destroy(&bo_va->mutex);
        kfree(bo_va);
 }
 
@@ -1236,13 +1255,13 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm)
                vm->ids[i].id = 0;
                vm->ids[i].flushed_updates = NULL;
        }
-       mutex_init(&vm->mutex);
        vm->va = RB_ROOT;
        spin_lock_init(&vm->status_lock);
        INIT_LIST_HEAD(&vm->invalidated);
        INIT_LIST_HEAD(&vm->cleared);
        INIT_LIST_HEAD(&vm->freed);
        spin_lock_init(&vm->it_lock);
+       spin_lock_init(&vm->freed_lock);
        pd_size = amdgpu_vm_directory_size(adev);
        pd_entries = amdgpu_vm_num_pdes(adev);
 
@@ -1320,7 +1339,6 @@ void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm)
                fence_put(vm->ids[i].flushed_updates);
        }
 
-       mutex_destroy(&vm->mutex);
 }
 
 /**
index cb0f7747e3dcac2dfa923d43fc0dd8574968d575..4dcc8fba579203297ece7849ab8a861ecbe33f10 100644 (file)
@@ -1250,7 +1250,7 @@ static void dce_v10_0_program_watermarks(struct amdgpu_device *adev,
        u32 pixel_period;
        u32 line_time = 0;
        u32 latency_watermark_a = 0, latency_watermark_b = 0;
-       u32 tmp, wm_mask;
+       u32 tmp, wm_mask, lb_vblank_lead_lines = 0;
 
        if (amdgpu_crtc->base.enabled && num_heads && mode) {
                pixel_period = 1000000 / (u32)mode->clock;
@@ -1333,6 +1333,7 @@ static void dce_v10_0_program_watermarks(struct amdgpu_device *adev,
                    (adev->mode_info.disp_priority == 2)) {
                        DRM_DEBUG_KMS("force priority to high\n");
                }
+               lb_vblank_lead_lines = DIV_ROUND_UP(lb_size, mode->crtc_hdisplay);
        }
 
        /* select wm A */
@@ -1357,6 +1358,8 @@ static void dce_v10_0_program_watermarks(struct amdgpu_device *adev,
        amdgpu_crtc->line_time = line_time;
        amdgpu_crtc->wm_high = latency_watermark_a;
        amdgpu_crtc->wm_low = latency_watermark_b;
+       /* Save number of lines the linebuffer leads before the scanout */
+       amdgpu_crtc->lb_vblank_lead_lines = lb_vblank_lead_lines;
 }
 
 /**
index 5af3721851d67e99b521328babc38c811a7e2c09..8f1e51128b33882d5680731b9afb08fcf1b1023c 100644 (file)
@@ -1238,7 +1238,7 @@ static void dce_v11_0_program_watermarks(struct amdgpu_device *adev,
        u32 pixel_period;
        u32 line_time = 0;
        u32 latency_watermark_a = 0, latency_watermark_b = 0;
-       u32 tmp, wm_mask;
+       u32 tmp, wm_mask, lb_vblank_lead_lines = 0;
 
        if (amdgpu_crtc->base.enabled && num_heads && mode) {
                pixel_period = 1000000 / (u32)mode->clock;
@@ -1321,6 +1321,7 @@ static void dce_v11_0_program_watermarks(struct amdgpu_device *adev,
                    (adev->mode_info.disp_priority == 2)) {
                        DRM_DEBUG_KMS("force priority to high\n");
                }
+               lb_vblank_lead_lines = DIV_ROUND_UP(lb_size, mode->crtc_hdisplay);
        }
 
        /* select wm A */
@@ -1345,6 +1346,8 @@ static void dce_v11_0_program_watermarks(struct amdgpu_device *adev,
        amdgpu_crtc->line_time = line_time;
        amdgpu_crtc->wm_high = latency_watermark_a;
        amdgpu_crtc->wm_low = latency_watermark_b;
+       /* Save number of lines the linebuffer leads before the scanout */
+       amdgpu_crtc->lb_vblank_lead_lines = lb_vblank_lead_lines;
 }
 
 /**
index 4f7b49a6dc500c431ba9aa52727232156f60bda1..42d954dc436d03206c48aafe7655966870dfc931 100644 (file)
@@ -1193,7 +1193,7 @@ static void dce_v8_0_program_watermarks(struct amdgpu_device *adev,
        u32 pixel_period;
        u32 line_time = 0;
        u32 latency_watermark_a = 0, latency_watermark_b = 0;
-       u32 tmp, wm_mask;
+       u32 tmp, wm_mask, lb_vblank_lead_lines = 0;
 
        if (amdgpu_crtc->base.enabled && num_heads && mode) {
                pixel_period = 1000000 / (u32)mode->clock;
@@ -1276,6 +1276,7 @@ static void dce_v8_0_program_watermarks(struct amdgpu_device *adev,
                    (adev->mode_info.disp_priority == 2)) {
                        DRM_DEBUG_KMS("force priority to high\n");
                }
+               lb_vblank_lead_lines = DIV_ROUND_UP(lb_size, mode->crtc_hdisplay);
        }
 
        /* select wm A */
@@ -1302,6 +1303,8 @@ static void dce_v8_0_program_watermarks(struct amdgpu_device *adev,
        amdgpu_crtc->line_time = line_time;
        amdgpu_crtc->wm_high = latency_watermark_a;
        amdgpu_crtc->wm_low = latency_watermark_b;
+       /* Save number of lines the linebuffer leads before the scanout */
+       amdgpu_crtc->lb_vblank_lead_lines = lb_vblank_lead_lines;
 }
 
 /**
index 7427d8cd4c43fae6068c8a3455ac98f3627ff044..ed8abb58a785ef3efaba87a806e7bcdef7188a1b 100644 (file)
@@ -513,7 +513,7 @@ static int gmc_v7_0_gart_enable(struct amdgpu_device *adev)
        WREG32(mmVM_L2_CNTL3, tmp);
        /* setup context0 */
        WREG32(mmVM_CONTEXT0_PAGE_TABLE_START_ADDR, adev->mc.gtt_start >> 12);
-       WREG32(mmVM_CONTEXT0_PAGE_TABLE_END_ADDR, (adev->mc.gtt_end >> 12) - 1);
+       WREG32(mmVM_CONTEXT0_PAGE_TABLE_END_ADDR, adev->mc.gtt_end >> 12);
        WREG32(mmVM_CONTEXT0_PAGE_TABLE_BASE_ADDR, adev->gart.table_addr >> 12);
        WREG32(mmVM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR,
                        (u32)(adev->dummy_page.addr >> 12));
index cb0e50ebb5285cef90b4a2879cd3cd800129c296..d390284408144c923d8571da0df70b3fab38879c 100644 (file)
@@ -657,7 +657,7 @@ static int gmc_v8_0_gart_enable(struct amdgpu_device *adev)
        WREG32(mmVM_L2_CNTL4, tmp);
        /* setup context0 */
        WREG32(mmVM_CONTEXT0_PAGE_TABLE_START_ADDR, adev->mc.gtt_start >> 12);
-       WREG32(mmVM_CONTEXT0_PAGE_TABLE_END_ADDR, (adev->mc.gtt_end >> 12) - 1);
+       WREG32(mmVM_CONTEXT0_PAGE_TABLE_END_ADDR, adev->mc.gtt_end >> 12);
        WREG32(mmVM_CONTEXT0_PAGE_TABLE_BASE_ADDR, adev->gart.table_addr >> 12);
        WREG32(mmVM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR,
                        (u32)(adev->dummy_page.addr >> 12));
index 6a52db6ad8d779afe7a82f29a731a4e912183bcb..370c6c9d81c26550302b974a4b794ed464090b65 100644 (file)
@@ -40,6 +40,9 @@
 
 #define GRBM_GFX_INDEX__VCE_INSTANCE__SHIFT    0x04
 #define GRBM_GFX_INDEX__VCE_INSTANCE_MASK      0x10
+#define mmVCE_LMI_VCPU_CACHE_40BIT_BAR0        0x8616
+#define mmVCE_LMI_VCPU_CACHE_40BIT_BAR1        0x8617
+#define mmVCE_LMI_VCPU_CACHE_40BIT_BAR2        0x8618
 
 #define VCE_V3_0_FW_SIZE       (384 * 1024)
 #define VCE_V3_0_STACK_SIZE    (64 * 1024)
@@ -130,9 +133,11 @@ static int vce_v3_0_start(struct amdgpu_device *adev)
 
                /* set BUSY flag */
                WREG32_P(mmVCE_STATUS, 1, ~1);
-
-               WREG32_P(mmVCE_VCPU_CNTL, VCE_VCPU_CNTL__CLK_EN_MASK,
-                       ~VCE_VCPU_CNTL__CLK_EN_MASK);
+               if (adev->asic_type >= CHIP_STONEY)
+                       WREG32_P(mmVCE_VCPU_CNTL, 1, ~0x200001);
+               else
+                       WREG32_P(mmVCE_VCPU_CNTL, VCE_VCPU_CNTL__CLK_EN_MASK,
+                               ~VCE_VCPU_CNTL__CLK_EN_MASK);
 
                WREG32_P(mmVCE_SOFT_RESET,
                         VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK,
@@ -391,8 +396,12 @@ static void vce_v3_0_mc_resume(struct amdgpu_device *adev, int idx)
        WREG32(mmVCE_LMI_SWAP_CNTL, 0);
        WREG32(mmVCE_LMI_SWAP_CNTL1, 0);
        WREG32(mmVCE_LMI_VM_CTRL, 0);
-
-       WREG32(mmVCE_LMI_VCPU_CACHE_40BIT_BAR, (adev->vce.gpu_addr >> 8));
+       if (adev->asic_type >= CHIP_STONEY) {
+               WREG32(mmVCE_LMI_VCPU_CACHE_40BIT_BAR0, (adev->vce.gpu_addr >> 8));
+               WREG32(mmVCE_LMI_VCPU_CACHE_40BIT_BAR1, (adev->vce.gpu_addr >> 8));
+               WREG32(mmVCE_LMI_VCPU_CACHE_40BIT_BAR2, (adev->vce.gpu_addr >> 8));
+       } else
+               WREG32(mmVCE_LMI_VCPU_CACHE_40BIT_BAR, (adev->vce.gpu_addr >> 8));
        offset = AMDGPU_VCE_FIRMWARE_OFFSET;
        size = VCE_V3_0_FW_SIZE;
        WREG32(mmVCE_VCPU_CACHE_OFFSET0, offset & 0x7fffffff);
@@ -576,6 +585,11 @@ static int vce_v3_0_process_interrupt(struct amdgpu_device *adev,
                                      struct amdgpu_iv_entry *entry)
 {
        DRM_DEBUG("IH: VCE\n");
+
+       WREG32_P(mmVCE_SYS_INT_STATUS,
+               VCE_SYS_INT_STATUS__VCE_SYS_INT_TRAP_INTERRUPT_INT_MASK,
+               ~VCE_SYS_INT_STATUS__VCE_SYS_INT_TRAP_INTERRUPT_INT_MASK);
+
        switch (entry->src_data) {
        case 0:
                amdgpu_fence_process(&adev->vce.ring[0]);
index ea30d6ad4c137e60e6f9c1ce4265305d60f85cc9..3a4820e863ecbbc8ee003c47f3ccc088804f4f53 100644 (file)
@@ -30,8 +30,7 @@
 #define CREATE_TRACE_POINTS
 #include "gpu_sched_trace.h"
 
-static struct amd_sched_job *
-amd_sched_entity_pop_job(struct amd_sched_entity *entity);
+static bool amd_sched_entity_is_ready(struct amd_sched_entity *entity);
 static void amd_sched_wakeup(struct amd_gpu_scheduler *sched);
 
 struct kmem_cache *sched_fence_slab;
@@ -64,36 +63,36 @@ static void amd_sched_rq_remove_entity(struct amd_sched_rq *rq,
 }
 
 /**
- * Select next job from a specified run queue with round robin policy.
- * Return NULL if nothing available.
+ * Select an entity which could provide a job to run
+ *
+ * @rq         The run queue to check.
+ *
+ * Try to find a ready entity, returns NULL if none found.
  */
-static struct amd_sched_job *
-amd_sched_rq_select_job(struct amd_sched_rq *rq)
+static struct amd_sched_entity *
+amd_sched_rq_select_entity(struct amd_sched_rq *rq)
 {
        struct amd_sched_entity *entity;
-       struct amd_sched_job *sched_job;
 
        spin_lock(&rq->lock);
 
        entity = rq->current_entity;
        if (entity) {
                list_for_each_entry_continue(entity, &rq->entities, list) {
-                       sched_job = amd_sched_entity_pop_job(entity);
-                       if (sched_job) {
+                       if (amd_sched_entity_is_ready(entity)) {
                                rq->current_entity = entity;
                                spin_unlock(&rq->lock);
-                               return sched_job;
+                               return entity;
                        }
                }
        }
 
        list_for_each_entry(entity, &rq->entities, list) {
 
-               sched_job = amd_sched_entity_pop_job(entity);
-               if (sched_job) {
+               if (amd_sched_entity_is_ready(entity)) {
                        rq->current_entity = entity;
                        spin_unlock(&rq->lock);
-                       return sched_job;
+                       return entity;
                }
 
                if (entity == rq->current_entity)
@@ -176,6 +175,24 @@ static bool amd_sched_entity_is_idle(struct amd_sched_entity *entity)
        return false;
 }
 
+/**
+ * Check if entity is ready
+ *
+ * @entity     The pointer to a valid scheduler entity
+ *
+ * Return true if entity could provide a job.
+ */
+static bool amd_sched_entity_is_ready(struct amd_sched_entity *entity)
+{
+       if (kfifo_is_empty(&entity->job_queue))
+               return false;
+
+       if (ACCESS_ONCE(entity->dependency))
+               return false;
+
+       return true;
+}
+
 /**
  * Destroy a context entity
  *
@@ -211,32 +228,53 @@ static void amd_sched_entity_wakeup(struct fence *f, struct fence_cb *cb)
        amd_sched_wakeup(entity->sched);
 }
 
+static bool amd_sched_entity_add_dependency_cb(struct amd_sched_entity *entity)
+{
+       struct amd_gpu_scheduler *sched = entity->sched;
+       struct fence * fence = entity->dependency;
+       struct amd_sched_fence *s_fence;
+
+       if (fence->context == entity->fence_context) {
+               /* We can ignore fences from ourself */
+               fence_put(entity->dependency);
+               return false;
+       }
+
+       s_fence = to_amd_sched_fence(fence);
+       if (s_fence && s_fence->sched == sched) {
+               /* Fence is from the same scheduler */
+               if (test_bit(AMD_SCHED_FENCE_SCHEDULED_BIT, &fence->flags)) {
+                       /* Ignore it when it is already scheduled */
+                       fence_put(entity->dependency);
+                       return false;
+               }
+
+               /* Wait for fence to be scheduled */
+               entity->cb.func = amd_sched_entity_wakeup;
+               list_add_tail(&entity->cb.node, &s_fence->scheduled_cb);
+               return true;
+       }
+
+       if (!fence_add_callback(entity->dependency, &entity->cb,
+                               amd_sched_entity_wakeup))
+               return true;
+
+       fence_put(entity->dependency);
+       return false;
+}
+
 static struct amd_sched_job *
 amd_sched_entity_pop_job(struct amd_sched_entity *entity)
 {
        struct amd_gpu_scheduler *sched = entity->sched;
        struct amd_sched_job *sched_job;
 
-       if (ACCESS_ONCE(entity->dependency))
-               return NULL;
-
        if (!kfifo_out_peek(&entity->job_queue, &sched_job, sizeof(sched_job)))
                return NULL;
 
-       while ((entity->dependency = sched->ops->dependency(sched_job))) {
-
-               if (entity->dependency->context == entity->fence_context) {
-                       /* We can ignore fences from ourself */
-                       fence_put(entity->dependency);
-                       continue;
-               }
-
-               if (fence_add_callback(entity->dependency, &entity->cb,
-                                      amd_sched_entity_wakeup))
-                       fence_put(entity->dependency);
-               else
+       while ((entity->dependency = sched->ops->dependency(sched_job)))
+               if (amd_sched_entity_add_dependency_cb(entity))
                        return NULL;
-       }
 
        return sched_job;
 }
@@ -250,6 +288,7 @@ amd_sched_entity_pop_job(struct amd_sched_entity *entity)
  */
 static bool amd_sched_entity_in(struct amd_sched_job *sched_job)
 {
+       struct amd_gpu_scheduler *sched = sched_job->sched;
        struct amd_sched_entity *entity = sched_job->s_entity;
        bool added, first = false;
 
@@ -264,7 +303,7 @@ static bool amd_sched_entity_in(struct amd_sched_job *sched_job)
 
        /* first job wakes up scheduler */
        if (first)
-               amd_sched_wakeup(sched_job->sched);
+               amd_sched_wakeup(sched);
 
        return added;
 }
@@ -280,9 +319,9 @@ void amd_sched_entity_push_job(struct amd_sched_job *sched_job)
 {
        struct amd_sched_entity *entity = sched_job->s_entity;
 
+       trace_amd_sched_job(sched_job);
        wait_event(entity->sched->job_scheduled,
                   amd_sched_entity_in(sched_job));
-       trace_amd_sched_job(sched_job);
 }
 
 /**
@@ -304,22 +343,22 @@ static void amd_sched_wakeup(struct amd_gpu_scheduler *sched)
 }
 
 /**
- * Select next to run
+ * Select next entity to process
 */
-static struct amd_sched_job *
-amd_sched_select_job(struct amd_gpu_scheduler *sched)
+static struct amd_sched_entity *
+amd_sched_select_entity(struct amd_gpu_scheduler *sched)
 {
-       struct amd_sched_job *sched_job;
+       struct amd_sched_entity *entity;
 
        if (!amd_sched_ready(sched))
                return NULL;
 
        /* Kernel run queue has higher priority than normal run queue*/
-       sched_job = amd_sched_rq_select_job(&sched->kernel_rq);
-       if (sched_job == NULL)
-               sched_job = amd_sched_rq_select_job(&sched->sched_rq);
+       entity = amd_sched_rq_select_entity(&sched->kernel_rq);
+       if (entity == NULL)
+               entity = amd_sched_rq_select_entity(&sched->sched_rq);
 
-       return sched_job;
+       return entity;
 }
 
 static void amd_sched_process_job(struct fence *f, struct fence_cb *cb)
@@ -381,13 +420,16 @@ static int amd_sched_main(void *param)
                unsigned long flags;
 
                wait_event_interruptible(sched->wake_up_worker,
-                       kthread_should_stop() ||
-                       (sched_job = amd_sched_select_job(sched)));
+                       (entity = amd_sched_select_entity(sched)) ||
+                       kthread_should_stop());
 
+               if (!entity)
+                       continue;
+
+               sched_job = amd_sched_entity_pop_job(entity);
                if (!sched_job)
                        continue;
 
-               entity = sched_job->s_entity;
                s_fence = sched_job->s_fence;
 
                if (sched->timeout != MAX_SCHEDULE_TIMEOUT) {
@@ -400,6 +442,7 @@ static int amd_sched_main(void *param)
 
                atomic_inc(&sched->hw_rq_count);
                fence = sched->ops->run_job(sched_job);
+               amd_sched_fence_scheduled(s_fence);
                if (fence) {
                        r = fence_add_callback(fence, &s_fence->cb,
                                               amd_sched_process_job);
index 939692b14f4b10ca3434f537f8ee2e214b2bec2e..a0f0ae53aacdefacc6a80f2506b5bd9f2a4cea9c 100644 (file)
@@ -27,6 +27,8 @@
 #include <linux/kfifo.h>
 #include <linux/fence.h>
 
+#define AMD_SCHED_FENCE_SCHEDULED_BIT  FENCE_FLAG_USER_BITS
+
 struct amd_gpu_scheduler;
 struct amd_sched_rq;
 
@@ -68,6 +70,7 @@ struct amd_sched_rq {
 struct amd_sched_fence {
        struct fence                    base;
        struct fence_cb                 cb;
+       struct list_head                scheduled_cb;
        struct amd_gpu_scheduler        *sched;
        spinlock_t                      lock;
        void                            *owner;
@@ -134,7 +137,7 @@ void amd_sched_entity_push_job(struct amd_sched_job *sched_job);
 
 struct amd_sched_fence *amd_sched_fence_create(
        struct amd_sched_entity *s_entity, void *owner);
+void amd_sched_fence_scheduled(struct amd_sched_fence *fence);
 void amd_sched_fence_signal(struct amd_sched_fence *fence);
 
-
 #endif
index 8d2130b9ff05c4cea8823a8461f9e63bcb80c390..87c78eecea649a2112035db7fb66bb467cf6f457 100644 (file)
@@ -35,6 +35,8 @@ struct amd_sched_fence *amd_sched_fence_create(struct amd_sched_entity *s_entity
        fence = kmem_cache_zalloc(sched_fence_slab, GFP_KERNEL);
        if (fence == NULL)
                return NULL;
+
+       INIT_LIST_HEAD(&fence->scheduled_cb);
        fence->owner = owner;
        fence->sched = s_entity->sched;
        spin_lock_init(&fence->lock);
@@ -55,6 +57,17 @@ void amd_sched_fence_signal(struct amd_sched_fence *fence)
                FENCE_TRACE(&fence->base, "was already signaled\n");
 }
 
+void amd_sched_fence_scheduled(struct amd_sched_fence *s_fence)
+{
+       struct fence_cb *cur, *tmp;
+
+       set_bit(AMD_SCHED_FENCE_SCHEDULED_BIT, &s_fence->base.flags);
+       list_for_each_entry_safe(cur, tmp, &s_fence->scheduled_cb, node) {
+               list_del_init(&cur->node);
+               cur->func(&s_fence->base, cur);
+       }
+}
+
 static const char *amd_sched_fence_get_driver_name(struct fence *fence)
 {
        return "amd_sched";
index 9362609df38ae4077ae934d96f5098ffaabd59dd..7dd6728dd092e23af63516295be42331bcc1f3c8 100644 (file)
@@ -160,6 +160,11 @@ int drm_setmaster_ioctl(struct drm_device *dev, void *data,
                goto out_unlock;
        }
 
+       if (!file_priv->allowed_master) {
+               ret = drm_new_set_master(dev, file_priv);
+               goto out_unlock;
+       }
+
        file_priv->minor->master = drm_master_get(file_priv->master);
        file_priv->is_master = 1;
        if (dev->driver->master_set) {
index c59ce4d0ef75f4e878ad5964c90e86afd2467456..6b5625e6611975735a1bd4c218edd3cfa9ec5e69 100644 (file)
@@ -125,6 +125,60 @@ static int drm_cpu_valid(void)
        return 1;
 }
 
+/**
+ * drm_new_set_master - Allocate a new master object and become master for the
+ * associated master realm.
+ *
+ * @dev: The associated device.
+ * @fpriv: File private identifying the client.
+ *
+ * This function must be called with dev::struct_mutex held.
+ * Returns negative error code on failure. Zero on success.
+ */
+int drm_new_set_master(struct drm_device *dev, struct drm_file *fpriv)
+{
+       struct drm_master *old_master;
+       int ret;
+
+       lockdep_assert_held_once(&dev->master_mutex);
+
+       /* create a new master */
+       fpriv->minor->master = drm_master_create(fpriv->minor);
+       if (!fpriv->minor->master)
+               return -ENOMEM;
+
+       /* take another reference for the copy in the local file priv */
+       old_master = fpriv->master;
+       fpriv->master = drm_master_get(fpriv->minor->master);
+
+       if (dev->driver->master_create) {
+               ret = dev->driver->master_create(dev, fpriv->master);
+               if (ret)
+                       goto out_err;
+       }
+       if (dev->driver->master_set) {
+               ret = dev->driver->master_set(dev, fpriv, true);
+               if (ret)
+                       goto out_err;
+       }
+
+       fpriv->is_master = 1;
+       fpriv->allowed_master = 1;
+       fpriv->authenticated = 1;
+       if (old_master)
+               drm_master_put(&old_master);
+
+       return 0;
+
+out_err:
+       /* drop both references and restore old master on failure */
+       drm_master_put(&fpriv->minor->master);
+       drm_master_put(&fpriv->master);
+       fpriv->master = old_master;
+
+       return ret;
+}
+
 /**
  * Called whenever a process opens /dev/drm.
  *
@@ -189,35 +243,9 @@ static int drm_open_helper(struct file *filp, struct drm_minor *minor)
        mutex_lock(&dev->master_mutex);
        if (drm_is_primary_client(priv) && !priv->minor->master) {
                /* create a new master */
-               priv->minor->master = drm_master_create(priv->minor);
-               if (!priv->minor->master) {
-                       ret = -ENOMEM;
+               ret = drm_new_set_master(dev, priv);
+               if (ret)
                        goto out_close;
-               }
-
-               priv->is_master = 1;
-               /* take another reference for the copy in the local file priv */
-               priv->master = drm_master_get(priv->minor->master);
-               priv->authenticated = 1;
-
-               if (dev->driver->master_create) {
-                       ret = dev->driver->master_create(dev, priv->master);
-                       if (ret) {
-                               /* drop both references if this fails */
-                               drm_master_put(&priv->minor->master);
-                               drm_master_put(&priv->master);
-                               goto out_close;
-                       }
-               }
-               if (dev->driver->master_set) {
-                       ret = dev->driver->master_set(dev, priv, true);
-                       if (ret) {
-                               /* drop both references if this fails */
-                               drm_master_put(&priv->minor->master);
-                               drm_master_put(&priv->master);
-                               goto out_close;
-                       }
-               }
        } else if (drm_is_primary_client(priv)) {
                /* get a reference to the master */
                priv->master = drm_master_get(priv->minor->master);
index 2151ea551d3bd6526d850754b79ece388a9279df..607f493ae80132890ad97422f58f9cdf95eefc75 100644 (file)
@@ -980,7 +980,8 @@ static void send_vblank_event(struct drm_device *dev,
                struct drm_pending_vblank_event *e,
                unsigned long seq, struct timeval *now)
 {
-       WARN_ON_SMP(!spin_is_locked(&dev->event_lock));
+       assert_spin_locked(&dev->event_lock);
+
        e->event.sequence = seq;
        e->event.tv_sec = now->tv_sec;
        e->event.tv_usec = now->tv_usec;
@@ -992,6 +993,57 @@ static void send_vblank_event(struct drm_device *dev,
                                         e->event.sequence);
 }
 
+/**
+ * drm_arm_vblank_event - arm vblank event after pageflip
+ * @dev: DRM device
+ * @pipe: CRTC index
+ * @e: the event to prepare to send
+ *
+ * A lot of drivers need to generate vblank events for the very next vblank
+ * interrupt. For example when the page flip interrupt happens when the page
+ * flip gets armed, but not when it actually executes within the next vblank
+ * period. This helper function implements exactly the required vblank arming
+ * behaviour.
+ *
+ * Caller must hold event lock. Caller must also hold a vblank reference for
+ * the event @e, which will be dropped when the next vblank arrives.
+ *
+ * This is the legacy version of drm_crtc_arm_vblank_event().
+ */
+void drm_arm_vblank_event(struct drm_device *dev, unsigned int pipe,
+                         struct drm_pending_vblank_event *e)
+{
+       assert_spin_locked(&dev->event_lock);
+
+       e->pipe = pipe;
+       e->event.sequence = drm_vblank_count(dev, pipe);
+       list_add_tail(&e->base.link, &dev->vblank_event_list);
+}
+EXPORT_SYMBOL(drm_arm_vblank_event);
+
+/**
+ * drm_crtc_arm_vblank_event - arm vblank event after pageflip
+ * @crtc: the source CRTC of the vblank event
+ * @e: the event to send
+ *
+ * A lot of drivers need to generate vblank events for the very next vblank
+ * interrupt. For example when the page flip interrupt happens when the page
+ * flip gets armed, but not when it actually executes within the next vblank
+ * period. This helper function implements exactly the required vblank arming
+ * behaviour.
+ *
+ * Caller must hold event lock. Caller must also hold a vblank reference for
+ * the event @e, which will be dropped when the next vblank arrives.
+ *
+ * This is the native KMS version of drm_arm_vblank_event().
+ */
+void drm_crtc_arm_vblank_event(struct drm_crtc *crtc,
+                              struct drm_pending_vblank_event *e)
+{
+       drm_arm_vblank_event(crtc->dev, drm_crtc_index(crtc), e);
+}
+EXPORT_SYMBOL(drm_crtc_arm_vblank_event);
+
 /**
  * drm_send_vblank_event - helper to send vblank event after pageflip
  * @dev: DRM device
index a3b22bdacd44f539a81429d7e1946d86d8cb4f78..8aab974b0564c4a8bef46a6a05d5c200831d70f6 100644 (file)
@@ -2734,6 +2734,8 @@ static const char *power_domain_str(enum intel_display_power_domain domain)
                return "AUX_C";
        case POWER_DOMAIN_AUX_D:
                return "AUX_D";
+       case POWER_DOMAIN_GMBUS:
+               return "GMBUS";
        case POWER_DOMAIN_INIT:
                return "INIT";
        default:
index 95bb27de774f8fb2c5bb8cc83567a45eb83a8e43..a01e51581c4c466a000e2aa6b22f42e97ec31b85 100644 (file)
@@ -199,6 +199,7 @@ enum intel_display_power_domain {
        POWER_DOMAIN_AUX_B,
        POWER_DOMAIN_AUX_C,
        POWER_DOMAIN_AUX_D,
+       POWER_DOMAIN_GMBUS,
        POWER_DOMAIN_INIT,
 
        POWER_DOMAIN_NUM,
index 91bb1fc27420f5a58f9fc2ca962a4b452f9cb7e6..32e6aade62238be511237c9ffad1933e18e561cb 100644 (file)
@@ -1210,8 +1210,16 @@ int __i915_wait_request(struct drm_i915_gem_request *req,
        if (i915_gem_request_completed(req, true))
                return 0;
 
-       timeout_expire = timeout ?
-               jiffies + nsecs_to_jiffies_timeout((u64)*timeout) : 0;
+       timeout_expire = 0;
+       if (timeout) {
+               if (WARN_ON(*timeout < 0))
+                       return -EINVAL;
+
+               if (*timeout == 0)
+                       return -ETIME;
+
+               timeout_expire = jiffies + nsecs_to_jiffies_timeout(*timeout);
+       }
 
        if (INTEL_INFO(dev_priv)->gen >= 6)
                gen6_rps_boost(dev_priv, rps, req->emitted_jiffies);
index 40a10b25956c2a26fc75500d2e10a77b639e43fb..f010391b87f5cd0803c7bc994f8b44fd68a5e9b6 100644 (file)
@@ -642,11 +642,10 @@ i915_gem_detect_bit_6_swizzle(struct drm_device *dev)
                }
 
                /* check for L-shaped memory aka modified enhanced addressing */
-               if (IS_GEN4(dev)) {
-                       uint32_t ddc2 = I915_READ(DCC2);
-
-                       if (!(ddc2 & DCC2_MODIFIED_ENHANCED_DISABLE))
-                               dev_priv->quirks |= QUIRK_PIN_SWIZZLED_PAGES;
+               if (IS_GEN4(dev) &&
+                   !(I915_READ(DCC2) & DCC2_MODIFIED_ENHANCED_DISABLE)) {
+                       swizzle_x = I915_BIT_6_SWIZZLE_UNKNOWN;
+                       swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN;
                }
 
                if (dcc == 0xffffffff) {
@@ -675,16 +674,35 @@ i915_gem_detect_bit_6_swizzle(struct drm_device *dev)
                 * matching, which was the case for the swizzling required in
                 * the table above, or from the 1-ch value being less than
                 * the minimum size of a rank.
+                *
+                * Reports indicate that the swizzling actually
+                * varies depending upon page placement inside the
+                * channels, i.e. we see swizzled pages where the
+                * banks of memory are paired and unswizzled on the
+                * uneven portion, so leave that as unknown.
                 */
-               if (I915_READ16(C0DRB3) != I915_READ16(C1DRB3)) {
-                       swizzle_x = I915_BIT_6_SWIZZLE_NONE;
-                       swizzle_y = I915_BIT_6_SWIZZLE_NONE;
-               } else {
+               if (I915_READ16(C0DRB3) == I915_READ16(C1DRB3)) {
                        swizzle_x = I915_BIT_6_SWIZZLE_9_10;
                        swizzle_y = I915_BIT_6_SWIZZLE_9;
                }
        }
 
+       if (swizzle_x == I915_BIT_6_SWIZZLE_UNKNOWN ||
+           swizzle_y == I915_BIT_6_SWIZZLE_UNKNOWN) {
+               /* Userspace likes to explode if it sees unknown swizzling,
+                * so lie. We will finish the lie when reporting through
+                * the get-tiling-ioctl by reporting the physical swizzle
+                * mode as unknown instead.
+                *
+                * As we don't strictly know what the swizzling is, it may be
+                * bit17 dependent, and so we need to also prevent the pages
+                * from being moved.
+                */
+               dev_priv->quirks |= QUIRK_PIN_SWIZZLED_PAGES;
+               swizzle_x = I915_BIT_6_SWIZZLE_NONE;
+               swizzle_y = I915_BIT_6_SWIZZLE_NONE;
+       }
+
        dev_priv->mm.bit_6_swizzle_x = swizzle_x;
        dev_priv->mm.bit_6_swizzle_y = swizzle_y;
 }
index 71860f8680f9fb95efae6ea310be6ef450d25e57..22e86d2e408d9493e6c2ea6a60e689a5c03934a9 100644 (file)
@@ -5194,11 +5194,31 @@ static enum intel_display_power_domain port_to_power_domain(enum port port)
        case PORT_E:
                return POWER_DOMAIN_PORT_DDI_E_2_LANES;
        default:
-               WARN_ON_ONCE(1);
+               MISSING_CASE(port);
                return POWER_DOMAIN_PORT_OTHER;
        }
 }
 
+static enum intel_display_power_domain port_to_aux_power_domain(enum port port)
+{
+       switch (port) {
+       case PORT_A:
+               return POWER_DOMAIN_AUX_A;
+       case PORT_B:
+               return POWER_DOMAIN_AUX_B;
+       case PORT_C:
+               return POWER_DOMAIN_AUX_C;
+       case PORT_D:
+               return POWER_DOMAIN_AUX_D;
+       case PORT_E:
+               /* FIXME: Check VBT for actual wiring of PORT E */
+               return POWER_DOMAIN_AUX_D;
+       default:
+               MISSING_CASE(port);
+               return POWER_DOMAIN_AUX_A;
+       }
+}
+
 #define for_each_power_domain(domain, mask)                            \
        for ((domain) = 0; (domain) < POWER_DOMAIN_NUM; (domain)++)     \
                if ((1 << (domain)) & (mask))
@@ -5230,6 +5250,36 @@ intel_display_port_power_domain(struct intel_encoder *intel_encoder)
        }
 }
 
+enum intel_display_power_domain
+intel_display_port_aux_power_domain(struct intel_encoder *intel_encoder)
+{
+       struct drm_device *dev = intel_encoder->base.dev;
+       struct intel_digital_port *intel_dig_port;
+
+       switch (intel_encoder->type) {
+       case INTEL_OUTPUT_UNKNOWN:
+       case INTEL_OUTPUT_HDMI:
+               /*
+                * Only DDI platforms should ever use these output types.
+                * We can get here after the HDMI detect code has already set
+                * the type of the shared encoder. Since we can't be sure
+                * what's the status of the given connectors, play safe and
+                * run the DP detection too.
+                */
+               WARN_ON_ONCE(!HAS_DDI(dev));
+       case INTEL_OUTPUT_DISPLAYPORT:
+       case INTEL_OUTPUT_EDP:
+               intel_dig_port = enc_to_dig_port(&intel_encoder->base);
+               return port_to_aux_power_domain(intel_dig_port->port);
+       case INTEL_OUTPUT_DP_MST:
+               intel_dig_port = enc_to_mst(&intel_encoder->base)->primary;
+               return port_to_aux_power_domain(intel_dig_port->port);
+       default:
+               MISSING_CASE(intel_encoder->type);
+               return POWER_DOMAIN_AUX_A;
+       }
+}
+
 static unsigned long get_crtc_power_domains(struct drm_crtc *crtc)
 {
        struct drm_device *dev = crtc->dev;
@@ -12460,7 +12510,6 @@ intel_pipe_config_compare(struct drm_device *dev,
        if (INTEL_INFO(dev)->gen < 8) {
                PIPE_CONF_CHECK_M_N(dp_m_n);
 
-               PIPE_CONF_CHECK_I(has_drrs);
                if (current_config->has_drrs)
                        PIPE_CONF_CHECK_M_N(dp_m2_n2);
        } else
index 09bdd94ca3ba435b452ef4593620b01fd59456d5..78b8ec84d576da24de0f96c56fabaf5d380ddea5 100644 (file)
@@ -277,7 +277,7 @@ static void pps_lock(struct intel_dp *intel_dp)
         * See vlv_power_sequencer_reset() why we need
         * a power domain reference here.
         */
-       power_domain = intel_display_port_power_domain(encoder);
+       power_domain = intel_display_port_aux_power_domain(encoder);
        intel_display_power_get(dev_priv, power_domain);
 
        mutex_lock(&dev_priv->pps_mutex);
@@ -293,7 +293,7 @@ static void pps_unlock(struct intel_dp *intel_dp)
 
        mutex_unlock(&dev_priv->pps_mutex);
 
-       power_domain = intel_display_port_power_domain(encoder);
+       power_domain = intel_display_port_aux_power_domain(encoder);
        intel_display_power_put(dev_priv, power_domain);
 }
 
@@ -816,8 +816,6 @@ intel_dp_aux_ch(struct intel_dp *intel_dp,
 
        intel_dp_check_edp(intel_dp);
 
-       intel_aux_display_runtime_get(dev_priv);
-
        /* Try to wait for any previous AUX channel activity */
        for (try = 0; try < 3; try++) {
                status = I915_READ_NOTRACE(ch_ctl);
@@ -926,7 +924,6 @@ done:
        ret = recv_bytes;
 out:
        pm_qos_update_request(&dev_priv->pm_qos, PM_QOS_DEFAULT_VALUE);
-       intel_aux_display_runtime_put(dev_priv);
 
        if (vdd)
                edp_panel_vdd_off(intel_dp, false);
@@ -1784,7 +1781,7 @@ static bool edp_panel_vdd_on(struct intel_dp *intel_dp)
        if (edp_have_panel_vdd(intel_dp))
                return need_to_disable;
 
-       power_domain = intel_display_port_power_domain(intel_encoder);
+       power_domain = intel_display_port_aux_power_domain(intel_encoder);
        intel_display_power_get(dev_priv, power_domain);
 
        DRM_DEBUG_KMS("Turning eDP port %c VDD on\n",
@@ -1874,7 +1871,7 @@ static void edp_panel_vdd_off_sync(struct intel_dp *intel_dp)
        if ((pp & POWER_TARGET_ON) == 0)
                intel_dp->last_power_cycle = jiffies;
 
-       power_domain = intel_display_port_power_domain(intel_encoder);
+       power_domain = intel_display_port_aux_power_domain(intel_encoder);
        intel_display_power_put(dev_priv, power_domain);
 }
 
@@ -2025,7 +2022,7 @@ static void edp_panel_off(struct intel_dp *intel_dp)
        wait_panel_off(intel_dp);
 
        /* We got a reference when we enabled the VDD. */
-       power_domain = intel_display_port_power_domain(intel_encoder);
+       power_domain = intel_display_port_aux_power_domain(intel_encoder);
        intel_display_power_put(dev_priv, power_domain);
 }
 
@@ -4765,26 +4762,6 @@ intel_dp_unset_edid(struct intel_dp *intel_dp)
        intel_dp->has_audio = false;
 }
 
-static enum intel_display_power_domain
-intel_dp_power_get(struct intel_dp *dp)
-{
-       struct intel_encoder *encoder = &dp_to_dig_port(dp)->base;
-       enum intel_display_power_domain power_domain;
-
-       power_domain = intel_display_port_power_domain(encoder);
-       intel_display_power_get(to_i915(encoder->base.dev), power_domain);
-
-       return power_domain;
-}
-
-static void
-intel_dp_power_put(struct intel_dp *dp,
-                  enum intel_display_power_domain power_domain)
-{
-       struct intel_encoder *encoder = &dp_to_dig_port(dp)->base;
-       intel_display_power_put(to_i915(encoder->base.dev), power_domain);
-}
-
 static enum drm_connector_status
 intel_dp_detect(struct drm_connector *connector, bool force)
 {
@@ -4808,7 +4785,8 @@ intel_dp_detect(struct drm_connector *connector, bool force)
                return connector_status_disconnected;
        }
 
-       power_domain = intel_dp_power_get(intel_dp);
+       power_domain = intel_display_port_aux_power_domain(intel_encoder);
+       intel_display_power_get(to_i915(dev), power_domain);
 
        /* Can't disconnect eDP, but you can close the lid... */
        if (is_edp(intel_dp))
@@ -4853,7 +4831,7 @@ intel_dp_detect(struct drm_connector *connector, bool force)
        }
 
 out:
-       intel_dp_power_put(intel_dp, power_domain);
+       intel_display_power_put(to_i915(dev), power_domain);
        return status;
 }
 
@@ -4862,6 +4840,7 @@ intel_dp_force(struct drm_connector *connector)
 {
        struct intel_dp *intel_dp = intel_attached_dp(connector);
        struct intel_encoder *intel_encoder = &dp_to_dig_port(intel_dp)->base;
+       struct drm_i915_private *dev_priv = to_i915(intel_encoder->base.dev);
        enum intel_display_power_domain power_domain;
 
        DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
@@ -4871,11 +4850,12 @@ intel_dp_force(struct drm_connector *connector)
        if (connector->status != connector_status_connected)
                return;
 
-       power_domain = intel_dp_power_get(intel_dp);
+       power_domain = intel_display_port_aux_power_domain(intel_encoder);
+       intel_display_power_get(dev_priv, power_domain);
 
        intel_dp_set_edid(intel_dp);
 
-       intel_dp_power_put(intel_dp, power_domain);
+       intel_display_power_put(dev_priv, power_domain);
 
        if (intel_encoder->type != INTEL_OUTPUT_EDP)
                intel_encoder->type = INTEL_OUTPUT_DISPLAYPORT;
@@ -5091,7 +5071,7 @@ static void intel_edp_panel_vdd_sanitize(struct intel_dp *intel_dp)
         * indefinitely.
         */
        DRM_DEBUG_KMS("VDD left on by BIOS, adjusting state tracking\n");
-       power_domain = intel_display_port_power_domain(&intel_dig_port->base);
+       power_domain = intel_display_port_aux_power_domain(&intel_dig_port->base);
        intel_display_power_get(dev_priv, power_domain);
 
        edp_panel_vdd_schedule_off(intel_dp);
@@ -5153,7 +5133,8 @@ intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd)
        enum intel_display_power_domain power_domain;
        enum irqreturn ret = IRQ_NONE;
 
-       if (intel_dig_port->base.type != INTEL_OUTPUT_EDP)
+       if (intel_dig_port->base.type != INTEL_OUTPUT_EDP &&
+           intel_dig_port->base.type != INTEL_OUTPUT_HDMI)
                intel_dig_port->base.type = INTEL_OUTPUT_DISPLAYPORT;
 
        if (long_hpd && intel_dig_port->base.type == INTEL_OUTPUT_EDP) {
@@ -5172,7 +5153,7 @@ intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd)
                      port_name(intel_dig_port->port),
                      long_hpd ? "long" : "short");
 
-       power_domain = intel_display_port_power_domain(intel_encoder);
+       power_domain = intel_display_port_aux_power_domain(intel_encoder);
        intel_display_power_get(dev_priv, power_domain);
 
        if (long_hpd) {
index 0598932ce6235b623df9ff6a62d74e100087f78e..f2a1142bff34310a40abd262a59106bffdecba6f 100644 (file)
@@ -1169,6 +1169,8 @@ void hsw_enable_ips(struct intel_crtc *crtc);
 void hsw_disable_ips(struct intel_crtc *crtc);
 enum intel_display_power_domain
 intel_display_port_power_domain(struct intel_encoder *intel_encoder);
+enum intel_display_power_domain
+intel_display_port_aux_power_domain(struct intel_encoder *intel_encoder);
 void intel_mode_from_pipe_config(struct drm_display_mode *mode,
                                 struct intel_crtc_state *pipe_config);
 void intel_crtc_wait_for_pending_flips(struct drm_crtc *crtc);
@@ -1377,8 +1379,6 @@ void intel_display_power_get(struct drm_i915_private *dev_priv,
                             enum intel_display_power_domain domain);
 void intel_display_power_put(struct drm_i915_private *dev_priv,
                             enum intel_display_power_domain domain);
-void intel_aux_display_runtime_get(struct drm_i915_private *dev_priv);
-void intel_aux_display_runtime_put(struct drm_i915_private *dev_priv);
 void intel_runtime_pm_get(struct drm_i915_private *dev_priv);
 void intel_runtime_pm_get_noresume(struct drm_i915_private *dev_priv);
 void intel_runtime_pm_put(struct drm_i915_private *dev_priv);
index 9eafa191cee2e33c34942006ece7b0b8374cbc8f..81cdd9ff38922397171e91558136ae0765229106 100644 (file)
@@ -1335,21 +1335,17 @@ intel_hdmi_set_edid(struct drm_connector *connector, bool force)
 {
        struct drm_i915_private *dev_priv = to_i915(connector->dev);
        struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
-       struct intel_encoder *intel_encoder =
-               &hdmi_to_dig_port(intel_hdmi)->base;
-       enum intel_display_power_domain power_domain;
        struct edid *edid = NULL;
        bool connected = false;
 
-       power_domain = intel_display_port_power_domain(intel_encoder);
-       intel_display_power_get(dev_priv, power_domain);
+       intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS);
 
        if (force)
                edid = drm_get_edid(connector,
                                    intel_gmbus_get_adapter(dev_priv,
                                    intel_hdmi->ddc_bus));
 
-       intel_display_power_put(dev_priv, power_domain);
+       intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS);
 
        to_intel_connector(connector)->detect_edid = edid;
        if (edid && edid->input & DRM_EDID_INPUT_DIGITAL) {
@@ -1383,6 +1379,8 @@ intel_hdmi_detect(struct drm_connector *connector, bool force)
        DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
                      connector->base.id, connector->name);
 
+       intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS);
+
        while (!live_status && --retry) {
                live_status = intel_digital_port_connected(dev_priv,
                                hdmi_to_dig_port(intel_hdmi));
@@ -1402,6 +1400,8 @@ intel_hdmi_detect(struct drm_connector *connector, bool force)
        } else
                status = connector_status_disconnected;
 
+       intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS);
+
        return status;
 }
 
index 1369fc41d03913f217894c700fa220465362b975..8324654037b65577fd4bdc65484576e9ceaf432a 100644 (file)
@@ -483,7 +483,7 @@ gmbus_xfer(struct i2c_adapter *adapter,
        int i = 0, inc, try = 0;
        int ret = 0;
 
-       intel_aux_display_runtime_get(dev_priv);
+       intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS);
        mutex_lock(&dev_priv->gmbus_mutex);
 
        if (bus->force_bit) {
@@ -595,7 +595,9 @@ timeout:
 
 out:
        mutex_unlock(&dev_priv->gmbus_mutex);
-       intel_aux_display_runtime_put(dev_priv);
+
+       intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS);
+
        return ret;
 }
 
index d89c1d0aa1b74793a4328c861c312a91709092e7..7e23d65c9b246ac6672ad432c0f4f4f38bab6254 100644 (file)
@@ -362,6 +362,7 @@ static void hsw_set_power_well(struct drm_i915_private *dev_priv,
        BIT(POWER_DOMAIN_AUX_C) |                       \
        BIT(POWER_DOMAIN_AUDIO) |                       \
        BIT(POWER_DOMAIN_VGA) |                         \
+       BIT(POWER_DOMAIN_GMBUS) |                       \
        BIT(POWER_DOMAIN_INIT))
 #define BXT_DISPLAY_POWERWELL_1_POWER_DOMAINS (                \
        BXT_DISPLAY_POWERWELL_2_POWER_DOMAINS |         \
@@ -1483,6 +1484,7 @@ void intel_display_power_put(struct drm_i915_private *dev_priv,
        BIT(POWER_DOMAIN_AUX_B) |                       \
        BIT(POWER_DOMAIN_AUX_C) |                       \
        BIT(POWER_DOMAIN_AUX_D) |                       \
+       BIT(POWER_DOMAIN_GMBUS) |                       \
        BIT(POWER_DOMAIN_INIT))
 #define HSW_DISPLAY_POWER_DOMAINS (                            \
        (POWER_DOMAIN_MASK & ~HSW_ALWAYS_ON_POWER_DOMAINS) |    \
@@ -1845,6 +1847,8 @@ int intel_power_domains_init(struct drm_i915_private *dev_priv)
        i915.disable_power_well = sanitize_disable_power_well_option(dev_priv,
                                                     i915.disable_power_well);
 
+       BUILD_BUG_ON(POWER_DOMAIN_NUM > 31);
+
        mutex_init(&power_domains->lock);
 
        /*
@@ -2063,36 +2067,6 @@ void intel_power_domains_init_hw(struct drm_i915_private *dev_priv)
        power_domains->initializing = false;
 }
 
-/**
- * intel_aux_display_runtime_get - grab an auxiliary power domain reference
- * @dev_priv: i915 device instance
- *
- * This function grabs a power domain reference for the auxiliary power domain
- * (for access to the GMBUS and DP AUX blocks) and ensures that it and all its
- * parents are powered up. Therefore users should only grab a reference to the
- * innermost power domain they need.
- *
- * Any power domain reference obtained by this function must have a symmetric
- * call to intel_aux_display_runtime_put() to release the reference again.
- */
-void intel_aux_display_runtime_get(struct drm_i915_private *dev_priv)
-{
-       intel_runtime_pm_get(dev_priv);
-}
-
-/**
- * intel_aux_display_runtime_put - release an auxiliary power domain reference
- * @dev_priv: i915 device instance
- *
- * This function drops the auxiliary power domain reference obtained by
- * intel_aux_display_runtime_get() and might power down the corresponding
- * hardware block right away if this is the last reference.
- */
-void intel_aux_display_runtime_put(struct drm_i915_private *dev_priv)
-{
-       intel_runtime_pm_put(dev_priv);
-}
-
 /**
  * intel_runtime_pm_get - grab a runtime pm reference
  * @dev_priv: i915 device instance
index 64f16ea779ef397346c9f75aa946096083225f04..7b990b4e96d234bcdc965572383092e3d9b303a0 100644 (file)
@@ -63,8 +63,7 @@ static void imx_drm_driver_lastclose(struct drm_device *drm)
 #if IS_ENABLED(CONFIG_DRM_IMX_FB_HELPER)
        struct imx_drm_device *imxdrm = drm->dev_private;
 
-       if (imxdrm->fbhelper)
-               drm_fbdev_cma_restore_mode(imxdrm->fbhelper);
+       drm_fbdev_cma_restore_mode(imxdrm->fbhelper);
 #endif
 }
 
@@ -340,7 +339,7 @@ err_kms:
  * imx_drm_add_crtc - add a new crtc
  */
 int imx_drm_add_crtc(struct drm_device *drm, struct drm_crtc *crtc,
-               struct imx_drm_crtc **new_crtc,
+               struct imx_drm_crtc **new_crtc, struct drm_plane *primary_plane,
                const struct imx_drm_crtc_helper_funcs *imx_drm_helper_funcs,
                struct device_node *port)
 {
@@ -379,7 +378,7 @@ int imx_drm_add_crtc(struct drm_device *drm, struct drm_crtc *crtc,
        drm_crtc_helper_add(crtc,
                        imx_drm_crtc->imx_drm_helper_funcs.crtc_helper_funcs);
 
-       drm_crtc_init(drm, crtc,
+       drm_crtc_init_with_planes(drm, crtc, primary_plane, NULL,
                        imx_drm_crtc->imx_drm_helper_funcs.crtc_funcs);
 
        return 0;
index 28e776d8d9d270259f0df5b270897cdb8aec0e24..83284b4d4be1ef86ebefbb3276ef41bf3d5eb6ef 100644 (file)
@@ -9,6 +9,7 @@ struct drm_display_mode;
 struct drm_encoder;
 struct drm_fbdev_cma;
 struct drm_framebuffer;
+struct drm_plane;
 struct imx_drm_crtc;
 struct platform_device;
 
@@ -24,7 +25,7 @@ struct imx_drm_crtc_helper_funcs {
 };
 
 int imx_drm_add_crtc(struct drm_device *drm, struct drm_crtc *crtc,
-               struct imx_drm_crtc **new_crtc,
+               struct imx_drm_crtc **new_crtc, struct drm_plane *primary_plane,
                const struct imx_drm_crtc_helper_funcs *imx_helper_funcs,
                struct device_node *port);
 int imx_drm_remove_crtc(struct imx_drm_crtc *);
index e671ad3694166041ce76c4eaa57539897eba81d1..f9597146dc674a041e89133143286063d07739f2 100644 (file)
@@ -721,6 +721,7 @@ static const struct of_device_id imx_tve_dt_ids[] = {
        { .compatible = "fsl,imx53-tve", },
        { /* sentinel */ }
 };
+MODULE_DEVICE_TABLE(of, imx_tve_dt_ids);
 
 static struct platform_driver imx_tve_driver = {
        .probe          = imx_tve_probe,
index 7bc8301faffffff69194f20ca9d64b8e398f6478..4ab841eebee19dc099758f0018d9cf5030b475c0 100644 (file)
@@ -212,7 +212,8 @@ static void ipu_crtc_handle_pageflip(struct ipu_crtc *ipu_crtc)
 
        spin_lock_irqsave(&drm->event_lock, flags);
        if (ipu_crtc->page_flip_event)
-               drm_send_vblank_event(drm, -1, ipu_crtc->page_flip_event);
+               drm_crtc_send_vblank_event(&ipu_crtc->base,
+                                          ipu_crtc->page_flip_event);
        ipu_crtc->page_flip_event = NULL;
        imx_drm_crtc_vblank_put(ipu_crtc->imx_crtc);
        spin_unlock_irqrestore(&drm->event_lock, flags);
@@ -349,7 +350,6 @@ static int ipu_crtc_init(struct ipu_crtc *ipu_crtc,
        struct ipu_soc *ipu = dev_get_drvdata(ipu_crtc->dev->parent);
        int dp = -EINVAL;
        int ret;
-       int id;
 
        ret = ipu_get_resources(ipu_crtc, pdata);
        if (ret) {
@@ -358,18 +358,23 @@ static int ipu_crtc_init(struct ipu_crtc *ipu_crtc,
                return ret;
        }
 
+       if (pdata->dp >= 0)
+               dp = IPU_DP_FLOW_SYNC_BG;
+       ipu_crtc->plane[0] = ipu_plane_init(drm, ipu, pdata->dma[0], dp, 0,
+                                           DRM_PLANE_TYPE_PRIMARY);
+       if (IS_ERR(ipu_crtc->plane[0])) {
+               ret = PTR_ERR(ipu_crtc->plane[0]);
+               goto err_put_resources;
+       }
+
        ret = imx_drm_add_crtc(drm, &ipu_crtc->base, &ipu_crtc->imx_crtc,
-                       &ipu_crtc_helper_funcs, ipu_crtc->dev->of_node);
+                       &ipu_crtc->plane[0]->base, &ipu_crtc_helper_funcs,
+                       ipu_crtc->dev->of_node);
        if (ret) {
                dev_err(ipu_crtc->dev, "adding crtc failed with %d.\n", ret);
                goto err_put_resources;
        }
 
-       if (pdata->dp >= 0)
-               dp = IPU_DP_FLOW_SYNC_BG;
-       id = imx_drm_crtc_id(ipu_crtc->imx_crtc);
-       ipu_crtc->plane[0] = ipu_plane_init(ipu_crtc->base.dev, ipu,
-                                           pdata->dma[0], dp, BIT(id), true);
        ret = ipu_plane_get_resources(ipu_crtc->plane[0]);
        if (ret) {
                dev_err(ipu_crtc->dev, "getting plane 0 resources failed with %d.\n",
@@ -379,10 +384,10 @@ static int ipu_crtc_init(struct ipu_crtc *ipu_crtc,
 
        /* If this crtc is using the DP, add an overlay plane */
        if (pdata->dp >= 0 && pdata->dma[1] > 0) {
-               ipu_crtc->plane[1] = ipu_plane_init(ipu_crtc->base.dev, ipu,
-                                                   pdata->dma[1],
-                                                   IPU_DP_FLOW_SYNC_FG,
-                                                   BIT(id), false);
+               ipu_crtc->plane[1] = ipu_plane_init(drm, ipu, pdata->dma[1],
+                                               IPU_DP_FLOW_SYNC_FG,
+                                               drm_crtc_mask(&ipu_crtc->base),
+                                               DRM_PLANE_TYPE_OVERLAY);
                if (IS_ERR(ipu_crtc->plane[1]))
                        ipu_crtc->plane[1] = NULL;
        }
@@ -407,28 +412,6 @@ err_put_resources:
        return ret;
 }
 
-static struct device_node *ipu_drm_get_port_by_id(struct device_node *parent,
-                                                 int port_id)
-{
-       struct device_node *port;
-       int id, ret;
-
-       port = of_get_child_by_name(parent, "port");
-       while (port) {
-               ret = of_property_read_u32(port, "reg", &id);
-               if (!ret && id == port_id)
-                       return port;
-
-               do {
-                       port = of_get_next_child(parent, port);
-                       if (!port)
-                               return NULL;
-               } while (of_node_cmp(port->name, "port"));
-       }
-
-       return NULL;
-}
-
 static int ipu_drm_bind(struct device *dev, struct device *master, void *data)
 {
        struct ipu_client_platformdata *pdata = dev->platform_data;
@@ -470,23 +453,11 @@ static const struct component_ops ipu_crtc_ops = {
 static int ipu_drm_probe(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
-       struct ipu_client_platformdata *pdata = dev->platform_data;
        int ret;
 
        if (!dev->platform_data)
                return -EINVAL;
 
-       if (!dev->of_node) {
-               /* Associate crtc device with the corresponding DI port node */
-               dev->of_node = ipu_drm_get_port_by_id(dev->parent->of_node,
-                                                     pdata->di + 2);
-               if (!dev->of_node) {
-                       dev_err(dev, "missing port@%d node in %s\n",
-                               pdata->di + 2, dev->parent->of_node->full_name);
-                       return -ENODEV;
-               }
-       }
-
        ret = dma_set_coherent_mask(dev, DMA_BIT_MASK(32));
        if (ret)
                return ret;
index 575f4c84388f0c64f54d2cdf598064011cfffd6e..e2ff410bab744442e5c6cb2e1bc27cbba58ee7f2 100644 (file)
@@ -381,7 +381,7 @@ static struct drm_plane_funcs ipu_plane_funcs = {
 
 struct ipu_plane *ipu_plane_init(struct drm_device *dev, struct ipu_soc *ipu,
                                 int dma, int dp, unsigned int possible_crtcs,
-                                bool priv)
+                                enum drm_plane_type type)
 {
        struct ipu_plane *ipu_plane;
        int ret;
@@ -399,10 +399,9 @@ struct ipu_plane *ipu_plane_init(struct drm_device *dev, struct ipu_soc *ipu,
        ipu_plane->dma = dma;
        ipu_plane->dp_flow = dp;
 
-       ret = drm_plane_init(dev, &ipu_plane->base, possible_crtcs,
-                            &ipu_plane_funcs, ipu_plane_formats,
-                            ARRAY_SIZE(ipu_plane_formats),
-                            priv);
+       ret = drm_universal_plane_init(dev, &ipu_plane->base, possible_crtcs,
+                                      &ipu_plane_funcs, ipu_plane_formats,
+                                      ARRAY_SIZE(ipu_plane_formats), type);
        if (ret) {
                DRM_ERROR("failed to initialize plane\n");
                kfree(ipu_plane);
index 9b5eff18f5b826b722d97b8e763dbd3017197aee..3a443b413c60caa9734883f7aaa95a69bb7f3e29 100644 (file)
@@ -34,7 +34,7 @@ struct ipu_plane {
 
 struct ipu_plane *ipu_plane_init(struct drm_device *dev, struct ipu_soc *ipu,
                                 int dma, int dp, unsigned int possible_crtcs,
-                                bool priv);
+                                enum drm_plane_type type);
 
 /* Init IDMAC, DMFC, DP */
 int ipu_plane_mode_set(struct ipu_plane *plane, struct drm_crtc *crtc,
index b4deb9cf9d71613fa49562c4619cf8ffec5a33f3..2e9b9f1b5cd2bc8e37f96a66ea2da2d2e61c2ba6 100644 (file)
@@ -54,7 +54,11 @@ static int imx_pd_connector_get_modes(struct drm_connector *connector)
 
        if (imxpd->panel && imxpd->panel->funcs &&
            imxpd->panel->funcs->get_modes) {
+               struct drm_display_info *di = &connector->display_info;
+
                num_modes = imxpd->panel->funcs->get_modes(imxpd->panel);
+               if (!imxpd->bus_format && di->num_bus_formats)
+                       imxpd->bus_format = di->bus_formats[0];
                if (num_modes > 0)
                        return num_modes;
        }
index 8f760002e4018ba05a6fb18a6ecc0d0cf53605fc..913192c94876febb1bf274213c92244b6af6b92d 100644 (file)
@@ -159,7 +159,6 @@ struct nvkm_device_func {
 struct nvkm_device_quirk {
        u8 tv_pin_mask;
        u8 tv_gpio;
-       bool War00C800_0;
 };
 
 struct nvkm_device_chip {
index 28bc202f9753e9fde7777461b5640a77a757a60b..40f845e312723744c52330bdc29b24666281b9f0 100644 (file)
@@ -7,6 +7,7 @@ struct nvkm_instmem {
        const struct nvkm_instmem_func *func;
        struct nvkm_subdev subdev;
 
+       spinlock_t lock;
        struct list_head list;
        u32 reserved;
 
index 8b8332e46f24059f561ca5b1f814ed849d51aa7b..d5e6938cc6bc06e9e2903a81da002289ae9e5688 100644 (file)
@@ -367,6 +367,7 @@ static int nouveau_rom_call(acpi_handle rom_handle, uint8_t *bios,
                return -ENODEV;
        }
        obj = (union acpi_object *)buffer.pointer;
+       len = min(len, (int)obj->buffer.length);
        memcpy(bios+offset, obj->buffer.pointer, len);
        kfree(buffer.pointer);
        return len;
index db6bc676054519b08f3dbe6e45a23782362c9376..64c8d932d5f19de27aa6f66c4e5371f5484cdd7c 100644 (file)
@@ -829,7 +829,6 @@ nouveau_finish_page_flip(struct nouveau_channel *chan,
        struct drm_device *dev = drm->dev;
        struct nouveau_page_flip_state *s;
        unsigned long flags;
-       int crtcid = -1;
 
        spin_lock_irqsave(&dev->event_lock, flags);
 
@@ -841,15 +840,19 @@ nouveau_finish_page_flip(struct nouveau_channel *chan,
 
        s = list_first_entry(&fctx->flip, struct nouveau_page_flip_state, head);
        if (s->event) {
-               /* Vblank timestamps/counts are only correct on >= NV-50 */
-               if (drm->device.info.family >= NV_DEVICE_INFO_V0_TESLA)
-                       crtcid = s->crtc;
+               if (drm->device.info.family < NV_DEVICE_INFO_V0_TESLA) {
+                       drm_arm_vblank_event(dev, s->crtc, s->event);
+               } else {
+                       drm_send_vblank_event(dev, s->crtc, s->event);
 
-               drm_send_vblank_event(dev, crtcid, s->event);
+                       /* Give up ownership of vblank for page-flipped crtc */
+                       drm_vblank_put(dev, s->crtc);
+               }
+       }
+       else {
+               /* Give up ownership of vblank for page-flipped crtc */
+               drm_vblank_put(dev, s->crtc);
        }
-
-       /* Give up ownership of vblank for page-flipped crtc */
-       drm_vblank_put(dev, s->crtc);
 
        list_del(&s->head);
        if (ps)
index 3050042e6c6d54b6fb1a07b48b66d23994e8d0ae..a02813e994ec574d57b695c310f6c60e443584f2 100644 (file)
@@ -39,6 +39,7 @@
 
 #include <nvif/client.h>
 #include <nvif/device.h>
+#include <nvif/ioctl.h>
 
 #include <drmP.h>
 
@@ -65,9 +66,10 @@ struct nouveau_drm_tile {
 };
 
 enum nouveau_drm_object_route {
-       NVDRM_OBJECT_NVIF = 0,
+       NVDRM_OBJECT_NVIF = NVIF_IOCTL_V0_OWNER_NVIF,
        NVDRM_OBJECT_USIF,
        NVDRM_OBJECT_ABI16,
+       NVDRM_OBJECT_ANY = NVIF_IOCTL_V0_OWNER_ANY,
 };
 
 enum nouveau_drm_notify_route {
index 89dc4ce63490e4d67d554b00ef44d18955479c7f..6ae1b3494bcd16a8492d65cffa95554d4125bfbc 100644 (file)
@@ -313,7 +313,10 @@ usif_ioctl(struct drm_file *filp, void __user *user, u32 argc)
        if (nvif_unpack(argv->v0, 0, 0, true)) {
                /* block access to objects not created via this interface */
                owner = argv->v0.owner;
-               argv->v0.owner = NVDRM_OBJECT_USIF;
+               if (argv->v0.object == 0ULL)
+                       argv->v0.owner = NVDRM_OBJECT_ANY; /* except client */
+               else
+                       argv->v0.owner = NVDRM_OBJECT_USIF;
        } else
                goto done;
 
index e3c783d0e2ab486abc37e09e5430b5013155392a..62ad0300cfa5ab0af8610773ae7d5c4b49e310bb 100644 (file)
@@ -258,12 +258,6 @@ nvkm_device_pci_10de_0df4[] = {
        {}
 };
 
-static const struct nvkm_device_pci_vendor
-nvkm_device_pci_10de_0fcd[] = {
-       { 0x17aa, 0x3801, NULL, { .War00C800_0 = true } }, /* Lenovo Y510P */
-       {}
-};
-
 static const struct nvkm_device_pci_vendor
 nvkm_device_pci_10de_0fd2[] = {
        { 0x1028, 0x0595, "GeForce GT 640M LE" },
@@ -684,7 +678,6 @@ nvkm_device_pci_10de_1189[] = {
 static const struct nvkm_device_pci_vendor
 nvkm_device_pci_10de_1199[] = {
        { 0x1458, 0xd001, "GeForce GTX 760" },
-       { 0x1462, 0x1106, "GeForce GTX 780M", { .War00C800_0 = true } }, /* Medion Erazer X7827 */
        {}
 };
 
@@ -694,14 +687,6 @@ nvkm_device_pci_10de_11e3[] = {
        {}
 };
 
-static const struct nvkm_device_pci_vendor
-nvkm_device_pci_10de_11fc[] = {
-       { 0x1179, 0x0001, NULL, { .War00C800_0 = true } }, /* Toshiba Tecra W50 */
-       { 0x17aa, 0x2211, NULL, { .War00C800_0 = true } }, /* Lenovo W541 */
-       { 0x17aa, 0x221e, NULL, { .War00C800_0 = true } }, /* Lenovo W541 */
-       {}
-};
-
 static const struct nvkm_device_pci_vendor
 nvkm_device_pci_10de_1247[] = {
        { 0x1043, 0x212a, "GeForce GT 635M" },
@@ -1356,7 +1341,7 @@ nvkm_device_pci_10de[] = {
        { 0x0fc6, "GeForce GTX 650" },
        { 0x0fc8, "GeForce GT 740" },
        { 0x0fc9, "GeForce GT 730" },
-       { 0x0fcd, "GeForce GT 755M", nvkm_device_pci_10de_0fcd },
+       { 0x0fcd, "GeForce GT 755M" },
        { 0x0fce, "GeForce GT 640M LE" },
        { 0x0fd1, "GeForce GT 650M" },
        { 0x0fd2, "GeForce GT 640M", nvkm_device_pci_10de_0fd2 },
@@ -1490,7 +1475,7 @@ nvkm_device_pci_10de[] = {
        { 0x11e2, "GeForce GTX 765M" },
        { 0x11e3, "GeForce GTX 760M", nvkm_device_pci_10de_11e3 },
        { 0x11fa, "Quadro K4000" },
-       { 0x11fc, "Quadro K2100M", nvkm_device_pci_10de_11fc },
+       { 0x11fc, "Quadro K2100M" },
        { 0x1200, "GeForce GTX 560 Ti" },
        { 0x1201, "GeForce GTX 560" },
        { 0x1203, "GeForce GTX 460 SE v2" },
index b5b875928abad24ad1350a9f342526680660a2b9..74de7a96c22afea939059db4a20ebc5adef162e1 100644 (file)
@@ -207,6 +207,8 @@ gf117_grctx_generate_attrib(struct gf100_grctx *info)
                        const u32 b =  beta * gr->ppc_tpc_nr[gpc][ppc];
                        const u32 t = timeslice_mode;
                        const u32 o = PPC_UNIT(gpc, ppc, 0);
+                       if (!(gr->ppc_mask[gpc] & (1 << ppc)))
+                               continue;
                        mmio_skip(info, o + 0xc0, (t << 28) | (b << 16) | ++bo);
                        mmio_wr32(info, o + 0xc0, (t << 28) | (b << 16) | --bo);
                        bo += grctx->attrib_nr_max * gr->ppc_tpc_nr[gpc][ppc];
index 194afe910d212885d01771a0355e4e8b009ab871..7dacb3cc0668afbce3841fecb99a189b15f780d6 100644 (file)
@@ -52,10 +52,12 @@ mmio_list_base:
 #endif
 
 #ifdef INCLUDE_CODE
+#define gpc_addr(reg,addr)                                                    /*
+*/     imm32(reg,addr)                                                       /*
+*/     or reg NV_PGRAPH_GPCX_GPCCS_MMIO_CTRL_BASE_ENABLE
 #define gpc_wr32(addr,reg)                                                    /*
+*/     gpc_addr($r14,addr)                                                   /*
 */     mov b32 $r15 reg                                                      /*
-*/     imm32($r14, addr)                                                     /*
-*/     or $r14 NV_PGRAPH_GPCX_GPCCS_MMIO_CTRL_BASE_ENABLE                    /*
 */     call(nv_wr32)
 
 // reports an exception to the host
@@ -161,7 +163,7 @@ init:
 
 #if NV_PGRAPH_GPCX_UNK__SIZE > 0
        // figure out which, and how many, UNKs are actually present
-       imm32($r14, 0x500c30)
+       gpc_addr($r14, 0x500c30)
        clear b32 $r2
        clear b32 $r3
        clear b32 $r4
index 64d07df4b8b14e3dd805948a783c41751adb8964..bb820ff28621f4e8c7dbb22cb6ac7f020dfafdfe 100644 (file)
@@ -314,7 +314,7 @@ uint32_t gf117_grgpc_code[] = {
        0x03f01200,
        0x0002d000,
        0x17f104bd,
-       0x10fe0542,
+       0x10fe0545,
        0x0007f100,
        0x0003f007,
        0xbd0000d0,
@@ -338,184 +338,184 @@ uint32_t gf117_grgpc_code[] = {
        0x02d00103,
        0xf104bd00,
        0xf00c30e7,
-       0x24bd50e3,
-       0x44bd34bd,
-/* 0x0430: init_unk_loop */
-       0xb06821f4,
-       0x0bf400f6,
-       0x01f7f00f,
-       0xfd04f2bb,
-       0x30b6054f,
-/* 0x0445: init_unk_next */
-       0x0120b601,
-       0xb004e0b6,
-       0x1bf40126,
-/* 0x0451: init_unk_done */
-       0x070380e2,
-       0xf1080480,
-       0xf0010027,
-       0x22cf0223,
-       0x9534bd00,
-       0x07f10825,
-       0x03f0c000,
-       0x0005d001,
-       0x07f104bd,
-       0x03f0c100,
-       0x0005d001,
-       0x0e9804bd,
-       0x010f9800,
-       0x015021f5,
-       0xbb002fbb,
-       0x0e98003f,
-       0x020f9801,
-       0x015021f5,
-       0xfd050e98,
-       0x2ebb00ef,
-       0x003ebb00,
-       0x98020e98,
-       0x21f5030f,
-       0x0e980150,
-       0x00effd07,
-       0xbb002ebb,
-       0x35b6003e,
-       0x0007f102,
-       0x0103f0d3,
-       0xbd0003d0,
-       0x0825b604,
-       0xb60635b6,
-       0x30b60120,
-       0x0824b601,
-       0xb90834b6,
-       0x21f5022f,
-       0x2fbb02d3,
-       0x003fbb00,
-       0x010007f1,
-       0xd00203f0,
+       0xe5f050e3,
+       0xbd24bd01,
+/* 0x0433: init_unk_loop */
+       0xf444bd34,
+       0xf6b06821,
+       0x0f0bf400,
+       0xbb01f7f0,
+       0x4ffd04f2,
+       0x0130b605,
+/* 0x0448: init_unk_next */
+       0xb60120b6,
+       0x26b004e0,
+       0xe21bf401,
+/* 0x0454: init_unk_done */
+       0x80070380,
+       0x27f10804,
+       0x23f00100,
+       0x0022cf02,
+       0x259534bd,
+       0x0007f108,
+       0x0103f0c0,
+       0xbd0005d0,
+       0x0007f104,
+       0x0103f0c1,
+       0xbd0005d0,
+       0x000e9804,
+       0xf5010f98,
+       0xbb015021,
+       0x3fbb002f,
+       0x010e9800,
+       0xf5020f98,
+       0x98015021,
+       0xeffd050e,
+       0x002ebb00,
+       0x98003ebb,
+       0x0f98020e,
+       0x5021f503,
+       0x070e9801,
+       0xbb00effd,
+       0x3ebb002e,
+       0x0235b600,
+       0xd30007f1,
+       0xd00103f0,
        0x04bd0003,
-       0x29f024bd,
-       0x0007f11f,
-       0x0203f008,
-       0xbd0002d0,
-/* 0x0505: main */
-       0x0031f404,
-       0xf00028f4,
-       0x21f424d7,
-       0xf401f439,
-       0xf404e4b0,
-       0x81fe1e18,
-       0x0627f001,
-       0x12fd20bd,
-       0x01e4b604,
-       0xfe051efd,
-       0x21f50018,
-       0x0ef405fa,
-/* 0x0535: main_not_ctx_xfer */
-       0x10ef94d3,
-       0xf501f5f0,
-       0xf4037e21,
-/* 0x0542: ih */
-       0x80f9c60e,
-       0xf90188fe,
-       0xf990f980,
-       0xf9b0f9a0,
-       0xf9e0f9d0,
-       0xf104bdf0,
-       0xf00200a7,
-       0xaacf00a3,
-       0x04abc400,
-       0xf02c0bf4,
-       0xe7f124d7,
-       0xe3f01a00,
-       0x00eecf00,
-       0x1900f7f1,
-       0xcf00f3f0,
-       0x21f400ff,
-       0x01e7f004,
-       0x1d0007f1,
-       0xd00003f0,
-       0x04bd000e,
-/* 0x0590: ih_no_fifo */
-       0x010007f1,
-       0xd00003f0,
-       0x04bd000a,
-       0xe0fcf0fc,
-       0xb0fcd0fc,
-       0x90fca0fc,
-       0x88fe80fc,
-       0xf480fc00,
-       0x01f80032,
-/* 0x05b4: hub_barrier_done */
-       0x9801f7f0,
-       0xfebb040e,
-       0x02ffb904,
-       0x9418e7f1,
-       0xf440e3f0,
-       0x00f89d21,
-/* 0x05cc: ctx_redswitch */
-       0xf120f7f0,
+       0xb60825b6,
+       0x20b60635,
+       0x0130b601,
+       0xb60824b6,
+       0x2fb90834,
+       0xd321f502,
+       0x002fbb02,
+       0xf1003fbb,
+       0xf0010007,
+       0x03d00203,
+       0xbd04bd00,
+       0x1f29f024,
+       0x080007f1,
+       0xd00203f0,
+       0x04bd0002,
+/* 0x0508: main */
+       0xf40031f4,
+       0xd7f00028,
+       0x3921f424,
+       0xb0f401f4,
+       0x18f404e4,
+       0x0181fe1e,
+       0xbd0627f0,
+       0x0412fd20,
+       0xfd01e4b6,
+       0x18fe051e,
+       0xfd21f500,
+       0xd30ef405,
+/* 0x0538: main_not_ctx_xfer */
+       0xf010ef94,
+       0x21f501f5,
+       0x0ef4037e,
+/* 0x0545: ih */
+       0xfe80f9c6,
+       0x80f90188,
+       0xa0f990f9,
+       0xd0f9b0f9,
+       0xf0f9e0f9,
+       0xa7f104bd,
+       0xa3f00200,
+       0x00aacf00,
+       0xf404abc4,
+       0xd7f02c0b,
+       0x00e7f124,
+       0x00e3f01a,
+       0xf100eecf,
+       0xf01900f7,
+       0xffcf00f3,
+       0x0421f400,
+       0xf101e7f0,
+       0xf01d0007,
+       0x0ed00003,
+/* 0x0593: ih_no_fifo */
+       0xf104bd00,
+       0xf0010007,
+       0x0ad00003,
+       0xfc04bd00,
+       0xfce0fcf0,
+       0xfcb0fcd0,
+       0xfc90fca0,
+       0x0088fe80,
+       0x32f480fc,
+/* 0x05b7: hub_barrier_done */
+       0xf001f800,
+       0x0e9801f7,
+       0x04febb04,
+       0xf102ffb9,
+       0xf09418e7,
+       0x21f440e3,
+/* 0x05cf: ctx_redswitch */
+       0xf000f89d,
+       0x07f120f7,
+       0x03f08500,
+       0x000fd001,
+       0xe7f004bd,
+/* 0x05e1: ctx_redswitch_delay */
+       0x01e2b608,
+       0xf1fd1bf4,
+       0xf10800f5,
+       0xf10200f5,
        0xf0850007,
        0x0fd00103,
-       0xf004bd00,
-/* 0x05de: ctx_redswitch_delay */
-       0xe2b608e7,
-       0xfd1bf401,
-       0x0800f5f1,
-       0x0200f5f1,
-       0x850007f1,
-       0xd00103f0,
-       0x04bd000f,
-/* 0x05fa: ctx_xfer */
-       0x07f100f8,
-       0x03f08100,
-       0x000fd002,
-       0x11f404bd,
-       0xcc21f507,
-/* 0x060d: ctx_xfer_not_load */
-       0x6a21f505,
-       0xf124bd02,
-       0xf047fc07,
-       0x02d00203,
-       0xf004bd00,
-       0x20b6012c,
-       0xfc07f103,
-       0x0203f04a,
-       0xbd0002d0,
-       0x01acf004,
-       0xf102a5f0,
-       0xf00000b7,
-       0x0c9850b3,
-       0x0fc4b604,
-       0x9800bcbb,
-       0x0d98000c,
-       0x00e7f001,
-       0x016f21f5,
-       0xf101acf0,
-       0xf04000b7,
-       0x0c9850b3,
-       0x0fc4b604,
-       0x9800bcbb,
-       0x0d98010c,
-       0x060f9802,
-       0x0800e7f1,
-       0x016f21f5,
+       0xf804bd00,
+/* 0x05fd: ctx_xfer */
+       0x0007f100,
+       0x0203f081,
+       0xbd000fd0,
+       0x0711f404,
+       0x05cf21f5,
+/* 0x0610: ctx_xfer_not_load */
+       0x026a21f5,
+       0x07f124bd,
+       0x03f047fc,
+       0x0002d002,
+       0x2cf004bd,
+       0x0320b601,
+       0x4afc07f1,
+       0xd00203f0,
+       0x04bd0002,
        0xf001acf0,
-       0xb7f104a5,
-       0xb3f03000,
+       0xb7f102a5,
+       0xb3f00000,
        0x040c9850,
        0xbb0fc4b6,
        0x0c9800bc,
-       0x030d9802,
-       0xf1080f98,
-       0xf50200e7,
-       0xf5016f21,
-       0xf4025e21,
-       0x12f40601,
-/* 0x06a9: ctx_xfer_post */
-       0x7f21f507,
-/* 0x06ad: ctx_xfer_done */
-       0xb421f502,
-       0x0000f805,
-       0x00000000,
+       0x010d9800,
+       0xf500e7f0,
+       0xf0016f21,
+       0xb7f101ac,
+       0xb3f04000,
+       0x040c9850,
+       0xbb0fc4b6,
+       0x0c9800bc,
+       0x020d9801,
+       0xf1060f98,
+       0xf50800e7,
+       0xf0016f21,
+       0xa5f001ac,
+       0x00b7f104,
+       0x50b3f030,
+       0xb6040c98,
+       0xbcbb0fc4,
+       0x020c9800,
+       0x98030d98,
+       0xe7f1080f,
+       0x21f50200,
+       0x21f5016f,
+       0x01f4025e,
+       0x0712f406,
+/* 0x06ac: ctx_xfer_post */
+       0x027f21f5,
+/* 0x06b0: ctx_xfer_done */
+       0x05b721f5,
+       0x000000f8,
        0x00000000,
        0x00000000,
        0x00000000,
index 2f596433c2220048fd55a7ee252f74619f7e041e..911976d209400fb565d84761875ba8ed0db94d3b 100644 (file)
@@ -314,7 +314,7 @@ uint32_t gk104_grgpc_code[] = {
        0x03f01200,
        0x0002d000,
        0x17f104bd,
-       0x10fe0542,
+       0x10fe0545,
        0x0007f100,
        0x0003f007,
        0xbd0000d0,
@@ -338,184 +338,184 @@ uint32_t gk104_grgpc_code[] = {
        0x02d00103,
        0xf104bd00,
        0xf00c30e7,
-       0x24bd50e3,
-       0x44bd34bd,
-/* 0x0430: init_unk_loop */
-       0xb06821f4,
-       0x0bf400f6,
-       0x01f7f00f,
-       0xfd04f2bb,
-       0x30b6054f,
-/* 0x0445: init_unk_next */
-       0x0120b601,
-       0xb004e0b6,
-       0x1bf40126,
-/* 0x0451: init_unk_done */
-       0x070380e2,
-       0xf1080480,
-       0xf0010027,
-       0x22cf0223,
-       0x9534bd00,
-       0x07f10825,
-       0x03f0c000,
-       0x0005d001,
-       0x07f104bd,
-       0x03f0c100,
-       0x0005d001,
-       0x0e9804bd,
-       0x010f9800,
-       0x015021f5,
-       0xbb002fbb,
-       0x0e98003f,
-       0x020f9801,
-       0x015021f5,
-       0xfd050e98,
-       0x2ebb00ef,
-       0x003ebb00,
-       0x98020e98,
-       0x21f5030f,
-       0x0e980150,
-       0x00effd07,
-       0xbb002ebb,
-       0x35b6003e,
-       0x0007f102,
-       0x0103f0d3,
-       0xbd0003d0,
-       0x0825b604,
-       0xb60635b6,
-       0x30b60120,
-       0x0824b601,
-       0xb90834b6,
-       0x21f5022f,
-       0x2fbb02d3,
-       0x003fbb00,
-       0x010007f1,
-       0xd00203f0,
+       0xe5f050e3,
+       0xbd24bd01,
+/* 0x0433: init_unk_loop */
+       0xf444bd34,
+       0xf6b06821,
+       0x0f0bf400,
+       0xbb01f7f0,
+       0x4ffd04f2,
+       0x0130b605,
+/* 0x0448: init_unk_next */
+       0xb60120b6,
+       0x26b004e0,
+       0xe21bf401,
+/* 0x0454: init_unk_done */
+       0x80070380,
+       0x27f10804,
+       0x23f00100,
+       0x0022cf02,
+       0x259534bd,
+       0x0007f108,
+       0x0103f0c0,
+       0xbd0005d0,
+       0x0007f104,
+       0x0103f0c1,
+       0xbd0005d0,
+       0x000e9804,
+       0xf5010f98,
+       0xbb015021,
+       0x3fbb002f,
+       0x010e9800,
+       0xf5020f98,
+       0x98015021,
+       0xeffd050e,
+       0x002ebb00,
+       0x98003ebb,
+       0x0f98020e,
+       0x5021f503,
+       0x070e9801,
+       0xbb00effd,
+       0x3ebb002e,
+       0x0235b600,
+       0xd30007f1,
+       0xd00103f0,
        0x04bd0003,
-       0x29f024bd,
-       0x0007f11f,
-       0x0203f008,
-       0xbd0002d0,
-/* 0x0505: main */
-       0x0031f404,
-       0xf00028f4,
-       0x21f424d7,
-       0xf401f439,
-       0xf404e4b0,
-       0x81fe1e18,
-       0x0627f001,
-       0x12fd20bd,
-       0x01e4b604,
-       0xfe051efd,
-       0x21f50018,
-       0x0ef405fa,
-/* 0x0535: main_not_ctx_xfer */
-       0x10ef94d3,
-       0xf501f5f0,
-       0xf4037e21,
-/* 0x0542: ih */
-       0x80f9c60e,
-       0xf90188fe,
-       0xf990f980,
-       0xf9b0f9a0,
-       0xf9e0f9d0,
-       0xf104bdf0,
-       0xf00200a7,
-       0xaacf00a3,
-       0x04abc400,
-       0xf02c0bf4,
-       0xe7f124d7,
-       0xe3f01a00,
-       0x00eecf00,
-       0x1900f7f1,
-       0xcf00f3f0,
-       0x21f400ff,
-       0x01e7f004,
-       0x1d0007f1,
-       0xd00003f0,
-       0x04bd000e,
-/* 0x0590: ih_no_fifo */
-       0x010007f1,
-       0xd00003f0,
-       0x04bd000a,
-       0xe0fcf0fc,
-       0xb0fcd0fc,
-       0x90fca0fc,
-       0x88fe80fc,
-       0xf480fc00,
-       0x01f80032,
-/* 0x05b4: hub_barrier_done */
-       0x9801f7f0,
-       0xfebb040e,
-       0x02ffb904,
-       0x9418e7f1,
-       0xf440e3f0,
-       0x00f89d21,
-/* 0x05cc: ctx_redswitch */
-       0xf120f7f0,
+       0xb60825b6,
+       0x20b60635,
+       0x0130b601,
+       0xb60824b6,
+       0x2fb90834,
+       0xd321f502,
+       0x002fbb02,
+       0xf1003fbb,
+       0xf0010007,
+       0x03d00203,
+       0xbd04bd00,
+       0x1f29f024,
+       0x080007f1,
+       0xd00203f0,
+       0x04bd0002,
+/* 0x0508: main */
+       0xf40031f4,
+       0xd7f00028,
+       0x3921f424,
+       0xb0f401f4,
+       0x18f404e4,
+       0x0181fe1e,
+       0xbd0627f0,
+       0x0412fd20,
+       0xfd01e4b6,
+       0x18fe051e,
+       0xfd21f500,
+       0xd30ef405,
+/* 0x0538: main_not_ctx_xfer */
+       0xf010ef94,
+       0x21f501f5,
+       0x0ef4037e,
+/* 0x0545: ih */
+       0xfe80f9c6,
+       0x80f90188,
+       0xa0f990f9,
+       0xd0f9b0f9,
+       0xf0f9e0f9,
+       0xa7f104bd,
+       0xa3f00200,
+       0x00aacf00,
+       0xf404abc4,
+       0xd7f02c0b,
+       0x00e7f124,
+       0x00e3f01a,
+       0xf100eecf,
+       0xf01900f7,
+       0xffcf00f3,
+       0x0421f400,
+       0xf101e7f0,
+       0xf01d0007,
+       0x0ed00003,
+/* 0x0593: ih_no_fifo */
+       0xf104bd00,
+       0xf0010007,
+       0x0ad00003,
+       0xfc04bd00,
+       0xfce0fcf0,
+       0xfcb0fcd0,
+       0xfc90fca0,
+       0x0088fe80,
+       0x32f480fc,
+/* 0x05b7: hub_barrier_done */
+       0xf001f800,
+       0x0e9801f7,
+       0x04febb04,
+       0xf102ffb9,
+       0xf09418e7,
+       0x21f440e3,
+/* 0x05cf: ctx_redswitch */
+       0xf000f89d,
+       0x07f120f7,
+       0x03f08500,
+       0x000fd001,
+       0xe7f004bd,
+/* 0x05e1: ctx_redswitch_delay */
+       0x01e2b608,
+       0xf1fd1bf4,
+       0xf10800f5,
+       0xf10200f5,
        0xf0850007,
        0x0fd00103,
-       0xf004bd00,
-/* 0x05de: ctx_redswitch_delay */
-       0xe2b608e7,
-       0xfd1bf401,
-       0x0800f5f1,
-       0x0200f5f1,
-       0x850007f1,
-       0xd00103f0,
-       0x04bd000f,
-/* 0x05fa: ctx_xfer */
-       0x07f100f8,
-       0x03f08100,
-       0x000fd002,
-       0x11f404bd,
-       0xcc21f507,
-/* 0x060d: ctx_xfer_not_load */
-       0x6a21f505,
-       0xf124bd02,
-       0xf047fc07,
-       0x02d00203,
-       0xf004bd00,
-       0x20b6012c,
-       0xfc07f103,
-       0x0203f04a,
-       0xbd0002d0,
-       0x01acf004,
-       0xf102a5f0,
-       0xf00000b7,
-       0x0c9850b3,
-       0x0fc4b604,
-       0x9800bcbb,
-       0x0d98000c,
-       0x00e7f001,
-       0x016f21f5,
-       0xf101acf0,
-       0xf04000b7,
-       0x0c9850b3,
-       0x0fc4b604,
-       0x9800bcbb,
-       0x0d98010c,
-       0x060f9802,
-       0x0800e7f1,
-       0x016f21f5,
+       0xf804bd00,
+/* 0x05fd: ctx_xfer */
+       0x0007f100,
+       0x0203f081,
+       0xbd000fd0,
+       0x0711f404,
+       0x05cf21f5,
+/* 0x0610: ctx_xfer_not_load */
+       0x026a21f5,
+       0x07f124bd,
+       0x03f047fc,
+       0x0002d002,
+       0x2cf004bd,
+       0x0320b601,
+       0x4afc07f1,
+       0xd00203f0,
+       0x04bd0002,
        0xf001acf0,
-       0xb7f104a5,
-       0xb3f03000,
+       0xb7f102a5,
+       0xb3f00000,
        0x040c9850,
        0xbb0fc4b6,
        0x0c9800bc,
-       0x030d9802,
-       0xf1080f98,
-       0xf50200e7,
-       0xf5016f21,
-       0xf4025e21,
-       0x12f40601,
-/* 0x06a9: ctx_xfer_post */
-       0x7f21f507,
-/* 0x06ad: ctx_xfer_done */
-       0xb421f502,
-       0x0000f805,
-       0x00000000,
+       0x010d9800,
+       0xf500e7f0,
+       0xf0016f21,
+       0xb7f101ac,
+       0xb3f04000,
+       0x040c9850,
+       0xbb0fc4b6,
+       0x0c9800bc,
+       0x020d9801,
+       0xf1060f98,
+       0xf50800e7,
+       0xf0016f21,
+       0xa5f001ac,
+       0x00b7f104,
+       0x50b3f030,
+       0xb6040c98,
+       0xbcbb0fc4,
+       0x020c9800,
+       0x98030d98,
+       0xe7f1080f,
+       0x21f50200,
+       0x21f5016f,
+       0x01f4025e,
+       0x0712f406,
+/* 0x06ac: ctx_xfer_post */
+       0x027f21f5,
+/* 0x06b0: ctx_xfer_done */
+       0x05b721f5,
+       0x000000f8,
        0x00000000,
        0x00000000,
        0x00000000,
index ee8e54db8fc9ed83bd5da4c176de4e4fbe6bed73..1c6e11b05df2e910685b76ebfbe37b046718d0bb 100644 (file)
@@ -314,7 +314,7 @@ uint32_t gk110_grgpc_code[] = {
        0x03f01200,
        0x0002d000,
        0x17f104bd,
-       0x10fe0542,
+       0x10fe0545,
        0x0007f100,
        0x0003f007,
        0xbd0000d0,
@@ -338,184 +338,184 @@ uint32_t gk110_grgpc_code[] = {
        0x02d00103,
        0xf104bd00,
        0xf00c30e7,
-       0x24bd50e3,
-       0x44bd34bd,
-/* 0x0430: init_unk_loop */
-       0xb06821f4,
-       0x0bf400f6,
-       0x01f7f00f,
-       0xfd04f2bb,
-       0x30b6054f,
-/* 0x0445: init_unk_next */
-       0x0120b601,
-       0xb004e0b6,
-       0x1bf40226,
-/* 0x0451: init_unk_done */
-       0x070380e2,
-       0xf1080480,
-       0xf0010027,
-       0x22cf0223,
-       0x9534bd00,
-       0x07f10825,
-       0x03f0c000,
-       0x0005d001,
-       0x07f104bd,
-       0x03f0c100,
-       0x0005d001,
-       0x0e9804bd,
-       0x010f9800,
-       0x015021f5,
-       0xbb002fbb,
-       0x0e98003f,
-       0x020f9801,
-       0x015021f5,
-       0xfd050e98,
-       0x2ebb00ef,
-       0x003ebb00,
-       0x98020e98,
-       0x21f5030f,
-       0x0e980150,
-       0x00effd07,
-       0xbb002ebb,
-       0x35b6003e,
-       0x0007f102,
-       0x0103f0d3,
-       0xbd0003d0,
-       0x0825b604,
-       0xb60635b6,
-       0x30b60120,
-       0x0824b601,
-       0xb90834b6,
-       0x21f5022f,
-       0x2fbb02d3,
-       0x003fbb00,
-       0x010007f1,
-       0xd00203f0,
+       0xe5f050e3,
+       0xbd24bd01,
+/* 0x0433: init_unk_loop */
+       0xf444bd34,
+       0xf6b06821,
+       0x0f0bf400,
+       0xbb01f7f0,
+       0x4ffd04f2,
+       0x0130b605,
+/* 0x0448: init_unk_next */
+       0xb60120b6,
+       0x26b004e0,
+       0xe21bf402,
+/* 0x0454: init_unk_done */
+       0x80070380,
+       0x27f10804,
+       0x23f00100,
+       0x0022cf02,
+       0x259534bd,
+       0x0007f108,
+       0x0103f0c0,
+       0xbd0005d0,
+       0x0007f104,
+       0x0103f0c1,
+       0xbd0005d0,
+       0x000e9804,
+       0xf5010f98,
+       0xbb015021,
+       0x3fbb002f,
+       0x010e9800,
+       0xf5020f98,
+       0x98015021,
+       0xeffd050e,
+       0x002ebb00,
+       0x98003ebb,
+       0x0f98020e,
+       0x5021f503,
+       0x070e9801,
+       0xbb00effd,
+       0x3ebb002e,
+       0x0235b600,
+       0xd30007f1,
+       0xd00103f0,
        0x04bd0003,
-       0x29f024bd,
-       0x0007f11f,
-       0x0203f030,
-       0xbd0002d0,
-/* 0x0505: main */
-       0x0031f404,
-       0xf00028f4,
-       0x21f424d7,
-       0xf401f439,
-       0xf404e4b0,
-       0x81fe1e18,
-       0x0627f001,
-       0x12fd20bd,
-       0x01e4b604,
-       0xfe051efd,
-       0x21f50018,
-       0x0ef405fa,
-/* 0x0535: main_not_ctx_xfer */
-       0x10ef94d3,
-       0xf501f5f0,
-       0xf4037e21,
-/* 0x0542: ih */
-       0x80f9c60e,
-       0xf90188fe,
-       0xf990f980,
-       0xf9b0f9a0,
-       0xf9e0f9d0,
-       0xf104bdf0,
-       0xf00200a7,
-       0xaacf00a3,
-       0x04abc400,
-       0xf02c0bf4,
-       0xe7f124d7,
-       0xe3f01a00,
-       0x00eecf00,
-       0x1900f7f1,
-       0xcf00f3f0,
-       0x21f400ff,
-       0x01e7f004,
-       0x1d0007f1,
-       0xd00003f0,
-       0x04bd000e,
-/* 0x0590: ih_no_fifo */
-       0x010007f1,
-       0xd00003f0,
-       0x04bd000a,
-       0xe0fcf0fc,
-       0xb0fcd0fc,
-       0x90fca0fc,
-       0x88fe80fc,
-       0xf480fc00,
-       0x01f80032,
-/* 0x05b4: hub_barrier_done */
-       0x9801f7f0,
-       0xfebb040e,
-       0x02ffb904,
-       0x9418e7f1,
-       0xf440e3f0,
-       0x00f89d21,
-/* 0x05cc: ctx_redswitch */
-       0xf120f7f0,
+       0xb60825b6,
+       0x20b60635,
+       0x0130b601,
+       0xb60824b6,
+       0x2fb90834,
+       0xd321f502,
+       0x002fbb02,
+       0xf1003fbb,
+       0xf0010007,
+       0x03d00203,
+       0xbd04bd00,
+       0x1f29f024,
+       0x300007f1,
+       0xd00203f0,
+       0x04bd0002,
+/* 0x0508: main */
+       0xf40031f4,
+       0xd7f00028,
+       0x3921f424,
+       0xb0f401f4,
+       0x18f404e4,
+       0x0181fe1e,
+       0xbd0627f0,
+       0x0412fd20,
+       0xfd01e4b6,
+       0x18fe051e,
+       0xfd21f500,
+       0xd30ef405,
+/* 0x0538: main_not_ctx_xfer */
+       0xf010ef94,
+       0x21f501f5,
+       0x0ef4037e,
+/* 0x0545: ih */
+       0xfe80f9c6,
+       0x80f90188,
+       0xa0f990f9,
+       0xd0f9b0f9,
+       0xf0f9e0f9,
+       0xa7f104bd,
+       0xa3f00200,
+       0x00aacf00,
+       0xf404abc4,
+       0xd7f02c0b,
+       0x00e7f124,
+       0x00e3f01a,
+       0xf100eecf,
+       0xf01900f7,
+       0xffcf00f3,
+       0x0421f400,
+       0xf101e7f0,
+       0xf01d0007,
+       0x0ed00003,
+/* 0x0593: ih_no_fifo */
+       0xf104bd00,
+       0xf0010007,
+       0x0ad00003,
+       0xfc04bd00,
+       0xfce0fcf0,
+       0xfcb0fcd0,
+       0xfc90fca0,
+       0x0088fe80,
+       0x32f480fc,
+/* 0x05b7: hub_barrier_done */
+       0xf001f800,
+       0x0e9801f7,
+       0x04febb04,
+       0xf102ffb9,
+       0xf09418e7,
+       0x21f440e3,
+/* 0x05cf: ctx_redswitch */
+       0xf000f89d,
+       0x07f120f7,
+       0x03f08500,
+       0x000fd001,
+       0xe7f004bd,
+/* 0x05e1: ctx_redswitch_delay */
+       0x01e2b608,
+       0xf1fd1bf4,
+       0xf10800f5,
+       0xf10200f5,
        0xf0850007,
        0x0fd00103,
-       0xf004bd00,
-/* 0x05de: ctx_redswitch_delay */
-       0xe2b608e7,
-       0xfd1bf401,
-       0x0800f5f1,
-       0x0200f5f1,
-       0x850007f1,
-       0xd00103f0,
-       0x04bd000f,
-/* 0x05fa: ctx_xfer */
-       0x07f100f8,
-       0x03f08100,
-       0x000fd002,
-       0x11f404bd,
-       0xcc21f507,
-/* 0x060d: ctx_xfer_not_load */
-       0x6a21f505,
-       0xf124bd02,
-       0xf047fc07,
-       0x02d00203,
-       0xf004bd00,
-       0x20b6012c,
-       0xfc07f103,
-       0x0203f04a,
-       0xbd0002d0,
-       0x01acf004,
-       0xf102a5f0,
-       0xf00000b7,
-       0x0c9850b3,
-       0x0fc4b604,
-       0x9800bcbb,
-       0x0d98000c,
-       0x00e7f001,
-       0x016f21f5,
-       0xf101acf0,
-       0xf04000b7,
-       0x0c9850b3,
-       0x0fc4b604,
-       0x9800bcbb,
-       0x0d98010c,
-       0x060f9802,
-       0x0800e7f1,
-       0x016f21f5,
+       0xf804bd00,
+/* 0x05fd: ctx_xfer */
+       0x0007f100,
+       0x0203f081,
+       0xbd000fd0,
+       0x0711f404,
+       0x05cf21f5,
+/* 0x0610: ctx_xfer_not_load */
+       0x026a21f5,
+       0x07f124bd,
+       0x03f047fc,
+       0x0002d002,
+       0x2cf004bd,
+       0x0320b601,
+       0x4afc07f1,
+       0xd00203f0,
+       0x04bd0002,
        0xf001acf0,
-       0xb7f104a5,
-       0xb3f03000,
+       0xb7f102a5,
+       0xb3f00000,
        0x040c9850,
        0xbb0fc4b6,
        0x0c9800bc,
-       0x030d9802,
-       0xf1080f98,
-       0xf50200e7,
-       0xf5016f21,
-       0xf4025e21,
-       0x12f40601,
-/* 0x06a9: ctx_xfer_post */
-       0x7f21f507,
-/* 0x06ad: ctx_xfer_done */
-       0xb421f502,
-       0x0000f805,
-       0x00000000,
+       0x010d9800,
+       0xf500e7f0,
+       0xf0016f21,
+       0xb7f101ac,
+       0xb3f04000,
+       0x040c9850,
+       0xbb0fc4b6,
+       0x0c9800bc,
+       0x020d9801,
+       0xf1060f98,
+       0xf50800e7,
+       0xf0016f21,
+       0xa5f001ac,
+       0x00b7f104,
+       0x50b3f030,
+       0xb6040c98,
+       0xbcbb0fc4,
+       0x020c9800,
+       0x98030d98,
+       0xe7f1080f,
+       0x21f50200,
+       0x21f5016f,
+       0x01f4025e,
+       0x0712f406,
+/* 0x06ac: ctx_xfer_post */
+       0x027f21f5,
+/* 0x06b0: ctx_xfer_done */
+       0x05b721f5,
+       0x000000f8,
        0x00000000,
        0x00000000,
        0x00000000,
index fbcc342f896f144708e059093156c0e99210e952..84af7ec6a78ea7df9f0f5e86e5a0e3764790a4d0 100644 (file)
@@ -276,7 +276,7 @@ uint32_t gk208_grgpc_code[] = {
        0x02020014,
        0xf6120040,
        0x04bd0002,
-       0xfe048141,
+       0xfe048441,
        0x00400010,
        0x0000f607,
        0x040204bd,
@@ -295,165 +295,165 @@ uint32_t gk208_grgpc_code[] = {
        0x01c90080,
        0xbd0002f6,
        0x0c308e04,
-       0xbd24bd50,
-/* 0x0383: init_unk_loop */
-       0x7e44bd34,
-       0xb0000065,
-       0x0bf400f6,
-       0xbb010f0e,
-       0x4ffd04f2,
-       0x0130b605,
-/* 0x0398: init_unk_next */
-       0xb60120b6,
-       0x26b004e0,
-       0xe21bf401,
-/* 0x03a4: init_unk_done */
-       0xb50703b5,
-       0x00820804,
-       0x22cf0201,
-       0x9534bd00,
-       0x00800825,
-       0x05f601c0,
-       0x8004bd00,
-       0xf601c100,
-       0x04bd0005,
-       0x98000e98,
-       0x207e010f,
-       0x2fbb0001,
-       0x003fbb00,
-       0x98010e98,
-       0x207e020f,
-       0x0e980001,
-       0x00effd05,
-       0xbb002ebb,
-       0x0e98003e,
-       0x030f9802,
-       0x0001207e,
-       0xfd070e98,
-       0x2ebb00ef,
-       0x003ebb00,
-       0x800235b6,
-       0xf601d300,
-       0x04bd0003,
-       0xb60825b6,
-       0x20b60635,
-       0x0130b601,
-       0xb60824b6,
-       0x2fb20834,
-       0x0002687e,
-       0xbb002fbb,
-       0x0080003f,
-       0x03f60201,
-       0xbd04bd00,
-       0x1f29f024,
-       0x02300080,
-       0xbd0002f6,
-/* 0x0445: main */
-       0x0031f404,
-       0x0d0028f4,
-       0x00377e24,
-       0xf401f400,
-       0xf404e4b0,
-       0x81fe1d18,
-       0xbd060201,
-       0x0412fd20,
-       0xfd01e4b6,
-       0x18fe051e,
-       0x05187e00,
-       0xd40ef400,
-/* 0x0474: main_not_ctx_xfer */
-       0xf010ef94,
-       0xf87e01f5,
-       0x0ef40002,
-/* 0x0481: ih */
-       0xfe80f9c7,
-       0x80f90188,
-       0xa0f990f9,
-       0xd0f9b0f9,
-       0xf0f9e0f9,
-       0x004a04bd,
-       0x00aacf02,
-       0xf404abc4,
-       0x240d1f0b,
-       0xcf1a004e,
-       0x004f00ee,
-       0x00ffcf19,
-       0x0000047e,
-       0x0040010e,
-       0x000ef61d,
-/* 0x04be: ih_no_fifo */
-       0x004004bd,
-       0x000af601,
-       0xf0fc04bd,
-       0xd0fce0fc,
-       0xa0fcb0fc,
-       0x80fc90fc,
-       0xfc0088fe,
-       0x0032f480,
-/* 0x04de: hub_barrier_done */
-       0x010f01f8,
-       0xbb040e98,
-       0xffb204fe,
-       0x4094188e,
-       0x00008f7e,
-/* 0x04f2: ctx_redswitch */
-       0x200f00f8,
+       0x01e5f050,
+       0x34bd24bd,
+/* 0x0386: init_unk_loop */
+       0x657e44bd,
+       0xf6b00000,
+       0x0e0bf400,
+       0xf2bb010f,
+       0x054ffd04,
+/* 0x039b: init_unk_next */
+       0xb60130b6,
+       0xe0b60120,
+       0x0126b004,
+/* 0x03a7: init_unk_done */
+       0xb5e21bf4,
+       0x04b50703,
+       0x01008208,
+       0x0022cf02,
+       0x259534bd,
+       0xc0008008,
+       0x0005f601,
+       0x008004bd,
+       0x05f601c1,
+       0x9804bd00,
+       0x0f98000e,
+       0x01207e01,
+       0x002fbb00,
+       0x98003fbb,
+       0x0f98010e,
+       0x01207e02,
+       0x050e9800,
+       0xbb00effd,
+       0x3ebb002e,
+       0x020e9800,
+       0x7e030f98,
+       0x98000120,
+       0xeffd070e,
+       0x002ebb00,
+       0xb6003ebb,
+       0x00800235,
+       0x03f601d3,
+       0xb604bd00,
+       0x35b60825,
+       0x0120b606,
+       0xb60130b6,
+       0x34b60824,
+       0x7e2fb208,
+       0xbb000268,
+       0x3fbb002f,
+       0x01008000,
+       0x0003f602,
+       0x24bd04bd,
+       0x801f29f0,
+       0xf6023000,
+       0x04bd0002,
+/* 0x0448: main */
+       0xf40031f4,
+       0x240d0028,
+       0x0000377e,
+       0xb0f401f4,
+       0x18f404e4,
+       0x0181fe1d,
+       0x20bd0602,
+       0xb60412fd,
+       0x1efd01e4,
+       0x0018fe05,
+       0x00051b7e,
+/* 0x0477: main_not_ctx_xfer */
+       0x94d40ef4,
+       0xf5f010ef,
+       0x02f87e01,
+       0xc70ef400,
+/* 0x0484: ih */
+       0x88fe80f9,
+       0xf980f901,
+       0xf9a0f990,
+       0xf9d0f9b0,
+       0xbdf0f9e0,
+       0x02004a04,
+       0xc400aacf,
+       0x0bf404ab,
+       0x4e240d1f,
+       0xeecf1a00,
+       0x19004f00,
+       0x7e00ffcf,
+       0x0e000004,
+       0x1d004001,
+       0xbd000ef6,
+/* 0x04c1: ih_no_fifo */
+       0x01004004,
+       0xbd000af6,
+       0xfcf0fc04,
+       0xfcd0fce0,
+       0xfca0fcb0,
+       0xfe80fc90,
+       0x80fc0088,
+       0xf80032f4,
+/* 0x04e1: hub_barrier_done */
+       0x98010f01,
+       0xfebb040e,
+       0x8effb204,
+       0x7e409418,
+       0xf800008f,
+/* 0x04f5: ctx_redswitch */
+       0x80200f00,
+       0xf6018500,
+       0x04bd000f,
+/* 0x0502: ctx_redswitch_delay */
+       0xe2b6080e,
+       0xfd1bf401,
+       0x0800f5f1,
+       0x0200f5f1,
        0x01850080,
        0xbd000ff6,
-/* 0x04ff: ctx_redswitch_delay */
-       0xb6080e04,
-       0x1bf401e2,
-       0x00f5f1fd,
-       0x00f5f108,
-       0x85008002,
-       0x000ff601,
-       0x00f804bd,
-/* 0x0518: ctx_xfer */
-       0x02810080,
-       0xbd000ff6,
-       0x0711f404,
-       0x0004f27e,
-/* 0x0528: ctx_xfer_not_load */
-       0x0002167e,
-       0xfc8024bd,
-       0x02f60247,
-       0xf004bd00,
-       0x20b6012c,
-       0x4afc8003,
+/* 0x051b: ctx_xfer */
+       0x8000f804,
+       0xf6028100,
+       0x04bd000f,
+       0x7e0711f4,
+/* 0x052b: ctx_xfer_not_load */
+       0x7e0004f5,
+       0xbd000216,
+       0x47fc8024,
        0x0002f602,
-       0xacf004bd,
-       0x02a5f001,
-       0x5000008b,
-       0xb6040c98,
-       0xbcbb0fc4,
-       0x000c9800,
-       0x0e010d98,
-       0x013d7e00,
-       0x01acf000,
-       0x5040008b,
-       0xb6040c98,
-       0xbcbb0fc4,
-       0x010c9800,
-       0x98020d98,
-       0x004e060f,
-       0x013d7e08,
-       0x01acf000,
-       0x8b04a5f0,
-       0x98503000,
+       0x2cf004bd,
+       0x0320b601,
+       0x024afc80,
+       0xbd0002f6,
+       0x01acf004,
+       0x8b02a5f0,
+       0x98500000,
        0xc4b6040c,
        0x00bcbb0f,
-       0x98020c98,
-       0x0f98030d,
-       0x02004e08,
+       0x98000c98,
+       0x000e010d,
        0x00013d7e,
-       0x00020a7e,
-       0xf40601f4,
-/* 0x05b2: ctx_xfer_post */
-       0x277e0712,
-/* 0x05b6: ctx_xfer_done */
-       0xde7e0002,
-       0x00f80004,
-       0x00000000,
+       0x8b01acf0,
+       0x98504000,
+       0xc4b6040c,
+       0x00bcbb0f,
+       0x98010c98,
+       0x0f98020d,
+       0x08004e06,
+       0x00013d7e,
+       0xf001acf0,
+       0x008b04a5,
+       0x0c985030,
+       0x0fc4b604,
+       0x9800bcbb,
+       0x0d98020c,
+       0x080f9803,
+       0x7e02004e,
+       0x7e00013d,
+       0xf400020a,
+       0x12f40601,
+/* 0x05b5: ctx_xfer_post */
+       0x02277e07,
+/* 0x05b9: ctx_xfer_done */
+       0x04e17e00,
+       0x0000f800,
        0x00000000,
        0x00000000,
        0x00000000,
index 51f5c3c6e96607914f5f7ffcc0973f7f4e347bcc..11bf363a6ae95842634853ca9b4418c00a6c660b 100644 (file)
@@ -289,7 +289,7 @@ uint32_t gm107_grgpc_code[] = {
        0x020014fe,
        0x12004002,
        0xbd0002f6,
-       0x05b04104,
+       0x05b34104,
        0x400010fe,
        0x00f60700,
        0x0204bd00,
@@ -308,259 +308,259 @@ uint32_t gm107_grgpc_code[] = {
        0xc900800f,
        0x0002f601,
        0x308e04bd,
-       0x24bd500c,
-       0x44bd34bd,
-/* 0x03b0: init_unk_loop */
-       0x0000657e,
-       0xf400f6b0,
-       0x010f0e0b,
-       0xfd04f2bb,
-       0x30b6054f,
-/* 0x03c5: init_unk_next */
-       0x0120b601,
-       0xb004e0b6,
-       0x1bf40226,
-/* 0x03d1: init_unk_done */
-       0x0703b5e2,
-       0x820804b5,
-       0xcf020100,
-       0x34bd0022,
-       0x80082595,
-       0xf601c000,
+       0xe5f0500c,
+       0xbd24bd01,
+/* 0x03b3: init_unk_loop */
+       0x7e44bd34,
+       0xb0000065,
+       0x0bf400f6,
+       0xbb010f0e,
+       0x4ffd04f2,
+       0x0130b605,
+/* 0x03c8: init_unk_next */
+       0xb60120b6,
+       0x26b004e0,
+       0xe21bf402,
+/* 0x03d4: init_unk_done */
+       0xb50703b5,
+       0x00820804,
+       0x22cf0201,
+       0x9534bd00,
+       0x00800825,
+       0x05f601c0,
+       0x8004bd00,
+       0xf601c100,
        0x04bd0005,
-       0x01c10080,
-       0xbd0005f6,
-       0x000e9804,
-       0x7e010f98,
-       0xbb000120,
-       0x3fbb002f,
-       0x010e9800,
-       0x7e020f98,
-       0x98000120,
-       0xeffd050e,
-       0x002ebb00,
-       0x98003ebb,
-       0x0f98020e,
-       0x01207e03,
-       0x070e9800,
-       0xbb00effd,
-       0x3ebb002e,
-       0x0235b600,
-       0x01d30080,
-       0xbd0003f6,
-       0x0825b604,
-       0xb60635b6,
-       0x30b60120,
-       0x0824b601,
-       0xb20834b6,
-       0x02687e2f,
-       0x002fbb00,
-       0x0f003fbb,
-       0x8effb23f,
-       0xf0501d60,
-       0x8f7e01e5,
-       0x0c0f0000,
-       0xa88effb2,
-       0xe5f0501d,
-       0x008f7e01,
-       0x03147e00,
-       0xb23f0f00,
-       0x1d608eff,
-       0x01e5f050,
-       0x00008f7e,
-       0xffb2000f,
-       0x501d9c8e,
-       0x7e01e5f0,
-       0x0f00008f,
-       0x03147e01,
-       0x8effb200,
+       0x98000e98,
+       0x207e010f,
+       0x2fbb0001,
+       0x003fbb00,
+       0x98010e98,
+       0x207e020f,
+       0x0e980001,
+       0x00effd05,
+       0xbb002ebb,
+       0x0e98003e,
+       0x030f9802,
+       0x0001207e,
+       0xfd070e98,
+       0x2ebb00ef,
+       0x003ebb00,
+       0x800235b6,
+       0xf601d300,
+       0x04bd0003,
+       0xb60825b6,
+       0x20b60635,
+       0x0130b601,
+       0xb60824b6,
+       0x2fb20834,
+       0x0002687e,
+       0xbb002fbb,
+       0x3f0f003f,
+       0x501d608e,
+       0xb201e5f0,
+       0x008f7eff,
+       0x8e0c0f00,
        0xf0501da8,
-       0x8f7e01e5,
-       0xff0f0000,
-       0x988effb2,
+       0xffb201e5,
+       0x00008f7e,
+       0x0003147e,
+       0x608e3f0f,
        0xe5f0501d,
-       0x008f7e01,
-       0xb2020f00,
-       0x1da88eff,
+       0x7effb201,
+       0x0f00008f,
+       0x1d9c8e00,
        0x01e5f050,
-       0x00008f7e,
+       0x8f7effb2,
+       0x010f0000,
        0x0003147e,
-       0x85050498,
-       0x98504000,
-       0x64b60406,
-       0x0056bb0f,
-/* 0x04e0: tpc_strand_init_tpc_loop */
-       0x05705eb8,
-       0x00657e00,
-       0xbdf6b200,
-/* 0x04ed: tpc_strand_init_idx_loop */
-       0x605eb874,
-       0x7fb20005,
-       0x00008f7e,
-       0x05885eb8,
-       0x082f9500,
-       0x00008f7e,
-       0x058c5eb8,
-       0x082f9500,
+       0x501da88e,
+       0xb201e5f0,
+       0x008f7eff,
+       0x8eff0f00,
+       0xf0501d98,
+       0xffb201e5,
        0x00008f7e,
-       0x05905eb8,
-       0x00657e00,
-       0x06f5b600,
-       0xb601f0b6,
-       0x2fbb08f4,
-       0x003fbb00,
-       0xb60170b6,
-       0x1bf40162,
-       0x0050b7bf,
-       0x0142b608,
-       0x0fa81bf4,
-       0x8effb23f,
-       0xf0501d60,
-       0x8f7e01e5,
-       0x0d0f0000,
-       0xa88effb2,
+       0xa88e020f,
        0xe5f0501d,
-       0x008f7e01,
-       0x03147e00,
-       0x01008000,
-       0x0003f602,
-       0x24bd04bd,
-       0x801f29f0,
-       0xf6023000,
-       0x04bd0002,
-/* 0x0574: main */
-       0xf40031f4,
-       0x240d0028,
-       0x0000377e,
-       0xb0f401f4,
-       0x18f404e4,
-       0x0181fe1d,
-       0x20bd0602,
-       0xb60412fd,
-       0x1efd01e4,
-       0x0018fe05,
-       0x0006477e,
-/* 0x05a3: main_not_ctx_xfer */
-       0x94d40ef4,
-       0xf5f010ef,
-       0x02f87e01,
-       0xc70ef400,
-/* 0x05b0: ih */
-       0x88fe80f9,
-       0xf980f901,
-       0xf9a0f990,
-       0xf9d0f9b0,
-       0xbdf0f9e0,
-       0x02004a04,
-       0xc400aacf,
-       0x0bf404ab,
-       0x4e240d1f,
-       0xeecf1a00,
-       0x19004f00,
-       0x7e00ffcf,
-       0x0e000004,
-       0x1d004001,
-       0xbd000ef6,
-/* 0x05ed: ih_no_fifo */
-       0x01004004,
-       0xbd000af6,
-       0xfcf0fc04,
-       0xfcd0fce0,
-       0xfca0fcb0,
-       0xfe80fc90,
-       0x80fc0088,
-       0xf80032f4,
-/* 0x060d: hub_barrier_done */
-       0x98010f01,
-       0xfebb040e,
-       0x8effb204,
-       0x7e409418,
-       0xf800008f,
-/* 0x0621: ctx_redswitch */
-       0x80200f00,
+       0x7effb201,
+       0x7e00008f,
+       0x98000314,
+       0x00850504,
+       0x06985040,
+       0x0f64b604,
+/* 0x04e3: tpc_strand_init_tpc_loop */
+       0xb80056bb,
+       0x0005705e,
+       0x0000657e,
+       0x74bdf6b2,
+/* 0x04f0: tpc_strand_init_idx_loop */
+       0x05605eb8,
+       0x7e7fb200,
+       0xb800008f,
+       0x0005885e,
+       0x7e082f95,
+       0xb800008f,
+       0x00058c5e,
+       0x7e082f95,
+       0xb800008f,
+       0x0005905e,
+       0x0000657e,
+       0xb606f5b6,
+       0xf4b601f0,
+       0x002fbb08,
+       0xb6003fbb,
+       0x62b60170,
+       0xbf1bf401,
+       0x080050b7,
+       0xf40142b6,
+       0x3f0fa81b,
+       0x501d608e,
+       0xb201e5f0,
+       0x008f7eff,
+       0x8e0d0f00,
+       0xf0501da8,
+       0xffb201e5,
+       0x00008f7e,
+       0x0003147e,
+       0x02010080,
+       0xbd0003f6,
+       0xf024bd04,
+       0x00801f29,
+       0x02f60230,
+/* 0x0577: main */
+       0xf404bd00,
+       0x28f40031,
+       0x7e240d00,
+       0xf4000037,
+       0xe4b0f401,
+       0x1d18f404,
+       0x020181fe,
+       0xfd20bd06,
+       0xe4b60412,
+       0x051efd01,
+       0x7e0018fe,
+       0xf400064a,
+/* 0x05a6: main_not_ctx_xfer */
+       0xef94d40e,
+       0x01f5f010,
+       0x0002f87e,
+/* 0x05b3: ih */
+       0xf9c70ef4,
+       0x0188fe80,
+       0x90f980f9,
+       0xb0f9a0f9,
+       0xe0f9d0f9,
+       0x04bdf0f9,
+       0xcf02004a,
+       0xabc400aa,
+       0x1f0bf404,
+       0x004e240d,
+       0x00eecf1a,
+       0xcf19004f,
+       0x047e00ff,
+       0x010e0000,
+       0xf61d0040,
+       0x04bd000e,
+/* 0x05f0: ih_no_fifo */
+       0xf6010040,
+       0x04bd000a,
+       0xe0fcf0fc,
+       0xb0fcd0fc,
+       0x90fca0fc,
+       0x88fe80fc,
+       0xf480fc00,
+       0x01f80032,
+/* 0x0610: hub_barrier_done */
+       0x0e98010f,
+       0x04febb04,
+       0x188effb2,
+       0x8f7e4094,
+       0x00f80000,
+/* 0x0624: ctx_redswitch */
+       0x0080200f,
+       0x0ff60185,
+       0x0e04bd00,
+/* 0x0631: ctx_redswitch_delay */
+       0x01e2b608,
+       0xf1fd1bf4,
+       0xf10800f5,
+       0x800200f5,
        0xf6018500,
        0x04bd000f,
-/* 0x062e: ctx_redswitch_delay */
-       0xe2b6080e,
-       0xfd1bf401,
-       0x0800f5f1,
-       0x0200f5f1,
-       0x01850080,
-       0xbd000ff6,
-/* 0x0647: ctx_xfer */
-       0x8000f804,
-       0xf6028100,
-       0x04bd000f,
-       0xc48effb2,
-       0xe5f0501d,
-       0x008f7e01,
-       0x0711f400,
-       0x0006217e,
-/* 0x0664: ctx_xfer_not_load */
-       0x0002167e,
-       0xfc8024bd,
-       0x02f60247,
-       0xf004bd00,
-       0x20b6012c,
-       0x4afc8003,
+/* 0x064a: ctx_xfer */
+       0x008000f8,
+       0x0ff60281,
+       0x8e04bd00,
+       0xf0501dc4,
+       0xffb201e5,
+       0x00008f7e,
+       0x7e0711f4,
+/* 0x0667: ctx_xfer_not_load */
+       0x7e000624,
+       0xbd000216,
+       0x47fc8024,
        0x0002f602,
-       0x0c0f04bd,
-       0xa88effb2,
-       0xe5f0501d,
-       0x008f7e01,
-       0x03147e00,
-       0xb23f0f00,
-       0x1d608eff,
-       0x01e5f050,
+       0x2cf004bd,
+       0x0320b601,
+       0x024afc80,
+       0xbd0002f6,
+       0x8e0c0f04,
+       0xf0501da8,
+       0xffb201e5,
        0x00008f7e,
-       0xffb2000f,
-       0x501d9c8e,
-       0x7e01e5f0,
+       0x0003147e,
+       0x608e3f0f,
+       0xe5f0501d,
+       0x7effb201,
        0x0f00008f,
-       0x03147e01,
-       0x01fcf000,
-       0xb203f0b6,
-       0x1da88eff,
+       0x1d9c8e00,
        0x01e5f050,
-       0x00008f7e,
-       0xf001acf0,
-       0x008b02a5,
-       0x0c985000,
-       0x0fc4b604,
-       0x9800bcbb,
-       0x0d98000c,
-       0x7e000e01,
-       0xf000013d,
-       0x008b01ac,
-       0x0c985040,
-       0x0fc4b604,
-       0x9800bcbb,
-       0x0d98010c,
-       0x060f9802,
-       0x7e08004e,
-       0xf000013d,
+       0x8f7effb2,
+       0x010f0000,
+       0x0003147e,
+       0xb601fcf0,
+       0xa88e03f0,
+       0xe5f0501d,
+       0x7effb201,
+       0xf000008f,
        0xa5f001ac,
-       0x30008b04,
+       0x00008b02,
        0x040c9850,
        0xbb0fc4b6,
        0x0c9800bc,
-       0x030d9802,
-       0x4e080f98,
-       0x3d7e0200,
-       0x0a7e0001,
-       0x147e0002,
-       0x01f40003,
-       0x1a12f406,
-/* 0x073c: ctx_xfer_post */
-       0x0002277e,
-       0xffb20d0f,
-       0x501da88e,
-       0x7e01e5f0,
-       0x7e00008f,
-/* 0x0753: ctx_xfer_done */
-       0x7e000314,
-       0xf800060d,
-       0x00000000,
+       0x010d9800,
+       0x3d7e000e,
+       0xacf00001,
+       0x40008b01,
+       0x040c9850,
+       0xbb0fc4b6,
+       0x0c9800bc,
+       0x020d9801,
+       0x4e060f98,
+       0x3d7e0800,
+       0xacf00001,
+       0x04a5f001,
+       0x5030008b,
+       0xb6040c98,
+       0xbcbb0fc4,
+       0x020c9800,
+       0x98030d98,
+       0x004e080f,
+       0x013d7e02,
+       0x020a7e00,
+       0x03147e00,
+       0x0601f400,
+/* 0x073f: ctx_xfer_post */
+       0x7e1a12f4,
+       0x0f000227,
+       0x1da88e0d,
+       0x01e5f050,
+       0x8f7effb2,
+       0x147e0000,
+/* 0x0756: ctx_xfer_done */
+       0x107e0003,
+       0x00f80006,
        0x00000000,
        0x00000000,
        0x00000000,
index dda7a7d224c9b9d22a5894e4930bc712644e157a..9f5dfc85147a50df62f30fdb84453c18a622380e 100644 (file)
@@ -143,7 +143,7 @@ gf100_gr_zbc_depth_get(struct gf100_gr *gr, int format,
 static int
 gf100_fermi_mthd_zbc_color(struct nvkm_object *object, void *data, u32 size)
 {
-       struct gf100_gr *gr = (void *)object->engine;
+       struct gf100_gr *gr = gf100_gr(nvkm_gr(object->engine));
        union {
                struct fermi_a_zbc_color_v0 v0;
        } *args = data;
@@ -189,7 +189,7 @@ gf100_fermi_mthd_zbc_color(struct nvkm_object *object, void *data, u32 size)
 static int
 gf100_fermi_mthd_zbc_depth(struct nvkm_object *object, void *data, u32 size)
 {
-       struct gf100_gr *gr = (void *)object->engine;
+       struct gf100_gr *gr = gf100_gr(nvkm_gr(object->engine));
        union {
                struct fermi_a_zbc_depth_v0 v0;
        } *args = data;
@@ -1530,6 +1530,8 @@ gf100_gr_oneinit(struct nvkm_gr *base)
                gr->ppc_nr[i]  = gr->func->ppc_nr;
                for (j = 0; j < gr->ppc_nr[i]; j++) {
                        u8 mask = nvkm_rd32(device, GPC_UNIT(i, 0x0c30 + (j * 4)));
+                       if (mask)
+                               gr->ppc_mask[i] |= (1 << j);
                        gr->ppc_tpc_nr[i][j] = hweight8(mask);
                }
        }
index 4611961b118743c304f6b40f545ffeb27ef0cb91..02e78b8d93f6743b67baee2a6c68757277ccf489 100644 (file)
@@ -97,6 +97,7 @@ struct gf100_gr {
        u8 tpc_nr[GPC_MAX];
        u8 tpc_total;
        u8 ppc_nr[GPC_MAX];
+       u8 ppc_mask[GPC_MAX];
        u8 ppc_tpc_nr[GPC_MAX][4];
 
        struct nvkm_memory *unk4188b4;
index 895ba74057d4aab45fb44ddfc707243b3252fbdb..1d7dd38292b375bd73ec35ff4e844cd2ae1defe7 100644 (file)
@@ -97,7 +97,9 @@ static void *
 nvkm_instobj_dtor(struct nvkm_memory *memory)
 {
        struct nvkm_instobj *iobj = nvkm_instobj(memory);
+       spin_lock(&iobj->imem->lock);
        list_del(&iobj->head);
+       spin_unlock(&iobj->imem->lock);
        nvkm_memory_del(&iobj->parent);
        return iobj;
 }
@@ -190,7 +192,9 @@ nvkm_instobj_new(struct nvkm_instmem *imem, u32 size, u32 align, bool zero,
                nvkm_memory_ctor(&nvkm_instobj_func_slow, &iobj->memory);
                iobj->parent = memory;
                iobj->imem = imem;
+               spin_lock(&iobj->imem->lock);
                list_add_tail(&iobj->head, &imem->list);
+               spin_unlock(&iobj->imem->lock);
                memory = &iobj->memory;
        }
 
@@ -309,5 +313,6 @@ nvkm_instmem_ctor(const struct nvkm_instmem_func *func,
 {
        nvkm_subdev_ctor(&nvkm_instmem, device, index, 0, &imem->subdev);
        imem->func = func;
+       spin_lock_init(&imem->lock);
        INIT_LIST_HEAD(&imem->list);
 }
index d942fa7b9f1871b362809baf0bac9c8c7d6ced2b..86f9f3b13f71f7caead9206f9cfcdab6bf88c728 100644 (file)
@@ -81,9 +81,7 @@ gk104_pmu_pgob(struct nvkm_pmu *pmu, bool enable)
        nvkm_mask(device, 0x000200, 0x00001000, 0x00001000);
        nvkm_rd32(device, 0x000200);
 
-       if ( nvkm_boolopt(device->cfgopt, "War00C800_0",
-           device->quirk ? device->quirk->War00C800_0 : false)) {
-               nvkm_info(&pmu->subdev, "hw bug workaround enabled\n");
+       if (nvkm_boolopt(device->cfgopt, "War00C800_0", true)) {
                switch (device->chipset) {
                case 0xe4:
                        magic(device, 0x04000000);
index b61509e26ec9f5d5192540c624e5c4ebdc96e087..b735173a18ff3d055dcfafcae2cd17c58b6a6c4a 100644 (file)
@@ -59,7 +59,7 @@ gk104_volt_set(struct nvkm_volt *base, u32 uv)
        duty = (uv - bios->base) * div / bios->pwm_range;
 
        nvkm_wr32(device, 0x20340, div);
-       nvkm_wr32(device, 0x20344, 0x8000000 | duty);
+       nvkm_wr32(device, 0x20344, 0x80000000 | duty);
 
        return 0;
 }
index 248953d2fdb742d69111193f62638c0a95f179d5..f81fb26410976840b02811de9693b875edfa3efa 100644 (file)
@@ -4173,11 +4173,7 @@ void cik_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib)
        control |= ib->length_dw | (vm_id << 24);
 
        radeon_ring_write(ring, header);
-       radeon_ring_write(ring,
-#ifdef __BIG_ENDIAN
-                         (2 << 0) |
-#endif
-                         (ib->gpu_addr & 0xFFFFFFFC));
+       radeon_ring_write(ring, (ib->gpu_addr & 0xFFFFFFFC));
        radeon_ring_write(ring, upper_32_bits(ib->gpu_addr) & 0xFFFF);
        radeon_ring_write(ring, control);
 }
@@ -8472,7 +8468,7 @@ restart_ih:
        if (queue_dp)
                schedule_work(&rdev->dp_work);
        if (queue_hotplug)
-               schedule_work(&rdev->hotplug_work);
+               schedule_delayed_work(&rdev->hotplug_work, 0);
        if (queue_reset) {
                rdev->needs_reset = true;
                wake_up_all(&rdev->fence_queue);
@@ -9630,6 +9626,9 @@ static void dce8_program_watermarks(struct radeon_device *rdev,
                    (rdev->disp_priority == 2)) {
                        DRM_DEBUG_KMS("force priority to high\n");
                }
+
+               /* Save number of lines the linebuffer leads before the scanout */
+               radeon_crtc->lb_vblank_lead_lines = DIV_ROUND_UP(lb_size, mode->crtc_hdisplay);
        }
 
        /* select wm A */
index 7f33767d7ed65f4a966cb2b3e01b250846cca340..2ad462896896b017402688352428082b6925df7b 100644 (file)
@@ -2372,6 +2372,9 @@ static void evergreen_program_watermarks(struct radeon_device *rdev,
                c.full = dfixed_div(c, a);
                priority_b_mark = dfixed_trunc(c);
                priority_b_cnt |= priority_b_mark & PRIORITY_MARK_MASK;
+
+               /* Save number of lines the linebuffer leads before the scanout */
+               radeon_crtc->lb_vblank_lead_lines = DIV_ROUND_UP(lb_size, mode->crtc_hdisplay);
        }
 
        /* select wm A */
@@ -5344,7 +5347,7 @@ restart_ih:
        if (queue_dp)
                schedule_work(&rdev->dp_work);
        if (queue_hotplug)
-               schedule_work(&rdev->hotplug_work);
+               schedule_delayed_work(&rdev->hotplug_work, 0);
        if (queue_hdmi)
                schedule_work(&rdev->audio_work);
        if (queue_thermal && rdev->pm.dpm_enabled)
index 238b13f045c180480ef4f49983bbc19b76016729..9e7e2bf03b815647451622d69c6cbce2d03582de 100644 (file)
@@ -806,7 +806,7 @@ int r100_irq_process(struct radeon_device *rdev)
                status = r100_irq_ack(rdev);
        }
        if (queue_hotplug)
-               schedule_work(&rdev->hotplug_work);
+               schedule_delayed_work(&rdev->hotplug_work, 0);
        if (rdev->msi_enabled) {
                switch (rdev->family) {
                case CHIP_RS400:
@@ -3217,6 +3217,9 @@ void r100_bandwidth_update(struct radeon_device *rdev)
        uint32_t pixel_bytes1 = 0;
        uint32_t pixel_bytes2 = 0;
 
+       /* Guess line buffer size to be 8192 pixels */
+       u32 lb_size = 8192;
+
        if (!rdev->mode_info.mode_config_initialized)
                return;
 
@@ -3631,6 +3634,13 @@ void r100_bandwidth_update(struct radeon_device *rdev)
                DRM_DEBUG_KMS("GRPH2_BUFFER_CNTL from to %x\n",
                          (unsigned int)RREG32(RADEON_GRPH2_BUFFER_CNTL));
        }
+
+       /* Save number of lines the linebuffer leads before the scanout */
+       if (mode1)
+           rdev->mode_info.crtcs[0]->lb_vblank_lead_lines = DIV_ROUND_UP(lb_size, mode1->crtc_hdisplay);
+
+       if (mode2)
+           rdev->mode_info.crtcs[1]->lb_vblank_lead_lines = DIV_ROUND_UP(lb_size, mode2->crtc_hdisplay);
 }
 
 int r100_ring_test(struct radeon_device *rdev, struct radeon_ring *ring)
index 4ea5b10ff5f412fb0fc2b161c8fe936ab154bd2f..cc2fdf0be37a600e313d239e07520331229a0035 100644 (file)
@@ -4276,7 +4276,7 @@ restart_ih:
                WREG32(IH_RB_RPTR, rptr);
        }
        if (queue_hotplug)
-               schedule_work(&rdev->hotplug_work);
+               schedule_delayed_work(&rdev->hotplug_work, 0);
        if (queue_hdmi)
                schedule_work(&rdev->audio_work);
        if (queue_thermal && rdev->pm.dpm_enabled)
index b6cbd816537e7e69bc920482961cdb47b6dfd68d..87db64983ea8c18a0305eeedf1e25f18cffc87ae 100644 (file)
@@ -2414,7 +2414,7 @@ struct radeon_device {
        struct r600_ih ih; /* r6/700 interrupt ring */
        struct radeon_rlc rlc;
        struct radeon_mec mec;
-       struct work_struct hotplug_work;
+       struct delayed_work hotplug_work;
        struct work_struct dp_work;
        struct work_struct audio_work;
        int num_crtc; /* number of crtcs */
index fe994aac3b0403357d40e9b29f46e8818be454bf..c77d349c561c6960e79d0b9338d7368302e1d188 100644 (file)
@@ -54,6 +54,9 @@ static struct radeon_agpmode_quirk radeon_agpmode_quirk_list[] = {
        /* Intel 82855PM host bridge / Mobility 9600 M10 RV350 Needs AGPMode 1 (lp #195051) */
        { PCI_VENDOR_ID_INTEL, 0x3340, PCI_VENDOR_ID_ATI, 0x4e50,
                PCI_VENDOR_ID_IBM, 0x0550, 1},
+       /* Intel 82855PM host bridge / RV250/M9 GL [Mobility FireGL 9000/Radeon 9000] needs AGPMode 1 (Thinkpad T40p) */
+       { PCI_VENDOR_ID_INTEL, 0x3340, PCI_VENDOR_ID_ATI, 0x4c66,
+               PCI_VENDOR_ID_IBM, 0x054d, 1},
        /* Intel 82855PM host bridge / Mobility M7 needs AGPMode 1 */
        { PCI_VENDOR_ID_INTEL, 0x3340, PCI_VENDOR_ID_ATI, 0x4c57,
                PCI_VENDOR_ID_IBM, 0x0530, 1},
index 5a2cafb4f1bc595220e603ed1942e65bf24b20b7..340f3f549f295314788fbf9b3052880b8095a7f1 100644 (file)
@@ -1234,13 +1234,32 @@ radeon_dvi_detect(struct drm_connector *connector, bool force)
        if (r < 0)
                return connector_status_disconnected;
 
+       if (radeon_connector->detected_hpd_without_ddc) {
+               force = true;
+               radeon_connector->detected_hpd_without_ddc = false;
+       }
+
        if (!force && radeon_check_hpd_status_unchanged(connector)) {
                ret = connector->status;
                goto exit;
        }
 
-       if (radeon_connector->ddc_bus)
+       if (radeon_connector->ddc_bus) {
                dret = radeon_ddc_probe(radeon_connector, false);
+
+               /* Sometimes the pins required for the DDC probe on DVI
+                * connectors don't make contact at the same time that the ones
+                * for HPD do. If the DDC probe fails even though we had an HPD
+                * signal, try again later */
+               if (!dret && !force &&
+                   connector->status != connector_status_connected) {
+                       DRM_DEBUG_KMS("hpd detected without ddc, retrying in 1 second\n");
+                       radeon_connector->detected_hpd_without_ddc = true;
+                       schedule_delayed_work(&rdev->hotplug_work,
+                                             msecs_to_jiffies(1000));
+                       goto exit;
+               }
+       }
        if (dret) {
                radeon_connector->detected_by_load = false;
                radeon_connector_free_edid(connector);
index a8d9927ed9eb9657d89e34c84481c9c9c9e3513f..1eca0acac016f314cd6960b9dda3067bcc04e83c 100644 (file)
@@ -322,7 +322,9 @@ void radeon_crtc_handle_vblank(struct radeon_device *rdev, int crtc_id)
         * to complete in this vblank?
         */
        if (update_pending &&
-           (DRM_SCANOUTPOS_VALID & radeon_get_crtc_scanoutpos(rdev->ddev, crtc_id, 0,
+           (DRM_SCANOUTPOS_VALID & radeon_get_crtc_scanoutpos(rdev->ddev,
+                                                              crtc_id,
+                                                              USE_REAL_VBLANKSTART,
                                                               &vpos, &hpos, NULL, NULL,
                                                               &rdev->mode_info.crtcs[crtc_id]->base.hwmode)) &&
            ((vpos >= (99 * rdev->mode_info.crtcs[crtc_id]->base.hwmode.crtc_vdisplay)/100) ||
@@ -401,6 +403,8 @@ static void radeon_flip_work_func(struct work_struct *__work)
        struct drm_crtc *crtc = &radeon_crtc->base;
        unsigned long flags;
        int r;
+       int vpos, hpos, stat, min_udelay;
+       struct drm_vblank_crtc *vblank = &crtc->dev->vblank[work->crtc_id];
 
         down_read(&rdev->exclusive_lock);
        if (work->fence) {
@@ -437,6 +441,41 @@ static void radeon_flip_work_func(struct work_struct *__work)
        /* set the proper interrupt */
        radeon_irq_kms_pflip_irq_get(rdev, radeon_crtc->crtc_id);
 
+       /* If this happens to execute within the "virtually extended" vblank
+        * interval before the start of the real vblank interval then it needs
+        * to delay programming the mmio flip until the real vblank is entered.
+        * This prevents completing a flip too early due to the way we fudge
+        * our vblank counter and vblank timestamps in order to work around the
+        * problem that the hw fires vblank interrupts before actual start of
+        * vblank (when line buffer refilling is done for a frame). It
+        * complements the fudging logic in radeon_get_crtc_scanoutpos() for
+        * timestamping and radeon_get_vblank_counter_kms() for vblank counts.
+        *
+        * In practice this won't execute very often unless on very fast
+        * machines because the time window for this to happen is very small.
+        */
+       for (;;) {
+               /* GET_DISTANCE_TO_VBLANKSTART returns distance to real vblank
+                * start in hpos, and to the "fudged earlier" vblank start in
+                * vpos.
+                */
+               stat = radeon_get_crtc_scanoutpos(rdev->ddev, work->crtc_id,
+                                                 GET_DISTANCE_TO_VBLANKSTART,
+                                                 &vpos, &hpos, NULL, NULL,
+                                                 &crtc->hwmode);
+
+               if ((stat & (DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_ACCURATE)) !=
+                   (DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_ACCURATE) ||
+                   !(vpos >= 0 && hpos <= 0))
+                       break;
+
+               /* Sleep at least until estimated real start of hw vblank */
+               spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
+               min_udelay = (-hpos + 1) * max(vblank->linedur_ns / 1000, 5);
+               usleep_range(min_udelay, 2 * min_udelay);
+               spin_lock_irqsave(&crtc->dev->event_lock, flags);
+       };
+
        /* do the flip (mmio) */
        radeon_page_flip(rdev, radeon_crtc->crtc_id, work->base);
 
@@ -1768,6 +1807,15 @@ bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc,
  * \param dev Device to query.
  * \param crtc Crtc to query.
  * \param flags Flags from caller (DRM_CALLED_FROM_VBLIRQ or 0).
+ *              For driver internal use only also supports these flags:
+ *
+ *              USE_REAL_VBLANKSTART to use the real start of vblank instead
+ *              of a fudged earlier start of vblank.
+ *
+ *              GET_DISTANCE_TO_VBLANKSTART to return distance to the
+ *              fudged earlier start of vblank in *vpos and the distance
+ *              to true start of vblank in *hpos.
+ *
  * \param *vpos Location where vertical scanout position should be stored.
  * \param *hpos Location where horizontal scanout position should go.
  * \param *stime Target location for timestamp taken immediately before
@@ -1911,10 +1959,40 @@ int radeon_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe,
                vbl_end = 0;
        }
 
+       /* Called from driver internal vblank counter query code? */
+       if (flags & GET_DISTANCE_TO_VBLANKSTART) {
+           /* Caller wants distance from real vbl_start in *hpos */
+           *hpos = *vpos - vbl_start;
+       }
+
+       /* Fudge vblank to start a few scanlines earlier to handle the
+        * problem that vblank irqs fire a few scanlines before start
+        * of vblank. Some driver internal callers need the true vblank
+        * start to be used and signal this via the USE_REAL_VBLANKSTART flag.
+        *
+        * The cause of the "early" vblank irq is that the irq is triggered
+        * by the line buffer logic when the line buffer read position enters
+        * the vblank, whereas our crtc scanout position naturally lags the
+        * line buffer read position.
+        */
+       if (!(flags & USE_REAL_VBLANKSTART))
+               vbl_start -= rdev->mode_info.crtcs[pipe]->lb_vblank_lead_lines;
+
        /* Test scanout position against vblank region. */
        if ((*vpos < vbl_start) && (*vpos >= vbl_end))
                in_vbl = false;
 
+       /* In vblank? */
+       if (in_vbl)
+           ret |= DRM_SCANOUTPOS_IN_VBLANK;
+
+       /* Called from driver internal vblank counter query code? */
+       if (flags & GET_DISTANCE_TO_VBLANKSTART) {
+               /* Caller wants distance from fudged earlier vbl_start */
+               *vpos -= vbl_start;
+               return ret;
+       }
+
        /* Check if inside vblank area and apply corrective offsets:
         * vpos will then be >=0 in video scanout area, but negative
         * within vblank area, counting down the number of lines until
@@ -1930,31 +2008,5 @@ int radeon_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe,
        /* Correct for shifted end of vbl at vbl_end. */
        *vpos = *vpos - vbl_end;
 
-       /* In vblank? */
-       if (in_vbl)
-               ret |= DRM_SCANOUTPOS_IN_VBLANK;
-
-       /* Is vpos outside nominal vblank area, but less than
-        * 1/100 of a frame height away from start of vblank?
-        * If so, assume this isn't a massively delayed vblank
-        * interrupt, but a vblank interrupt that fired a few
-        * microseconds before true start of vblank. Compensate
-        * by adding a full frame duration to the final timestamp.
-        * Happens, e.g., on ATI R500, R600.
-        *
-        * We only do this if DRM_CALLED_FROM_VBLIRQ.
-        */
-       if ((flags & DRM_CALLED_FROM_VBLIRQ) && !in_vbl) {
-               vbl_start = mode->crtc_vdisplay;
-               vtotal = mode->crtc_vtotal;
-
-               if (vbl_start - *vpos < vtotal / 100) {
-                       *vpos -= vtotal;
-
-                       /* Signal this correction as "applied". */
-                       ret |= 0x8;
-               }
-       }
-
        return ret;
 }
index 171d3e43c30cc02257df75645c6c77f0a726de33..979f3bf65f2c474f231a26eb47af963d4436be0f 100644 (file)
@@ -74,7 +74,7 @@ irqreturn_t radeon_driver_irq_handler_kms(int irq, void *arg)
 static void radeon_hotplug_work_func(struct work_struct *work)
 {
        struct radeon_device *rdev = container_of(work, struct radeon_device,
-                                                 hotplug_work);
+                                                 hotplug_work.work);
        struct drm_device *dev = rdev->ddev;
        struct drm_mode_config *mode_config = &dev->mode_config;
        struct drm_connector *connector;
@@ -302,7 +302,7 @@ int radeon_irq_kms_init(struct radeon_device *rdev)
                }
        }
 
-       INIT_WORK(&rdev->hotplug_work, radeon_hotplug_work_func);
+       INIT_DELAYED_WORK(&rdev->hotplug_work, radeon_hotplug_work_func);
        INIT_WORK(&rdev->dp_work, radeon_dp_work_func);
        INIT_WORK(&rdev->audio_work, r600_audio_update_hdmi);
 
@@ -310,7 +310,7 @@ int radeon_irq_kms_init(struct radeon_device *rdev)
        r = drm_irq_install(rdev->ddev, rdev->ddev->pdev->irq);
        if (r) {
                rdev->irq.installed = false;
-               flush_work(&rdev->hotplug_work);
+               flush_delayed_work(&rdev->hotplug_work);
                return r;
        }
 
@@ -333,7 +333,7 @@ void radeon_irq_kms_fini(struct radeon_device *rdev)
                rdev->irq.installed = false;
                if (rdev->msi_enabled)
                        pci_disable_msi(rdev->pdev);
-               flush_work(&rdev->hotplug_work);
+               flush_delayed_work(&rdev->hotplug_work);
        }
 }
 
index 0ec6fcca16d3b12b898d8c9c036ab330cdc47226..d290a8a09036e9d28aa78332f7f2d22ee46ec0e2 100644 (file)
@@ -755,6 +755,8 @@ void radeon_driver_preclose_kms(struct drm_device *dev,
  */
 u32 radeon_get_vblank_counter_kms(struct drm_device *dev, int crtc)
 {
+       int vpos, hpos, stat;
+       u32 count;
        struct radeon_device *rdev = dev->dev_private;
 
        if (crtc < 0 || crtc >= rdev->num_crtc) {
@@ -762,7 +764,53 @@ u32 radeon_get_vblank_counter_kms(struct drm_device *dev, int crtc)
                return -EINVAL;
        }
 
-       return radeon_get_vblank_counter(rdev, crtc);
+       /* The hw increments its frame counter at start of vsync, not at start
+        * of vblank, as is required by DRM core vblank counter handling.
+        * Cook the hw count here to make it appear to the caller as if it
+        * incremented at start of vblank. We measure distance to start of
+        * vblank in vpos. vpos therefore will be >= 0 between start of vblank
+        * and start of vsync, so vpos >= 0 means to bump the hw frame counter
+        * result by 1 to give the proper appearance to caller.
+        */
+       if (rdev->mode_info.crtcs[crtc]) {
+               /* Repeat readout if needed to provide stable result if
+                * we cross start of vsync during the queries.
+                */
+               do {
+                       count = radeon_get_vblank_counter(rdev, crtc);
+                       /* Ask radeon_get_crtc_scanoutpos to return vpos as
+                        * distance to start of vblank, instead of regular
+                        * vertical scanout pos.
+                        */
+                       stat = radeon_get_crtc_scanoutpos(
+                               dev, crtc, GET_DISTANCE_TO_VBLANKSTART,
+                               &vpos, &hpos, NULL, NULL,
+                               &rdev->mode_info.crtcs[crtc]->base.hwmode);
+               } while (count != radeon_get_vblank_counter(rdev, crtc));
+
+               if (((stat & (DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_ACCURATE)) !=
+                   (DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_ACCURATE))) {
+                       DRM_DEBUG_VBL("Query failed! stat %d\n", stat);
+               }
+               else {
+                       DRM_DEBUG_VBL("crtc %d: dist from vblank start %d\n",
+                                     crtc, vpos);
+
+                       /* Bump counter if we are at >= leading edge of vblank,
+                        * but before vsync where vpos would turn negative and
+                        * the hw counter really increments.
+                        */
+                       if (vpos >= 0)
+                               count++;
+               }
+       }
+       else {
+           /* Fallback to use value as is. */
+           count = radeon_get_vblank_counter(rdev, crtc);
+           DRM_DEBUG_VBL("NULL mode info! Returned count may be wrong.\n");
+       }
+
+       return count;
 }
 
 /**
index 830e171c3a9e35c108f69acd2d4d45386033cd8b..bba112628b478476b0685dc8416ef4badc170d46 100644 (file)
@@ -367,6 +367,7 @@ struct radeon_crtc {
        u32 line_time;
        u32 wm_low;
        u32 wm_high;
+       u32 lb_vblank_lead_lines;
        struct drm_display_mode hw_mode;
        enum radeon_output_csc output_csc;
 };
@@ -553,6 +554,7 @@ struct radeon_connector {
        void *con_priv;
        bool dac_load_detect;
        bool detected_by_load; /* if the connection status was determined by load */
+       bool detected_hpd_without_ddc; /* if an HPD signal was detected on DVI, but ddc probing failed */
        uint16_t connector_object_id;
        struct radeon_hpd hpd;
        struct radeon_router router;
@@ -686,6 +688,9 @@ struct atom_voltage_table
        struct atom_voltage_table_entry entries[MAX_VOLTAGE_ENTRIES];
 };
 
+/* Driver internal use only flags of radeon_get_crtc_scanoutpos() */
+#define USE_REAL_VBLANKSTART           (1 << 30)
+#define GET_DISTANCE_TO_VBLANKSTART    (1 << 31)
 
 extern void
 radeon_add_atom_connector(struct drm_device *dev,
index f4f03dcc153049358b7167695c27fff60af55d46..59abebd6b5dc42d4941131adb51b76ab677d3fd4 100644 (file)
@@ -1756,7 +1756,9 @@ static bool radeon_pm_in_vbl(struct radeon_device *rdev)
         */
        for (crtc = 0; (crtc < rdev->num_crtc) && in_vbl; crtc++) {
                if (rdev->pm.active_crtcs & (1 << crtc)) {
-                       vbl_status = radeon_get_crtc_scanoutpos(rdev->ddev, crtc, 0,
+                       vbl_status = radeon_get_crtc_scanoutpos(rdev->ddev,
+                                                               crtc,
+                                                               USE_REAL_VBLANKSTART,
                                                                &vpos, &hpos, NULL, NULL,
                                                                &rdev->mode_info.crtcs[crtc]->base.hwmode);
                        if ((vbl_status & DRM_SCANOUTPOS_VALID) &&
index 574f62bbd215bcf58c125861f7718aaabba7c423..7eb1ae758906142b86f5c7fd1c01dcc50ce74946 100644 (file)
@@ -361,31 +361,31 @@ int radeon_vce_get_create_msg(struct radeon_device *rdev, int ring,
 
        /* stitch together an VCE create msg */
        ib.length_dw = 0;
-       ib.ptr[ib.length_dw++] = 0x0000000c; /* len */
-       ib.ptr[ib.length_dw++] = 0x00000001; /* session cmd */
-       ib.ptr[ib.length_dw++] = handle;
-
-       ib.ptr[ib.length_dw++] = 0x00000030; /* len */
-       ib.ptr[ib.length_dw++] = 0x01000001; /* create cmd */
-       ib.ptr[ib.length_dw++] = 0x00000000;
-       ib.ptr[ib.length_dw++] = 0x00000042;
-       ib.ptr[ib.length_dw++] = 0x0000000a;
-       ib.ptr[ib.length_dw++] = 0x00000001;
-       ib.ptr[ib.length_dw++] = 0x00000080;
-       ib.ptr[ib.length_dw++] = 0x00000060;
-       ib.ptr[ib.length_dw++] = 0x00000100;
-       ib.ptr[ib.length_dw++] = 0x00000100;
-       ib.ptr[ib.length_dw++] = 0x0000000c;
-       ib.ptr[ib.length_dw++] = 0x00000000;
-
-       ib.ptr[ib.length_dw++] = 0x00000014; /* len */
-       ib.ptr[ib.length_dw++] = 0x05000005; /* feedback buffer */
-       ib.ptr[ib.length_dw++] = upper_32_bits(dummy);
-       ib.ptr[ib.length_dw++] = dummy;
-       ib.ptr[ib.length_dw++] = 0x00000001;
+       ib.ptr[ib.length_dw++] = cpu_to_le32(0x0000000c); /* len */
+       ib.ptr[ib.length_dw++] = cpu_to_le32(0x00000001); /* session cmd */
+       ib.ptr[ib.length_dw++] = cpu_to_le32(handle);
+
+       ib.ptr[ib.length_dw++] = cpu_to_le32(0x00000030); /* len */
+       ib.ptr[ib.length_dw++] = cpu_to_le32(0x01000001); /* create cmd */
+       ib.ptr[ib.length_dw++] = cpu_to_le32(0x00000000);
+       ib.ptr[ib.length_dw++] = cpu_to_le32(0x00000042);
+       ib.ptr[ib.length_dw++] = cpu_to_le32(0x0000000a);
+       ib.ptr[ib.length_dw++] = cpu_to_le32(0x00000001);
+       ib.ptr[ib.length_dw++] = cpu_to_le32(0x00000080);
+       ib.ptr[ib.length_dw++] = cpu_to_le32(0x00000060);
+       ib.ptr[ib.length_dw++] = cpu_to_le32(0x00000100);
+       ib.ptr[ib.length_dw++] = cpu_to_le32(0x00000100);
+       ib.ptr[ib.length_dw++] = cpu_to_le32(0x0000000c);
+       ib.ptr[ib.length_dw++] = cpu_to_le32(0x00000000);
+
+       ib.ptr[ib.length_dw++] = cpu_to_le32(0x00000014); /* len */
+       ib.ptr[ib.length_dw++] = cpu_to_le32(0x05000005); /* feedback buffer */
+       ib.ptr[ib.length_dw++] = cpu_to_le32(upper_32_bits(dummy));
+       ib.ptr[ib.length_dw++] = cpu_to_le32(dummy);
+       ib.ptr[ib.length_dw++] = cpu_to_le32(0x00000001);
 
        for (i = ib.length_dw; i < ib_size_dw; ++i)
-               ib.ptr[i] = 0x0;
+               ib.ptr[i] = cpu_to_le32(0x0);
 
        r = radeon_ib_schedule(rdev, &ib, NULL, false);
        if (r) {
@@ -428,21 +428,21 @@ int radeon_vce_get_destroy_msg(struct radeon_device *rdev, int ring,
 
        /* stitch together an VCE destroy msg */
        ib.length_dw = 0;
-       ib.ptr[ib.length_dw++] = 0x0000000c; /* len */
-       ib.ptr[ib.length_dw++] = 0x00000001; /* session cmd */
-       ib.ptr[ib.length_dw++] = handle;
+       ib.ptr[ib.length_dw++] = cpu_to_le32(0x0000000c); /* len */
+       ib.ptr[ib.length_dw++] = cpu_to_le32(0x00000001); /* session cmd */
+       ib.ptr[ib.length_dw++] = cpu_to_le32(handle);
 
-       ib.ptr[ib.length_dw++] = 0x00000014; /* len */
-       ib.ptr[ib.length_dw++] = 0x05000005; /* feedback buffer */
-       ib.ptr[ib.length_dw++] = upper_32_bits(dummy);
-       ib.ptr[ib.length_dw++] = dummy;
-       ib.ptr[ib.length_dw++] = 0x00000001;
+       ib.ptr[ib.length_dw++] = cpu_to_le32(0x00000014); /* len */
+       ib.ptr[ib.length_dw++] = cpu_to_le32(0x05000005); /* feedback buffer */
+       ib.ptr[ib.length_dw++] = cpu_to_le32(upper_32_bits(dummy));
+       ib.ptr[ib.length_dw++] = cpu_to_le32(dummy);
+       ib.ptr[ib.length_dw++] = cpu_to_le32(0x00000001);
 
-       ib.ptr[ib.length_dw++] = 0x00000008; /* len */
-       ib.ptr[ib.length_dw++] = 0x02000001; /* destroy cmd */
+       ib.ptr[ib.length_dw++] = cpu_to_le32(0x00000008); /* len */
+       ib.ptr[ib.length_dw++] = cpu_to_le32(0x02000001); /* destroy cmd */
 
        for (i = ib.length_dw; i < ib_size_dw; ++i)
-               ib.ptr[i] = 0x0;
+               ib.ptr[i] = cpu_to_le32(0x0);
 
        r = radeon_ib_schedule(rdev, &ib, NULL, false);
        if (r) {
@@ -699,12 +699,12 @@ bool radeon_vce_semaphore_emit(struct radeon_device *rdev,
 {
        uint64_t addr = semaphore->gpu_addr;
 
-       radeon_ring_write(ring, VCE_CMD_SEMAPHORE);
-       radeon_ring_write(ring, (addr >> 3) & 0x000FFFFF);
-       radeon_ring_write(ring, (addr >> 23) & 0x000FFFFF);
-       radeon_ring_write(ring, 0x01003000 | (emit_wait ? 1 : 0));
+       radeon_ring_write(ring, cpu_to_le32(VCE_CMD_SEMAPHORE));
+       radeon_ring_write(ring, cpu_to_le32((addr >> 3) & 0x000FFFFF));
+       radeon_ring_write(ring, cpu_to_le32((addr >> 23) & 0x000FFFFF));
+       radeon_ring_write(ring, cpu_to_le32(0x01003000 | (emit_wait ? 1 : 0)));
        if (!emit_wait)
-               radeon_ring_write(ring, VCE_CMD_END);
+               radeon_ring_write(ring, cpu_to_le32(VCE_CMD_END));
 
        return true;
 }
@@ -719,10 +719,10 @@ bool radeon_vce_semaphore_emit(struct radeon_device *rdev,
 void radeon_vce_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib)
 {
        struct radeon_ring *ring = &rdev->ring[ib->ring];
-       radeon_ring_write(ring, VCE_CMD_IB);
-       radeon_ring_write(ring, ib->gpu_addr);
-       radeon_ring_write(ring, upper_32_bits(ib->gpu_addr));
-       radeon_ring_write(ring, ib->length_dw);
+       radeon_ring_write(ring, cpu_to_le32(VCE_CMD_IB));
+       radeon_ring_write(ring, cpu_to_le32(ib->gpu_addr));
+       radeon_ring_write(ring, cpu_to_le32(upper_32_bits(ib->gpu_addr)));
+       radeon_ring_write(ring, cpu_to_le32(ib->length_dw));
 }
 
 /**
@@ -738,12 +738,12 @@ void radeon_vce_fence_emit(struct radeon_device *rdev,
        struct radeon_ring *ring = &rdev->ring[fence->ring];
        uint64_t addr = rdev->fence_drv[fence->ring].gpu_addr;
 
-       radeon_ring_write(ring, VCE_CMD_FENCE);
-       radeon_ring_write(ring, addr);
-       radeon_ring_write(ring, upper_32_bits(addr));
-       radeon_ring_write(ring, fence->seq);
-       radeon_ring_write(ring, VCE_CMD_TRAP);
-       radeon_ring_write(ring, VCE_CMD_END);
+       radeon_ring_write(ring, cpu_to_le32(VCE_CMD_FENCE));
+       radeon_ring_write(ring, cpu_to_le32(addr));
+       radeon_ring_write(ring, cpu_to_le32(upper_32_bits(addr)));
+       radeon_ring_write(ring, cpu_to_le32(fence->seq));
+       radeon_ring_write(ring, cpu_to_le32(VCE_CMD_TRAP));
+       radeon_ring_write(ring, cpu_to_le32(VCE_CMD_END));
 }
 
 /**
@@ -765,7 +765,7 @@ int radeon_vce_ring_test(struct radeon_device *rdev, struct radeon_ring *ring)
                          ring->idx, r);
                return r;
        }
-       radeon_ring_write(ring, VCE_CMD_END);
+       radeon_ring_write(ring, cpu_to_le32(VCE_CMD_END));
        radeon_ring_unlock_commit(rdev, ring, false);
 
        for (i = 0; i < rdev->usec_timeout; i++) {
index 97a904835759f7876b2b69be104493cf302554a7..6244f4e44e9a541d15d5a76ac36beff8822c3145 100644 (file)
@@ -813,7 +813,7 @@ int rs600_irq_process(struct radeon_device *rdev)
                status = rs600_irq_ack(rdev);
        }
        if (queue_hotplug)
-               schedule_work(&rdev->hotplug_work);
+               schedule_delayed_work(&rdev->hotplug_work, 0);
        if (queue_hdmi)
                schedule_work(&rdev->audio_work);
        if (rdev->msi_enabled) {
index 516ca27cfa12847e904bd9f8ecb8047db53bdba5..6bc44c24e837b30e39970f0a74e64eab4be88294 100644 (file)
@@ -207,6 +207,9 @@ void rs690_line_buffer_adjust(struct radeon_device *rdev,
 {
        u32 tmp;
 
+       /* Guess line buffer size to be 8192 pixels */
+       u32 lb_size = 8192;
+
        /*
         * Line Buffer Setup
         * There is a single line buffer shared by both display controllers.
@@ -243,6 +246,13 @@ void rs690_line_buffer_adjust(struct radeon_device *rdev,
                tmp |= V_006520_DC_LB_MEMORY_SPLIT_D1_1Q_D2_3Q;
        }
        WREG32(R_006520_DC_LB_MEMORY_SPLIT, tmp);
+
+       /* Save number of lines the linebuffer leads before the scanout */
+       if (mode1)
+               rdev->mode_info.crtcs[0]->lb_vblank_lead_lines = DIV_ROUND_UP(lb_size, mode1->crtc_hdisplay);
+
+       if (mode2)
+               rdev->mode_info.crtcs[1]->lb_vblank_lead_lines = DIV_ROUND_UP(lb_size, mode2->crtc_hdisplay);
 }
 
 struct rs690_watermark {
index 3f5e1cf138ba46a2b0385f979a67fc4bac98ceee..d37ba2cb886e90f54093ca8069c6732994535b8e 100644 (file)
@@ -464,7 +464,7 @@ void rv730_stop_dpm(struct radeon_device *rdev)
        result = rv770_send_msg_to_smc(rdev, PPSMC_MSG_TwoLevelsDisabled);
 
        if (result != PPSMC_Result_OK)
-               DRM_ERROR("Could not force DPM to low\n");
+               DRM_DEBUG("Could not force DPM to low\n");
 
        WREG32_P(GENERAL_PWRMGT, 0, ~GLOBAL_PWRMGT_EN);
 
index b9c770745a7a1f717cb9c894a6882c090fd8153c..e830c8935db0d9f1a7455a5c4df4c54727241dbc 100644 (file)
@@ -193,7 +193,7 @@ void rv770_stop_dpm(struct radeon_device *rdev)
        result = rv770_send_msg_to_smc(rdev, PPSMC_MSG_TwoLevelsDisabled);
 
        if (result != PPSMC_Result_OK)
-               DRM_ERROR("Could not force DPM to low.\n");
+               DRM_DEBUG("Could not force DPM to low.\n");
 
        WREG32_P(GENERAL_PWRMGT, 0, ~GLOBAL_PWRMGT_EN);
 
@@ -1418,7 +1418,7 @@ int rv770_resume_smc(struct radeon_device *rdev)
 int rv770_set_sw_state(struct radeon_device *rdev)
 {
        if (rv770_send_msg_to_smc(rdev, PPSMC_MSG_SwitchToSwState) != PPSMC_Result_OK)
-               return -EINVAL;
+               DRM_DEBUG("rv770_set_sw_state failed\n");
        return 0;
 }
 
index 07037e32dea327f935ef39e0bdafea8fb640b39a..f878d6962da58b4aed296c22e485846bc14183c4 100644 (file)
@@ -2376,6 +2376,9 @@ static void dce6_program_watermarks(struct radeon_device *rdev,
                c.full = dfixed_div(c, a);
                priority_b_mark = dfixed_trunc(c);
                priority_b_cnt |= priority_b_mark & PRIORITY_MARK_MASK;
+
+               /* Save number of lines the linebuffer leads before the scanout */
+               radeon_crtc->lb_vblank_lead_lines = DIV_ROUND_UP(lb_size, mode->crtc_hdisplay);
        }
 
        /* select wm A */
@@ -6848,7 +6851,7 @@ restart_ih:
        if (queue_dp)
                schedule_work(&rdev->dp_work);
        if (queue_hotplug)
-               schedule_work(&rdev->hotplug_work);
+               schedule_delayed_work(&rdev->hotplug_work, 0);
        if (queue_thermal && rdev->pm.dpm_enabled)
                schedule_work(&rdev->pm.dpm.thermal.work);
        rdev->ih.rptr = rptr;
index 8caea0a33dd84560be30f18b882dc8c4b3daed17..d908321b94ced4ffe10936f4c7ef37fc518d127a 100644 (file)
@@ -67,6 +67,7 @@ static int rockchip_drm_gem_object_mmap(struct drm_gem_object *obj,
         * VM_PFNMAP flag that was set by drm_gem_mmap_obj()/drm_gem_mmap().
         */
        vma->vm_flags &= ~VM_PFNMAP;
+       vma->vm_pgoff = 0;
 
        ret = dma_mmap_attrs(drm->dev, vma, rk_obj->kvaddr, rk_obj->dma_addr,
                             obj->size, &rk_obj->dma_attrs);
index 5d8ae5e49c440f98afda4c02d6aea8e335c78c82..03c47eeadc812ba649e68ad97270d5c512efea86 100644 (file)
@@ -374,6 +374,7 @@ static const struct of_device_id vop_driver_dt_match[] = {
          .data = &rk3288_vop },
        {},
 };
+MODULE_DEVICE_TABLE(of, vop_driver_dt_match);
 
 static inline void vop_writel(struct vop *vop, uint32_t offset, uint32_t v)
 {
@@ -959,8 +960,8 @@ static int vop_update_plane_event(struct drm_plane *plane,
        val = (dest.y2 - dest.y1 - 1) << 16;
        val |= (dest.x2 - dest.x1 - 1) & 0xffff;
        VOP_WIN_SET(vop, win, dsp_info, val);
-       val = (dsp_sty - 1) << 16;
-       val |= (dsp_stx - 1) & 0xffff;
+       val = dsp_sty << 16;
+       val |= dsp_stx & 0xffff;
        VOP_WIN_SET(vop, win, dsp_st, val);
        VOP_WIN_SET(vop, win, rb_swap, rb_swap);
 
@@ -1289,7 +1290,7 @@ static void vop_win_state_complete(struct vop_win *vop_win,
 
        if (state->event) {
                spin_lock_irqsave(&drm->event_lock, flags);
-               drm_send_vblank_event(drm, -1, state->event);
+               drm_crtc_send_vblank_event(crtc, state->event);
                spin_unlock_irqrestore(&drm->event_lock, flags);
        }
 
@@ -1575,32 +1576,25 @@ static int vop_initial(struct vop *vop)
                return PTR_ERR(vop->dclk);
        }
 
-       ret = clk_prepare(vop->hclk);
-       if (ret < 0) {
-               dev_err(vop->dev, "failed to prepare hclk\n");
-               return ret;
-       }
-
        ret = clk_prepare(vop->dclk);
        if (ret < 0) {
                dev_err(vop->dev, "failed to prepare dclk\n");
-               goto err_unprepare_hclk;
+               return ret;
        }
 
-       ret = clk_prepare(vop->aclk);
+       /* Enable both the hclk and aclk to setup the vop */
+       ret = clk_prepare_enable(vop->hclk);
        if (ret < 0) {
-               dev_err(vop->dev, "failed to prepare aclk\n");
+               dev_err(vop->dev, "failed to prepare/enable hclk\n");
                goto err_unprepare_dclk;
        }
 
-       /*
-        * enable hclk, so that we can config vop register.
-        */
-       ret = clk_enable(vop->hclk);
+       ret = clk_prepare_enable(vop->aclk);
        if (ret < 0) {
-               dev_err(vop->dev, "failed to prepare aclk\n");
-               goto err_unprepare_aclk;
+               dev_err(vop->dev, "failed to prepare/enable aclk\n");
+               goto err_disable_hclk;
        }
+
        /*
         * do hclk_reset, reset all vop registers.
         */
@@ -1608,7 +1602,7 @@ static int vop_initial(struct vop *vop)
        if (IS_ERR(ahb_rst)) {
                dev_err(vop->dev, "failed to get ahb reset\n");
                ret = PTR_ERR(ahb_rst);
-               goto err_disable_hclk;
+               goto err_disable_aclk;
        }
        reset_control_assert(ahb_rst);
        usleep_range(10, 20);
@@ -1634,26 +1628,25 @@ static int vop_initial(struct vop *vop)
        if (IS_ERR(vop->dclk_rst)) {
                dev_err(vop->dev, "failed to get dclk reset\n");
                ret = PTR_ERR(vop->dclk_rst);
-               goto err_unprepare_aclk;
+               goto err_disable_aclk;
        }
        reset_control_assert(vop->dclk_rst);
        usleep_range(10, 20);
        reset_control_deassert(vop->dclk_rst);
 
        clk_disable(vop->hclk);
+       clk_disable(vop->aclk);
 
        vop->is_enabled = false;
 
        return 0;
 
+err_disable_aclk:
+       clk_disable_unprepare(vop->aclk);
 err_disable_hclk:
-       clk_disable(vop->hclk);
-err_unprepare_aclk:
-       clk_unprepare(vop->aclk);
+       clk_disable_unprepare(vop->hclk);
 err_unprepare_dclk:
        clk_unprepare(vop->dclk);
-err_unprepare_hclk:
-       clk_unprepare(vop->hclk);
        return ret;
 }
 
index 6a954544727f3f13cfa8d9be0b8ff4cbf39d9367..f154fb1929bd18e300e226d8fe89925b9e8b3754 100644 (file)
@@ -180,7 +180,7 @@ int ttm_write_lock(struct ttm_lock *lock, bool interruptible)
                        spin_unlock(&lock->lock);
                }
        } else
-               wait_event(lock->queue, __ttm_read_lock(lock));
+               wait_event(lock->queue, __ttm_write_lock(lock));
 
        return ret;
 }
index f545913a56c7a972fe71dea32a20972f5440f5fb..578fe0a9324cd9bd710e3d9ef2d393e8311d3cb2 100644 (file)
@@ -412,7 +412,7 @@ static const struct drm_connector_funcs virtio_gpu_connector_funcs = {
        .save = virtio_gpu_conn_save,
        .restore = virtio_gpu_conn_restore,
        .detect = virtio_gpu_conn_detect,
-       .fill_modes = drm_helper_probe_single_connector_modes,
+       .fill_modes = drm_helper_probe_single_connector_modes_nomerge,
        .destroy = virtio_gpu_conn_destroy,
        .reset = drm_atomic_helper_connector_reset,
        .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
index a09cf8529b9f6374649e2f943ef84e3cf08eeda1..c49812b80dd0dae82c77096f75fbd4cced19ffb1 100644 (file)
@@ -1233,6 +1233,7 @@ static void vmw_master_drop(struct drm_device *dev,
 
        vmw_fp->locked_master = drm_master_get(file_priv->master);
        ret = ttm_vt_lock(&vmaster->lock, false, vmw_fp->tfile);
+       vmw_kms_legacy_hotspot_clear(dev_priv);
        if (unlikely((ret != 0))) {
                DRM_ERROR("Unable to lock TTM at VT switch.\n");
                drm_master_put(&vmw_fp->locked_master);
index a8ae9dfb83b7d4916023d9e8e3835da42f0c3979..469cdd520615d036fdb99b0f7e27ed67ce3abd67 100644 (file)
@@ -925,6 +925,7 @@ int vmw_kms_present(struct vmw_private *dev_priv,
                    uint32_t num_clips);
 int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data,
                                struct drm_file *file_priv);
+void vmw_kms_legacy_hotspot_clear(struct vmw_private *dev_priv);
 
 int vmw_dumb_create(struct drm_file *file_priv,
                    struct drm_device *dev,
index a8baf5f5e76558679d128de151d2caaea193bc6c..b6a0806b06bffaf6da9178905f9b2f6bb037d384 100644 (file)
@@ -390,7 +390,7 @@ void *vmw_fifo_reserve_dx(struct vmw_private *dev_priv, uint32_t bytes,
        else if (ctx_id == SVGA3D_INVALID_ID)
                ret = vmw_local_fifo_reserve(dev_priv, bytes);
        else {
-               WARN_ON("Command buffer has not been allocated.\n");
+               WARN(1, "Command buffer has not been allocated.\n");
                ret = NULL;
        }
        if (IS_ERR_OR_NULL(ret)) {
index 9fcd7f82995c3e1a517930cb8a89a23351c55c15..9b4bb9e74d7300793f3ecb1c0feef42085780819 100644 (file)
@@ -133,13 +133,19 @@ void vmw_cursor_update_position(struct vmw_private *dev_priv,
        vmw_mmio_write(++count, fifo_mem + SVGA_FIFO_CURSOR_COUNT);
 }
 
-int vmw_du_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv,
-                          uint32_t handle, uint32_t width, uint32_t height)
+
+/*
+ * vmw_du_crtc_cursor_set2 - Driver cursor_set2 callback.
+ */
+int vmw_du_crtc_cursor_set2(struct drm_crtc *crtc, struct drm_file *file_priv,
+                           uint32_t handle, uint32_t width, uint32_t height,
+                           int32_t hot_x, int32_t hot_y)
 {
        struct vmw_private *dev_priv = vmw_priv(crtc->dev);
        struct vmw_display_unit *du = vmw_crtc_to_du(crtc);
        struct vmw_surface *surface = NULL;
        struct vmw_dma_buffer *dmabuf = NULL;
+       s32 hotspot_x, hotspot_y;
        int ret;
 
        /*
@@ -151,6 +157,8 @@ int vmw_du_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv,
         */
        drm_modeset_unlock_crtc(crtc);
        drm_modeset_lock_all(dev_priv->dev);
+       hotspot_x = hot_x + du->hotspot_x;
+       hotspot_y = hot_y + du->hotspot_y;
 
        /* A lot of the code assumes this */
        if (handle && (width != 64 || height != 64)) {
@@ -187,31 +195,34 @@ int vmw_du_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv,
                vmw_dmabuf_unreference(&du->cursor_dmabuf);
 
        /* setup new image */
+       ret = 0;
        if (surface) {
                /* vmw_user_surface_lookup takes one reference */
                du->cursor_surface = surface;
 
                du->cursor_surface->snooper.crtc = crtc;
                du->cursor_age = du->cursor_surface->snooper.age;
-               vmw_cursor_update_image(dev_priv, surface->snooper.image,
-                                       64, 64, du->hotspot_x, du->hotspot_y);
+               ret = vmw_cursor_update_image(dev_priv, surface->snooper.image,
+                                             64, 64, hotspot_x, hotspot_y);
        } else if (dmabuf) {
                /* vmw_user_surface_lookup takes one reference */
                du->cursor_dmabuf = dmabuf;
 
                ret = vmw_cursor_update_dmabuf(dev_priv, dmabuf, width, height,
-                                              du->hotspot_x, du->hotspot_y);
+                                              hotspot_x, hotspot_y);
        } else {
                vmw_cursor_update_position(dev_priv, false, 0, 0);
-               ret = 0;
                goto out;
        }
 
-       vmw_cursor_update_position(dev_priv, true,
-                                  du->cursor_x + du->hotspot_x,
-                                  du->cursor_y + du->hotspot_y);
+       if (!ret) {
+               vmw_cursor_update_position(dev_priv, true,
+                                          du->cursor_x + hotspot_x,
+                                          du->cursor_y + hotspot_y);
+               du->core_hotspot_x = hot_x;
+               du->core_hotspot_y = hot_y;
+       }
 
-       ret = 0;
 out:
        drm_modeset_unlock_all(dev_priv->dev);
        drm_modeset_lock_crtc(crtc, crtc->cursor);
@@ -239,8 +250,10 @@ int vmw_du_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
        drm_modeset_lock_all(dev_priv->dev);
 
        vmw_cursor_update_position(dev_priv, shown,
-                                  du->cursor_x + du->hotspot_x,
-                                  du->cursor_y + du->hotspot_y);
+                                  du->cursor_x + du->hotspot_x +
+                                  du->core_hotspot_x,
+                                  du->cursor_y + du->hotspot_y +
+                                  du->core_hotspot_y);
 
        drm_modeset_unlock_all(dev_priv->dev);
        drm_modeset_lock_crtc(crtc, crtc->cursor);
@@ -334,6 +347,29 @@ err_unreserve:
        ttm_bo_unreserve(bo);
 }
 
+/**
+ * vmw_kms_legacy_hotspot_clear - Clear legacy hotspots
+ *
+ * @dev_priv: Pointer to the device private struct.
+ *
+ * Clears all legacy hotspots.
+ */
+void vmw_kms_legacy_hotspot_clear(struct vmw_private *dev_priv)
+{
+       struct drm_device *dev = dev_priv->dev;
+       struct vmw_display_unit *du;
+       struct drm_crtc *crtc;
+
+       drm_modeset_lock_all(dev);
+       drm_for_each_crtc(crtc, dev) {
+               du = vmw_crtc_to_du(crtc);
+
+               du->hotspot_x = 0;
+               du->hotspot_y = 0;
+       }
+       drm_modeset_unlock_all(dev);
+}
+
 void vmw_kms_cursor_post_execbuf(struct vmw_private *dev_priv)
 {
        struct drm_device *dev = dev_priv->dev;
@@ -351,7 +387,9 @@ void vmw_kms_cursor_post_execbuf(struct vmw_private *dev_priv)
                du->cursor_age = du->cursor_surface->snooper.age;
                vmw_cursor_update_image(dev_priv,
                                        du->cursor_surface->snooper.image,
-                                       64, 64, du->hotspot_x, du->hotspot_y);
+                                       64, 64,
+                                       du->hotspot_x + du->core_hotspot_x,
+                                       du->hotspot_y + du->core_hotspot_y);
        }
 
        mutex_unlock(&dev->mode_config.mutex);
index 782df7ca97946220414dd66a2afbe4f94b6d403a..edd81503516dbbda1fab84ecd53ecc0df689f24e 100644 (file)
@@ -159,6 +159,8 @@ struct vmw_display_unit {
 
        int hotspot_x;
        int hotspot_y;
+       s32 core_hotspot_x;
+       s32 core_hotspot_y;
 
        unsigned unit;
 
@@ -193,8 +195,9 @@ void vmw_du_crtc_restore(struct drm_crtc *crtc);
 void vmw_du_crtc_gamma_set(struct drm_crtc *crtc,
                           u16 *r, u16 *g, u16 *b,
                           uint32_t start, uint32_t size);
-int vmw_du_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv,
-                          uint32_t handle, uint32_t width, uint32_t height);
+int vmw_du_crtc_cursor_set2(struct drm_crtc *crtc, struct drm_file *file_priv,
+                           uint32_t handle, uint32_t width, uint32_t height,
+                           int32_t hot_x, int32_t hot_y);
 int vmw_du_crtc_cursor_move(struct drm_crtc *crtc, int x, int y);
 int vmw_du_connector_dpms(struct drm_connector *connector, int mode);
 void vmw_du_connector_save(struct drm_connector *connector);
index bb63e4d795fae43bc07599babe45bedf26f6e114..52caecb4502ed3086b8ea6e15fac9e45a08d4659 100644 (file)
@@ -297,7 +297,7 @@ static int vmw_ldu_crtc_set_config(struct drm_mode_set *set)
 static struct drm_crtc_funcs vmw_legacy_crtc_funcs = {
        .save = vmw_du_crtc_save,
        .restore = vmw_du_crtc_restore,
-       .cursor_set = vmw_du_crtc_cursor_set,
+       .cursor_set2 = vmw_du_crtc_cursor_set2,
        .cursor_move = vmw_du_crtc_cursor_move,
        .gamma_set = vmw_du_crtc_gamma_set,
        .destroy = vmw_ldu_crtc_destroy,
index b96d1ab610c5527fb190ea476cdbbb82a2b2e158..13926ff192e3d6ce55b0e741ef66a04c9377596b 100644 (file)
@@ -533,7 +533,7 @@ out_no_fence:
 static struct drm_crtc_funcs vmw_screen_object_crtc_funcs = {
        .save = vmw_du_crtc_save,
        .restore = vmw_du_crtc_restore,
-       .cursor_set = vmw_du_crtc_cursor_set,
+       .cursor_set2 = vmw_du_crtc_cursor_set2,
        .cursor_move = vmw_du_crtc_cursor_move,
        .gamma_set = vmw_du_crtc_gamma_set,
        .destroy = vmw_sou_crtc_destroy,
index b1fc1c02792d4c3f89cb76a0dfb0f16f3dce2c47..f823fc3efed72473108acab83d65191a00e40e9a 100644 (file)
@@ -1043,7 +1043,7 @@ out_finish:
 static struct drm_crtc_funcs vmw_stdu_crtc_funcs = {
        .save = vmw_du_crtc_save,
        .restore = vmw_du_crtc_restore,
-       .cursor_set = vmw_du_crtc_cursor_set,
+       .cursor_set2 = vmw_du_crtc_cursor_set2,
        .cursor_move = vmw_du_crtc_cursor_move,
        .gamma_set = vmw_du_crtc_gamma_set,
        .destroy = vmw_stdu_crtc_destroy,
index ba47b30d28fad4f3d187393a44a17bd9605f6ad4..f2e13eb8339ffc1287110e247e0e54e922b7d72a 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/irqchip/chained_irq.h>
 #include <linux/irqdomain.h>
 #include <linux/of_device.h>
+#include <linux/of_graph.h>
 
 #include <drm/drm_fourcc.h>
 
@@ -993,11 +994,25 @@ static void platform_device_unregister_children(struct platform_device *pdev)
 struct ipu_platform_reg {
        struct ipu_client_platformdata pdata;
        const char *name;
-       int reg_offset;
 };
 
+/* These must be in the order of the corresponding device tree port nodes */
 static const struct ipu_platform_reg client_reg[] = {
        {
+               .pdata = {
+                       .csi = 0,
+                       .dma[0] = IPUV3_CHANNEL_CSI0,
+                       .dma[1] = -EINVAL,
+               },
+               .name = "imx-ipuv3-camera",
+       }, {
+               .pdata = {
+                       .csi = 1,
+                       .dma[0] = IPUV3_CHANNEL_CSI1,
+                       .dma[1] = -EINVAL,
+               },
+               .name = "imx-ipuv3-camera",
+       }, {
                .pdata = {
                        .di = 0,
                        .dc = 5,
@@ -1015,22 +1030,6 @@ static const struct ipu_platform_reg client_reg[] = {
                        .dma[1] = -EINVAL,
                },
                .name = "imx-ipuv3-crtc",
-       }, {
-               .pdata = {
-                       .csi = 0,
-                       .dma[0] = IPUV3_CHANNEL_CSI0,
-                       .dma[1] = -EINVAL,
-               },
-               .reg_offset = IPU_CM_CSI0_REG_OFS,
-               .name = "imx-ipuv3-camera",
-       }, {
-               .pdata = {
-                       .csi = 1,
-                       .dma[0] = IPUV3_CHANNEL_CSI1,
-                       .dma[1] = -EINVAL,
-               },
-               .reg_offset = IPU_CM_CSI1_REG_OFS,
-               .name = "imx-ipuv3-camera",
        },
 };
 
@@ -1051,22 +1050,30 @@ static int ipu_add_client_devices(struct ipu_soc *ipu, unsigned long ipu_base)
        for (i = 0; i < ARRAY_SIZE(client_reg); i++) {
                const struct ipu_platform_reg *reg = &client_reg[i];
                struct platform_device *pdev;
-               struct resource res;
-
-               if (reg->reg_offset) {
-                       memset(&res, 0, sizeof(res));
-                       res.flags = IORESOURCE_MEM;
-                       res.start = ipu_base + ipu->devtype->cm_ofs + reg->reg_offset;
-                       res.end = res.start + PAGE_SIZE - 1;
-                       pdev = platform_device_register_resndata(dev, reg->name,
-                               id++, &res, 1, &reg->pdata, sizeof(reg->pdata));
-               } else {
-                       pdev = platform_device_register_data(dev, reg->name,
-                               id++, &reg->pdata, sizeof(reg->pdata));
+
+               pdev = platform_device_alloc(reg->name, id++);
+               if (!pdev) {
+                       ret = -ENOMEM;
+                       goto err_register;
+               }
+
+               pdev->dev.parent = dev;
+
+               /* Associate subdevice with the corresponding port node */
+               pdev->dev.of_node = of_graph_get_port_by_id(dev->of_node, i);
+               if (!pdev->dev.of_node) {
+                       dev_err(dev, "missing port@%d node in %s\n", i,
+                               dev->of_node->full_name);
+                       ret = -ENODEV;
+                       goto err_register;
                }
 
-               if (IS_ERR(pdev)) {
-                       ret = PTR_ERR(pdev);
+               ret = platform_device_add_data(pdev, &reg->pdata,
+                                              sizeof(reg->pdata));
+               if (!ret)
+                       ret = platform_device_add(pdev);
+               if (ret) {
+                       platform_device_put(pdev);
                        goto err_register;
                }
        }
index 3166e4bc4eb6daea9a9fcad4eb5fce4b62b1b418..9abcaa53bd25a4149e850562628bdc17e81161ed 100644 (file)
@@ -395,8 +395,10 @@ int vga_get(struct pci_dev *pdev, unsigned int rsrc, int interruptible)
                set_current_state(interruptible ?
                                  TASK_INTERRUPTIBLE :
                                  TASK_UNINTERRUPTIBLE);
-               if (signal_pending(current)) {
-                       rc = -EINTR;
+               if (interruptible && signal_pending(current)) {
+                       __set_current_state(TASK_RUNNING);
+                       remove_wait_queue(&vga_wait_queue, &wait);
+                       rc = -ERESTARTSYS;
                        break;
                }
                schedule();
index ac1feea51be365e3a4c81042b56be75fec26a6a1..8b78a7f1f779faa586abd156a0f9ce7082616bc5 100644 (file)
 #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_A001      0xa001
 
 #define USB_VENDOR_ID_ELAN             0x04f3
-#define USB_DEVICE_ID_ELAN_TOUCHSCREEN 0x0089
-#define USB_DEVICE_ID_ELAN_TOUCHSCREEN_009B    0x009b
-#define USB_DEVICE_ID_ELAN_TOUCHSCREEN_0103    0x0103
-#define USB_DEVICE_ID_ELAN_TOUCHSCREEN_010c    0x010c
-#define USB_DEVICE_ID_ELAN_TOUCHSCREEN_016F    0x016f
 
 #define USB_VENDOR_ID_ELECOM           0x056e
 #define USB_DEVICE_ID_ELECOM_BM084     0x0061
 #define USB_DEVICE_ID_LOGITECH_HARMONY_FIRST  0xc110
 #define USB_DEVICE_ID_LOGITECH_HARMONY_LAST 0xc14f
 #define USB_DEVICE_ID_LOGITECH_HARMONY_PS3 0x0306
+#define USB_DEVICE_ID_LOGITECH_KEYBOARD_G710_PLUS 0xc24d
 #define USB_DEVICE_ID_LOGITECH_MOUSE_C01A      0xc01a
 #define USB_DEVICE_ID_LOGITECH_MOUSE_C05A      0xc05a
 #define USB_DEVICE_ID_LOGITECH_MOUSE_C06A      0xc06a
index c20ac76c0a8cb28ebbc8ea75827f3cfba5e2a787..c690fae02cf823d16b6d985d944b6bda143b6282 100644 (file)
@@ -665,8 +665,9 @@ static int lg_probe(struct hid_device *hdev, const struct hid_device_id *id)
        struct lg_drv_data *drv_data;
        int ret;
 
-       /* Only work with the 1st interface (G29 presents multiple) */
-       if (iface_num != 0) {
+       /* G29 only work with the 1st interface */
+       if ((hdev->product == USB_DEVICE_ID_LOGITECH_G29_WHEEL) &&
+           (iface_num != 0)) {
                dbg_hid("%s: ignoring ifnum %d\n", __func__, iface_num);
                return -ENODEV;
        }
index 94bb137abe3281bfb023c7bc438ad8bcf0d716a4..7dd0953cd70f222f037c72b7c217b76eff8d2942 100644 (file)
@@ -72,11 +72,7 @@ static const struct hid_blacklist {
        { USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_PIXART_USB_OPTICAL_MOUSE, HID_QUIRK_ALWAYS_POLL },
        { USB_VENDOR_ID_DMI, USB_DEVICE_ID_DMI_ENC, HID_QUIRK_NOGET },
        { USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_WIIU, HID_QUIRK_MULTI_INPUT },
-       { USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ELAN_TOUCHSCREEN, HID_QUIRK_ALWAYS_POLL },
-       { USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ELAN_TOUCHSCREEN_009B, HID_QUIRK_ALWAYS_POLL },
-       { USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ELAN_TOUCHSCREEN_0103, HID_QUIRK_ALWAYS_POLL },
-       { USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ELAN_TOUCHSCREEN_010c, HID_QUIRK_ALWAYS_POLL },
-       { USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ELAN_TOUCHSCREEN_016F, HID_QUIRK_ALWAYS_POLL },
+       { USB_VENDOR_ID_ELAN, HID_ANY_ID, HID_QUIRK_ALWAYS_POLL },
        { USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2700, HID_QUIRK_NOGET },
        { USB_VENDOR_ID_FORMOSA, USB_DEVICE_ID_FORMOSA_IR_RECEIVER, HID_QUIRK_NO_INIT_REPORTS },
        { USB_VENDOR_ID_FREESCALE, USB_DEVICE_ID_FREESCALE_MX28, HID_QUIRK_NOGET },
@@ -84,6 +80,7 @@ static const struct hid_blacklist {
        { USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0B4A, HID_QUIRK_ALWAYS_POLL },
        { USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE, HID_QUIRK_ALWAYS_POLL },
        { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_C077, HID_QUIRK_ALWAYS_POLL },
+       { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_KEYBOARD_G710_PLUS, HID_QUIRK_NOGET },
        { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_C01A, HID_QUIRK_ALWAYS_POLL },
        { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_C05A, HID_QUIRK_ALWAYS_POLL },
        { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_C06A, HID_QUIRK_ALWAYS_POLL },
@@ -339,7 +336,8 @@ static const struct hid_blacklist *usbhid_exists_squirk(const u16 idVendor,
 
        for (; hid_blacklist[n].idVendor; n++)
                if (hid_blacklist[n].idVendor == idVendor &&
-                               hid_blacklist[n].idProduct == idProduct)
+                       (hid_blacklist[n].idProduct == (__u16) HID_ANY_ID ||
+                               hid_blacklist[n].idProduct == idProduct))
                        bl_entry = &hid_blacklist[n];
 
        if (bl_entry != NULL)
index 0c4618b4d51549cb7bfe8fead1e3ce61c1882366..c2babe50a0d8f59464f8b77837132192e70e3726 100644 (file)
@@ -839,8 +839,10 @@ static int vadc_get_dt_data(struct vadc_priv *vadc, struct device_node *node)
 
        for_each_available_child_of_node(node, child) {
                ret = vadc_get_dt_channel_data(vadc->dev, &prop, child);
-               if (ret)
+               if (ret) {
+                       of_node_put(child);
                        return ret;
+               }
 
                vadc->chan_props[index] = prop;
 
index bfbf1c56bd22630e19ac739eadd514157071ab2b..6eb600ff70569ef6ceb902afcc49ddce08b09953 100644 (file)
@@ -159,7 +159,7 @@ static irqreturn_t iio_simple_dummy_get_timestamp(int irq, void *private)
        struct iio_dummy_state *st = iio_priv(indio_dev);
 
        st->event_timestamp = iio_get_time_ns();
-       return IRQ_HANDLED;
+       return IRQ_WAKE_THREAD;
 }
 
 /**
index a4b164a478c434c92927b28567d2f17f788f78cb..139ae916225f10b2b3293aebd7efeffa23961ac1 100644 (file)
@@ -303,7 +303,7 @@ static int iio_scan_mask_set(struct iio_dev *indio_dev,
        if (trialmask == NULL)
                return -ENOMEM;
        if (!indio_dev->masklength) {
-               WARN_ON("Trying to set scanmask prior to registering buffer\n");
+               WARN(1, "Trying to set scanmask prior to registering buffer\n");
                goto err_invalid_mask;
        }
        bitmap_copy(trialmask, buffer->scan_mask, indio_dev->masklength);
index a45eb2c53d0fd1c35550098fc221fdf7d850d6fe..fd01f3493fc7792792d015c604903197ba506073 100644 (file)
@@ -665,7 +665,7 @@ int __iio_device_attr_init(struct device_attribute *dev_attr,
                        break;
                case IIO_SEPARATE:
                        if (!chan->indexed) {
-                               WARN_ON("Differential channels must be indexed\n");
+                               WARN(1, "Differential channels must be indexed\n");
                                ret = -EINVAL;
                                goto error_free_full_postfix;
                        }
index 7d269ef9e0625a81cdf1832c53667e9ed1039f18..f6a07dc32ae486a045b97cfb4406783a9aa05ab8 100644 (file)
@@ -453,6 +453,7 @@ static int apds9960_set_power_state(struct apds9960_data *data, bool on)
                        usleep_range(data->als_adc_int_us,
                                     APDS9960_MAX_INT_TIME_IN_US);
        } else {
+               pm_runtime_mark_last_busy(dev);
                ret = pm_runtime_put_autosuspend(dev);
        }
 
index e7ea44d61942e2669805a2f30444ef6bb4251bf3..93e29fb67fa00f94e9ca0a614addfc5cde7ebb76 100644 (file)
@@ -176,10 +176,10 @@ static int lidar_get_measurement(struct lidar_data *data, u16 *reg)
                if (ret < 0)
                        break;
 
-               /* return 0 since laser is likely pointed out of range */
+               /* return -EINVAL since laser is likely pointed out of range */
                if (ret & LIDAR_REG_STATUS_INVALID) {
                        *reg = 0;
-                       ret = 0;
+                       ret = -EINVAL;
                        break;
                }
 
@@ -245,7 +245,7 @@ static irqreturn_t lidar_trigger_handler(int irq, void *private)
        if (!ret) {
                iio_push_to_buffers_with_timestamp(indio_dev, data->buffer,
                                                   iio_get_time_ns());
-       } else {
+       } else if (ret != -EINVAL) {
                dev_err(&data->client->dev, "cannot read LIDAR measurement");
        }
 
index 944cd90417bcc9b2a51d27f903feffad6f2307ea..d2d5d004f16dbb11fc4a57b5ce47004da567a137 100644 (file)
@@ -1126,10 +1126,7 @@ static bool validate_ipv4_net_dev(struct net_device *net_dev,
 
        rcu_read_lock();
        err = fib_lookup(dev_net(net_dev), &fl4, &res, 0);
-       if (err)
-               return false;
-
-       ret = FIB_RES_DEV(res) == net_dev;
+       ret = err == 0 && FIB_RES_DEV(res) == net_dev;
        rcu_read_unlock();
 
        return ret;
index 8d8af7a41a30fae4ceb520ce0d11b6f541905c96..2281de122038e45a5c375f7d7669111ab2aee2de 100644 (file)
@@ -1811,6 +1811,11 @@ static int validate_mad(const struct ib_mad_hdr *mad_hdr,
                if (qp_num == 0)
                        valid = 1;
        } else {
+               /* CM attributes other than ClassPortInfo only use Send method */
+               if ((mad_hdr->mgmt_class == IB_MGMT_CLASS_CM) &&
+                   (mad_hdr->attr_id != IB_MGMT_CLASSPORTINFO_ATTR_ID) &&
+                   (mad_hdr->method != IB_MGMT_METHOD_SEND))
+                       goto out;
                /* Filter GSI packets sent to QP0 */
                if (qp_num != 0)
                        valid = 1;
index 2aba774f835b9caca8e9e1645d1efd6cf6f08bf9..a95a32ba596edc03728cf7790a6752c951cde951 100644 (file)
@@ -512,7 +512,7 @@ static int ib_nl_get_path_rec_attrs_len(ib_sa_comp_mask comp_mask)
        return len;
 }
 
-static int ib_nl_send_msg(struct ib_sa_query *query)
+static int ib_nl_send_msg(struct ib_sa_query *query, gfp_t gfp_mask)
 {
        struct sk_buff *skb = NULL;
        struct nlmsghdr *nlh;
@@ -526,7 +526,7 @@ static int ib_nl_send_msg(struct ib_sa_query *query)
        if (len <= 0)
                return -EMSGSIZE;
 
-       skb = nlmsg_new(len, GFP_KERNEL);
+       skb = nlmsg_new(len, gfp_mask);
        if (!skb)
                return -ENOMEM;
 
@@ -544,7 +544,7 @@ static int ib_nl_send_msg(struct ib_sa_query *query)
        /* Repair the nlmsg header length */
        nlmsg_end(skb, nlh);
 
-       ret = ibnl_multicast(skb, nlh, RDMA_NL_GROUP_LS, GFP_KERNEL);
+       ret = ibnl_multicast(skb, nlh, RDMA_NL_GROUP_LS, gfp_mask);
        if (!ret)
                ret = len;
        else
@@ -553,7 +553,7 @@ static int ib_nl_send_msg(struct ib_sa_query *query)
        return ret;
 }
 
-static int ib_nl_make_request(struct ib_sa_query *query)
+static int ib_nl_make_request(struct ib_sa_query *query, gfp_t gfp_mask)
 {
        unsigned long flags;
        unsigned long delay;
@@ -562,25 +562,27 @@ static int ib_nl_make_request(struct ib_sa_query *query)
        INIT_LIST_HEAD(&query->list);
        query->seq = (u32)atomic_inc_return(&ib_nl_sa_request_seq);
 
+       /* Put the request on the list first.*/
        spin_lock_irqsave(&ib_nl_request_lock, flags);
-       ret = ib_nl_send_msg(query);
-       if (ret <= 0) {
-               ret = -EIO;
-               goto request_out;
-       } else {
-               ret = 0;
-       }
-
        delay = msecs_to_jiffies(sa_local_svc_timeout_ms);
        query->timeout = delay + jiffies;
        list_add_tail(&query->list, &ib_nl_request_list);
        /* Start the timeout if this is the only request */
        if (ib_nl_request_list.next == &query->list)
                queue_delayed_work(ib_nl_wq, &ib_nl_timed_work, delay);
-
-request_out:
        spin_unlock_irqrestore(&ib_nl_request_lock, flags);
 
+       ret = ib_nl_send_msg(query, gfp_mask);
+       if (ret <= 0) {
+               ret = -EIO;
+               /* Remove the request */
+               spin_lock_irqsave(&ib_nl_request_lock, flags);
+               list_del(&query->list);
+               spin_unlock_irqrestore(&ib_nl_request_lock, flags);
+       } else {
+               ret = 0;
+       }
+
        return ret;
 }
 
@@ -1108,7 +1110,7 @@ static int send_mad(struct ib_sa_query *query, int timeout_ms, gfp_t gfp_mask)
 
        if (query->flags & IB_SA_ENABLE_LOCAL_SERVICE) {
                if (!ibnl_chk_listeners(RDMA_NL_GROUP_LS)) {
-                       if (!ib_nl_make_request(query))
+                       if (!ib_nl_make_request(query, gfp_mask))
                                return id;
                }
                ib_sa_disable_local_svc(query);
index 94816aeb95a0a186760fbe98de55edc69266a54c..1c02deab068fbf1031d5b21db960feb9b06865c5 100644 (file)
@@ -62,9 +62,11 @@ static struct uverbs_lock_class rule_lock_class = { .name = "RULE-uobj" };
  * The ib_uobject locking scheme is as follows:
  *
  * - ib_uverbs_idr_lock protects the uverbs idrs themselves, so it
- *   needs to be held during all idr operations.  When an object is
+ *   needs to be held during all idr write operations.  When an object is
  *   looked up, a reference must be taken on the object's kref before
- *   dropping this lock.
+ *   dropping this lock.  For read operations, the rcu_read_lock()
+ *   and rcu_write_lock() but similarly the kref reference is grabbed
+ *   before the rcu_read_unlock().
  *
  * - Each object also has an rwsem.  This rwsem must be held for
  *   reading while an operation that uses the object is performed.
@@ -96,7 +98,7 @@ static void init_uobj(struct ib_uobject *uobj, u64 user_handle,
 
 static void release_uobj(struct kref *kref)
 {
-       kfree(container_of(kref, struct ib_uobject, ref));
+       kfree_rcu(container_of(kref, struct ib_uobject, ref), rcu);
 }
 
 static void put_uobj(struct ib_uobject *uobj)
@@ -145,7 +147,7 @@ static struct ib_uobject *__idr_get_uobj(struct idr *idr, int id,
 {
        struct ib_uobject *uobj;
 
-       spin_lock(&ib_uverbs_idr_lock);
+       rcu_read_lock();
        uobj = idr_find(idr, id);
        if (uobj) {
                if (uobj->context == context)
@@ -153,7 +155,7 @@ static struct ib_uobject *__idr_get_uobj(struct idr *idr, int id,
                else
                        uobj = NULL;
        }
-       spin_unlock(&ib_uverbs_idr_lock);
+       rcu_read_unlock();
 
        return uobj;
 }
@@ -2446,6 +2448,7 @@ ssize_t ib_uverbs_post_send(struct ib_uverbs_file *file,
        int                             i, sg_ind;
        int                             is_ud;
        ssize_t                         ret = -EINVAL;
+       size_t                          next_size;
 
        if (copy_from_user(&cmd, buf, sizeof cmd))
                return -EFAULT;
@@ -2490,7 +2493,8 @@ ssize_t ib_uverbs_post_send(struct ib_uverbs_file *file,
                                goto out_put;
                        }
 
-                       ud = alloc_wr(sizeof(*ud), user_wr->num_sge);
+                       next_size = sizeof(*ud);
+                       ud = alloc_wr(next_size, user_wr->num_sge);
                        if (!ud) {
                                ret = -ENOMEM;
                                goto out_put;
@@ -2511,7 +2515,8 @@ ssize_t ib_uverbs_post_send(struct ib_uverbs_file *file,
                           user_wr->opcode == IB_WR_RDMA_READ) {
                        struct ib_rdma_wr *rdma;
 
-                       rdma = alloc_wr(sizeof(*rdma), user_wr->num_sge);
+                       next_size = sizeof(*rdma);
+                       rdma = alloc_wr(next_size, user_wr->num_sge);
                        if (!rdma) {
                                ret = -ENOMEM;
                                goto out_put;
@@ -2525,7 +2530,8 @@ ssize_t ib_uverbs_post_send(struct ib_uverbs_file *file,
                           user_wr->opcode == IB_WR_ATOMIC_FETCH_AND_ADD) {
                        struct ib_atomic_wr *atomic;
 
-                       atomic = alloc_wr(sizeof(*atomic), user_wr->num_sge);
+                       next_size = sizeof(*atomic);
+                       atomic = alloc_wr(next_size, user_wr->num_sge);
                        if (!atomic) {
                                ret = -ENOMEM;
                                goto out_put;
@@ -2540,7 +2546,8 @@ ssize_t ib_uverbs_post_send(struct ib_uverbs_file *file,
                } else if (user_wr->opcode == IB_WR_SEND ||
                           user_wr->opcode == IB_WR_SEND_WITH_IMM ||
                           user_wr->opcode == IB_WR_SEND_WITH_INV) {
-                       next = alloc_wr(sizeof(*next), user_wr->num_sge);
+                       next_size = sizeof(*next);
+                       next = alloc_wr(next_size, user_wr->num_sge);
                        if (!next) {
                                ret = -ENOMEM;
                                goto out_put;
@@ -2572,7 +2579,7 @@ ssize_t ib_uverbs_post_send(struct ib_uverbs_file *file,
 
                if (next->num_sge) {
                        next->sg_list = (void *) next +
-                               ALIGN(sizeof *next, sizeof (struct ib_sge));
+                               ALIGN(next_size, sizeof(struct ib_sge));
                        if (copy_from_user(next->sg_list,
                                           buf + sizeof cmd +
                                           cmd.wr_count * cmd.wqe_size +
index 043a60ee6836db72e498410ebd80e004ed220c7d..545906dec26dc5e936df37c635c68b94bb27e226 100644 (file)
@@ -1516,7 +1516,7 @@ EXPORT_SYMBOL(ib_map_mr_sg);
  * @sg_nents:      number of entries in sg
  * @set_page:      driver page assignment function pointer
  *
- * Core service helper for drivers to covert the largest
+ * Core service helper for drivers to convert the largest
  * prefix of given sg list to a page vector. The sg list
  * prefix converted is the prefix that meet the requirements
  * of ib_map_mr_sg.
@@ -1533,7 +1533,7 @@ int ib_sg_to_pages(struct ib_mr *mr,
        u64 last_end_dma_addr = 0, last_page_addr = 0;
        unsigned int last_page_off = 0;
        u64 page_mask = ~((u64)mr->page_size - 1);
-       int i;
+       int i, ret;
 
        mr->iova = sg_dma_address(&sgl[0]);
        mr->length = 0;
@@ -1544,27 +1544,29 @@ int ib_sg_to_pages(struct ib_mr *mr,
                u64 end_dma_addr = dma_addr + dma_len;
                u64 page_addr = dma_addr & page_mask;
 
-               if (i && page_addr != dma_addr) {
-                       if (last_end_dma_addr != dma_addr) {
-                               /* gap */
-                               goto done;
-
-                       } else if (last_page_off + dma_len <= mr->page_size) {
-                               /* chunk this fragment with the last */
-                               mr->length += dma_len;
-                               last_end_dma_addr += dma_len;
-                               last_page_off += dma_len;
-                               continue;
-                       } else {
-                               /* map starting from the next page */
-                               page_addr = last_page_addr + mr->page_size;
-                               dma_len -= mr->page_size - last_page_off;
-                       }
+               /*
+                * For the second and later elements, check whether either the
+                * end of element i-1 or the start of element i is not aligned
+                * on a page boundary.
+                */
+               if (i && (last_page_off != 0 || page_addr != dma_addr)) {
+                       /* Stop mapping if there is a gap. */
+                       if (last_end_dma_addr != dma_addr)
+                               break;
+
+                       /*
+                        * Coalesce this element with the last. If it is small
+                        * enough just update mr->length. Otherwise start
+                        * mapping from the next page.
+                        */
+                       goto next_page;
                }
 
                do {
-                       if (unlikely(set_page(mr, page_addr)))
-                               goto done;
+                       ret = set_page(mr, page_addr);
+                       if (unlikely(ret < 0))
+                               return i ? : ret;
+next_page:
                        page_addr += mr->page_size;
                } while (page_addr < end_dma_addr);
 
@@ -1574,7 +1576,6 @@ int ib_sg_to_pages(struct ib_mr *mr,
                last_page_off = end_dma_addr & ~page_mask;
        }
 
-done:
        return i;
 }
 EXPORT_SYMBOL(ib_sg_to_pages);
index f567160a4a56ed141320b2d153d21f2031cbb464..97d6878f993828085a0f26f941572674ce68b967 100644 (file)
@@ -456,7 +456,7 @@ static int mlx4_ib_query_device(struct ib_device *ibdev,
        props->max_qp_wr           = dev->dev->caps.max_wqes - MLX4_IB_SQ_MAX_SPARE;
        props->max_sge             = min(dev->dev->caps.max_sq_sg,
                                         dev->dev->caps.max_rq_sg);
-       props->max_sge_rd = props->max_sge;
+       props->max_sge_rd          = MLX4_MAX_SGE_RD;
        props->max_cq              = dev->dev->quotas.cq;
        props->max_cqe             = dev->dev->caps.max_cqes;
        props->max_mr              = dev->dev->quotas.mpt;
index a2e4ca56da44e5d9cec5ee4b6a02cf6ab9d7356c..13eaaf45288f80d4bb6658d5a18985a978e8c98d 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/log2.h>
 #include <linux/slab.h>
 #include <linux/netdevice.h>
+#include <linux/vmalloc.h>
 
 #include <rdma/ib_cache.h>
 #include <rdma/ib_pack.h>
@@ -795,8 +796,14 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd,
                if (err)
                        goto err_mtt;
 
-               qp->sq.wrid  = kmalloc(qp->sq.wqe_cnt * sizeof (u64), gfp);
-               qp->rq.wrid  = kmalloc(qp->rq.wqe_cnt * sizeof (u64), gfp);
+               qp->sq.wrid = kmalloc(qp->sq.wqe_cnt * sizeof(u64), gfp);
+               if (!qp->sq.wrid)
+                       qp->sq.wrid = __vmalloc(qp->sq.wqe_cnt * sizeof(u64),
+                                               gfp, PAGE_KERNEL);
+               qp->rq.wrid = kmalloc(qp->rq.wqe_cnt * sizeof(u64), gfp);
+               if (!qp->rq.wrid)
+                       qp->rq.wrid = __vmalloc(qp->rq.wqe_cnt * sizeof(u64),
+                                               gfp, PAGE_KERNEL);
                if (!qp->sq.wrid || !qp->rq.wrid) {
                        err = -ENOMEM;
                        goto err_wrid;
@@ -886,8 +893,8 @@ err_wrid:
                if (qp_has_rq(init_attr))
                        mlx4_ib_db_unmap_user(to_mucontext(pd->uobject->context), &qp->db);
        } else {
-               kfree(qp->sq.wrid);
-               kfree(qp->rq.wrid);
+               kvfree(qp->sq.wrid);
+               kvfree(qp->rq.wrid);
        }
 
 err_mtt:
@@ -1062,8 +1069,8 @@ static void destroy_qp_common(struct mlx4_ib_dev *dev, struct mlx4_ib_qp *qp,
                                              &qp->db);
                ib_umem_release(qp->umem);
        } else {
-               kfree(qp->sq.wrid);
-               kfree(qp->rq.wrid);
+               kvfree(qp->sq.wrid);
+               kvfree(qp->rq.wrid);
                if (qp->mlx4_ib_qp_type & (MLX4_IB_QPT_PROXY_SMI_OWNER |
                    MLX4_IB_QPT_PROXY_SMI | MLX4_IB_QPT_PROXY_GSI))
                        free_proxy_bufs(&dev->ib_dev, qp);
index dce5dfe3a70ea957a6780eca47e0c15e0d054300..8d133c40fa0e56c658eb096c11971073b846574a 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/mlx4/qp.h>
 #include <linux/mlx4/srq.h>
 #include <linux/slab.h>
+#include <linux/vmalloc.h>
 
 #include "mlx4_ib.h"
 #include "user.h"
@@ -172,8 +173,12 @@ struct ib_srq *mlx4_ib_create_srq(struct ib_pd *pd,
 
                srq->wrid = kmalloc(srq->msrq.max * sizeof (u64), GFP_KERNEL);
                if (!srq->wrid) {
-                       err = -ENOMEM;
-                       goto err_mtt;
+                       srq->wrid = __vmalloc(srq->msrq.max * sizeof(u64),
+                                             GFP_KERNEL, PAGE_KERNEL);
+                       if (!srq->wrid) {
+                               err = -ENOMEM;
+                               goto err_mtt;
+                       }
                }
        }
 
@@ -204,7 +209,7 @@ err_wrid:
        if (pd->uobject)
                mlx4_ib_db_unmap_user(to_mucontext(pd->uobject->context), &srq->db);
        else
-               kfree(srq->wrid);
+               kvfree(srq->wrid);
 
 err_mtt:
        mlx4_mtt_cleanup(dev->dev, &srq->mtt);
index ec8993a7b3beea5a91370c1f66979dae583f49d4..6000f7aeede94301cbb7c281bfaae26299770106 100644 (file)
@@ -381,7 +381,19 @@ static void __cache_work_func(struct mlx5_cache_ent *ent)
                        }
                }
        } else if (ent->cur > 2 * ent->limit) {
-               if (!someone_adding(cache) &&
+               /*
+                * The remove_keys() logic is performed as garbage collection
+                * task. Such task is intended to be run when no other active
+                * processes are running.
+                *
+                * The need_resched() will return TRUE if there are user tasks
+                * to be activated in near future.
+                *
+                * In such case, we don't execute remove_keys() and postpone
+                * the garbage collection work to try to run in next cycle,
+                * in order to free CPU resources to other tasks.
+                */
+               if (!need_resched() && !someone_adding(cache) &&
                    time_after(jiffies, cache->last_add + 300 * HZ)) {
                        remove_keys(dev, i, 1);
                        if (ent->cur > ent->limit)
index 5e27f76805e28af0c0e0acdc9864360f8cf09b41..4c7c3c84a7417c32f2f348f7c91c2ce0e4b4e1b0 100644 (file)
@@ -292,7 +292,7 @@ int qib_refresh_qsfp_cache(struct qib_pportdata *ppd, struct qib_qsfp_cache *cp)
                qib_dev_porterr(ppd->dd, ppd->port,
                                "QSFP byte0 is 0x%02X, S/B 0x0C/D\n", peek[0]);
 
-       if ((peek[2] & 2) == 0) {
+       if ((peek[2] & 4) == 0) {
                /*
                 * If cable is paged, rather than "flat memory", we need to
                 * set the page to zero, Even if it already appears to be zero.
@@ -538,7 +538,7 @@ int qib_qsfp_dump(struct qib_pportdata *ppd, char *buf, int len)
        sofar += scnprintf(buf + sofar, len - sofar, "Date:%.*s\n",
                           QSFP_DATE_LEN, cd.date);
        sofar += scnprintf(buf + sofar, len - sofar, "Lot:%.*s\n",
-                          QSFP_LOT_LEN, cd.date);
+                          QSFP_LOT_LEN, cd.lot);
 
        while (bidx < QSFP_DEFAULT_HDR_CNT) {
                int iidx;
index 2baf5ad251ed24a02682051058e6d1a406419e04..bc803f33d5f6883200ca21e462febebb94393cd4 100644 (file)
@@ -329,9 +329,9 @@ struct qib_sge {
 struct qib_mr {
        struct ib_mr ibmr;
        struct ib_umem *umem;
-       struct qib_mregion mr;  /* must be last */
        u64 *pages;
        u32 npages;
+       struct qib_mregion mr;  /* must be last */
 };
 
 /*
index a93070210109699909075e02212fc6ae70710960..42f4da620f2e9f97062b9183b6ebf3ed54e56cfe 100644 (file)
@@ -1293,7 +1293,7 @@ u8 iser_check_task_pi_status(struct iscsi_iser_task *iser_task,
                if (mr_status.fail_status & IB_MR_CHECK_SIG_STATUS) {
                        sector_t sector_off = mr_status.sig_err.sig_err_offset;
 
-                       do_div(sector_off, sector_size + 8);
+                       sector_div(sector_off, sector_size + 8);
                        *sector = scsi_get_lba(iser_task->sc) + sector_off;
 
                        pr_err("PI error found type %d at sector %llx "
index dfbbbb28090b2301c7742fd28b145b62054a76af..8a51c3b5d657e5a49ae50c4e5f104a7298d732f2 100644 (file)
@@ -157,16 +157,9 @@ isert_create_qp(struct isert_conn *isert_conn,
        attr.recv_cq = comp->cq;
        attr.cap.max_send_wr = ISERT_QP_MAX_REQ_DTOS;
        attr.cap.max_recv_wr = ISERT_QP_MAX_RECV_DTOS + 1;
-       /*
-        * FIXME: Use devattr.max_sge - 2 for max_send_sge as
-        * work-around for RDMA_READs with ConnectX-2.
-        *
-        * Also, still make sure to have at least two SGEs for
-        * outgoing control PDU responses.
-        */
-       attr.cap.max_send_sge = max(2, device->dev_attr.max_sge - 2);
-       isert_conn->max_sge = attr.cap.max_send_sge;
-
+       attr.cap.max_send_sge = device->dev_attr.max_sge;
+       isert_conn->max_sge = min(device->dev_attr.max_sge,
+                                 device->dev_attr.max_sge_rd);
        attr.cap.max_recv_sge = 1;
        attr.sq_sig_type = IB_SIGNAL_REQ_WR;
        attr.qp_type = IB_QPT_RC;
index 9909022dc6c3eebd4c52ef3e7dca5221dc8b6038..3db9a659719b0f6283af610bf01b8f65d27292a9 100644 (file)
@@ -488,7 +488,7 @@ static int srp_create_ch_ib(struct srp_rdma_ch *ch)
        struct ib_qp *qp;
        struct ib_fmr_pool *fmr_pool = NULL;
        struct srp_fr_pool *fr_pool = NULL;
-       const int m = 1 + dev->use_fast_reg;
+       const int m = dev->use_fast_reg ? 3 : 1;
        struct ib_cq_init_attr cq_attr = {};
        int ret;
 
@@ -994,16 +994,16 @@ static int srp_connect_ch(struct srp_rdma_ch *ch, bool multich)
 
        ret = srp_lookup_path(ch);
        if (ret)
-               return ret;
+               goto out;
 
        while (1) {
                init_completion(&ch->done);
                ret = srp_send_req(ch, multich);
                if (ret)
-                       return ret;
+                       goto out;
                ret = wait_for_completion_interruptible(&ch->done);
                if (ret < 0)
-                       return ret;
+                       goto out;
 
                /*
                 * The CM event handling code will set status to
@@ -1011,15 +1011,16 @@ static int srp_connect_ch(struct srp_rdma_ch *ch, bool multich)
                 * back, or SRP_DLID_REDIRECT if we get a lid/qp
                 * redirect REJ back.
                 */
-               switch (ch->status) {
+               ret = ch->status;
+               switch (ret) {
                case 0:
                        ch->connected = true;
-                       return 0;
+                       goto out;
 
                case SRP_PORT_REDIRECT:
                        ret = srp_lookup_path(ch);
                        if (ret)
-                               return ret;
+                               goto out;
                        break;
 
                case SRP_DLID_REDIRECT:
@@ -1028,13 +1029,16 @@ static int srp_connect_ch(struct srp_rdma_ch *ch, bool multich)
                case SRP_STALE_CONN:
                        shost_printk(KERN_ERR, target->scsi_host, PFX
                                     "giving up on stale connection\n");
-                       ch->status = -ECONNRESET;
-                       return ch->status;
+                       ret = -ECONNRESET;
+                       goto out;
 
                default:
-                       return ch->status;
+                       goto out;
                }
        }
+
+out:
+       return ret <= 0 ? ret : -ENODEV;
 }
 
 static int srp_inv_rkey(struct srp_rdma_ch *ch, u32 rkey)
@@ -1309,7 +1313,7 @@ reset_state:
 }
 
 static int srp_map_finish_fr(struct srp_map_state *state,
-                            struct srp_rdma_ch *ch)
+                            struct srp_rdma_ch *ch, int sg_nents)
 {
        struct srp_target_port *target = ch->target;
        struct srp_device *dev = target->srp_host->srp_dev;
@@ -1324,10 +1328,10 @@ static int srp_map_finish_fr(struct srp_map_state *state,
 
        WARN_ON_ONCE(!dev->use_fast_reg);
 
-       if (state->sg_nents == 0)
+       if (sg_nents == 0)
                return 0;
 
-       if (state->sg_nents == 1 && target->global_mr) {
+       if (sg_nents == 1 && target->global_mr) {
                srp_map_desc(state, sg_dma_address(state->sg),
                             sg_dma_len(state->sg),
                             target->global_mr->rkey);
@@ -1341,8 +1345,7 @@ static int srp_map_finish_fr(struct srp_map_state *state,
        rkey = ib_inc_rkey(desc->mr->rkey);
        ib_update_fast_reg_key(desc->mr, rkey);
 
-       n = ib_map_mr_sg(desc->mr, state->sg, state->sg_nents,
-                        dev->mr_page_size);
+       n = ib_map_mr_sg(desc->mr, state->sg, sg_nents, dev->mr_page_size);
        if (unlikely(n < 0))
                return n;
 
@@ -1448,16 +1451,15 @@ static int srp_map_sg_fr(struct srp_map_state *state, struct srp_rdma_ch *ch,
        state->fr.next = req->fr_list;
        state->fr.end = req->fr_list + ch->target->cmd_sg_cnt;
        state->sg = scat;
-       state->sg_nents = scsi_sg_count(req->scmnd);
 
-       while (state->sg_nents) {
+       while (count) {
                int i, n;
 
-               n = srp_map_finish_fr(state, ch);
+               n = srp_map_finish_fr(state, ch, count);
                if (unlikely(n < 0))
                        return n;
 
-               state->sg_nents -= n;
+               count -= n;
                for (i = 0; i < n; i++)
                        state->sg = sg_next(state->sg);
        }
@@ -1517,10 +1519,12 @@ static int srp_map_idb(struct srp_rdma_ch *ch, struct srp_request *req,
 
        if (dev->use_fast_reg) {
                state.sg = idb_sg;
-               state.sg_nents = 1;
                sg_set_buf(idb_sg, req->indirect_desc, idb_len);
                idb_sg->dma_address = req->indirect_dma_addr; /* hack! */
-               ret = srp_map_finish_fr(&state, ch);
+#ifdef CONFIG_NEED_SG_DMA_LENGTH
+               idb_sg->dma_length = idb_sg->length;          /* hack^2 */
+#endif
+               ret = srp_map_finish_fr(&state, ch, 1);
                if (ret < 0)
                        return ret;
        } else if (dev->use_fmr) {
@@ -1655,7 +1659,7 @@ static int srp_map_data(struct scsi_cmnd *scmnd, struct srp_rdma_ch *ch,
                        return ret;
                req->nmdesc++;
        } else {
-               idb_rkey = target->global_mr->rkey;
+               idb_rkey = cpu_to_be32(target->global_mr->rkey);
        }
 
        indirect_hdr->table_desc.va = cpu_to_be64(req->indirect_dma_addr);
index 87a2a919dc43877141426e6d373d12727dc4b65e..f6af531f9f32c990cd30c7139d247c643144e55d 100644 (file)
@@ -300,10 +300,7 @@ struct srp_map_state {
        dma_addr_t              base_dma_addr;
        u32                     dma_len;
        u32                     total_len;
-       union {
-               unsigned int    npages;
-               int             sg_nents;
-       };
+       unsigned int            npages;
        unsigned int            nmdesc;
        unsigned int            ndesc;
 };
index 598ab3f0e0ac54b79f1438c2193f8bc112949975..cadf104e30746b34d242eaa6e91637b8f99e5370 100644 (file)
@@ -210,7 +210,12 @@ int __init fpga_irq_of_init(struct device_node *node,
                parent_irq = -1;
        }
 
+#ifdef CONFIG_ARCH_VERSATILE
+       fpga_irq_init(base, node->name, IRQ_SIC_START, parent_irq, valid_mask,
+                                 node);
+#else
        fpga_irq_init(base, node->name, 0, parent_irq, valid_mask, node);
+#endif
 
        writel(clear_mask, base + IRQ_ENABLE_CLEAR);
        writel(clear_mask, base + FIQ_ENABLE_CLEAR);
index b33f53b3ca93257a6ec34f409c46e5f1d7662172..bf04d2a3cf4afe4614765b2b3d08d32ec77571a6 100644 (file)
@@ -1896,7 +1896,7 @@ static void EChannel_proc_rcv(struct hisax_d_if *d_if)
                                ptr--;
                                *ptr++ = '\n';
                                *ptr = 0;
-                               HiSax_putstatus(cs, NULL, "%s", cs->dlog);
+                               HiSax_putstatus(cs, NULL, cs->dlog);
                        } else
                                HiSax_putstatus(cs, "LogEcho: ",
                                                "warning Frame too big (%d)",
index 4a48255281887e8c03f9dbacccf404f4f9c52476..90449e1e91e5a27924da01df6215dfa6c326651e 100644 (file)
@@ -901,7 +901,7 @@ Begin:
                                        ptr--;
                                        *ptr++ = '\n';
                                        *ptr = 0;
-                                       HiSax_putstatus(cs, NULL, "%s", cs->dlog);
+                                       HiSax_putstatus(cs, NULL, cs->dlog);
                                } else
                                        HiSax_putstatus(cs, "LogEcho: ", "warning Frame too big (%d)", total - 3);
                        }
index b1fad81f0722e64b2e0d671215e8dc89c295f4a1..13b2151c10f54ff9fd5bcec76e1ceef2b99aa472 100644 (file)
@@ -674,7 +674,7 @@ receive_emsg(struct IsdnCardState *cs)
                                        ptr--;
                                        *ptr++ = '\n';
                                        *ptr = 0;
-                                       HiSax_putstatus(cs, NULL, "%s", cs->dlog);
+                                       HiSax_putstatus(cs, NULL, cs->dlog);
                                } else
                                        HiSax_putstatus(cs, "LogEcho: ", "warning Frame too big (%d)", skb->len);
                        }
index b420f8bd862e454df2cc08f4da84b8bc7ef76e57..ba4beb25d872dbc24d2cbe55a411dee28f219b47 100644 (file)
@@ -1179,7 +1179,7 @@ LogFrame(struct IsdnCardState *cs, u_char *buf, int size)
                dp--;
                *dp++ = '\n';
                *dp = 0;
-               HiSax_putstatus(cs, NULL, "%s", cs->dlog);
+               HiSax_putstatus(cs, NULL, cs->dlog);
        } else
                HiSax_putstatus(cs, "LogFrame: ", "warning Frame too big (%d)", size);
 }
@@ -1246,7 +1246,7 @@ dlogframe(struct IsdnCardState *cs, struct sk_buff *skb, int dir)
        }
        if (finish) {
                *dp = 0;
-               HiSax_putstatus(cs, NULL, "%s", cs->dlog);
+               HiSax_putstatus(cs, NULL, cs->dlog);
                return;
        }
        if ((0xfe & buf[0]) == PROTO_DIS_N0) {  /* 1TR6 */
@@ -1509,5 +1509,5 @@ dlogframe(struct IsdnCardState *cs, struct sk_buff *skb, int dir)
                dp += sprintf(dp, "Unknown protocol %x!", buf[0]);
        }
        *dp = 0;
-       HiSax_putstatus(cs, NULL, "%s", cs->dlog);
+       HiSax_putstatus(cs, NULL, cs->dlog);
 }
index a16bf56d3f283ece1cd204920ca84aff41eec915..85a339030e4b8ec4a85c46185e561576c47268db 100644 (file)
@@ -18,6 +18,7 @@ if NVM
 
 config NVM_DEBUG
        bool "Open-Channel SSD debugging support"
+       default n
        ---help---
        Exposes a debug management interface to create/remove targets at:
 
index f659e605a4067bed3489723470e32cc9ae02b791..8f41b245cd55b55862911baaf2220d885fc30142 100644 (file)
@@ -74,7 +74,7 @@ EXPORT_SYMBOL(nvm_unregister_target);
 void *nvm_dev_dma_alloc(struct nvm_dev *dev, gfp_t mem_flags,
                                                        dma_addr_t *dma_handler)
 {
-       return dev->ops->dev_dma_alloc(dev->q, dev->ppalist_pool, mem_flags,
+       return dev->ops->dev_dma_alloc(dev, dev->ppalist_pool, mem_flags,
                                                                dma_handler);
 }
 EXPORT_SYMBOL(nvm_dev_dma_alloc);
@@ -97,15 +97,47 @@ static struct nvmm_type *nvm_find_mgr_type(const char *name)
        return NULL;
 }
 
+struct nvmm_type *nvm_init_mgr(struct nvm_dev *dev)
+{
+       struct nvmm_type *mt;
+       int ret;
+
+       lockdep_assert_held(&nvm_lock);
+
+       list_for_each_entry(mt, &nvm_mgrs, list) {
+               ret = mt->register_mgr(dev);
+               if (ret < 0) {
+                       pr_err("nvm: media mgr failed to init (%d) on dev %s\n",
+                                                               ret, dev->name);
+                       return NULL; /* initialization failed */
+               } else if (ret > 0)
+                       return mt;
+       }
+
+       return NULL;
+}
+
 int nvm_register_mgr(struct nvmm_type *mt)
 {
+       struct nvm_dev *dev;
        int ret = 0;
 
        down_write(&nvm_lock);
-       if (nvm_find_mgr_type(mt->name))
+       if (nvm_find_mgr_type(mt->name)) {
                ret = -EEXIST;
-       else
+               goto finish;
+       } else {
                list_add(&mt->list, &nvm_mgrs);
+       }
+
+       /* try to register media mgr if any device have none configured */
+       list_for_each_entry(dev, &nvm_devices, devices) {
+               if (dev->mt)
+                       continue;
+
+               dev->mt = nvm_init_mgr(dev);
+       }
+finish:
        up_write(&nvm_lock);
 
        return ret;
@@ -160,11 +192,6 @@ int nvm_erase_blk(struct nvm_dev *dev, struct nvm_block *blk)
 }
 EXPORT_SYMBOL(nvm_erase_blk);
 
-static void nvm_core_free(struct nvm_dev *dev)
-{
-       kfree(dev);
-}
-
 static int nvm_core_init(struct nvm_dev *dev)
 {
        struct nvm_id *id = &dev->identity;
@@ -179,12 +206,21 @@ static int nvm_core_init(struct nvm_dev *dev)
        dev->sec_size = grp->csecs;
        dev->oob_size = grp->sos;
        dev->sec_per_pg = grp->fpg_sz / grp->csecs;
-       dev->addr_mode = id->ppat;
-       dev->addr_format = id->ppaf;
+       memcpy(&dev->ppaf, &id->ppaf, sizeof(struct nvm_addr_format));
 
        dev->plane_mode = NVM_PLANE_SINGLE;
        dev->max_rq_size = dev->ops->max_phys_sect * dev->sec_size;
 
+       if (grp->mtype != 0) {
+               pr_err("nvm: memory type not supported\n");
+               return -EINVAL;
+       }
+
+       if (grp->fmtype != 0 && grp->fmtype != 1) {
+               pr_err("nvm: flash type not supported\n");
+               return -EINVAL;
+       }
+
        if (grp->mpos & 0x020202)
                dev->plane_mode = NVM_PLANE_DOUBLE;
        if (grp->mpos & 0x040404)
@@ -213,21 +249,17 @@ static void nvm_free(struct nvm_dev *dev)
 
        if (dev->mt)
                dev->mt->unregister_mgr(dev);
-
-       nvm_core_free(dev);
 }
 
 static int nvm_init(struct nvm_dev *dev)
 {
-       struct nvmm_type *mt;
-       int ret = 0;
+       int ret = -EINVAL;
 
        if (!dev->q || !dev->ops)
-               return -EINVAL;
+               return ret;
 
-       if (dev->ops->identity(dev->q, &dev->identity)) {
+       if (dev->ops->identity(dev, &dev->identity)) {
                pr_err("nvm: device could not be identified\n");
-               ret = -EINVAL;
                goto err;
        }
 
@@ -251,29 +283,12 @@ static int nvm_init(struct nvm_dev *dev)
                goto err;
        }
 
-       /* register with device with a supported manager */
-       list_for_each_entry(mt, &nvm_mgrs, list) {
-               ret = mt->register_mgr(dev);
-               if (ret < 0)
-                       goto err; /* initialization failed */
-               if (ret > 0) {
-                       dev->mt = mt;
-                       break; /* successfully initialized */
-               }
-       }
-
-       if (!ret) {
-               pr_info("nvm: no compatible manager found.\n");
-               return 0;
-       }
-
        pr_info("nvm: registered %s [%u/%u/%u/%u/%u/%u]\n",
                        dev->name, dev->sec_per_pg, dev->nr_planes,
                        dev->pgs_per_blk, dev->blks_per_lun, dev->nr_luns,
                        dev->nr_chnls);
        return 0;
 err:
-       nvm_free(dev);
        pr_err("nvm: failed to initialize nvm\n");
        return ret;
 }
@@ -308,22 +323,27 @@ int nvm_register(struct request_queue *q, char *disk_name,
        if (ret)
                goto err_init;
 
-       down_write(&nvm_lock);
-       list_add(&dev->devices, &nvm_devices);
-       up_write(&nvm_lock);
+       if (dev->ops->max_phys_sect > 256) {
+               pr_info("nvm: max sectors supported is 256.\n");
+               ret = -EINVAL;
+               goto err_init;
+       }
 
        if (dev->ops->max_phys_sect > 1) {
-               dev->ppalist_pool = dev->ops->create_dma_pool(dev->q,
-                                                               "ppalist");
+               dev->ppalist_pool = dev->ops->create_dma_pool(dev, "ppalist");
                if (!dev->ppalist_pool) {
                        pr_err("nvm: could not create ppa pool\n");
-                       return -ENOMEM;
+                       ret = -ENOMEM;
+                       goto err_init;
                }
-       } else if (dev->ops->max_phys_sect > 256) {
-               pr_info("nvm: max sectors supported is 256.\n");
-               return -EINVAL;
        }
 
+       /* register device with a supported media manager */
+       down_write(&nvm_lock);
+       dev->mt = nvm_init_mgr(dev);
+       list_add(&dev->devices, &nvm_devices);
+       up_write(&nvm_lock);
+
        return 0;
 err_init:
        kfree(dev);
@@ -333,19 +353,22 @@ EXPORT_SYMBOL(nvm_register);
 
 void nvm_unregister(char *disk_name)
 {
-       struct nvm_dev *dev = nvm_find_nvm_dev(disk_name);
+       struct nvm_dev *dev;
 
+       down_write(&nvm_lock);
+       dev = nvm_find_nvm_dev(disk_name);
        if (!dev) {
                pr_err("nvm: could not find device %s to unregister\n",
                                                                disk_name);
+               up_write(&nvm_lock);
                return;
        }
 
-       nvm_exit(dev);
-
-       down_write(&nvm_lock);
        list_del(&dev->devices);
        up_write(&nvm_lock);
+
+       nvm_exit(dev);
+       kfree(dev);
 }
 EXPORT_SYMBOL(nvm_unregister);
 
@@ -358,38 +381,24 @@ static int nvm_create_target(struct nvm_dev *dev,
 {
        struct nvm_ioctl_create_simple *s = &create->conf.s;
        struct request_queue *tqueue;
-       struct nvmm_type *mt;
        struct gendisk *tdisk;
        struct nvm_tgt_type *tt;
        struct nvm_target *t;
        void *targetdata;
-       int ret = 0;
 
        if (!dev->mt) {
-               /* register with device with a supported NVM manager */
-               list_for_each_entry(mt, &nvm_mgrs, list) {
-                       ret = mt->register_mgr(dev);
-                       if (ret < 0)
-                               return ret; /* initialization failed */
-                       if (ret > 0) {
-                               dev->mt = mt;
-                               break; /* successfully initialized */
-                       }
-               }
-
-               if (!ret) {
-                       pr_info("nvm: no compatible nvm manager found.\n");
-                       return -ENODEV;
-               }
+               pr_info("nvm: device has no media manager registered.\n");
+               return -ENODEV;
        }
 
+       down_write(&nvm_lock);
        tt = nvm_find_target_type(create->tgttype);
        if (!tt) {
                pr_err("nvm: target type %s not found\n", create->tgttype);
+               up_write(&nvm_lock);
                return -EINVAL;
        }
 
-       down_write(&nvm_lock);
        list_for_each_entry(t, &dev->online_targets, list) {
                if (!strcmp(create->tgtname, t->disk->disk_name)) {
                        pr_err("nvm: target name already exists.\n");
@@ -457,11 +466,11 @@ static void nvm_remove_target(struct nvm_target *t)
        lockdep_assert_held(&nvm_lock);
 
        del_gendisk(tdisk);
+       blk_cleanup_queue(q);
+
        if (tt->exit)
                tt->exit(tdisk->private_data);
 
-       blk_cleanup_queue(q);
-
        put_disk(tdisk);
 
        list_del(&t->list);
@@ -473,7 +482,9 @@ static int __nvm_configure_create(struct nvm_ioctl_create *create)
        struct nvm_dev *dev;
        struct nvm_ioctl_create_simple *s;
 
+       down_write(&nvm_lock);
        dev = nvm_find_nvm_dev(create->dev);
+       up_write(&nvm_lock);
        if (!dev) {
                pr_err("nvm: device not found\n");
                return -EINVAL;
@@ -532,7 +543,9 @@ static int nvm_configure_show(const char *val)
                return -EINVAL;
        }
 
+       down_write(&nvm_lock);
        dev = nvm_find_nvm_dev(devname);
+       up_write(&nvm_lock);
        if (!dev) {
                pr_err("nvm: device not found\n");
                return -EINVAL;
@@ -541,7 +554,7 @@ static int nvm_configure_show(const char *val)
        if (!dev->mt)
                return 0;
 
-       dev->mt->free_blocks_print(dev);
+       dev->mt->lun_info_print(dev);
 
        return 0;
 }
@@ -677,8 +690,10 @@ static long nvm_ioctl_info(struct file *file, void __user *arg)
        info->tgtsize = tgt_iter;
        up_write(&nvm_lock);
 
-       if (copy_to_user(arg, info, sizeof(struct nvm_ioctl_info)))
+       if (copy_to_user(arg, info, sizeof(struct nvm_ioctl_info))) {
+               kfree(info);
                return -EFAULT;
+       }
 
        kfree(info);
        return 0;
@@ -721,8 +736,11 @@ static long nvm_ioctl_get_devices(struct file *file, void __user *arg)
 
        devices->nr_devices = i;
 
-       if (copy_to_user(arg, devices, sizeof(struct nvm_ioctl_get_devices)))
+       if (copy_to_user(arg, devices,
+                        sizeof(struct nvm_ioctl_get_devices))) {
+               kfree(devices);
                return -EFAULT;
+       }
 
        kfree(devices);
        return 0;
index ae1fb2bdc5f44b25aecdf010afdf9894de0dfede..f434e89e1c7a1d824d0ac491c80234eb955e976f 100644 (file)
@@ -60,23 +60,27 @@ static int gennvm_luns_init(struct nvm_dev *dev, struct gen_nvm *gn)
                lun->vlun.lun_id = i % dev->luns_per_chnl;
                lun->vlun.chnl_id = i / dev->luns_per_chnl;
                lun->vlun.nr_free_blocks = dev->blks_per_lun;
+               lun->vlun.nr_inuse_blocks = 0;
+               lun->vlun.nr_bad_blocks = 0;
        }
        return 0;
 }
 
-static int gennvm_block_bb(u32 lun_id, void *bb_bitmap, unsigned int nr_blocks,
+static int gennvm_block_bb(struct ppa_addr ppa, int nr_blocks, u8 *blks,
                                                                void *private)
 {
        struct gen_nvm *gn = private;
-       struct gen_lun *lun = &gn->luns[lun_id];
+       struct nvm_dev *dev = gn->dev;
+       struct gen_lun *lun;
        struct nvm_block *blk;
        int i;
 
-       if (unlikely(bitmap_empty(bb_bitmap, nr_blocks)))
-               return 0;
+       lun = &gn->luns[(dev->nr_luns * ppa.g.ch) + ppa.g.lun];
+
+       for (i = 0; i < nr_blocks; i++) {
+               if (blks[i] == 0)
+                       continue;
 
-       i = -1;
-       while ((i = find_next_bit(bb_bitmap, nr_blocks, i + 1)) < nr_blocks) {
                blk = &lun->vlun.blocks[i];
                if (!blk) {
                        pr_err("gennvm: BB data is out of bounds.\n");
@@ -84,6 +88,7 @@ static int gennvm_block_bb(u32 lun_id, void *bb_bitmap, unsigned int nr_blocks,
                }
 
                list_move_tail(&blk->list, &lun->bb_list);
+               lun->vlun.nr_bad_blocks++;
        }
 
        return 0;
@@ -136,6 +141,7 @@ static int gennvm_block_map(u64 slba, u32 nlb, __le64 *entries, void *private)
                        list_move_tail(&blk->list, &lun->used_list);
                        blk->type = 1;
                        lun->vlun.nr_free_blocks--;
+                       lun->vlun.nr_inuse_blocks++;
                }
        }
 
@@ -164,22 +170,32 @@ static int gennvm_blocks_init(struct nvm_dev *dev, struct gen_nvm *gn)
                        block->id = cur_block_id++;
 
                        /* First block is reserved for device */
-                       if (unlikely(lun_iter == 0 && blk_iter == 0))
+                       if (unlikely(lun_iter == 0 && blk_iter == 0)) {
+                               lun->vlun.nr_free_blocks--;
                                continue;
+                       }
 
                        list_add_tail(&block->list, &lun->free_list);
                }
 
                if (dev->ops->get_bb_tbl) {
-                       ret = dev->ops->get_bb_tbl(dev->q, lun->vlun.id,
-                                       dev->blks_per_lun, gennvm_block_bb, gn);
+                       struct ppa_addr ppa;
+
+                       ppa.ppa = 0;
+                       ppa.g.ch = lun->vlun.chnl_id;
+                       ppa.g.lun = lun->vlun.id;
+                       ppa = generic_to_dev_addr(dev, ppa);
+
+                       ret = dev->ops->get_bb_tbl(dev, ppa,
+                                               dev->blks_per_lun,
+                                               gennvm_block_bb, gn);
                        if (ret)
                                pr_err("gennvm: could not read BB table\n");
                }
        }
 
        if (dev->ops->get_l2p_tbl) {
-               ret = dev->ops->get_l2p_tbl(dev->q, 0, dev->total_pages,
+               ret = dev->ops->get_l2p_tbl(dev, 0, dev->total_pages,
                                                        gennvm_block_map, dev);
                if (ret) {
                        pr_err("gennvm: could not read L2P table.\n");
@@ -190,15 +206,27 @@ static int gennvm_blocks_init(struct nvm_dev *dev, struct gen_nvm *gn)
        return 0;
 }
 
+static void gennvm_free(struct nvm_dev *dev)
+{
+       gennvm_blocks_free(dev);
+       gennvm_luns_free(dev);
+       kfree(dev->mp);
+       dev->mp = NULL;
+}
+
 static int gennvm_register(struct nvm_dev *dev)
 {
        struct gen_nvm *gn;
        int ret;
 
+       if (!try_module_get(THIS_MODULE))
+               return -ENODEV;
+
        gn = kzalloc(sizeof(struct gen_nvm), GFP_KERNEL);
        if (!gn)
                return -ENOMEM;
 
+       gn->dev = dev;
        gn->nr_luns = dev->nr_luns;
        dev->mp = gn;
 
@@ -216,16 +244,15 @@ static int gennvm_register(struct nvm_dev *dev)
 
        return 1;
 err:
-       kfree(gn);
+       gennvm_free(dev);
+       module_put(THIS_MODULE);
        return ret;
 }
 
 static void gennvm_unregister(struct nvm_dev *dev)
 {
-       gennvm_blocks_free(dev);
-       gennvm_luns_free(dev);
-       kfree(dev->mp);
-       dev->mp = NULL;
+       gennvm_free(dev);
+       module_put(THIS_MODULE);
 }
 
 static struct nvm_block *gennvm_get_blk(struct nvm_dev *dev,
@@ -240,23 +267,21 @@ static struct nvm_block *gennvm_get_blk(struct nvm_dev *dev,
        if (list_empty(&lun->free_list)) {
                pr_err_ratelimited("gennvm: lun %u have no free pages available",
                                                                lun->vlun.id);
-               spin_unlock(&vlun->lock);
                goto out;
        }
 
-       while (!is_gc && lun->vlun.nr_free_blocks < lun->reserved_blocks) {
-               spin_unlock(&vlun->lock);
+       if (!is_gc && lun->vlun.nr_free_blocks < lun->reserved_blocks)
                goto out;
-       }
 
        blk = list_first_entry(&lun->free_list, struct nvm_block, list);
        list_move_tail(&blk->list, &lun->used_list);
        blk->type = 1;
 
        lun->vlun.nr_free_blocks--;
+       lun->vlun.nr_inuse_blocks++;
 
-       spin_unlock(&vlun->lock);
 out:
+       spin_unlock(&vlun->lock);
        return blk;
 }
 
@@ -271,16 +296,21 @@ static void gennvm_put_blk(struct nvm_dev *dev, struct nvm_block *blk)
        case 1:
                list_move_tail(&blk->list, &lun->free_list);
                lun->vlun.nr_free_blocks++;
+               lun->vlun.nr_inuse_blocks--;
                blk->type = 0;
                break;
        case 2:
                list_move_tail(&blk->list, &lun->bb_list);
+               lun->vlun.nr_bad_blocks++;
+               lun->vlun.nr_inuse_blocks--;
                break;
        default:
                WARN_ON_ONCE(1);
                pr_err("gennvm: erroneous block type (%lu -> %u)\n",
                                                        blk->id, blk->type);
                list_move_tail(&blk->list, &lun->bb_list);
+               lun->vlun.nr_bad_blocks++;
+               lun->vlun.nr_inuse_blocks--;
        }
 
        spin_unlock(&vlun->lock);
@@ -292,10 +322,10 @@ static void gennvm_addr_to_generic_mode(struct nvm_dev *dev, struct nvm_rq *rqd)
 
        if (rqd->nr_pages > 1) {
                for (i = 0; i < rqd->nr_pages; i++)
-                       rqd->ppa_list[i] = addr_to_generic_mode(dev,
+                       rqd->ppa_list[i] = dev_to_generic_addr(dev,
                                                        rqd->ppa_list[i]);
        } else {
-               rqd->ppa_addr = addr_to_generic_mode(dev, rqd->ppa_addr);
+               rqd->ppa_addr = dev_to_generic_addr(dev, rqd->ppa_addr);
        }
 }
 
@@ -305,10 +335,10 @@ static void gennvm_generic_to_addr_mode(struct nvm_dev *dev, struct nvm_rq *rqd)
 
        if (rqd->nr_pages > 1) {
                for (i = 0; i < rqd->nr_pages; i++)
-                       rqd->ppa_list[i] = generic_to_addr_mode(dev,
+                       rqd->ppa_list[i] = generic_to_dev_addr(dev,
                                                        rqd->ppa_list[i]);
        } else {
-               rqd->ppa_addr = generic_to_addr_mode(dev, rqd->ppa_addr);
+               rqd->ppa_addr = generic_to_dev_addr(dev, rqd->ppa_addr);
        }
 }
 
@@ -321,7 +351,7 @@ static int gennvm_submit_io(struct nvm_dev *dev, struct nvm_rq *rqd)
        gennvm_generic_to_addr_mode(dev, rqd);
 
        rqd->dev = dev;
-       return dev->ops->submit_io(dev->q, rqd);
+       return dev->ops->submit_io(dev, rqd);
 }
 
 static void gennvm_blk_set_type(struct nvm_dev *dev, struct ppa_addr *ppa,
@@ -354,10 +384,10 @@ static void gennvm_mark_blk_bad(struct nvm_dev *dev, struct nvm_rq *rqd)
 {
        int i;
 
-       if (!dev->ops->set_bb)
+       if (!dev->ops->set_bb_tbl)
                return;
 
-       if (dev->ops->set_bb(dev->q, rqd, 1))
+       if (dev->ops->set_bb_tbl(dev, rqd, 1))
                return;
 
        gennvm_addr_to_generic_mode(dev, rqd);
@@ -425,7 +455,7 @@ static int gennvm_erase_blk(struct nvm_dev *dev, struct nvm_block *blk,
 
        gennvm_generic_to_addr_mode(dev, &rqd);
 
-       ret = dev->ops->erase_block(dev->q, &rqd);
+       ret = dev->ops->erase_block(dev, &rqd);
 
        if (plane_cnt)
                nvm_dev_dma_free(dev, rqd.ppa_list, rqd.dma_ppa_list);
@@ -440,15 +470,24 @@ static struct nvm_lun *gennvm_get_lun(struct nvm_dev *dev, int lunid)
        return &gn->luns[lunid].vlun;
 }
 
-static void gennvm_free_blocks_print(struct nvm_dev *dev)
+static void gennvm_lun_info_print(struct nvm_dev *dev)
 {
        struct gen_nvm *gn = dev->mp;
        struct gen_lun *lun;
        unsigned int i;
 
-       gennvm_for_each_lun(gn, lun, i)
-               pr_info("%s: lun%8u\t%u\n",
-                                       dev->name, i, lun->vlun.nr_free_blocks);
+
+       gennvm_for_each_lun(gn, lun, i) {
+               spin_lock(&lun->vlun.lock);
+
+               pr_info("%s: lun%8u\t%u\t%u\t%u\n",
+                               dev->name, i,
+                               lun->vlun.nr_free_blocks,
+                               lun->vlun.nr_inuse_blocks,
+                               lun->vlun.nr_bad_blocks);
+
+               spin_unlock(&lun->vlun.lock);
+       }
 }
 
 static struct nvmm_type gennvm = {
@@ -466,7 +505,7 @@ static struct nvmm_type gennvm = {
        .erase_blk      = gennvm_erase_blk,
 
        .get_lun        = gennvm_get_lun,
-       .free_blocks_print = gennvm_free_blocks_print,
+       .lun_info_print = gennvm_lun_info_print,
 };
 
 static int __init gennvm_module_init(void)
index d23bd3501ddc4e56abc8ce177e0fd82aa94fec13..9c24b5b32dac2cb37acc39a5d7c54449296fe231 100644 (file)
@@ -35,6 +35,8 @@ struct gen_lun {
 };
 
 struct gen_nvm {
+       struct nvm_dev *dev;
+
        int nr_luns;
        struct gen_lun *luns;
 };
index 7ba64c87ba1c10306c9b96d132f0d2f869a628da..134e4faba48259434db7d55d446f40f3deb206b9 100644 (file)
@@ -123,12 +123,42 @@ static u64 block_to_addr(struct rrpc *rrpc, struct rrpc_block *rblk)
        return blk->id * rrpc->dev->pgs_per_blk;
 }
 
+static struct ppa_addr linear_to_generic_addr(struct nvm_dev *dev,
+                                                       struct ppa_addr r)
+{
+       struct ppa_addr l;
+       int secs, pgs, blks, luns;
+       sector_t ppa = r.ppa;
+
+       l.ppa = 0;
+
+       div_u64_rem(ppa, dev->sec_per_pg, &secs);
+       l.g.sec = secs;
+
+       sector_div(ppa, dev->sec_per_pg);
+       div_u64_rem(ppa, dev->sec_per_blk, &pgs);
+       l.g.pg = pgs;
+
+       sector_div(ppa, dev->pgs_per_blk);
+       div_u64_rem(ppa, dev->blks_per_lun, &blks);
+       l.g.blk = blks;
+
+       sector_div(ppa, dev->blks_per_lun);
+       div_u64_rem(ppa, dev->luns_per_chnl, &luns);
+       l.g.lun = luns;
+
+       sector_div(ppa, dev->luns_per_chnl);
+       l.g.ch = ppa;
+
+       return l;
+}
+
 static struct ppa_addr rrpc_ppa_to_gaddr(struct nvm_dev *dev, u64 addr)
 {
        struct ppa_addr paddr;
 
        paddr.ppa = addr;
-       return __linear_to_generic_addr(dev, paddr);
+       return linear_to_generic_addr(dev, paddr);
 }
 
 /* requires lun->lock taken */
@@ -152,7 +182,7 @@ static struct rrpc_block *rrpc_get_blk(struct rrpc *rrpc, struct rrpc_lun *rlun,
        struct nvm_block *blk;
        struct rrpc_block *rblk;
 
-       blk = nvm_get_blk(rrpc->dev, rlun->parent, 0);
+       blk = nvm_get_blk(rrpc->dev, rlun->parent, flags);
        if (!blk)
                return NULL;
 
@@ -172,6 +202,20 @@ static void rrpc_put_blk(struct rrpc *rrpc, struct rrpc_block *rblk)
        nvm_put_blk(rrpc->dev, rblk->parent);
 }
 
+static void rrpc_put_blks(struct rrpc *rrpc)
+{
+       struct rrpc_lun *rlun;
+       int i;
+
+       for (i = 0; i < rrpc->nr_luns; i++) {
+               rlun = &rrpc->luns[i];
+               if (rlun->cur)
+                       rrpc_put_blk(rrpc, rlun->cur);
+               if (rlun->gc_cur)
+                       rrpc_put_blk(rrpc, rlun->gc_cur);
+       }
+}
+
 static struct rrpc_lun *get_next_lun(struct rrpc *rrpc)
 {
        int next = atomic_inc_return(&rrpc->next_lun);
@@ -972,7 +1016,7 @@ static int rrpc_map_init(struct rrpc *rrpc)
                return 0;
 
        /* Bring up the mapping table from device */
-       ret = dev->ops->get_l2p_tbl(dev->q, 0, dev->total_pages,
+       ret = dev->ops->get_l2p_tbl(dev, 0, dev->total_pages,
                                                        rrpc_l2p_update, rrpc);
        if (ret) {
                pr_err("nvm: rrpc: could not read L2P table.\n");
@@ -1194,18 +1238,21 @@ static int rrpc_luns_configure(struct rrpc *rrpc)
 
                rblk = rrpc_get_blk(rrpc, rlun, 0);
                if (!rblk)
-                       return -EINVAL;
+                       goto err;
 
                rrpc_set_lun_cur(rlun, rblk);
 
                /* Emergency gc block */
                rblk = rrpc_get_blk(rrpc, rlun, 1);
                if (!rblk)
-                       return -EINVAL;
+                       goto err;
                rlun->gc_cur = rblk;
        }
 
        return 0;
+err:
+       rrpc_put_blks(rrpc);
+       return -EINVAL;
 }
 
 static struct nvm_tgt_type tt_rrpc;
index 917d47e290ae08be08f4c964a3326f1f67acd077..3147c8d09ea84a0a76d0fd7ead35931a89e29aed 100644 (file)
@@ -112,7 +112,8 @@ struct iv_tcw_private {
  * and encrypts / decrypts at the same time.
  */
 enum flags { DM_CRYPT_SUSPENDED, DM_CRYPT_KEY_VALID,
-            DM_CRYPT_SAME_CPU, DM_CRYPT_NO_OFFLOAD };
+            DM_CRYPT_SAME_CPU, DM_CRYPT_NO_OFFLOAD,
+            DM_CRYPT_EXIT_THREAD};
 
 /*
  * The fields in here must be read only after initialization.
@@ -1203,20 +1204,18 @@ continue_locked:
                if (!RB_EMPTY_ROOT(&cc->write_tree))
                        goto pop_from_list;
 
+               if (unlikely(test_bit(DM_CRYPT_EXIT_THREAD, &cc->flags))) {
+                       spin_unlock_irq(&cc->write_thread_wait.lock);
+                       break;
+               }
+
                __set_current_state(TASK_INTERRUPTIBLE);
                __add_wait_queue(&cc->write_thread_wait, &wait);
 
                spin_unlock_irq(&cc->write_thread_wait.lock);
 
-               if (unlikely(kthread_should_stop())) {
-                       set_task_state(current, TASK_RUNNING);
-                       remove_wait_queue(&cc->write_thread_wait, &wait);
-                       break;
-               }
-
                schedule();
 
-               set_task_state(current, TASK_RUNNING);
                spin_lock_irq(&cc->write_thread_wait.lock);
                __remove_wait_queue(&cc->write_thread_wait, &wait);
                goto continue_locked;
@@ -1531,8 +1530,13 @@ static void crypt_dtr(struct dm_target *ti)
        if (!cc)
                return;
 
-       if (cc->write_thread)
+       if (cc->write_thread) {
+               spin_lock_irq(&cc->write_thread_wait.lock);
+               set_bit(DM_CRYPT_EXIT_THREAD, &cc->flags);
+               wake_up_locked(&cc->write_thread_wait);
+               spin_unlock_irq(&cc->write_thread_wait.lock);
                kthread_stop(cc->write_thread);
+       }
 
        if (cc->io_queue)
                destroy_workqueue(cc->io_queue);
index aaa6caa46a9f2dbceaf3d9c1aac92037b3b731b2..cfa29f574c2a9e1454788a5757471835b254d857 100644 (file)
@@ -1537,32 +1537,34 @@ static int multipath_prepare_ioctl(struct dm_target *ti,
                struct block_device **bdev, fmode_t *mode)
 {
        struct multipath *m = ti->private;
-       struct pgpath *pgpath;
        unsigned long flags;
        int r;
 
-       r = 0;
-
        spin_lock_irqsave(&m->lock, flags);
 
        if (!m->current_pgpath)
                __choose_pgpath(m, 0);
 
-       pgpath = m->current_pgpath;
-
-       if (pgpath) {
-               *bdev = pgpath->path.dev->bdev;
-               *mode = pgpath->path.dev->mode;
+       if (m->current_pgpath) {
+               if (!m->queue_io) {
+                       *bdev = m->current_pgpath->path.dev->bdev;
+                       *mode = m->current_pgpath->path.dev->mode;
+                       r = 0;
+               } else {
+                       /* pg_init has not started or completed */
+                       r = -ENOTCONN;
+               }
+       } else {
+               /* No path is available */
+               if (m->queue_if_no_path)
+                       r = -ENOTCONN;
+               else
+                       r = -EIO;
        }
 
-       if ((pgpath && m->queue_io) || (!pgpath && m->queue_if_no_path))
-               r = -ENOTCONN;
-       else if (!*bdev)
-               r = -EIO;
-
        spin_unlock_irqrestore(&m->lock, flags);
 
-       if (r == -ENOTCONN && !fatal_signal_pending(current)) {
+       if (r == -ENOTCONN) {
                spin_lock_irqsave(&m->lock, flags);
                if (!m->current_pg) {
                        /* Path status changed, redo selection */
index 1fa45695b68a4eb6ed3db388d30f6e88f06fee21..c219a053c7f66d1ebae80a19b005af38914dbe8c 100644 (file)
@@ -1206,6 +1206,12 @@ static int __reserve_metadata_snap(struct dm_pool_metadata *pmd)
        struct dm_block *copy, *sblock;
        dm_block_t held_root;
 
+       /*
+        * We commit to ensure the btree roots which we increment in a
+        * moment are up to date.
+        */
+       __commit_transaction(pmd);
+
        /*
         * Copy the superblock.
         */
@@ -1538,7 +1544,7 @@ static int __remove(struct dm_thin_device *td, dm_block_t block)
 static int __remove_range(struct dm_thin_device *td, dm_block_t begin, dm_block_t end)
 {
        int r;
-       unsigned count;
+       unsigned count, total_count = 0;
        struct dm_pool_metadata *pmd = td->pmd;
        dm_block_t keys[1] = { td->id };
        __le64 value;
@@ -1561,11 +1567,29 @@ static int __remove_range(struct dm_thin_device *td, dm_block_t begin, dm_block_
        if (r)
                return r;
 
-       r = dm_btree_remove_leaves(&pmd->bl_info, mapping_root, &begin, end, &mapping_root, &count);
-       if (r)
-               return r;
+       /*
+        * Remove leaves stops at the first unmapped entry, so we have to
+        * loop round finding mapped ranges.
+        */
+       while (begin < end) {
+               r = dm_btree_lookup_next(&pmd->bl_info, mapping_root, &begin, &begin, &value);
+               if (r == -ENODATA)
+                       break;
+
+               if (r)
+                       return r;
+
+               if (begin >= end)
+                       break;
+
+               r = dm_btree_remove_leaves(&pmd->bl_info, mapping_root, &begin, end, &mapping_root, &count);
+               if (r)
+                       return r;
+
+               total_count += count;
+       }
 
-       td->mapped_blocks -= count;
+       td->mapped_blocks -= total_count;
        td->changed = 1;
 
        /*
index 3897b90bd462d852e0aec27a792be14655efa150..63903a5a5d9ee3b580d552673b42b9716b99322c 100644 (file)
@@ -2432,6 +2432,7 @@ static void set_pool_mode(struct pool *pool, enum pool_mode new_mode)
        case PM_WRITE:
                if (old_mode != new_mode)
                        notify_of_pool_mode_change(pool, "write");
+               pool->pf.error_if_no_space = pt->requested_pf.error_if_no_space;
                dm_pool_metadata_read_write(pool->pmd);
                pool->process_bio = process_bio;
                pool->process_discard = process_discard_bio;
@@ -4249,10 +4250,9 @@ static void thin_io_hints(struct dm_target *ti, struct queue_limits *limits)
 {
        struct thin_c *tc = ti->private;
        struct pool *pool = tc->pool;
-       struct queue_limits *pool_limits = dm_get_queue_limits(pool->pool_md);
 
-       if (!pool_limits->discard_granularity)
-               return; /* pool's discard support is disabled */
+       if (!pool->pf.discard_enabled)
+               return;
 
        limits->discard_granularity = pool->sectors_per_block << SECTOR_SHIFT;
        limits->max_discard_sectors = 2048 * 1024 * 16; /* 16G */
index 6e15f3565892fce8315cef992e0b2721e8c20088..5df40480228b7a26e3c73ac78e963ce47ed25448 100644 (file)
@@ -591,7 +591,7 @@ retry:
 
 out:
        dm_put_live_table(md, *srcu_idx);
-       if (r == -ENOTCONN) {
+       if (r == -ENOTCONN && !fatal_signal_pending(current)) {
                msleep(10);
                goto retry;
        }
@@ -603,9 +603,10 @@ static int dm_blk_ioctl(struct block_device *bdev, fmode_t mode,
 {
        struct mapped_device *md = bdev->bd_disk->private_data;
        struct dm_target *tgt;
+       struct block_device *tgt_bdev = NULL;
        int srcu_idx, r;
 
-       r = dm_get_live_table_for_ioctl(md, &tgt, &bdev, &mode, &srcu_idx);
+       r = dm_get_live_table_for_ioctl(md, &tgt, &tgt_bdev, &mode, &srcu_idx);
        if (r < 0)
                return r;
 
@@ -620,7 +621,7 @@ static int dm_blk_ioctl(struct block_device *bdev, fmode_t mode,
                        goto out;
        }
 
-       r =  __blkdev_driver_ioctl(bdev, mode, cmd, arg);
+       r =  __blkdev_driver_ioctl(tgt_bdev, mode, cmd, arg);
 out:
        dm_put_live_table(md, srcu_idx);
        return r;
index c573402033b2dd9e89dc11ad2f6e1b7e8bbb4263..b1ced58eb5e1475b440a15de0e26811fb90b8159 100644 (file)
@@ -63,6 +63,11 @@ int lower_bound(struct btree_node *n, uint64_t key)
        return bsearch(n, key, 0);
 }
 
+static int upper_bound(struct btree_node *n, uint64_t key)
+{
+       return bsearch(n, key, 1);
+}
+
 void inc_children(struct dm_transaction_manager *tm, struct btree_node *n,
                  struct dm_btree_value_type *vt)
 {
@@ -252,6 +257,16 @@ static void pop_frame(struct del_stack *s)
        dm_tm_unlock(s->tm, f->b);
 }
 
+static void unlock_all_frames(struct del_stack *s)
+{
+       struct frame *f;
+
+       while (unprocessed_frames(s)) {
+               f = s->spine + s->top--;
+               dm_tm_unlock(s->tm, f->b);
+       }
+}
+
 int dm_btree_del(struct dm_btree_info *info, dm_block_t root)
 {
        int r;
@@ -308,9 +323,13 @@ int dm_btree_del(struct dm_btree_info *info, dm_block_t root)
                        pop_frame(s);
                }
        }
-
 out:
+       if (r) {
+               /* cleanup all frames of del_stack */
+               unlock_all_frames(s);
+       }
        kfree(s);
+
        return r;
 }
 EXPORT_SYMBOL_GPL(dm_btree_del);
@@ -392,6 +411,82 @@ int dm_btree_lookup(struct dm_btree_info *info, dm_block_t root,
 }
 EXPORT_SYMBOL_GPL(dm_btree_lookup);
 
+static int dm_btree_lookup_next_single(struct dm_btree_info *info, dm_block_t root,
+                                      uint64_t key, uint64_t *rkey, void *value_le)
+{
+       int r, i;
+       uint32_t flags, nr_entries;
+       struct dm_block *node;
+       struct btree_node *n;
+
+       r = bn_read_lock(info, root, &node);
+       if (r)
+               return r;
+
+       n = dm_block_data(node);
+       flags = le32_to_cpu(n->header.flags);
+       nr_entries = le32_to_cpu(n->header.nr_entries);
+
+       if (flags & INTERNAL_NODE) {
+               i = lower_bound(n, key);
+               if (i < 0 || i >= nr_entries) {
+                       r = -ENODATA;
+                       goto out;
+               }
+
+               r = dm_btree_lookup_next_single(info, value64(n, i), key, rkey, value_le);
+               if (r == -ENODATA && i < (nr_entries - 1)) {
+                       i++;
+                       r = dm_btree_lookup_next_single(info, value64(n, i), key, rkey, value_le);
+               }
+
+       } else {
+               i = upper_bound(n, key);
+               if (i < 0 || i >= nr_entries) {
+                       r = -ENODATA;
+                       goto out;
+               }
+
+               *rkey = le64_to_cpu(n->keys[i]);
+               memcpy(value_le, value_ptr(n, i), info->value_type.size);
+       }
+out:
+       dm_tm_unlock(info->tm, node);
+       return r;
+}
+
+int dm_btree_lookup_next(struct dm_btree_info *info, dm_block_t root,
+                        uint64_t *keys, uint64_t *rkey, void *value_le)
+{
+       unsigned level;
+       int r = -ENODATA;
+       __le64 internal_value_le;
+       struct ro_spine spine;
+
+       init_ro_spine(&spine, info);
+       for (level = 0; level < info->levels - 1u; level++) {
+               r = btree_lookup_raw(&spine, root, keys[level],
+                                    lower_bound, rkey,
+                                    &internal_value_le, sizeof(uint64_t));
+               if (r)
+                       goto out;
+
+               if (*rkey != keys[level]) {
+                       r = -ENODATA;
+                       goto out;
+               }
+
+               root = le64_to_cpu(internal_value_le);
+       }
+
+       r = dm_btree_lookup_next_single(info, root, keys[level], rkey, value_le);
+out:
+       exit_ro_spine(&spine);
+       return r;
+}
+
+EXPORT_SYMBOL_GPL(dm_btree_lookup_next);
+
 /*
  * Splits a node by creating a sibling node and shifting half the nodes
  * contents across.  Assumes there is a parent node, and it has room for
@@ -473,8 +568,10 @@ static int btree_split_sibling(struct shadow_spine *s, unsigned parent_index,
 
        r = insert_at(sizeof(__le64), pn, parent_index + 1,
                      le64_to_cpu(rn->keys[0]), &location);
-       if (r)
+       if (r) {
+               unlock_block(s->info, right);
                return r;
+       }
 
        if (key < le64_to_cpu(rn->keys[0])) {
                unlock_block(s->info, right);
index 11d8cf78621dded80328187e1009ca0dc35c6997..c74301fa5a379517b9c37e7e98ab380d97f3b9b0 100644 (file)
@@ -109,6 +109,13 @@ int dm_btree_del(struct dm_btree_info *info, dm_block_t root);
 int dm_btree_lookup(struct dm_btree_info *info, dm_block_t root,
                    uint64_t *keys, void *value_le);
 
+/*
+ * Tries to find the first key where the bottom level key is >= to that
+ * given.  Useful for skipping empty sections of the btree.
+ */
+int dm_btree_lookup_next(struct dm_btree_info *info, dm_block_t root,
+                        uint64_t *keys, uint64_t *rkey, void *value_le);
+
 /*
  * Insertion (or overwrite an existing value).  O(ln(n))
  */
@@ -135,9 +142,10 @@ int dm_btree_remove(struct dm_btree_info *info, dm_block_t root,
                    uint64_t *keys, dm_block_t *new_root);
 
 /*
- * Removes values between 'keys' and keys2, where keys2 is keys with the
- * final key replaced with 'end_key'.  'end_key' is the one-past-the-end
- * value.  'keys' may be altered.
+ * Removes a _contiguous_ run of values starting from 'keys' and not
+ * reaching keys2 (where keys2 is keys with the final key replaced with
+ * 'end_key').  'end_key' is the one-past-the-end value.  'keys' may be
+ * altered.
  */
 int dm_btree_remove_leaves(struct dm_btree_info *info, dm_block_t root,
                           uint64_t *keys, uint64_t end_key,
index 53091295fce9b7d9ffec9b91a6a0bdddd20ed67f..fca6dbcf9a4727f85d61f7d161094870f5db24d5 100644 (file)
@@ -136,7 +136,7 @@ static int brb_push(struct bop_ring_buffer *brb,
        return 0;
 }
 
-static int brb_pop(struct bop_ring_buffer *brb, struct block_op *result)
+static int brb_peek(struct bop_ring_buffer *brb, struct block_op *result)
 {
        struct block_op *bop;
 
@@ -147,6 +147,17 @@ static int brb_pop(struct bop_ring_buffer *brb, struct block_op *result)
        result->type = bop->type;
        result->block = bop->block;
 
+       return 0;
+}
+
+static int brb_pop(struct bop_ring_buffer *brb)
+{
+       struct block_op *bop;
+
+       if (brb_empty(brb))
+               return -ENODATA;
+
+       bop = brb->bops + brb->begin;
        brb->begin = brb_next(brb, brb->begin);
 
        return 0;
@@ -211,7 +222,7 @@ static int apply_bops(struct sm_metadata *smm)
        while (!brb_empty(&smm->uncommitted)) {
                struct block_op bop;
 
-               r = brb_pop(&smm->uncommitted, &bop);
+               r = brb_peek(&smm->uncommitted, &bop);
                if (r) {
                        DMERR("bug in bop ring buffer");
                        break;
@@ -220,6 +231,8 @@ static int apply_bops(struct sm_metadata *smm)
                r = commit_bop(smm, &bop);
                if (r)
                        break;
+
+               brb_pop(&smm->uncommitted);
        }
 
        return r;
@@ -683,7 +696,6 @@ static struct dm_space_map bootstrap_ops = {
 static int sm_metadata_extend(struct dm_space_map *sm, dm_block_t extra_blocks)
 {
        int r, i;
-       enum allocation_event ev;
        struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm);
        dm_block_t old_len = smm->ll.nr_blocks;
 
@@ -705,11 +717,12 @@ static int sm_metadata_extend(struct dm_space_map *sm, dm_block_t extra_blocks)
         * allocate any new blocks.
         */
        do {
-               for (i = old_len; !r && i < smm->begin; i++) {
-                       r = sm_ll_inc(&smm->ll, i, &ev);
-                       if (r)
-                               goto out;
-               }
+               for (i = old_len; !r && i < smm->begin; i++)
+                       r = add_bop(smm, BOP_INC, i);
+
+               if (r)
+                       goto out;
+
                old_len = smm->begin;
 
                r = apply_bops(smm);
@@ -754,7 +767,6 @@ int dm_sm_metadata_create(struct dm_space_map *sm,
 {
        int r;
        dm_block_t i;
-       enum allocation_event ev;
        struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm);
 
        smm->begin = superblock + 1;
@@ -782,7 +794,7 @@ int dm_sm_metadata_create(struct dm_space_map *sm,
         * allocated blocks that they were built from.
         */
        for (i = superblock; !r && i < smm->begin; i++)
-               r = sm_ll_inc(&smm->ll, i, &ev);
+               r = add_bop(smm, BOP_INC, i);
 
        if (r)
                return r;
index d2e75c88f4d2165762913c27c57e5d4487e431ad..f4090979349068b3057d0cd9d8a17d15168ce734 100644 (file)
@@ -497,6 +497,7 @@ static u64 calculate_sr(struct cxl_context *ctx)
 {
        u64 sr = 0;
 
+       set_endian(sr);
        if (ctx->master)
                sr |= CXL_PSL_SR_An_MP;
        if (mfspr(SPRN_LPCR) & LPCR_TC)
@@ -506,7 +507,6 @@ static u64 calculate_sr(struct cxl_context *ctx)
                sr |= CXL_PSL_SR_An_HV;
        } else {
                sr |= CXL_PSL_SR_An_PR | CXL_PSL_SR_An_R;
-               set_endian(sr);
                sr &= ~(CXL_PSL_SR_An_HV);
                if (!test_tsk_thread_flag(current, TIF_32BIT))
                        sr |= CXL_PSL_SR_An_SF;
index 57dadd52b428a536d71f2364c006641e5e765083..1deb8ff90a89528e147b42353500d1610ff4a285 100644 (file)
@@ -501,8 +501,6 @@ static int bfin_can_err(struct net_device *dev, u16 isrc, u16 status)
                        cf->data[2] |= CAN_ERR_PROT_FORM;
                else if (status & SER)
                        cf->data[2] |= CAN_ERR_PROT_STUFF;
-               else
-                       cf->data[2] |= CAN_ERR_PROT_UNSPEC;
        }
 
        priv->can.state = state;
index 5d214d1353320856cf3de91d837b910df3f3de24..f91b094288dad3d86064f24a33a97ad58756f3ca 100644 (file)
@@ -962,7 +962,6 @@ static int c_can_handle_bus_err(struct net_device *dev,
         * type of the last error to occur on the CAN bus
         */
        cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
-       cf->data[2] |= CAN_ERR_PROT_UNSPEC;
 
        switch (lec_type) {
        case LEC_STUFF_ERROR:
@@ -975,8 +974,7 @@ static int c_can_handle_bus_err(struct net_device *dev,
                break;
        case LEC_ACK_ERROR:
                netdev_dbg(dev, "ack error\n");
-               cf->data[3] |= (CAN_ERR_PROT_LOC_ACK |
-                               CAN_ERR_PROT_LOC_ACK_DEL);
+               cf->data[3] = CAN_ERR_PROT_LOC_ACK;
                break;
        case LEC_BIT1_ERROR:
                netdev_dbg(dev, "bit1 error\n");
@@ -988,8 +986,7 @@ static int c_can_handle_bus_err(struct net_device *dev,
                break;
        case LEC_CRC_ERROR:
                netdev_dbg(dev, "CRC error\n");
-               cf->data[3] |= (CAN_ERR_PROT_LOC_CRC_SEQ |
-                               CAN_ERR_PROT_LOC_CRC_DEL);
+               cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ;
                break;
        default:
                break;
index 70a8cbb29e75844a02bea49a937bf0c05a200910..1e37313054f3950ee30e6c6fccad874d9262013a 100644 (file)
@@ -578,7 +578,7 @@ static int cc770_err(struct net_device *dev, u8 status)
                                cf->data[2] |= CAN_ERR_PROT_BIT0;
                                break;
                        case STAT_LEC_CRC:
-                               cf->data[3] |= CAN_ERR_PROT_LOC_CRC_SEQ;
+                               cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ;
                                break;
                        }
                }
index 868fe945e35a39786bf15fb8b142c36a720179a5..41c0fc9f3b1465d9dbbde6b5c7798b1e40cf43ef 100644 (file)
@@ -535,13 +535,13 @@ static void do_bus_err(struct net_device *dev,
        if (reg_esr & FLEXCAN_ESR_ACK_ERR) {
                netdev_dbg(dev, "ACK_ERR irq\n");
                cf->can_id |= CAN_ERR_ACK;
-               cf->data[3] |= CAN_ERR_PROT_LOC_ACK;
+               cf->data[3] = CAN_ERR_PROT_LOC_ACK;
                tx_errors = 1;
        }
        if (reg_esr & FLEXCAN_ESR_CRC_ERR) {
                netdev_dbg(dev, "CRC_ERR irq\n");
                cf->data[2] |= CAN_ERR_PROT_BIT;
-               cf->data[3] |= CAN_ERR_PROT_LOC_CRC_SEQ;
+               cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ;
                rx_errors = 1;
        }
        if (reg_esr & FLEXCAN_ESR_FRM_ERR) {
index c1e85368a198bd898f853c5842c58fbb3b01b04b..5d04f5464faf29a8b1c99dcc8bae86becbd1c485 100644 (file)
@@ -1096,7 +1096,6 @@ static int ican3_handle_cevtind(struct ican3_dev *mod, struct ican3_msg *msg)
                        cf->data[2] |= CAN_ERR_PROT_STUFF;
                        break;
                default:
-                       cf->data[2] |= CAN_ERR_PROT_UNSPEC;
                        cf->data[3] = ecc & ECC_SEG;
                        break;
                }
index ef655177bb5e5b62a7be1f821d08a88226ba7b84..39cf911f7a1e3c364d7818bdc6bcd162a6490951 100644 (file)
@@ -487,7 +487,6 @@ static int m_can_handle_lec_err(struct net_device *dev,
         * type of the last error to occur on the CAN bus
         */
        cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
-       cf->data[2] |= CAN_ERR_PROT_UNSPEC;
 
        switch (lec_type) {
        case LEC_STUFF_ERROR:
@@ -500,8 +499,7 @@ static int m_can_handle_lec_err(struct net_device *dev,
                break;
        case LEC_ACK_ERROR:
                netdev_dbg(dev, "ack error\n");
-               cf->data[3] |= (CAN_ERR_PROT_LOC_ACK |
-                               CAN_ERR_PROT_LOC_ACK_DEL);
+               cf->data[3] = CAN_ERR_PROT_LOC_ACK;
                break;
        case LEC_BIT1_ERROR:
                netdev_dbg(dev, "bit1 error\n");
@@ -513,8 +511,7 @@ static int m_can_handle_lec_err(struct net_device *dev,
                break;
        case LEC_CRC_ERROR:
                netdev_dbg(dev, "CRC error\n");
-               cf->data[3] |= (CAN_ERR_PROT_LOC_CRC_SEQ |
-                               CAN_ERR_PROT_LOC_CRC_DEL);
+               cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ;
                break;
        default:
                break;
index e187ca783da0946def7585ff8d85ac76ea201e05..c1317889d3d8d97858604feeb63fa4f7cec8a368 100644 (file)
@@ -559,8 +559,7 @@ static void pch_can_error(struct net_device *ndev, u32 status)
                stats->rx_errors++;
                break;
        case PCH_CRC_ERR:
-               cf->data[3] |= CAN_ERR_PROT_LOC_CRC_SEQ |
-                              CAN_ERR_PROT_LOC_CRC_DEL;
+               cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ;
                priv->can.can_stats.bus_error++;
                stats->rx_errors++;
                break;
index 7bd54191f962a4ad3079eabdcefb0d001a14bf0b..bc46be39549d2ab317862ba376ccb063be65b7be 100644 (file)
@@ -241,17 +241,16 @@ static void rcar_can_error(struct net_device *ndev)
                u8 ecsr;
 
                netdev_dbg(priv->ndev, "Bus error interrupt:\n");
-               if (skb) {
+               if (skb)
                        cf->can_id |= CAN_ERR_BUSERROR | CAN_ERR_PROT;
-                       cf->data[2] = CAN_ERR_PROT_UNSPEC;
-               }
+
                ecsr = readb(&priv->regs->ecsr);
                if (ecsr & RCAR_CAN_ECSR_ADEF) {
                        netdev_dbg(priv->ndev, "ACK Delimiter Error\n");
                        tx_errors++;
                        writeb(~RCAR_CAN_ECSR_ADEF, &priv->regs->ecsr);
                        if (skb)
-                               cf->data[3] |= CAN_ERR_PROT_LOC_ACK_DEL;
+                               cf->data[3] = CAN_ERR_PROT_LOC_ACK_DEL;
                }
                if (ecsr & RCAR_CAN_ECSR_BE0F) {
                        netdev_dbg(priv->ndev, "Bit Error (dominant)\n");
@@ -272,7 +271,7 @@ static void rcar_can_error(struct net_device *ndev)
                        rx_errors++;
                        writeb(~RCAR_CAN_ECSR_CEF, &priv->regs->ecsr);
                        if (skb)
-                               cf->data[3] |= CAN_ERR_PROT_LOC_CRC_SEQ;
+                               cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ;
                }
                if (ecsr & RCAR_CAN_ECSR_AEF) {
                        netdev_dbg(priv->ndev, "ACK Error\n");
@@ -280,7 +279,7 @@ static void rcar_can_error(struct net_device *ndev)
                        writeb(~RCAR_CAN_ECSR_AEF, &priv->regs->ecsr);
                        if (skb) {
                                cf->can_id |= CAN_ERR_ACK;
-                               cf->data[3] |= CAN_ERR_PROT_LOC_ACK;
+                               cf->data[3] = CAN_ERR_PROT_LOC_ACK;
                        }
                }
                if (ecsr & RCAR_CAN_ECSR_FEF) {
index 7b92e911a6168badb3e30f8fc55b2e6fdd0f61dc..8dda3b703d39a1e82ce7fc6a63707e883d235313 100644 (file)
@@ -218,6 +218,9 @@ static void sja1000_start(struct net_device *dev)
        priv->write_reg(priv, SJA1000_RXERR, 0x0);
        priv->read_reg(priv, SJA1000_ECC);
 
+       /* clear interrupt flags */
+       priv->read_reg(priv, SJA1000_IR);
+
        /* leave reset mode */
        set_normal_mode(dev);
 }
@@ -446,7 +449,6 @@ static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status)
                        cf->data[2] |= CAN_ERR_PROT_STUFF;
                        break;
                default:
-                       cf->data[2] |= CAN_ERR_PROT_UNSPEC;
                        cf->data[3] = ecc & ECC_SEG;
                        break;
                }
index d9a42c6467836cdf3aa00adc1d5a4f059b97469e..68ef0a4cd82153cd65699ab0a4d80a5a201393e6 100644 (file)
@@ -575,7 +575,6 @@ static int sun4i_can_err(struct net_device *dev, u8 isrc, u8 status)
                                cf->data[2] |= CAN_ERR_PROT_STUFF;
                                break;
                        default:
-                               cf->data[2] |= CAN_ERR_PROT_UNSPEC;
                                cf->data[3] = (ecc & SUN4I_STA_ERR_SEG_CODE)
                                               >> 16;
                                break;
index cf345cbfe8198ef23ee328fc2eb67f5841751ee1..680d1ff07a55ddd60ceb09eb42bb98faaa42ad9f 100644 (file)
@@ -722,7 +722,6 @@ static int ti_hecc_error(struct net_device *ndev, int int_status,
        if (err_status & HECC_BUS_ERROR) {
                ++priv->can.can_stats.bus_error;
                cf->can_id |= CAN_ERR_BUSERROR | CAN_ERR_PROT;
-               cf->data[2] |= CAN_ERR_PROT_UNSPEC;
                if (err_status & HECC_CANES_FE) {
                        hecc_set_bit(priv, HECC_CANES, HECC_CANES_FE);
                        cf->data[2] |= CAN_ERR_PROT_FORM;
@@ -737,13 +736,11 @@ static int ti_hecc_error(struct net_device *ndev, int int_status,
                }
                if (err_status & HECC_CANES_CRCE) {
                        hecc_set_bit(priv, HECC_CANES, HECC_CANES_CRCE);
-                       cf->data[3] |= CAN_ERR_PROT_LOC_CRC_SEQ |
-                                       CAN_ERR_PROT_LOC_CRC_DEL;
+                       cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ;
                }
                if (err_status & HECC_CANES_ACKE) {
                        hecc_set_bit(priv, HECC_CANES, HECC_CANES_ACKE);
-                       cf->data[3] |= CAN_ERR_PROT_LOC_ACK |
-                                       CAN_ERR_PROT_LOC_ACK_DEL;
+                       cf->data[3] = CAN_ERR_PROT_LOC_ACK;
                }
        }
 
index 2d390384ef3bb3d3845fcf6102bef70715f1dd21..fc5b75675cd8b6dbebbbc79d357001676900fefa 100644 (file)
@@ -377,7 +377,6 @@ static void ems_usb_rx_err(struct ems_usb *dev, struct ems_cpc_msg *msg)
                        cf->data[2] |= CAN_ERR_PROT_STUFF;
                        break;
                default:
-                       cf->data[2] |= CAN_ERR_PROT_UNSPEC;
                        cf->data[3] = ecc & SJA1000_ECC_SEG;
                        break;
                }
index 0e5a4493ba4fee6d3c4fb5626a676f18802a6ef3..113e64fcd73be9a16635f0029ed3c6d0c2a17306 100644 (file)
@@ -282,7 +282,6 @@ static void esd_usb2_rx_event(struct esd_usb2_net_priv *priv,
                                cf->data[2] |= CAN_ERR_PROT_STUFF;
                                break;
                        default:
-                               cf->data[2] |= CAN_ERR_PROT_UNSPEC;
                                cf->data[3] = ecc & SJA1000_ECC_SEG;
                                break;
                        }
index 8b17a9065b0b193a0c5e5a93048c637f0f7fbad3..022bfa13ebfa0c85491cfc2cb17a3437c01f0205 100644 (file)
@@ -944,10 +944,9 @@ static void kvaser_usb_rx_error(const struct kvaser_usb *dev,
                        cf->can_id |= CAN_ERR_BUSERROR | CAN_ERR_PROT;
 
                        if (es->leaf.error_factor & M16C_EF_ACKE)
-                               cf->data[3] |= (CAN_ERR_PROT_LOC_ACK);
+                               cf->data[3] = CAN_ERR_PROT_LOC_ACK;
                        if (es->leaf.error_factor & M16C_EF_CRCE)
-                               cf->data[3] |= (CAN_ERR_PROT_LOC_CRC_SEQ |
-                                               CAN_ERR_PROT_LOC_CRC_DEL);
+                               cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ;
                        if (es->leaf.error_factor & M16C_EF_FORME)
                                cf->data[2] |= CAN_ERR_PROT_FORM;
                        if (es->leaf.error_factor & M16C_EF_STFE)
index de95b1ccba3e3b6d4d00e313acb280cd178a000d..a731720f1d132501d12d6241ccee833ae2e61787 100644 (file)
@@ -401,9 +401,7 @@ static void usb_8dev_rx_err_msg(struct usb_8dev_priv *priv,
                tx_errors = 1;
                break;
        case USB_8DEV_STATUSMSG_CRC:
-               cf->data[2] |= CAN_ERR_PROT_UNSPEC;
-               cf->data[3] |= CAN_ERR_PROT_LOC_CRC_SEQ |
-                              CAN_ERR_PROT_LOC_CRC_DEL;
+               cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ;
                rx_errors = 1;
                break;
        case USB_8DEV_STATUSMSG_BIT0:
index fc55e8e0351dfe5f3ca436d8aed64bf6d660db84..51670b322409b6606736751dae23433e1d165500 100644 (file)
@@ -608,17 +608,15 @@ static void xcan_err_interrupt(struct net_device *ndev, u32 isr)
 
        /* Check for error interrupt */
        if (isr & XCAN_IXR_ERROR_MASK) {
-               if (skb) {
+               if (skb)
                        cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
-                       cf->data[2] |= CAN_ERR_PROT_UNSPEC;
-               }
 
                /* Check for Ack error interrupt */
                if (err_status & XCAN_ESR_ACKER_MASK) {
                        stats->tx_errors++;
                        if (skb) {
                                cf->can_id |= CAN_ERR_ACK;
-                               cf->data[3] |= CAN_ERR_PROT_LOC_ACK;
+                               cf->data[3] = CAN_ERR_PROT_LOC_ACK;
                        }
                }
 
@@ -654,8 +652,7 @@ static void xcan_err_interrupt(struct net_device *ndev, u32 isr)
                        stats->rx_errors++;
                        if (skb) {
                                cf->can_id |= CAN_ERR_PROT;
-                               cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ |
-                                               CAN_ERR_PROT_LOC_CRC_DEL;
+                               cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ;
                        }
                }
                        priv->can.can_stats.bus_error++;
index 955d06b9cdba75e82fa87deb26fbb37e08140f87..31c5e476fd648fff18a9a4701ba0b214656e45db 100644 (file)
@@ -29,6 +29,7 @@ source "drivers/net/ethernet/apm/Kconfig"
 source "drivers/net/ethernet/apple/Kconfig"
 source "drivers/net/ethernet/arc/Kconfig"
 source "drivers/net/ethernet/atheros/Kconfig"
+source "drivers/net/ethernet/aurora/Kconfig"
 source "drivers/net/ethernet/cadence/Kconfig"
 source "drivers/net/ethernet/adi/Kconfig"
 source "drivers/net/ethernet/broadcom/Kconfig"
index 4a2ee98738f04ef6eda76d776176dba22a9a7ef0..071f84eb6f3f8c8f0b7add3e31d1873609dc4486 100644 (file)
@@ -15,6 +15,7 @@ obj-$(CONFIG_NET_XGENE) += apm/
 obj-$(CONFIG_NET_VENDOR_APPLE) += apple/
 obj-$(CONFIG_NET_VENDOR_ARC) += arc/
 obj-$(CONFIG_NET_VENDOR_ATHEROS) += atheros/
+obj-$(CONFIG_NET_VENDOR_AURORA) += aurora/
 obj-$(CONFIG_NET_CADENCE) += cadence/
 obj-$(CONFIG_NET_BFIN) += adi/
 obj-$(CONFIG_NET_VENDOR_BROADCOM) += broadcom/
index 991412ce6f48fbbf6fdfd6255003a0aa90e67e01..9147a0107c44034f015beba83cfc150398c1ac93 100644 (file)
@@ -450,12 +450,12 @@ static netdev_tx_t xgene_enet_start_xmit(struct sk_buff *skb,
                return NETDEV_TX_OK;
        }
 
-       pdata->ring_ops->wr_cmd(tx_ring, count);
        skb_tx_timestamp(skb);
 
        pdata->stats.tx_packets++;
        pdata->stats.tx_bytes += skb->len;
 
+       pdata->ring_ops->wr_cmd(tx_ring, count);
        return NETDEV_TX_OK;
 }
 
@@ -688,10 +688,10 @@ static int xgene_enet_open(struct net_device *ndev)
        mac_ops->tx_enable(pdata);
        mac_ops->rx_enable(pdata);
 
+       xgene_enet_napi_enable(pdata);
        ret = xgene_enet_register_irq(ndev);
        if (ret)
                return ret;
-       xgene_enet_napi_enable(pdata);
 
        if (pdata->phy_mode == PHY_INTERFACE_MODE_RGMII)
                phy_start(pdata->phy_dev);
@@ -715,13 +715,13 @@ static int xgene_enet_close(struct net_device *ndev)
        else
                cancel_delayed_work_sync(&pdata->link_work);
 
-       xgene_enet_napi_disable(pdata);
-       xgene_enet_free_irq(ndev);
-       xgene_enet_process_ring(pdata->rx_ring, -1);
-
        mac_ops->tx_disable(pdata);
        mac_ops->rx_disable(pdata);
 
+       xgene_enet_free_irq(ndev);
+       xgene_enet_napi_disable(pdata);
+       xgene_enet_process_ring(pdata->rx_ring, -1);
+
        return 0;
 }
 
@@ -1474,15 +1474,15 @@ static int xgene_enet_probe(struct platform_device *pdev)
        }
        ndev->hw_features = ndev->features;
 
-       ret = register_netdev(ndev);
+       ret = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(64));
        if (ret) {
-               netdev_err(ndev, "Failed to register netdev\n");
+               netdev_err(ndev, "No usable DMA configuration\n");
                goto err;
        }
 
-       ret = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(64));
+       ret = register_netdev(ndev);
        if (ret) {
-               netdev_err(ndev, "No usable DMA configuration\n");
+               netdev_err(ndev, "Failed to register netdev\n");
                goto err;
        }
 
@@ -1490,14 +1490,17 @@ static int xgene_enet_probe(struct platform_device *pdev)
        if (ret)
                goto err;
 
-       xgene_enet_napi_add(pdata);
        mac_ops = pdata->mac_ops;
-       if (pdata->phy_mode == PHY_INTERFACE_MODE_RGMII)
+       if (pdata->phy_mode == PHY_INTERFACE_MODE_RGMII) {
                ret = xgene_enet_mdio_config(pdata);
-       else
+               if (ret)
+                       goto err;
+       } else {
                INIT_DELAYED_WORK(&pdata->link_work, mac_ops->link_state);
+       }
 
-       return ret;
+       xgene_enet_napi_add(pdata);
+       return 0;
 err:
        unregister_netdev(ndev);
        free_netdev(ndev);
index c8af3ce3ea38d16d4c470ec5773b2d4f088b0f15..bd377a6b067d4e7cc2e4640514d6910a03167450 100644 (file)
@@ -1534,6 +1534,8 @@ static const struct pci_device_id alx_pci_tbl[] = {
          .driver_data = ALX_DEV_QUIRK_MSI_INTX_DISABLE_BUG },
        { PCI_VDEVICE(ATTANSIC, ALX_DEV_ID_E2200),
          .driver_data = ALX_DEV_QUIRK_MSI_INTX_DISABLE_BUG },
+       { PCI_VDEVICE(ATTANSIC, ALX_DEV_ID_E2400),
+         .driver_data = ALX_DEV_QUIRK_MSI_INTX_DISABLE_BUG },
        { PCI_VDEVICE(ATTANSIC, ALX_DEV_ID_AR8162),
          .driver_data = ALX_DEV_QUIRK_MSI_INTX_DISABLE_BUG },
        { PCI_VDEVICE(ATTANSIC, ALX_DEV_ID_AR8171) },
index af006b44b2a66ec3fd0892672e6a61a9ca362cc3..0959e6824cb635f0262524db9729988986193fb4 100644 (file)
@@ -37,6 +37,7 @@
 
 #define ALX_DEV_ID_AR8161                              0x1091
 #define ALX_DEV_ID_E2200                               0xe091
+#define ALX_DEV_ID_E2400                               0xe0a1
 #define ALX_DEV_ID_AR8162                              0x1090
 #define ALX_DEV_ID_AR8171                              0x10A1
 #define ALX_DEV_ID_AR8172                              0x10A0
diff --git a/drivers/net/ethernet/aurora/Kconfig b/drivers/net/ethernet/aurora/Kconfig
new file mode 100644 (file)
index 0000000..a3c7106
--- /dev/null
@@ -0,0 +1,20 @@
+config NET_VENDOR_AURORA
+       bool "Aurora VLSI devices"
+       help
+         If you have a network (Ethernet) device belonging to this class,
+         say Y.
+
+         Note that the answer to this question doesn't directly affect the
+         kernel: saying N will just cause the configurator to skip all
+         questions about Aurora devices. If you say Y, you will be asked
+         for your specific device in the following questions.
+
+if NET_VENDOR_AURORA
+
+config AURORA_NB8800
+       tristate "Aurora AU-NB8800 support"
+       select PHYLIB
+       help
+        Support for the AU-NB8800 gigabit Ethernet controller.
+
+endif
diff --git a/drivers/net/ethernet/aurora/Makefile b/drivers/net/ethernet/aurora/Makefile
new file mode 100644 (file)
index 0000000..6cb528a
--- /dev/null
@@ -0,0 +1 @@
+obj-$(CONFIG_AURORA_NB8800) += nb8800.o
diff --git a/drivers/net/ethernet/aurora/nb8800.c b/drivers/net/ethernet/aurora/nb8800.c
new file mode 100644 (file)
index 0000000..ecc4a33
--- /dev/null
@@ -0,0 +1,1552 @@
+/*
+ * Copyright (C) 2015 Mans Rullgard <mans@mansr.com>
+ *
+ * Mostly rewritten, based on driver from Sigma Designs.  Original
+ * copyright notice below.
+ *
+ *
+ * Driver for tangox SMP864x/SMP865x/SMP867x/SMP868x builtin Ethernet Mac.
+ *
+ * Copyright (C) 2005 Maxime Bizon <mbizon@freebox.fr>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/etherdevice.h>
+#include <linux/delay.h>
+#include <linux/ethtool.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/of_device.h>
+#include <linux/of_mdio.h>
+#include <linux/of_net.h>
+#include <linux/dma-mapping.h>
+#include <linux/phy.h>
+#include <linux/cache.h>
+#include <linux/jiffies.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <asm/barrier.h>
+
+#include "nb8800.h"
+
+static void nb8800_tx_done(struct net_device *dev);
+static int nb8800_dma_stop(struct net_device *dev);
+
+static inline u8 nb8800_readb(struct nb8800_priv *priv, int reg)
+{
+       return readb_relaxed(priv->base + reg);
+}
+
+static inline u32 nb8800_readl(struct nb8800_priv *priv, int reg)
+{
+       return readl_relaxed(priv->base + reg);
+}
+
+static inline void nb8800_writeb(struct nb8800_priv *priv, int reg, u8 val)
+{
+       writeb_relaxed(val, priv->base + reg);
+}
+
+static inline void nb8800_writew(struct nb8800_priv *priv, int reg, u16 val)
+{
+       writew_relaxed(val, priv->base + reg);
+}
+
+static inline void nb8800_writel(struct nb8800_priv *priv, int reg, u32 val)
+{
+       writel_relaxed(val, priv->base + reg);
+}
+
+static inline void nb8800_maskb(struct nb8800_priv *priv, int reg,
+                               u32 mask, u32 val)
+{
+       u32 old = nb8800_readb(priv, reg);
+       u32 new = (old & ~mask) | (val & mask);
+
+       if (new != old)
+               nb8800_writeb(priv, reg, new);
+}
+
+static inline void nb8800_maskl(struct nb8800_priv *priv, int reg,
+                               u32 mask, u32 val)
+{
+       u32 old = nb8800_readl(priv, reg);
+       u32 new = (old & ~mask) | (val & mask);
+
+       if (new != old)
+               nb8800_writel(priv, reg, new);
+}
+
+static inline void nb8800_modb(struct nb8800_priv *priv, int reg, u8 bits,
+                              bool set)
+{
+       nb8800_maskb(priv, reg, bits, set ? bits : 0);
+}
+
+static inline void nb8800_setb(struct nb8800_priv *priv, int reg, u8 bits)
+{
+       nb8800_maskb(priv, reg, bits, bits);
+}
+
+static inline void nb8800_clearb(struct nb8800_priv *priv, int reg, u8 bits)
+{
+       nb8800_maskb(priv, reg, bits, 0);
+}
+
+static inline void nb8800_modl(struct nb8800_priv *priv, int reg, u32 bits,
+                              bool set)
+{
+       nb8800_maskl(priv, reg, bits, set ? bits : 0);
+}
+
+static inline void nb8800_setl(struct nb8800_priv *priv, int reg, u32 bits)
+{
+       nb8800_maskl(priv, reg, bits, bits);
+}
+
+static inline void nb8800_clearl(struct nb8800_priv *priv, int reg, u32 bits)
+{
+       nb8800_maskl(priv, reg, bits, 0);
+}
+
+static int nb8800_mdio_wait(struct mii_bus *bus)
+{
+       struct nb8800_priv *priv = bus->priv;
+       u32 val;
+
+       return readl_poll_timeout_atomic(priv->base + NB8800_MDIO_CMD,
+                                        val, !(val & MDIO_CMD_GO), 1, 1000);
+}
+
+static int nb8800_mdio_cmd(struct mii_bus *bus, u32 cmd)
+{
+       struct nb8800_priv *priv = bus->priv;
+       int err;
+
+       err = nb8800_mdio_wait(bus);
+       if (err)
+               return err;
+
+       nb8800_writel(priv, NB8800_MDIO_CMD, cmd);
+       udelay(10);
+       nb8800_writel(priv, NB8800_MDIO_CMD, cmd | MDIO_CMD_GO);
+
+       return nb8800_mdio_wait(bus);
+}
+
+static int nb8800_mdio_read(struct mii_bus *bus, int phy_id, int reg)
+{
+       struct nb8800_priv *priv = bus->priv;
+       u32 val;
+       int err;
+
+       err = nb8800_mdio_cmd(bus, MDIO_CMD_ADDR(phy_id) | MDIO_CMD_REG(reg));
+       if (err)
+               return err;
+
+       val = nb8800_readl(priv, NB8800_MDIO_STS);
+       if (val & MDIO_STS_ERR)
+               return 0xffff;
+
+       return val & 0xffff;
+}
+
+static int nb8800_mdio_write(struct mii_bus *bus, int phy_id, int reg, u16 val)
+{
+       u32 cmd = MDIO_CMD_ADDR(phy_id) | MDIO_CMD_REG(reg) |
+               MDIO_CMD_DATA(val) | MDIO_CMD_WR;
+
+       return nb8800_mdio_cmd(bus, cmd);
+}
+
+static void nb8800_mac_tx(struct net_device *dev, bool enable)
+{
+       struct nb8800_priv *priv = netdev_priv(dev);
+
+       while (nb8800_readl(priv, NB8800_TXC_CR) & TCR_EN)
+               cpu_relax();
+
+       nb8800_modb(priv, NB8800_TX_CTL1, TX_EN, enable);
+}
+
+static void nb8800_mac_rx(struct net_device *dev, bool enable)
+{
+       nb8800_modb(netdev_priv(dev), NB8800_RX_CTL, RX_EN, enable);
+}
+
+static void nb8800_mac_af(struct net_device *dev, bool enable)
+{
+       nb8800_modb(netdev_priv(dev), NB8800_RX_CTL, RX_AF_EN, enable);
+}
+
+static void nb8800_start_rx(struct net_device *dev)
+{
+       nb8800_setl(netdev_priv(dev), NB8800_RXC_CR, RCR_EN);
+}
+
+static int nb8800_alloc_rx(struct net_device *dev, unsigned int i, bool napi)
+{
+       struct nb8800_priv *priv = netdev_priv(dev);
+       struct nb8800_rx_desc *rxd = &priv->rx_descs[i];
+       struct nb8800_rx_buf *rxb = &priv->rx_bufs[i];
+       int size = L1_CACHE_ALIGN(RX_BUF_SIZE);
+       dma_addr_t dma_addr;
+       struct page *page;
+       unsigned long offset;
+       void *data;
+
+       data = napi ? napi_alloc_frag(size) : netdev_alloc_frag(size);
+       if (!data)
+               return -ENOMEM;
+
+       page = virt_to_head_page(data);
+       offset = data - page_address(page);
+
+       dma_addr = dma_map_page(&dev->dev, page, offset, RX_BUF_SIZE,
+                               DMA_FROM_DEVICE);
+
+       if (dma_mapping_error(&dev->dev, dma_addr)) {
+               skb_free_frag(data);
+               return -ENOMEM;
+       }
+
+       rxb->page = page;
+       rxb->offset = offset;
+       rxd->desc.s_addr = dma_addr;
+
+       return 0;
+}
+
+static void nb8800_receive(struct net_device *dev, unsigned int i,
+                          unsigned int len)
+{
+       struct nb8800_priv *priv = netdev_priv(dev);
+       struct nb8800_rx_desc *rxd = &priv->rx_descs[i];
+       struct page *page = priv->rx_bufs[i].page;
+       int offset = priv->rx_bufs[i].offset;
+       void *data = page_address(page) + offset;
+       dma_addr_t dma = rxd->desc.s_addr;
+       struct sk_buff *skb;
+       unsigned int size;
+       int err;
+
+       size = len <= RX_COPYBREAK ? len : RX_COPYHDR;
+
+       skb = napi_alloc_skb(&priv->napi, size);
+       if (!skb) {
+               netdev_err(dev, "rx skb allocation failed\n");
+               dev->stats.rx_dropped++;
+               return;
+       }
+
+       if (len <= RX_COPYBREAK) {
+               dma_sync_single_for_cpu(&dev->dev, dma, len, DMA_FROM_DEVICE);
+               memcpy(skb_put(skb, len), data, len);
+               dma_sync_single_for_device(&dev->dev, dma, len,
+                                          DMA_FROM_DEVICE);
+       } else {
+               err = nb8800_alloc_rx(dev, i, true);
+               if (err) {
+                       netdev_err(dev, "rx buffer allocation failed\n");
+                       dev->stats.rx_dropped++;
+                       return;
+               }
+
+               dma_unmap_page(&dev->dev, dma, RX_BUF_SIZE, DMA_FROM_DEVICE);
+               memcpy(skb_put(skb, RX_COPYHDR), data, RX_COPYHDR);
+               skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page,
+                               offset + RX_COPYHDR, len - RX_COPYHDR,
+                               RX_BUF_SIZE);
+       }
+
+       skb->protocol = eth_type_trans(skb, dev);
+       napi_gro_receive(&priv->napi, skb);
+}
+
+static void nb8800_rx_error(struct net_device *dev, u32 report)
+{
+       if (report & RX_LENGTH_ERR)
+               dev->stats.rx_length_errors++;
+
+       if (report & RX_FCS_ERR)
+               dev->stats.rx_crc_errors++;
+
+       if (report & RX_FIFO_OVERRUN)
+               dev->stats.rx_fifo_errors++;
+
+       if (report & RX_ALIGNMENT_ERROR)
+               dev->stats.rx_frame_errors++;
+
+       dev->stats.rx_errors++;
+}
+
+static int nb8800_poll(struct napi_struct *napi, int budget)
+{
+       struct net_device *dev = napi->dev;
+       struct nb8800_priv *priv = netdev_priv(dev);
+       struct nb8800_rx_desc *rxd;
+       unsigned int last = priv->rx_eoc;
+       unsigned int next;
+       int work = 0;
+
+       nb8800_tx_done(dev);
+
+again:
+       while (work < budget) {
+               struct nb8800_rx_buf *rxb;
+               unsigned int len;
+
+               next = (last + 1) % RX_DESC_COUNT;
+
+               rxb = &priv->rx_bufs[next];
+               rxd = &priv->rx_descs[next];
+
+               if (!rxd->report)
+                       break;
+
+               len = RX_BYTES_TRANSFERRED(rxd->report);
+
+               if (IS_RX_ERROR(rxd->report))
+                       nb8800_rx_error(dev, rxd->report);
+               else
+                       nb8800_receive(dev, next, len);
+
+               dev->stats.rx_packets++;
+               dev->stats.rx_bytes += len;
+
+               if (rxd->report & RX_MULTICAST_PKT)
+                       dev->stats.multicast++;
+
+               rxd->report = 0;
+               last = next;
+               work++;
+       }
+
+       if (work) {
+               priv->rx_descs[last].desc.config |= DESC_EOC;
+               wmb();  /* ensure new EOC is written before clearing old */
+               priv->rx_descs[priv->rx_eoc].desc.config &= ~DESC_EOC;
+               priv->rx_eoc = last;
+               nb8800_start_rx(dev);
+       }
+
+       if (work < budget) {
+               nb8800_writel(priv, NB8800_RX_ITR, priv->rx_itr_irq);
+
+               /* If a packet arrived after we last checked but
+                * before writing RX_ITR, the interrupt will be
+                * delayed, so we retrieve it now.
+                */
+               if (priv->rx_descs[next].report)
+                       goto again;
+
+               napi_complete_done(napi, work);
+       }
+
+       return work;
+}
+
+static void __nb8800_tx_dma_start(struct net_device *dev)
+{
+       struct nb8800_priv *priv = netdev_priv(dev);
+       struct nb8800_tx_buf *txb;
+       u32 txc_cr;
+
+       txb = &priv->tx_bufs[priv->tx_queue];
+       if (!txb->ready)
+               return;
+
+       txc_cr = nb8800_readl(priv, NB8800_TXC_CR);
+       if (txc_cr & TCR_EN)
+               return;
+
+       nb8800_writel(priv, NB8800_TX_DESC_ADDR, txb->dma_desc);
+       wmb();          /* ensure desc addr is written before starting DMA */
+       nb8800_writel(priv, NB8800_TXC_CR, txc_cr | TCR_EN);
+
+       priv->tx_queue = (priv->tx_queue + txb->chain_len) % TX_DESC_COUNT;
+}
+
+static void nb8800_tx_dma_start(struct net_device *dev)
+{
+       struct nb8800_priv *priv = netdev_priv(dev);
+
+       spin_lock_irq(&priv->tx_lock);
+       __nb8800_tx_dma_start(dev);
+       spin_unlock_irq(&priv->tx_lock);
+}
+
+static void nb8800_tx_dma_start_irq(struct net_device *dev)
+{
+       struct nb8800_priv *priv = netdev_priv(dev);
+
+       spin_lock(&priv->tx_lock);
+       __nb8800_tx_dma_start(dev);
+       spin_unlock(&priv->tx_lock);
+}
+
+static int nb8800_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+       struct nb8800_priv *priv = netdev_priv(dev);
+       struct nb8800_tx_desc *txd;
+       struct nb8800_tx_buf *txb;
+       struct nb8800_dma_desc *desc;
+       dma_addr_t dma_addr;
+       unsigned int dma_len;
+       unsigned int align;
+       unsigned int next;
+
+       if (atomic_read(&priv->tx_free) <= NB8800_DESC_LOW) {
+               netif_stop_queue(dev);
+               return NETDEV_TX_BUSY;
+       }
+
+       align = (8 - (uintptr_t)skb->data) & 7;
+
+       dma_len = skb->len - align;
+       dma_addr = dma_map_single(&dev->dev, skb->data + align,
+                                 dma_len, DMA_TO_DEVICE);
+
+       if (dma_mapping_error(&dev->dev, dma_addr)) {
+               netdev_err(dev, "tx dma mapping error\n");
+               kfree_skb(skb);
+               dev->stats.tx_dropped++;
+               return NETDEV_TX_OK;
+       }
+
+       if (atomic_dec_return(&priv->tx_free) <= NB8800_DESC_LOW) {
+               netif_stop_queue(dev);
+               skb->xmit_more = 0;
+       }
+
+       next = priv->tx_next;
+       txb = &priv->tx_bufs[next];
+       txd = &priv->tx_descs[next];
+       desc = &txd->desc[0];
+
+       next = (next + 1) % TX_DESC_COUNT;
+
+       if (align) {
+               memcpy(txd->buf, skb->data, align);
+
+               desc->s_addr =
+                       txb->dma_desc + offsetof(struct nb8800_tx_desc, buf);
+               desc->n_addr = txb->dma_desc + sizeof(txd->desc[0]);
+               desc->config = DESC_BTS(2) | DESC_DS | align;
+
+               desc++;
+       }
+
+       desc->s_addr = dma_addr;
+       desc->n_addr = priv->tx_bufs[next].dma_desc;
+       desc->config = DESC_BTS(2) | DESC_DS | DESC_EOF | dma_len;
+
+       if (!skb->xmit_more)
+               desc->config |= DESC_EOC;
+
+       txb->skb = skb;
+       txb->dma_addr = dma_addr;
+       txb->dma_len = dma_len;
+
+       if (!priv->tx_chain) {
+               txb->chain_len = 1;
+               priv->tx_chain = txb;
+       } else {
+               priv->tx_chain->chain_len++;
+       }
+
+       netdev_sent_queue(dev, skb->len);
+
+       priv->tx_next = next;
+
+       if (!skb->xmit_more) {
+               smp_wmb();
+               priv->tx_chain->ready = true;
+               priv->tx_chain = NULL;
+               nb8800_tx_dma_start(dev);
+       }
+
+       return NETDEV_TX_OK;
+}
+
+static void nb8800_tx_error(struct net_device *dev, u32 report)
+{
+       if (report & TX_LATE_COLLISION)
+               dev->stats.collisions++;
+
+       if (report & TX_PACKET_DROPPED)
+               dev->stats.tx_dropped++;
+
+       if (report & TX_FIFO_UNDERRUN)
+               dev->stats.tx_fifo_errors++;
+
+       dev->stats.tx_errors++;
+}
+
+static void nb8800_tx_done(struct net_device *dev)
+{
+       struct nb8800_priv *priv = netdev_priv(dev);
+       unsigned int limit = priv->tx_next;
+       unsigned int done = priv->tx_done;
+       unsigned int packets = 0;
+       unsigned int len = 0;
+
+       while (done != limit) {
+               struct nb8800_tx_desc *txd = &priv->tx_descs[done];
+               struct nb8800_tx_buf *txb = &priv->tx_bufs[done];
+               struct sk_buff *skb;
+
+               if (!txd->report)
+                       break;
+
+               skb = txb->skb;
+               len += skb->len;
+
+               dma_unmap_single(&dev->dev, txb->dma_addr, txb->dma_len,
+                                DMA_TO_DEVICE);
+
+               if (IS_TX_ERROR(txd->report)) {
+                       nb8800_tx_error(dev, txd->report);
+                       kfree_skb(skb);
+               } else {
+                       consume_skb(skb);
+               }
+
+               dev->stats.tx_packets++;
+               dev->stats.tx_bytes += TX_BYTES_TRANSFERRED(txd->report);
+               dev->stats.collisions += TX_EARLY_COLLISIONS(txd->report);
+
+               txb->skb = NULL;
+               txb->ready = false;
+               txd->report = 0;
+
+               done = (done + 1) % TX_DESC_COUNT;
+               packets++;
+       }
+
+       if (packets) {
+               smp_mb__before_atomic();
+               atomic_add(packets, &priv->tx_free);
+               netdev_completed_queue(dev, packets, len);
+               netif_wake_queue(dev);
+               priv->tx_done = done;
+       }
+}
+
+static irqreturn_t nb8800_irq(int irq, void *dev_id)
+{
+       struct net_device *dev = dev_id;
+       struct nb8800_priv *priv = netdev_priv(dev);
+       irqreturn_t ret = IRQ_NONE;
+       u32 val;
+
+       /* tx interrupt */
+       val = nb8800_readl(priv, NB8800_TXC_SR);
+       if (val) {
+               nb8800_writel(priv, NB8800_TXC_SR, val);
+
+               if (val & TSR_DI)
+                       nb8800_tx_dma_start_irq(dev);
+
+               if (val & TSR_TI)
+                       napi_schedule_irqoff(&priv->napi);
+
+               if (unlikely(val & TSR_DE))
+                       netdev_err(dev, "TX DMA error\n");
+
+               /* should never happen with automatic status retrieval */
+               if (unlikely(val & TSR_TO))
+                       netdev_err(dev, "TX Status FIFO overflow\n");
+
+               ret = IRQ_HANDLED;
+       }
+
+       /* rx interrupt */
+       val = nb8800_readl(priv, NB8800_RXC_SR);
+       if (val) {
+               nb8800_writel(priv, NB8800_RXC_SR, val);
+
+               if (likely(val & (RSR_RI | RSR_DI))) {
+                       nb8800_writel(priv, NB8800_RX_ITR, priv->rx_itr_poll);
+                       napi_schedule_irqoff(&priv->napi);
+               }
+
+               if (unlikely(val & RSR_DE))
+                       netdev_err(dev, "RX DMA error\n");
+
+               /* should never happen with automatic status retrieval */
+               if (unlikely(val & RSR_RO))
+                       netdev_err(dev, "RX Status FIFO overflow\n");
+
+               ret = IRQ_HANDLED;
+       }
+
+       return ret;
+}
+
+static void nb8800_mac_config(struct net_device *dev)
+{
+       struct nb8800_priv *priv = netdev_priv(dev);
+       bool gigabit = priv->speed == SPEED_1000;
+       u32 mac_mode_mask = RGMII_MODE | HALF_DUPLEX | GMAC_MODE;
+       u32 mac_mode = 0;
+       u32 slot_time;
+       u32 phy_clk;
+       u32 ict;
+
+       if (!priv->duplex)
+               mac_mode |= HALF_DUPLEX;
+
+       if (gigabit) {
+               if (priv->phy_mode == PHY_INTERFACE_MODE_RGMII)
+                       mac_mode |= RGMII_MODE;
+
+               mac_mode |= GMAC_MODE;
+               phy_clk = 125000000;
+
+               /* Should be 512 but register is only 8 bits */
+               slot_time = 255;
+       } else {
+               phy_clk = 25000000;
+               slot_time = 128;
+       }
+
+       ict = DIV_ROUND_UP(phy_clk, clk_get_rate(priv->clk));
+
+       nb8800_writeb(priv, NB8800_IC_THRESHOLD, ict);
+       nb8800_writeb(priv, NB8800_SLOT_TIME, slot_time);
+       nb8800_maskb(priv, NB8800_MAC_MODE, mac_mode_mask, mac_mode);
+}
+
+static void nb8800_pause_config(struct net_device *dev)
+{
+       struct nb8800_priv *priv = netdev_priv(dev);
+       struct phy_device *phydev = priv->phydev;
+       u32 rxcr;
+
+       if (priv->pause_aneg) {
+               if (!phydev || !phydev->link)
+                       return;
+
+               priv->pause_rx = phydev->pause;
+               priv->pause_tx = phydev->pause ^ phydev->asym_pause;
+       }
+
+       nb8800_modb(priv, NB8800_RX_CTL, RX_PAUSE_EN, priv->pause_rx);
+
+       rxcr = nb8800_readl(priv, NB8800_RXC_CR);
+       if (!!(rxcr & RCR_FL) == priv->pause_tx)
+               return;
+
+       if (netif_running(dev)) {
+               napi_disable(&priv->napi);
+               netif_tx_lock_bh(dev);
+               nb8800_dma_stop(dev);
+               nb8800_modl(priv, NB8800_RXC_CR, RCR_FL, priv->pause_tx);
+               nb8800_start_rx(dev);
+               netif_tx_unlock_bh(dev);
+               napi_enable(&priv->napi);
+       } else {
+               nb8800_modl(priv, NB8800_RXC_CR, RCR_FL, priv->pause_tx);
+       }
+}
+
+static void nb8800_link_reconfigure(struct net_device *dev)
+{
+       struct nb8800_priv *priv = netdev_priv(dev);
+       struct phy_device *phydev = priv->phydev;
+       int change = 0;
+
+       if (phydev->link) {
+               if (phydev->speed != priv->speed) {
+                       priv->speed = phydev->speed;
+                       change = 1;
+               }
+
+               if (phydev->duplex != priv->duplex) {
+                       priv->duplex = phydev->duplex;
+                       change = 1;
+               }
+
+               if (change)
+                       nb8800_mac_config(dev);
+
+               nb8800_pause_config(dev);
+       }
+
+       if (phydev->link != priv->link) {
+               priv->link = phydev->link;
+               change = 1;
+       }
+
+       if (change)
+               phy_print_status(priv->phydev);
+}
+
+static void nb8800_update_mac_addr(struct net_device *dev)
+{
+       struct nb8800_priv *priv = netdev_priv(dev);
+       int i;
+
+       for (i = 0; i < ETH_ALEN; i++)
+               nb8800_writeb(priv, NB8800_SRC_ADDR(i), dev->dev_addr[i]);
+
+       for (i = 0; i < ETH_ALEN; i++)
+               nb8800_writeb(priv, NB8800_UC_ADDR(i), dev->dev_addr[i]);
+}
+
+static int nb8800_set_mac_address(struct net_device *dev, void *addr)
+{
+       struct sockaddr *sock = addr;
+
+       if (netif_running(dev))
+               return -EBUSY;
+
+       ether_addr_copy(dev->dev_addr, sock->sa_data);
+       nb8800_update_mac_addr(dev);
+
+       return 0;
+}
+
+static void nb8800_mc_init(struct net_device *dev, int val)
+{
+       struct nb8800_priv *priv = netdev_priv(dev);
+
+       nb8800_writeb(priv, NB8800_MC_INIT, val);
+       readb_poll_timeout_atomic(priv->base + NB8800_MC_INIT, val, !val,
+                                 1, 1000);
+}
+
+static void nb8800_set_rx_mode(struct net_device *dev)
+{
+       struct nb8800_priv *priv = netdev_priv(dev);
+       struct netdev_hw_addr *ha;
+       int i;
+
+       if (dev->flags & (IFF_PROMISC | IFF_ALLMULTI)) {
+               nb8800_mac_af(dev, false);
+               return;
+       }
+
+       nb8800_mac_af(dev, true);
+       nb8800_mc_init(dev, 0);
+
+       netdev_for_each_mc_addr(ha, dev) {
+               for (i = 0; i < ETH_ALEN; i++)
+                       nb8800_writeb(priv, NB8800_MC_ADDR(i), ha->addr[i]);
+
+               nb8800_mc_init(dev, 0xff);
+       }
+}
+
+#define RX_DESC_SIZE (RX_DESC_COUNT * sizeof(struct nb8800_rx_desc))
+#define TX_DESC_SIZE (TX_DESC_COUNT * sizeof(struct nb8800_tx_desc))
+
+static void nb8800_dma_free(struct net_device *dev)
+{
+       struct nb8800_priv *priv = netdev_priv(dev);
+       unsigned int i;
+
+       if (priv->rx_bufs) {
+               for (i = 0; i < RX_DESC_COUNT; i++)
+                       if (priv->rx_bufs[i].page)
+                               put_page(priv->rx_bufs[i].page);
+
+               kfree(priv->rx_bufs);
+               priv->rx_bufs = NULL;
+       }
+
+       if (priv->tx_bufs) {
+               for (i = 0; i < TX_DESC_COUNT; i++)
+                       kfree_skb(priv->tx_bufs[i].skb);
+
+               kfree(priv->tx_bufs);
+               priv->tx_bufs = NULL;
+       }
+
+       if (priv->rx_descs) {
+               dma_free_coherent(dev->dev.parent, RX_DESC_SIZE, priv->rx_descs,
+                                 priv->rx_desc_dma);
+               priv->rx_descs = NULL;
+       }
+
+       if (priv->tx_descs) {
+               dma_free_coherent(dev->dev.parent, TX_DESC_SIZE, priv->tx_descs,
+                                 priv->tx_desc_dma);
+               priv->tx_descs = NULL;
+       }
+}
+
+static void nb8800_dma_reset(struct net_device *dev)
+{
+       struct nb8800_priv *priv = netdev_priv(dev);
+       struct nb8800_rx_desc *rxd;
+       struct nb8800_tx_desc *txd;
+       unsigned int i;
+
+       for (i = 0; i < RX_DESC_COUNT; i++) {
+               dma_addr_t rx_dma = priv->rx_desc_dma + i * sizeof(*rxd);
+
+               rxd = &priv->rx_descs[i];
+               rxd->desc.n_addr = rx_dma + sizeof(*rxd);
+               rxd->desc.r_addr =
+                       rx_dma + offsetof(struct nb8800_rx_desc, report);
+               rxd->desc.config = priv->rx_dma_config;
+               rxd->report = 0;
+       }
+
+       rxd->desc.n_addr = priv->rx_desc_dma;
+       rxd->desc.config |= DESC_EOC;
+
+       priv->rx_eoc = RX_DESC_COUNT - 1;
+
+       for (i = 0; i < TX_DESC_COUNT; i++) {
+               struct nb8800_tx_buf *txb = &priv->tx_bufs[i];
+               dma_addr_t r_dma = txb->dma_desc +
+                       offsetof(struct nb8800_tx_desc, report);
+
+               txd = &priv->tx_descs[i];
+               txd->desc[0].r_addr = r_dma;
+               txd->desc[1].r_addr = r_dma;
+               txd->report = 0;
+       }
+
+       priv->tx_next = 0;
+       priv->tx_queue = 0;
+       priv->tx_done = 0;
+       atomic_set(&priv->tx_free, TX_DESC_COUNT);
+
+       nb8800_writel(priv, NB8800_RX_DESC_ADDR, priv->rx_desc_dma);
+
+       wmb();          /* ensure all setup is written before starting */
+}
+
+static int nb8800_dma_init(struct net_device *dev)
+{
+       struct nb8800_priv *priv = netdev_priv(dev);
+       unsigned int n_rx = RX_DESC_COUNT;
+       unsigned int n_tx = TX_DESC_COUNT;
+       unsigned int i;
+       int err;
+
+       priv->rx_descs = dma_alloc_coherent(dev->dev.parent, RX_DESC_SIZE,
+                                           &priv->rx_desc_dma, GFP_KERNEL);
+       if (!priv->rx_descs)
+               goto err_out;
+
+       priv->rx_bufs = kcalloc(n_rx, sizeof(*priv->rx_bufs), GFP_KERNEL);
+       if (!priv->rx_bufs)
+               goto err_out;
+
+       for (i = 0; i < n_rx; i++) {
+               err = nb8800_alloc_rx(dev, i, false);
+               if (err)
+                       goto err_out;
+       }
+
+       priv->tx_descs = dma_alloc_coherent(dev->dev.parent, TX_DESC_SIZE,
+                                           &priv->tx_desc_dma, GFP_KERNEL);
+       if (!priv->tx_descs)
+               goto err_out;
+
+       priv->tx_bufs = kcalloc(n_tx, sizeof(*priv->tx_bufs), GFP_KERNEL);
+       if (!priv->tx_bufs)
+               goto err_out;
+
+       for (i = 0; i < n_tx; i++)
+               priv->tx_bufs[i].dma_desc =
+                       priv->tx_desc_dma + i * sizeof(struct nb8800_tx_desc);
+
+       nb8800_dma_reset(dev);
+
+       return 0;
+
+err_out:
+       nb8800_dma_free(dev);
+
+       return -ENOMEM;
+}
+
+static int nb8800_dma_stop(struct net_device *dev)
+{
+       struct nb8800_priv *priv = netdev_priv(dev);
+       struct nb8800_tx_buf *txb = &priv->tx_bufs[0];
+       struct nb8800_tx_desc *txd = &priv->tx_descs[0];
+       int retry = 5;
+       u32 txcr;
+       u32 rxcr;
+       int err;
+       unsigned int i;
+
+       /* wait for tx to finish */
+       err = readl_poll_timeout_atomic(priv->base + NB8800_TXC_CR, txcr,
+                                       !(txcr & TCR_EN) &&
+                                       priv->tx_done == priv->tx_next,
+                                       1000, 1000000);
+       if (err)
+               return err;
+
+       /* The rx DMA only stops if it reaches the end of chain.
+        * To make this happen, we set the EOC flag on all rx
+        * descriptors, put the device in loopback mode, and send
+        * a few dummy frames.  The interrupt handler will ignore
+        * these since NAPI is disabled and no real frames are in
+        * the tx queue.
+        */
+
+       for (i = 0; i < RX_DESC_COUNT; i++)
+               priv->rx_descs[i].desc.config |= DESC_EOC;
+
+       txd->desc[0].s_addr =
+               txb->dma_desc + offsetof(struct nb8800_tx_desc, buf);
+       txd->desc[0].config = DESC_BTS(2) | DESC_DS | DESC_EOF | DESC_EOC | 8;
+       memset(txd->buf, 0, sizeof(txd->buf));
+
+       nb8800_mac_af(dev, false);
+       nb8800_setb(priv, NB8800_MAC_MODE, LOOPBACK_EN);
+
+       do {
+               nb8800_writel(priv, NB8800_TX_DESC_ADDR, txb->dma_desc);
+               wmb();
+               nb8800_writel(priv, NB8800_TXC_CR, txcr | TCR_EN);
+
+               err = readl_poll_timeout_atomic(priv->base + NB8800_RXC_CR,
+                                               rxcr, !(rxcr & RCR_EN),
+                                               1000, 100000);
+       } while (err && --retry);
+
+       nb8800_mac_af(dev, true);
+       nb8800_clearb(priv, NB8800_MAC_MODE, LOOPBACK_EN);
+       nb8800_dma_reset(dev);
+
+       return retry ? 0 : -ETIMEDOUT;
+}
+
+static void nb8800_pause_adv(struct net_device *dev)
+{
+       struct nb8800_priv *priv = netdev_priv(dev);
+       u32 adv = 0;
+
+       if (!priv->phydev)
+               return;
+
+       if (priv->pause_rx)
+               adv |= ADVERTISED_Pause | ADVERTISED_Asym_Pause;
+       if (priv->pause_tx)
+               adv ^= ADVERTISED_Asym_Pause;
+
+       priv->phydev->supported |= adv;
+       priv->phydev->advertising |= adv;
+}
+
+static int nb8800_open(struct net_device *dev)
+{
+       struct nb8800_priv *priv = netdev_priv(dev);
+       int err;
+
+       /* clear any pending interrupts */
+       nb8800_writel(priv, NB8800_RXC_SR, 0xf);
+       nb8800_writel(priv, NB8800_TXC_SR, 0xf);
+
+       err = nb8800_dma_init(dev);
+       if (err)
+               return err;
+
+       err = request_irq(dev->irq, nb8800_irq, 0, dev_name(&dev->dev), dev);
+       if (err)
+               goto err_free_dma;
+
+       nb8800_mac_rx(dev, true);
+       nb8800_mac_tx(dev, true);
+
+       priv->phydev = of_phy_connect(dev, priv->phy_node,
+                                     nb8800_link_reconfigure, 0,
+                                     priv->phy_mode);
+       if (!priv->phydev)
+               goto err_free_irq;
+
+       nb8800_pause_adv(dev);
+
+       netdev_reset_queue(dev);
+       napi_enable(&priv->napi);
+       netif_start_queue(dev);
+
+       nb8800_start_rx(dev);
+       phy_start(priv->phydev);
+
+       return 0;
+
+err_free_irq:
+       free_irq(dev->irq, dev);
+err_free_dma:
+       nb8800_dma_free(dev);
+
+       return err;
+}
+
+static int nb8800_stop(struct net_device *dev)
+{
+       struct nb8800_priv *priv = netdev_priv(dev);
+
+       phy_stop(priv->phydev);
+
+       netif_stop_queue(dev);
+       napi_disable(&priv->napi);
+
+       nb8800_dma_stop(dev);
+       nb8800_mac_rx(dev, false);
+       nb8800_mac_tx(dev, false);
+
+       phy_disconnect(priv->phydev);
+       priv->phydev = NULL;
+
+       free_irq(dev->irq, dev);
+
+       nb8800_dma_free(dev);
+
+       return 0;
+}
+
+static int nb8800_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{
+       struct nb8800_priv *priv = netdev_priv(dev);
+
+       return phy_mii_ioctl(priv->phydev, rq, cmd);
+}
+
+static const struct net_device_ops nb8800_netdev_ops = {
+       .ndo_open               = nb8800_open,
+       .ndo_stop               = nb8800_stop,
+       .ndo_start_xmit         = nb8800_xmit,
+       .ndo_set_mac_address    = nb8800_set_mac_address,
+       .ndo_set_rx_mode        = nb8800_set_rx_mode,
+       .ndo_do_ioctl           = nb8800_ioctl,
+       .ndo_change_mtu         = eth_change_mtu,
+       .ndo_validate_addr      = eth_validate_addr,
+};
+
+static int nb8800_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+       struct nb8800_priv *priv = netdev_priv(dev);
+
+       if (!priv->phydev)
+               return -ENODEV;
+
+       return phy_ethtool_gset(priv->phydev, cmd);
+}
+
+static int nb8800_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+       struct nb8800_priv *priv = netdev_priv(dev);
+
+       if (!priv->phydev)
+               return -ENODEV;
+
+       return phy_ethtool_sset(priv->phydev, cmd);
+}
+
+static int nb8800_nway_reset(struct net_device *dev)
+{
+       struct nb8800_priv *priv = netdev_priv(dev);
+
+       if (!priv->phydev)
+               return -ENODEV;
+
+       return genphy_restart_aneg(priv->phydev);
+}
+
+static void nb8800_get_pauseparam(struct net_device *dev,
+                                 struct ethtool_pauseparam *pp)
+{
+       struct nb8800_priv *priv = netdev_priv(dev);
+
+       pp->autoneg = priv->pause_aneg;
+       pp->rx_pause = priv->pause_rx;
+       pp->tx_pause = priv->pause_tx;
+}
+
+static int nb8800_set_pauseparam(struct net_device *dev,
+                                struct ethtool_pauseparam *pp)
+{
+       struct nb8800_priv *priv = netdev_priv(dev);
+
+       priv->pause_aneg = pp->autoneg;
+       priv->pause_rx = pp->rx_pause;
+       priv->pause_tx = pp->tx_pause;
+
+       nb8800_pause_adv(dev);
+
+       if (!priv->pause_aneg)
+               nb8800_pause_config(dev);
+       else if (priv->phydev)
+               phy_start_aneg(priv->phydev);
+
+       return 0;
+}
+
+static const char nb8800_stats_names[][ETH_GSTRING_LEN] = {
+       "rx_bytes_ok",
+       "rx_frames_ok",
+       "rx_undersize_frames",
+       "rx_fragment_frames",
+       "rx_64_byte_frames",
+       "rx_127_byte_frames",
+       "rx_255_byte_frames",
+       "rx_511_byte_frames",
+       "rx_1023_byte_frames",
+       "rx_max_size_frames",
+       "rx_oversize_frames",
+       "rx_bad_fcs_frames",
+       "rx_broadcast_frames",
+       "rx_multicast_frames",
+       "rx_control_frames",
+       "rx_pause_frames",
+       "rx_unsup_control_frames",
+       "rx_align_error_frames",
+       "rx_overrun_frames",
+       "rx_jabber_frames",
+       "rx_bytes",
+       "rx_frames",
+
+       "tx_bytes_ok",
+       "tx_frames_ok",
+       "tx_64_byte_frames",
+       "tx_127_byte_frames",
+       "tx_255_byte_frames",
+       "tx_511_byte_frames",
+       "tx_1023_byte_frames",
+       "tx_max_size_frames",
+       "tx_oversize_frames",
+       "tx_broadcast_frames",
+       "tx_multicast_frames",
+       "tx_control_frames",
+       "tx_pause_frames",
+       "tx_underrun_frames",
+       "tx_single_collision_frames",
+       "tx_multi_collision_frames",
+       "tx_deferred_collision_frames",
+       "tx_late_collision_frames",
+       "tx_excessive_collision_frames",
+       "tx_bytes",
+       "tx_frames",
+       "tx_collisions",
+};
+
+#define NB8800_NUM_STATS ARRAY_SIZE(nb8800_stats_names)
+
+static int nb8800_get_sset_count(struct net_device *dev, int sset)
+{
+       if (sset == ETH_SS_STATS)
+               return NB8800_NUM_STATS;
+
+       return -EOPNOTSUPP;
+}
+
+static void nb8800_get_strings(struct net_device *dev, u32 sset, u8 *buf)
+{
+       if (sset == ETH_SS_STATS)
+               memcpy(buf, &nb8800_stats_names, sizeof(nb8800_stats_names));
+}
+
+static u32 nb8800_read_stat(struct net_device *dev, int index)
+{
+       struct nb8800_priv *priv = netdev_priv(dev);
+
+       nb8800_writeb(priv, NB8800_STAT_INDEX, index);
+
+       return nb8800_readl(priv, NB8800_STAT_DATA);
+}
+
+static void nb8800_get_ethtool_stats(struct net_device *dev,
+                                    struct ethtool_stats *estats, u64 *st)
+{
+       unsigned int i;
+       u32 rx, tx;
+
+       for (i = 0; i < NB8800_NUM_STATS / 2; i++) {
+               rx = nb8800_read_stat(dev, i);
+               tx = nb8800_read_stat(dev, i | 0x80);
+               st[i] = rx;
+               st[i + NB8800_NUM_STATS / 2] = tx;
+       }
+}
+
+static const struct ethtool_ops nb8800_ethtool_ops = {
+       .get_settings           = nb8800_get_settings,
+       .set_settings           = nb8800_set_settings,
+       .nway_reset             = nb8800_nway_reset,
+       .get_link               = ethtool_op_get_link,
+       .get_pauseparam         = nb8800_get_pauseparam,
+       .set_pauseparam         = nb8800_set_pauseparam,
+       .get_sset_count         = nb8800_get_sset_count,
+       .get_strings            = nb8800_get_strings,
+       .get_ethtool_stats      = nb8800_get_ethtool_stats,
+};
+
+static int nb8800_hw_init(struct net_device *dev)
+{
+       struct nb8800_priv *priv = netdev_priv(dev);
+       u32 val;
+
+       val = TX_RETRY_EN | TX_PAD_EN | TX_APPEND_FCS;
+       nb8800_writeb(priv, NB8800_TX_CTL1, val);
+
+       /* Collision retry count */
+       nb8800_writeb(priv, NB8800_TX_CTL2, 5);
+
+       val = RX_PAD_STRIP | RX_AF_EN;
+       nb8800_writeb(priv, NB8800_RX_CTL, val);
+
+       /* Chosen by fair dice roll */
+       nb8800_writeb(priv, NB8800_RANDOM_SEED, 4);
+
+       /* TX cycles per deferral period */
+       nb8800_writeb(priv, NB8800_TX_SDP, 12);
+
+       /* The following three threshold values have been
+        * experimentally determined for good results.
+        */
+
+       /* RX/TX FIFO threshold for partial empty (64-bit entries) */
+       nb8800_writeb(priv, NB8800_PE_THRESHOLD, 0);
+
+       /* RX/TX FIFO threshold for partial full (64-bit entries) */
+       nb8800_writeb(priv, NB8800_PF_THRESHOLD, 255);
+
+       /* Buffer size for transmit (64-bit entries) */
+       nb8800_writeb(priv, NB8800_TX_BUFSIZE, 64);
+
+       /* Configure tx DMA */
+
+       val = nb8800_readl(priv, NB8800_TXC_CR);
+       val &= TCR_LE;          /* keep endian setting */
+       val |= TCR_DM;          /* DMA descriptor mode */
+       val |= TCR_RS;          /* automatically store tx status  */
+       val |= TCR_DIE;         /* interrupt on DMA chain completion */
+       val |= TCR_TFI(7);      /* interrupt after 7 frames transmitted */
+       val |= TCR_BTS(2);      /* 32-byte bus transaction size */
+       nb8800_writel(priv, NB8800_TXC_CR, val);
+
+       /* TX complete interrupt after 10 ms or 7 frames (see above) */
+       val = clk_get_rate(priv->clk) / 100;
+       nb8800_writel(priv, NB8800_TX_ITR, val);
+
+       /* Configure rx DMA */
+
+       val = nb8800_readl(priv, NB8800_RXC_CR);
+       val &= RCR_LE;          /* keep endian setting */
+       val |= RCR_DM;          /* DMA descriptor mode */
+       val |= RCR_RS;          /* automatically store rx status */
+       val |= RCR_DIE;         /* interrupt at end of DMA chain */
+       val |= RCR_RFI(7);      /* interrupt after 7 frames received */
+       val |= RCR_BTS(2);      /* 32-byte bus transaction size */
+       nb8800_writel(priv, NB8800_RXC_CR, val);
+
+       /* The rx interrupt can fire before the DMA has completed
+        * unless a small delay is added.  50 us is hopefully enough.
+        */
+       priv->rx_itr_irq = clk_get_rate(priv->clk) / 20000;
+
+       /* In NAPI poll mode we want to disable interrupts, but the
+        * hardware does not permit this.  Delay 10 ms instead.
+        */
+       priv->rx_itr_poll = clk_get_rate(priv->clk) / 100;
+
+       nb8800_writel(priv, NB8800_RX_ITR, priv->rx_itr_irq);
+
+       priv->rx_dma_config = RX_BUF_SIZE | DESC_BTS(2) | DESC_DS | DESC_EOF;
+
+       /* Flow control settings */
+
+       /* Pause time of 0.1 ms */
+       val = 100000 / 512;
+       nb8800_writeb(priv, NB8800_PQ1, val >> 8);
+       nb8800_writeb(priv, NB8800_PQ2, val & 0xff);
+
+       /* Auto-negotiate by default */
+       priv->pause_aneg = true;
+       priv->pause_rx = true;
+       priv->pause_tx = true;
+
+       nb8800_mc_init(dev, 0);
+
+       return 0;
+}
+
+static int nb8800_tangox_init(struct net_device *dev)
+{
+       struct nb8800_priv *priv = netdev_priv(dev);
+       u32 pad_mode = PAD_MODE_MII;
+
+       switch (priv->phy_mode) {
+       case PHY_INTERFACE_MODE_MII:
+       case PHY_INTERFACE_MODE_GMII:
+               pad_mode = PAD_MODE_MII;
+               break;
+
+       case PHY_INTERFACE_MODE_RGMII:
+               pad_mode = PAD_MODE_RGMII;
+               break;
+
+       case PHY_INTERFACE_MODE_RGMII_TXID:
+               pad_mode = PAD_MODE_RGMII | PAD_MODE_GTX_CLK_DELAY;
+               break;
+
+       default:
+               dev_err(dev->dev.parent, "unsupported phy mode %s\n",
+                       phy_modes(priv->phy_mode));
+               return -EINVAL;
+       }
+
+       nb8800_writeb(priv, NB8800_TANGOX_PAD_MODE, pad_mode);
+
+       return 0;
+}
+
+static int nb8800_tangox_reset(struct net_device *dev)
+{
+       struct nb8800_priv *priv = netdev_priv(dev);
+       int clk_div;
+
+       nb8800_writeb(priv, NB8800_TANGOX_RESET, 0);
+       usleep_range(1000, 10000);
+       nb8800_writeb(priv, NB8800_TANGOX_RESET, 1);
+
+       wmb();          /* ensure reset is cleared before proceeding */
+
+       clk_div = DIV_ROUND_UP(clk_get_rate(priv->clk), 2 * MAX_MDC_CLOCK);
+       nb8800_writew(priv, NB8800_TANGOX_MDIO_CLKDIV, clk_div);
+
+       return 0;
+}
+
+static const struct nb8800_ops nb8800_tangox_ops = {
+       .init   = nb8800_tangox_init,
+       .reset  = nb8800_tangox_reset,
+};
+
+static int nb8800_tango4_init(struct net_device *dev)
+{
+       struct nb8800_priv *priv = netdev_priv(dev);
+       int err;
+
+       err = nb8800_tangox_init(dev);
+       if (err)
+               return err;
+
+       /* On tango4 interrupt on DMA completion per frame works and gives
+        * better performance despite generating more rx interrupts.
+        */
+
+       /* Disable unnecessary interrupt on rx completion */
+       nb8800_clearl(priv, NB8800_RXC_CR, RCR_RFI(7));
+
+       /* Request interrupt on descriptor DMA completion */
+       priv->rx_dma_config |= DESC_ID;
+
+       return 0;
+}
+
+static const struct nb8800_ops nb8800_tango4_ops = {
+       .init   = nb8800_tango4_init,
+       .reset  = nb8800_tangox_reset,
+};
+
+static const struct of_device_id nb8800_dt_ids[] = {
+       {
+               .compatible = "aurora,nb8800",
+       },
+       {
+               .compatible = "sigma,smp8642-ethernet",
+               .data = &nb8800_tangox_ops,
+       },
+       {
+               .compatible = "sigma,smp8734-ethernet",
+               .data = &nb8800_tango4_ops,
+       },
+       { }
+};
+
+static int nb8800_probe(struct platform_device *pdev)
+{
+       const struct of_device_id *match;
+       const struct nb8800_ops *ops = NULL;
+       struct nb8800_priv *priv;
+       struct resource *res;
+       struct net_device *dev;
+       struct mii_bus *bus;
+       const unsigned char *mac;
+       void __iomem *base;
+       int irq;
+       int ret;
+
+       match = of_match_device(nb8800_dt_ids, &pdev->dev);
+       if (match)
+               ops = match->data;
+
+       irq = platform_get_irq(pdev, 0);
+       if (irq <= 0) {
+               dev_err(&pdev->dev, "No IRQ\n");
+               return -EINVAL;
+       }
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       base = devm_ioremap_resource(&pdev->dev, res);
+       if (IS_ERR(base))
+               return PTR_ERR(base);
+
+       dev_dbg(&pdev->dev, "AU-NB8800 Ethernet at %pa\n", &res->start);
+
+       dev = alloc_etherdev(sizeof(*priv));
+       if (!dev)
+               return -ENOMEM;
+
+       platform_set_drvdata(pdev, dev);
+       SET_NETDEV_DEV(dev, &pdev->dev);
+
+       priv = netdev_priv(dev);
+       priv->base = base;
+
+       priv->phy_mode = of_get_phy_mode(pdev->dev.of_node);
+       if (priv->phy_mode < 0)
+               priv->phy_mode = PHY_INTERFACE_MODE_RGMII;
+
+       priv->clk = devm_clk_get(&pdev->dev, NULL);
+       if (IS_ERR(priv->clk)) {
+               dev_err(&pdev->dev, "failed to get clock\n");
+               ret = PTR_ERR(priv->clk);
+               goto err_free_dev;
+       }
+
+       ret = clk_prepare_enable(priv->clk);
+       if (ret)
+               goto err_free_dev;
+
+       spin_lock_init(&priv->tx_lock);
+
+       if (ops && ops->reset) {
+               ret = ops->reset(dev);
+               if (ret)
+                       goto err_free_dev;
+       }
+
+       bus = devm_mdiobus_alloc(&pdev->dev);
+       if (!bus) {
+               ret = -ENOMEM;
+               goto err_disable_clk;
+       }
+
+       bus->name = "nb8800-mii";
+       bus->read = nb8800_mdio_read;
+       bus->write = nb8800_mdio_write;
+       bus->parent = &pdev->dev;
+       snprintf(bus->id, MII_BUS_ID_SIZE, "%lx.nb8800-mii",
+                (unsigned long)res->start);
+       bus->priv = priv;
+
+       ret = of_mdiobus_register(bus, pdev->dev.of_node);
+       if (ret) {
+               dev_err(&pdev->dev, "failed to register MII bus\n");
+               goto err_disable_clk;
+       }
+
+       priv->phy_node = of_parse_phandle(pdev->dev.of_node, "phy-handle", 0);
+       if (!priv->phy_node) {
+               dev_err(&pdev->dev, "no PHY specified\n");
+               ret = -ENODEV;
+               goto err_free_bus;
+       }
+
+       priv->mii_bus = bus;
+
+       ret = nb8800_hw_init(dev);
+       if (ret)
+               goto err_free_bus;
+
+       if (ops && ops->init) {
+               ret = ops->init(dev);
+               if (ret)
+                       goto err_free_bus;
+       }
+
+       dev->netdev_ops = &nb8800_netdev_ops;
+       dev->ethtool_ops = &nb8800_ethtool_ops;
+       dev->flags |= IFF_MULTICAST;
+       dev->irq = irq;
+
+       mac = of_get_mac_address(pdev->dev.of_node);
+       if (mac)
+               ether_addr_copy(dev->dev_addr, mac);
+
+       if (!is_valid_ether_addr(dev->dev_addr))
+               eth_hw_addr_random(dev);
+
+       nb8800_update_mac_addr(dev);
+
+       netif_carrier_off(dev);
+
+       ret = register_netdev(dev);
+       if (ret) {
+               netdev_err(dev, "failed to register netdev\n");
+               goto err_free_dma;
+       }
+
+       netif_napi_add(dev, &priv->napi, nb8800_poll, NAPI_POLL_WEIGHT);
+
+       netdev_info(dev, "MAC address %pM\n", dev->dev_addr);
+
+       return 0;
+
+err_free_dma:
+       nb8800_dma_free(dev);
+err_free_bus:
+       mdiobus_unregister(bus);
+err_disable_clk:
+       clk_disable_unprepare(priv->clk);
+err_free_dev:
+       free_netdev(dev);
+
+       return ret;
+}
+
+static int nb8800_remove(struct platform_device *pdev)
+{
+       struct net_device *ndev = platform_get_drvdata(pdev);
+       struct nb8800_priv *priv = netdev_priv(ndev);
+
+       unregister_netdev(ndev);
+
+       mdiobus_unregister(priv->mii_bus);
+
+       clk_disable_unprepare(priv->clk);
+
+       nb8800_dma_free(ndev);
+       free_netdev(ndev);
+
+       return 0;
+}
+
+static struct platform_driver nb8800_driver = {
+       .driver = {
+               .name           = "nb8800",
+               .of_match_table = nb8800_dt_ids,
+       },
+       .probe  = nb8800_probe,
+       .remove = nb8800_remove,
+};
+
+module_platform_driver(nb8800_driver);
+
+MODULE_DESCRIPTION("Aurora AU-NB8800 Ethernet driver");
+MODULE_AUTHOR("Mans Rullgard <mans@mansr.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/ethernet/aurora/nb8800.h b/drivers/net/ethernet/aurora/nb8800.h
new file mode 100644 (file)
index 0000000..e5adbc2
--- /dev/null
@@ -0,0 +1,316 @@
+#ifndef _NB8800_H_
+#define _NB8800_H_
+
+#include <linux/types.h>
+#include <linux/skbuff.h>
+#include <linux/phy.h>
+#include <linux/clk.h>
+#include <linux/bitops.h>
+
+#define RX_DESC_COUNT                  256
+#define TX_DESC_COUNT                  256
+
+#define NB8800_DESC_LOW                        4
+
+#define RX_BUF_SIZE                    1552
+
+#define RX_COPYBREAK                   256
+#define RX_COPYHDR                     128
+
+#define MAX_MDC_CLOCK                  2500000
+
+/* Stargate Solutions SSN8800 core registers */
+#define NB8800_TX_CTL1                 0x000
+#define TX_TPD                         BIT(5)
+#define TX_APPEND_FCS                  BIT(4)
+#define TX_PAD_EN                      BIT(3)
+#define TX_RETRY_EN                    BIT(2)
+#define TX_EN                          BIT(0)
+
+#define NB8800_TX_CTL2                 0x001
+
+#define NB8800_RX_CTL                  0x004
+#define RX_BC_DISABLE                  BIT(7)
+#define RX_RUNT                                BIT(6)
+#define RX_AF_EN                       BIT(5)
+#define RX_PAUSE_EN                    BIT(3)
+#define RX_SEND_CRC                    BIT(2)
+#define RX_PAD_STRIP                   BIT(1)
+#define RX_EN                          BIT(0)
+
+#define NB8800_RANDOM_SEED             0x008
+#define NB8800_TX_SDP                  0x14
+#define NB8800_TX_TPDP1                        0x18
+#define NB8800_TX_TPDP2                        0x19
+#define NB8800_SLOT_TIME               0x1c
+
+#define NB8800_MDIO_CMD                        0x020
+#define MDIO_CMD_GO                    BIT(31)
+#define MDIO_CMD_WR                    BIT(26)
+#define MDIO_CMD_ADDR(x)               ((x) << 21)
+#define MDIO_CMD_REG(x)                        ((x) << 16)
+#define MDIO_CMD_DATA(x)               ((x) <<  0)
+
+#define NB8800_MDIO_STS                        0x024
+#define MDIO_STS_ERR                   BIT(31)
+
+#define NB8800_MC_ADDR(i)              (0x028 + (i))
+#define NB8800_MC_INIT                 0x02e
+#define NB8800_UC_ADDR(i)              (0x03c + (i))
+
+#define NB8800_MAC_MODE                        0x044
+#define RGMII_MODE                     BIT(7)
+#define HALF_DUPLEX                    BIT(4)
+#define BURST_EN                       BIT(3)
+#define LOOPBACK_EN                    BIT(2)
+#define GMAC_MODE                      BIT(0)
+
+#define NB8800_IC_THRESHOLD            0x050
+#define NB8800_PE_THRESHOLD            0x051
+#define NB8800_PF_THRESHOLD            0x052
+#define NB8800_TX_BUFSIZE              0x054
+#define NB8800_FIFO_CTL                        0x056
+#define NB8800_PQ1                     0x060
+#define NB8800_PQ2                     0x061
+#define NB8800_SRC_ADDR(i)             (0x06a + (i))
+#define NB8800_STAT_DATA               0x078
+#define NB8800_STAT_INDEX              0x07c
+#define NB8800_STAT_CLEAR              0x07d
+
+#define NB8800_SLEEP_MODE              0x07e
+#define SLEEP_MODE                     BIT(0)
+
+#define NB8800_WAKEUP                  0x07f
+#define WAKEUP                         BIT(0)
+
+/* Aurora NB8800 host interface registers */
+#define NB8800_TXC_CR                  0x100
+#define TCR_LK                         BIT(12)
+#define TCR_DS                         BIT(11)
+#define TCR_BTS(x)                     (((x) & 0x7) << 8)
+#define TCR_DIE                                BIT(7)
+#define TCR_TFI(x)                     (((x) & 0x7) << 4)
+#define TCR_LE                         BIT(3)
+#define TCR_RS                         BIT(2)
+#define TCR_DM                         BIT(1)
+#define TCR_EN                         BIT(0)
+
+#define NB8800_TXC_SR                  0x104
+#define TSR_DE                         BIT(3)
+#define TSR_DI                         BIT(2)
+#define TSR_TO                         BIT(1)
+#define TSR_TI                         BIT(0)
+
+#define NB8800_TX_SAR                  0x108
+#define NB8800_TX_DESC_ADDR            0x10c
+
+#define NB8800_TX_REPORT_ADDR          0x110
+#define TX_BYTES_TRANSFERRED(x)                (((x) >> 16) & 0xffff)
+#define TX_FIRST_DEFERRAL              BIT(7)
+#define TX_EARLY_COLLISIONS(x)         (((x) >> 3) & 0xf)
+#define TX_LATE_COLLISION              BIT(2)
+#define TX_PACKET_DROPPED              BIT(1)
+#define TX_FIFO_UNDERRUN               BIT(0)
+#define IS_TX_ERROR(r)                 ((r) & 0x07)
+
+#define NB8800_TX_FIFO_SR              0x114
+#define NB8800_TX_ITR                  0x118
+
+#define NB8800_RXC_CR                  0x200
+#define RCR_FL                         BIT(13)
+#define RCR_LK                         BIT(12)
+#define RCR_DS                         BIT(11)
+#define RCR_BTS(x)                     (((x) & 7) << 8)
+#define RCR_DIE                                BIT(7)
+#define RCR_RFI(x)                     (((x) & 7) << 4)
+#define RCR_LE                         BIT(3)
+#define RCR_RS                         BIT(2)
+#define RCR_DM                         BIT(1)
+#define RCR_EN                         BIT(0)
+
+#define NB8800_RXC_SR                  0x204
+#define RSR_DE                         BIT(3)
+#define RSR_DI                         BIT(2)
+#define RSR_RO                         BIT(1)
+#define RSR_RI                         BIT(0)
+
+#define NB8800_RX_SAR                  0x208
+#define NB8800_RX_DESC_ADDR            0x20c
+
+#define NB8800_RX_REPORT_ADDR          0x210
+#define RX_BYTES_TRANSFERRED(x)                (((x) >> 16) & 0xFFFF)
+#define RX_MULTICAST_PKT               BIT(9)
+#define RX_BROADCAST_PKT               BIT(8)
+#define RX_LENGTH_ERR                  BIT(7)
+#define RX_FCS_ERR                     BIT(6)
+#define RX_RUNT_PKT                    BIT(5)
+#define RX_FIFO_OVERRUN                        BIT(4)
+#define RX_LATE_COLLISION              BIT(3)
+#define RX_ALIGNMENT_ERROR             BIT(2)
+#define RX_ERROR_MASK                  0xfc
+#define IS_RX_ERROR(r)                 ((r) & RX_ERROR_MASK)
+
+#define NB8800_RX_FIFO_SR              0x214
+#define NB8800_RX_ITR                  0x218
+
+/* Sigma Designs SMP86xx additional registers */
+#define NB8800_TANGOX_PAD_MODE         0x400
+#define PAD_MODE_MASK                  0x7
+#define PAD_MODE_MII                   0x0
+#define PAD_MODE_RGMII                 0x1
+#define PAD_MODE_GTX_CLK_INV           BIT(3)
+#define PAD_MODE_GTX_CLK_DELAY         BIT(4)
+
+#define NB8800_TANGOX_MDIO_CLKDIV      0x420
+#define NB8800_TANGOX_RESET            0x424
+
+/* Hardware DMA descriptor */
+struct nb8800_dma_desc {
+       u32                             s_addr; /* start address */
+       u32                             n_addr; /* next descriptor address */
+       u32                             r_addr; /* report address */
+       u32                             config;
+} __aligned(8);
+
+#define DESC_ID                                BIT(23)
+#define DESC_EOC                       BIT(22)
+#define DESC_EOF                       BIT(21)
+#define DESC_LK                                BIT(20)
+#define DESC_DS                                BIT(19)
+#define DESC_BTS(x)                    (((x) & 0x7) << 16)
+
+/* DMA descriptor and associated data for rx.
+ * Allocated from coherent memory.
+ */
+struct nb8800_rx_desc {
+       /* DMA descriptor */
+       struct nb8800_dma_desc          desc;
+
+       /* Status report filled in by hardware */
+       u32                             report;
+};
+
+/* Address of buffer on rx ring */
+struct nb8800_rx_buf {
+       struct page                     *page;
+       unsigned long                   offset;
+};
+
+/* DMA descriptors and associated data for tx.
+ * Allocated from coherent memory.
+ */
+struct nb8800_tx_desc {
+       /* DMA descriptor.  The second descriptor is used if packet
+        * data is unaligned.
+        */
+       struct nb8800_dma_desc          desc[2];
+
+       /* Status report filled in by hardware */
+       u32                             report;
+
+       /* Bounce buffer for initial unaligned part of packet */
+       u8                              buf[8] __aligned(8);
+};
+
+/* Packet in tx queue */
+struct nb8800_tx_buf {
+       /* Currently queued skb */
+       struct sk_buff                  *skb;
+
+       /* DMA address of the first descriptor */
+       dma_addr_t                      dma_desc;
+
+       /* DMA address of packet data */
+       dma_addr_t                      dma_addr;
+
+       /* Length of DMA mapping, less than skb->len if alignment
+        * buffer is used.
+        */
+       unsigned int                    dma_len;
+
+       /* Number of packets in chain starting here */
+       unsigned int                    chain_len;
+
+       /* Packet chain ready to be submitted to hardware */
+       bool                            ready;
+};
+
+struct nb8800_priv {
+       struct napi_struct              napi;
+
+       void __iomem                    *base;
+
+       /* RX DMA descriptors */
+       struct nb8800_rx_desc           *rx_descs;
+
+       /* RX buffers referenced by DMA descriptors */
+       struct nb8800_rx_buf            *rx_bufs;
+
+       /* Current end of chain */
+       u32                             rx_eoc;
+
+       /* Value for rx interrupt time register in NAPI interrupt mode */
+       u32                             rx_itr_irq;
+
+       /* Value for rx interrupt time register in NAPI poll mode */
+       u32                             rx_itr_poll;
+
+       /* Value for config field of rx DMA descriptors */
+       u32                             rx_dma_config;
+
+       /* TX DMA descriptors */
+       struct nb8800_tx_desc           *tx_descs;
+
+       /* TX packet queue */
+       struct nb8800_tx_buf            *tx_bufs;
+
+       /* Number of free tx queue entries */
+       atomic_t                        tx_free;
+
+       /* First free tx queue entry */
+       u32                             tx_next;
+
+       /* Next buffer to transmit */
+       u32                             tx_queue;
+
+       /* Start of current packet chain */
+       struct nb8800_tx_buf            *tx_chain;
+
+       /* Next buffer to reclaim */
+       u32                             tx_done;
+
+       /* Lock for DMA activation */
+       spinlock_t                      tx_lock;
+
+       struct mii_bus                  *mii_bus;
+       struct device_node              *phy_node;
+       struct phy_device               *phydev;
+
+       /* PHY connection type from DT */
+       int                             phy_mode;
+
+       /* Current link status */
+       int                             speed;
+       int                             duplex;
+       int                             link;
+
+       /* Pause settings */
+       bool                            pause_aneg;
+       bool                            pause_rx;
+       bool                            pause_tx;
+
+       /* DMA base address of rx descriptors, see rx_descs above */
+       dma_addr_t                      rx_desc_dma;
+
+       /* DMA base address of tx descriptors, see tx_descs above */
+       dma_addr_t                      tx_desc_dma;
+
+       struct clk                      *clk;
+};
+
+struct nb8800_ops {
+       int                             (*init)(struct net_device *dev);
+       int                             (*reset)(struct net_device *dev);
+};
+
+#endif /* _NB8800_H_ */
index c9b036789184e5cadc7a6e9892e1778c2b9b1582..2e611dc5f16210393852110c7dda5dadf4dfc560 100644 (file)
@@ -10139,8 +10139,8 @@ static void __bnx2x_del_vxlan_port(struct bnx2x *bp, u16 port)
                DP(BNX2X_MSG_SP, "Invalid vxlan port\n");
                return;
        }
-       bp->vxlan_dst_port--;
-       if (bp->vxlan_dst_port)
+       bp->vxlan_dst_port_count--;
+       if (bp->vxlan_dst_port_count)
                return;
 
        if (netif_running(bp->dev)) {
index db15c5ee09c53a528ea405961734dae927af0e06..bdf094fb6ef92062d62d428109e277ba9e9d15f5 100644 (file)
@@ -3625,6 +3625,7 @@ static int bnxt_hwrm_func_qcaps(struct bnxt *bp)
                pf->fw_fid = le16_to_cpu(resp->fid);
                pf->port_id = le16_to_cpu(resp->port_id);
                memcpy(pf->mac_addr, resp->perm_mac_address, ETH_ALEN);
+               memcpy(bp->dev->dev_addr, pf->mac_addr, ETH_ALEN);
                pf->max_rsscos_ctxs = le16_to_cpu(resp->max_rsscos_ctx);
                pf->max_cp_rings = le16_to_cpu(resp->max_cmpl_rings);
                pf->max_tx_rings = le16_to_cpu(resp->max_tx_rings);
@@ -3648,8 +3649,11 @@ static int bnxt_hwrm_func_qcaps(struct bnxt *bp)
 
                vf->fw_fid = le16_to_cpu(resp->fid);
                memcpy(vf->mac_addr, resp->perm_mac_address, ETH_ALEN);
-               if (!is_valid_ether_addr(vf->mac_addr))
-                       random_ether_addr(vf->mac_addr);
+               if (is_valid_ether_addr(vf->mac_addr))
+                       /* overwrite netdev dev_adr with admin VF MAC */
+                       memcpy(bp->dev->dev_addr, vf->mac_addr, ETH_ALEN);
+               else
+                       random_ether_addr(bp->dev->dev_addr);
 
                vf->max_rsscos_ctxs = le16_to_cpu(resp->max_rsscos_ctx);
                vf->max_cp_rings = le16_to_cpu(resp->max_cmpl_rings);
@@ -3880,6 +3884,8 @@ static int bnxt_alloc_rfs_vnics(struct bnxt *bp)
 #endif
 }
 
+static int bnxt_cfg_rx_mode(struct bnxt *);
+
 static int bnxt_init_chip(struct bnxt *bp, bool irq_re_init)
 {
        int rc = 0;
@@ -3946,11 +3952,9 @@ static int bnxt_init_chip(struct bnxt *bp, bool irq_re_init)
                bp->vnic_info[0].rx_mask |=
                                CFA_L2_SET_RX_MASK_REQ_MASK_PROMISCUOUS;
 
-       rc = bnxt_hwrm_cfa_l2_set_rx_mask(bp, 0);
-       if (rc) {
-               netdev_err(bp->dev, "HWRM cfa l2 rx mask failure rc: %x\n", rc);
+       rc = bnxt_cfg_rx_mode(bp);
+       if (rc)
                goto err_out;
-       }
 
        rc = bnxt_hwrm_set_coal(bp);
        if (rc)
@@ -4865,7 +4869,7 @@ static void bnxt_set_rx_mode(struct net_device *dev)
        }
 }
 
-static void bnxt_cfg_rx_mode(struct bnxt *bp)
+static int bnxt_cfg_rx_mode(struct bnxt *bp)
 {
        struct net_device *dev = bp->dev;
        struct bnxt_vnic_info *vnic = &bp->vnic_info[0];
@@ -4914,6 +4918,7 @@ static void bnxt_cfg_rx_mode(struct bnxt *bp)
                        netdev_err(bp->dev, "HWRM vnic filter failure rc: %x\n",
                                   rc);
                        vnic->uc_filter_count = i;
+                       return rc;
                }
        }
 
@@ -4922,6 +4927,8 @@ skip_uc:
        if (rc)
                netdev_err(bp->dev, "HWRM cfa l2 rx mask failure rc: %x\n",
                           rc);
+
+       return rc;
 }
 
 static netdev_features_t bnxt_fix_features(struct net_device *dev,
@@ -5212,13 +5219,27 @@ init_err:
 static int bnxt_change_mac_addr(struct net_device *dev, void *p)
 {
        struct sockaddr *addr = p;
+       struct bnxt *bp = netdev_priv(dev);
+       int rc = 0;
 
        if (!is_valid_ether_addr(addr->sa_data))
                return -EADDRNOTAVAIL;
 
+#ifdef CONFIG_BNXT_SRIOV
+       if (BNXT_VF(bp) && is_valid_ether_addr(bp->vf.mac_addr))
+               return -EADDRNOTAVAIL;
+#endif
+
+       if (ether_addr_equal(addr->sa_data, dev->dev_addr))
+               return 0;
+
        memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
+       if (netif_running(dev)) {
+               bnxt_close_nic(bp, false, false);
+               rc = bnxt_open_nic(bp, false, false);
+       }
 
-       return 0;
+       return rc;
 }
 
 /* rtnl_lock held */
@@ -5686,15 +5707,12 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        bnxt_set_tpa_flags(bp);
        bnxt_set_ring_params(bp);
        dflt_rings = netif_get_num_default_rss_queues();
-       if (BNXT_PF(bp)) {
-               memcpy(dev->dev_addr, bp->pf.mac_addr, ETH_ALEN);
+       if (BNXT_PF(bp))
                bp->pf.max_irqs = max_irqs;
-       } else {
 #if defined(CONFIG_BNXT_SRIOV)
-               memcpy(dev->dev_addr, bp->vf.mac_addr, ETH_ALEN);
+       else
                bp->vf.max_irqs = max_irqs;
 #endif
-       }
        bnxt_get_max_rings(bp, &max_rx_rings, &max_tx_rings);
        bp->rx_nr_rings = min_t(int, dflt_rings, max_rx_rings);
        bp->tx_nr_rings_per_tc = min_t(int, dflt_rings, max_tx_rings);
index f4cf6886106906d90bff221038b83914d9bbbd24..7a9af2887d8ed83f6a8672f8c1b6e18cd572c28a 100644 (file)
@@ -804,10 +804,9 @@ void bnxt_update_vf_mac(struct bnxt *bp)
        if (!is_valid_ether_addr(resp->perm_mac_address))
                goto update_vf_mac_exit;
 
-       if (ether_addr_equal(resp->perm_mac_address, bp->vf.mac_addr))
-               goto update_vf_mac_exit;
-
-       memcpy(bp->vf.mac_addr, resp->perm_mac_address, ETH_ALEN);
+       if (!ether_addr_equal(resp->perm_mac_address, bp->vf.mac_addr))
+               memcpy(bp->vf.mac_addr, resp->perm_mac_address, ETH_ALEN);
+       /* overwrite netdev dev_adr with admin VF MAC */
        memcpy(bp->dev->dev_addr, bp->vf.mac_addr, ETH_ALEN);
 update_vf_mac_exit:
        mutex_unlock(&bp->hwrm_cmd_lock);
index 88c1e1a834f8c44491c76269be7c6aa805906ab2..169059c92f80b776fb3901578ba56bb959624a07 100644 (file)
@@ -1682,6 +1682,8 @@ static void macb_init_hw(struct macb *bp)
        macb_set_hwaddr(bp);
 
        config = macb_mdc_clk_div(bp);
+       if (bp->phy_interface == PHY_INTERFACE_MODE_SGMII)
+               config |= GEM_BIT(SGMIIEN) | GEM_BIT(PCSSEL);
        config |= MACB_BF(RBOF, NET_IP_ALIGN);  /* Make eth data aligned */
        config |= MACB_BIT(PAE);                /* PAuse Enable */
        config |= MACB_BIT(DRFCS);              /* Discard Rx FCS */
@@ -2416,6 +2418,8 @@ static int macb_init(struct platform_device *pdev)
        /* Set MII management clock divider */
        val = macb_mdc_clk_div(bp);
        val |= macb_dbw(bp);
+       if (bp->phy_interface == PHY_INTERFACE_MODE_SGMII)
+               val |= GEM_BIT(SGMIIEN) | GEM_BIT(PCSSEL);
        macb_writel(bp, NCFGR, val);
 
        return 0;
index 6e1faea00ca829f5c9df34b45518d7e1a881c5c3..d83b0db7782194ad0695f0d2454a69ccf1d68220 100644 (file)
 /* GEM specific NCFGR bitfields. */
 #define GEM_GBE_OFFSET         10 /* Gigabit mode enable */
 #define GEM_GBE_SIZE           1
+#define GEM_PCSSEL_OFFSET      11
+#define GEM_PCSSEL_SIZE                1
 #define GEM_CLK_OFFSET         18 /* MDC clock division */
 #define GEM_CLK_SIZE           3
 #define GEM_DBW_OFFSET         21 /* Data bus width */
 #define GEM_DBW_SIZE           2
 #define GEM_RXCOEN_OFFSET      24
 #define GEM_RXCOEN_SIZE                1
+#define GEM_SGMIIEN_OFFSET     27
+#define GEM_SGMIIEN_SIZE       1
+
 
 /* Constants for data bus width. */
 #define GEM_DBW32              0 /* 32 bit AMBA AHB data bus width */
index d3950b20feb9e2a62d5a13aab9b08e0683fb7365..39ca6744a4e68fe317f93e1318e729509c1b978e 100644 (file)
  * Calculated for SCLK of 700Mhz
  * value written should be a 1/16th of what is expected
  *
- * 1 tick per 0.05usec = value of 2.2
- * This 10% would be covered in CQ timer thresh value
+ * 1 tick per 0.025usec
  */
-#define NICPF_CLK_PER_INT_TICK         2
+#define NICPF_CLK_PER_INT_TICK         1
 
 /* Time to wait before we decide that a SQ is stuck.
  *
index c561fdcb79a730aeeb890c5a985b05cb873faa45..4b7fd63ae57c1d26ab54d9359297c56f35c6105c 100644 (file)
@@ -37,6 +37,7 @@ struct nicpf {
 #define        NIC_GET_BGX_FROM_VF_LMAC_MAP(map)       ((map >> 4) & 0xF)
 #define        NIC_GET_LMAC_FROM_VF_LMAC_MAP(map)      (map & 0xF)
        u8                      vf_lmac_map[MAX_LMAC];
+       u8                      lmac_cnt;
        struct delayed_work     dwork;
        struct workqueue_struct *check_link;
        u8                      link[MAX_LMAC];
@@ -279,6 +280,7 @@ static void nic_set_lmac_vf_mapping(struct nicpf *nic)
        u64 lmac_credit;
 
        nic->num_vf_en = 0;
+       nic->lmac_cnt = 0;
 
        for (bgx = 0; bgx < NIC_MAX_BGX; bgx++) {
                if (!(bgx_map & (1 << bgx)))
@@ -288,6 +290,7 @@ static void nic_set_lmac_vf_mapping(struct nicpf *nic)
                        nic->vf_lmac_map[next_bgx_lmac++] =
                                                NIC_SET_VF_LMAC_MAP(bgx, lmac);
                nic->num_vf_en += lmac_cnt;
+               nic->lmac_cnt += lmac_cnt;
 
                /* Program LMAC credits */
                lmac_credit = (1ull << 1); /* channel credit enable */
@@ -715,6 +718,13 @@ static void nic_handle_mbx_intr(struct nicpf *nic, int vf)
        case NIC_MBOX_MSG_CFG_DONE:
                /* Last message of VF config msg sequence */
                nic->vf_enabled[vf] = true;
+               if (vf >= nic->lmac_cnt)
+                       goto unlock;
+
+               bgx = NIC_GET_BGX_FROM_VF_LMAC_MAP(nic->vf_lmac_map[vf]);
+               lmac = NIC_GET_LMAC_FROM_VF_LMAC_MAP(nic->vf_lmac_map[vf]);
+
+               bgx_lmac_rx_tx_enable(nic->node, bgx, lmac, true);
                goto unlock;
        case NIC_MBOX_MSG_SHUTDOWN:
                /* First msg in VF teardown sequence */
@@ -722,6 +732,14 @@ static void nic_handle_mbx_intr(struct nicpf *nic, int vf)
                if (vf >= nic->num_vf_en)
                        nic->sqs_used[vf - nic->num_vf_en] = false;
                nic->pqs_vf[vf] = 0;
+
+               if (vf >= nic->lmac_cnt)
+                       break;
+
+               bgx = NIC_GET_BGX_FROM_VF_LMAC_MAP(nic->vf_lmac_map[vf]);
+               lmac = NIC_GET_LMAC_FROM_VF_LMAC_MAP(nic->vf_lmac_map[vf]);
+
+               bgx_lmac_rx_tx_enable(nic->node, bgx, lmac, false);
                break;
        case NIC_MBOX_MSG_ALLOC_SQS:
                nic_alloc_sqs(nic, &mbx.sqs_alloc);
@@ -940,7 +958,7 @@ static void nic_poll_for_link(struct work_struct *work)
 
        mbx.link_status.msg = NIC_MBOX_MSG_BGX_LINK_CHANGE;
 
-       for (vf = 0; vf < nic->num_vf_en; vf++) {
+       for (vf = 0; vf < nic->lmac_cnt; vf++) {
                /* Poll only if VF is UP */
                if (!nic->vf_enabled[vf])
                        continue;
@@ -1074,8 +1092,7 @@ static void nic_remove(struct pci_dev *pdev)
 
        if (nic->check_link) {
                /* Destroy work Queue */
-               cancel_delayed_work(&nic->dwork);
-               flush_workqueue(nic->check_link);
+               cancel_delayed_work_sync(&nic->dwork);
                destroy_workqueue(nic->check_link);
        }
 
index af54c10945c25175e344ebf052e47e88c62219a3..a12b2e38cf61221fc4de44f6395eb60de76825a5 100644 (file)
@@ -112,6 +112,13 @@ static int nicvf_get_settings(struct net_device *netdev,
 
        cmd->supported = 0;
        cmd->transceiver = XCVR_EXTERNAL;
+
+       if (!nic->link_up) {
+               cmd->duplex = DUPLEX_UNKNOWN;
+               ethtool_cmd_speed_set(cmd, SPEED_UNKNOWN);
+               return 0;
+       }
+
        if (nic->speed <= 1000) {
                cmd->port = PORT_MII;
                cmd->autoneg = AUTONEG_ENABLE;
@@ -125,6 +132,13 @@ static int nicvf_get_settings(struct net_device *netdev,
        return 0;
 }
 
+static u32 nicvf_get_link(struct net_device *netdev)
+{
+       struct nicvf *nic = netdev_priv(netdev);
+
+       return nic->link_up;
+}
+
 static void nicvf_get_drvinfo(struct net_device *netdev,
                              struct ethtool_drvinfo *info)
 {
@@ -660,7 +674,7 @@ static int nicvf_set_channels(struct net_device *dev,
 
 static const struct ethtool_ops nicvf_ethtool_ops = {
        .get_settings           = nicvf_get_settings,
-       .get_link               = ethtool_op_get_link,
+       .get_link               = nicvf_get_link,
        .get_drvinfo            = nicvf_get_drvinfo,
        .get_msglevel           = nicvf_get_msglevel,
        .set_msglevel           = nicvf_set_msglevel,
index 7f709cbdcd87d2f0a0beedd338437218ee0af094..dde8dc720cd3f3b7d513776662a4f05b1241486d 100644 (file)
@@ -1057,6 +1057,7 @@ int nicvf_stop(struct net_device *netdev)
 
        netif_carrier_off(netdev);
        netif_tx_stop_all_queues(nic->netdev);
+       nic->link_up = false;
 
        /* Teardown secondary qsets first */
        if (!nic->sqs_mode) {
@@ -1211,9 +1212,6 @@ int nicvf_open(struct net_device *netdev)
        nic->drv_stats.txq_stop = 0;
        nic->drv_stats.txq_wake = 0;
 
-       netif_carrier_on(netdev);
-       netif_tx_start_all_queues(netdev);
-
        return 0;
 cleanup:
        nicvf_disable_intr(nic, NICVF_INTR_MBOX, 0);
index e404ea837727eada97159544ccaca9406c7dd940..206b6a71a545aff776cdd88809c2f59b2f9d1216 100644 (file)
@@ -592,7 +592,7 @@ void nicvf_cmp_queue_config(struct nicvf *nic, struct queue_set *qs,
        /* Set threshold value for interrupt generation */
        nicvf_queue_reg_write(nic, NIC_QSET_CQ_0_7_THRESH, qidx, cq->thresh);
        nicvf_queue_reg_write(nic, NIC_QSET_CQ_0_7_CFG2,
-                             qidx, nic->cq_coalesce_usecs);
+                             qidx, CMP_QUEUE_TIMER_THRESH);
 }
 
 /* Configures transmit queue */
index fb4957d099144ca7ff62064b66be137dbbf6733e..033e8306e91c6942862ffe9dae0ca3836a8228f5 100644 (file)
@@ -76,7 +76,7 @@
 #define CMP_QSIZE              CMP_QUEUE_SIZE2
 #define CMP_QUEUE_LEN          (1ULL << (CMP_QSIZE + 10))
 #define CMP_QUEUE_CQE_THRESH   0
-#define CMP_QUEUE_TIMER_THRESH 220 /* 10usec */
+#define CMP_QUEUE_TIMER_THRESH 80 /* ~2usec */
 
 #define RBDR_SIZE              RBDR_SIZE0
 #define RCV_BUF_COUNT          (1ULL << (RBDR_SIZE + 13))
index 180aa9fabf4820df042f18cba8c39d5ce1668e9d..9df26c2263bcc37bdfced23e2db688c151942733 100644 (file)
@@ -186,6 +186,23 @@ void bgx_set_lmac_mac(int node, int bgx_idx, int lmacid, const u8 *mac)
 }
 EXPORT_SYMBOL(bgx_set_lmac_mac);
 
+void bgx_lmac_rx_tx_enable(int node, int bgx_idx, int lmacid, bool enable)
+{
+       struct bgx *bgx = bgx_vnic[(node * MAX_BGX_PER_CN88XX) + bgx_idx];
+       u64 cfg;
+
+       if (!bgx)
+               return;
+
+       cfg = bgx_reg_read(bgx, lmacid, BGX_CMRX_CFG);
+       if (enable)
+               cfg |= CMR_PKT_RX_EN | CMR_PKT_TX_EN;
+       else
+               cfg &= ~(CMR_PKT_RX_EN | CMR_PKT_TX_EN);
+       bgx_reg_write(bgx, lmacid, BGX_CMRX_CFG, cfg);
+}
+EXPORT_SYMBOL(bgx_lmac_rx_tx_enable);
+
 static void bgx_sgmii_change_link_state(struct lmac *lmac)
 {
        struct bgx *bgx = lmac->bgx;
@@ -612,6 +629,8 @@ static void bgx_poll_for_link(struct work_struct *work)
                lmac->last_duplex = 1;
        } else {
                lmac->link_up = 0;
+               lmac->last_speed = SPEED_UNKNOWN;
+               lmac->last_duplex = DUPLEX_UNKNOWN;
        }
 
        if (lmac->last_link != lmac->link_up) {
@@ -654,8 +673,7 @@ static int bgx_lmac_enable(struct bgx *bgx, u8 lmacid)
        }
 
        /* Enable lmac */
-       bgx_reg_modify(bgx, lmacid, BGX_CMRX_CFG,
-                      CMR_EN | CMR_PKT_RX_EN | CMR_PKT_TX_EN);
+       bgx_reg_modify(bgx, lmacid, BGX_CMRX_CFG, CMR_EN);
 
        /* Restore default cfg, incase low level firmware changed it */
        bgx_reg_write(bgx, lmacid, BGX_CMRX_RX_DMAC_CTL, 0x03);
@@ -695,8 +713,7 @@ static void bgx_lmac_disable(struct bgx *bgx, u8 lmacid)
        lmac = &bgx->lmac[lmacid];
        if (lmac->check_link) {
                /* Destroy work queue */
-               cancel_delayed_work(&lmac->dwork);
-               flush_workqueue(lmac->check_link);
+               cancel_delayed_work_sync(&lmac->dwork);
                destroy_workqueue(lmac->check_link);
        }
 
@@ -1009,6 +1026,9 @@ static int bgx_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        struct bgx *bgx = NULL;
        u8 lmac;
 
+       /* Load octeon mdio driver */
+       octeon_mdiobus_force_mod_depencency();
+
        bgx = devm_kzalloc(dev, sizeof(*bgx), GFP_KERNEL);
        if (!bgx)
                return -ENOMEM;
index 07b7ec66c60db8dd398b7ff60321598c9317c4c9..149e179363a1e6dd71e0b7cbd00f26a5e5ef0116 100644 (file)
@@ -182,6 +182,8 @@ enum MCAST_MODE {
 #define BCAST_ACCEPT   1
 #define CAM_ACCEPT     1
 
+void octeon_mdiobus_force_mod_depencency(void);
+void bgx_lmac_rx_tx_enable(int node, int bgx_idx, int lmacid, bool enable);
 void bgx_add_dmac_addr(u64 dmac, int node, int bgx_idx, int lmac);
 unsigned bgx_get_map(int node);
 int bgx_get_lmac_count(int node, int bgx);
index ed41559bae771b8d58e49f21a46f7a79d9f20cac..b553409e04ad33ed50fafe3bdaa8de74d965e6eb 100644 (file)
@@ -98,8 +98,7 @@ static int csr0 = 0x01A00000 | 0x4800;
 #elif defined(__mips__)
 static int csr0 = 0x00200000 | 0x4000;
 #else
-#warning Processor architecture undefined!
-static int csr0 = 0x00A00000 | 0x4800;
+static int csr0;
 #endif
 
 /* Operational parameters that usually are not changed. */
@@ -1982,6 +1981,12 @@ static int __init tulip_init (void)
        pr_info("%s", version);
 #endif
 
+       if (!csr0) {
+               pr_warn("tulip: unknown CPU architecture, using default csr0\n");
+               /* default to 8 longword cache line alignment */
+               csr0 = 0x00A00000 | 0x4800;
+       }
+
        /* copy module parms into globals */
        tulip_rx_copybreak = rx_copybreak;
        tulip_max_interrupt_work = max_interrupt_work;
index 9beb3d34d4bad9f81ec8c11c560150d8b4640ed8..3c0e4d5c5fef41a8fe1fe99c0a163d30cd74fc31 100644 (file)
@@ -907,7 +907,7 @@ static void init_registers(struct net_device *dev)
 #elif defined(CONFIG_SPARC) || defined (CONFIG_PARISC) || defined(CONFIG_ARM)
        i |= 0x4800;
 #else
-#warning Processor architecture undefined
+       dev_warn(&dev->dev, "unknown CPU architecture, using default csr0 setting\n");
        i |= 0x4800;
 #endif
        iowrite32(i, ioaddr + PCIBusCfg);
index ff76d4e9dc1ba5eab90413f82592a876092a8ddf..bee32a9d9876f02719a5c46be9b65ff145f76c3b 100644 (file)
@@ -7,7 +7,8 @@ config NET_VENDOR_FREESCALE
        default y
        depends on FSL_SOC || QUICC_ENGINE || CPM1 || CPM2 || PPC_MPC512x || \
                   M523x || M527x || M5272 || M528x || M520x || M532x || \
-                  ARCH_MXC || ARCH_MXS || (PPC_MPC52xx && PPC_BESTCOMM)
+                  ARCH_MXC || ARCH_MXS || (PPC_MPC52xx && PPC_BESTCOMM) || \
+                  ARCH_LAYERSCAPE
        ---help---
          If you have a network (Ethernet) card belonging to this class, say Y.
 
index 3e6b9b437497dba9431fdedd3cf03262c0af3b0f..7cf898455e60076d52c1031422f3d90a3a10f4a3 100644 (file)
@@ -647,9 +647,9 @@ static int gfar_parse_group(struct device_node *np,
        if (model && strcasecmp(model, "FEC")) {
                gfar_irq(grp, RX)->irq = irq_of_parse_and_map(np, 1);
                gfar_irq(grp, ER)->irq = irq_of_parse_and_map(np, 2);
-               if (gfar_irq(grp, TX)->irq == NO_IRQ ||
-                   gfar_irq(grp, RX)->irq == NO_IRQ ||
-                   gfar_irq(grp, ER)->irq == NO_IRQ)
+               if (!gfar_irq(grp, TX)->irq ||
+                   !gfar_irq(grp, RX)->irq ||
+                   !gfar_irq(grp, ER)->irq)
                        return -EINVAL;
        }
 
index 664d0c261269097bccae55c12dcd7abcab140d5b..b40fba929d650d282c23f5d96636806ef4797d48 100644 (file)
@@ -467,7 +467,7 @@ static int gianfar_ptp_probe(struct platform_device *dev)
 
        etsects->irq = platform_get_irq(dev, 0);
 
-       if (etsects->irq == NO_IRQ) {
+       if (etsects->irq < 0) {
                pr_err("irq not in device tree\n");
                goto no_node;
        }
index 639263d5e833a04d19967f6df3cd20d8ce574a3b..7781e80896a60a59e12eec15582cc3743447e1dd 100644 (file)
@@ -627,8 +627,10 @@ static netdev_tx_t fm10k_xmit_frame(struct sk_buff *skb, struct net_device *dev)
 
                /* verify the skb head is not shared */
                err = skb_cow_head(skb, 0);
-               if (err)
+               if (err) {
+                       dev_kfree_skb(skb);
                        return NETDEV_TX_OK;
+               }
 
                /* locate vlan header */
                vhdr = (struct vlan_hdr *)(skb->data + ETH_HLEN);
index e84c7f2634d3759805326707a29c33737bcad615..ed622fa29dfab61c448c0c446ad2cae467ee1df2 100644 (file)
@@ -36,7 +36,7 @@
 
 /* Registers */
 #define MVNETA_RXQ_CONFIG_REG(q)                (0x1400 + ((q) << 2))
-#define      MVNETA_RXQ_HW_BUF_ALLOC            BIT(1)
+#define      MVNETA_RXQ_HW_BUF_ALLOC            BIT(0)
 #define      MVNETA_RXQ_PKT_OFFSET_ALL_MASK     (0xf    << 8)
 #define      MVNETA_RXQ_PKT_OFFSET_MASK(offs)   ((offs) << 8)
 #define MVNETA_RXQ_THRESHOLD_REG(q)             (0x14c0 + ((q) << 2))
@@ -62,6 +62,7 @@
 #define MVNETA_WIN_SIZE(w)                      (0x2204 + ((w) << 3))
 #define MVNETA_WIN_REMAP(w)                     (0x2280 + ((w) << 2))
 #define MVNETA_BASE_ADDR_ENABLE                 0x2290
+#define MVNETA_ACCESS_PROTECT_ENABLE            0x2294
 #define MVNETA_PORT_CONFIG                      0x2400
 #define      MVNETA_UNI_PROMISC_MODE            BIT(0)
 #define      MVNETA_DEF_RXQ(q)                  ((q) << 1)
 
 #define MVNETA_INTR_ENABLE                       0x25b8
 #define      MVNETA_TXQ_INTR_ENABLE_ALL_MASK     0x0000ff00
-#define      MVNETA_RXQ_INTR_ENABLE_ALL_MASK     0xff000000  // note: neta says it's 0x000000FF
+#define      MVNETA_RXQ_INTR_ENABLE_ALL_MASK     0x000000ff
 
 #define MVNETA_RXQ_CMD                           0x2680
 #define      MVNETA_RXQ_DISABLE_SHIFT            8
 #define MVNETA_VLAN_TAG_LEN             4
 
 #define MVNETA_CPU_D_CACHE_LINE_SIZE    32
+#define MVNETA_TX_CSUM_DEF_SIZE                1600
 #define MVNETA_TX_CSUM_MAX_SIZE                9800
 #define MVNETA_ACC_MODE_EXT            1
 
@@ -1579,12 +1581,16 @@ static int mvneta_rx(struct mvneta_port *pp, int rx_todo,
                }
 
                skb = build_skb(data, pp->frag_size > PAGE_SIZE ? 0 : pp->frag_size);
-               if (!skb)
-                       goto err_drop_frame;
 
+               /* After refill old buffer has to be unmapped regardless
+                * the skb is successfully built or not.
+                */
                dma_unmap_single(dev->dev.parent, phys_addr,
                                 MVNETA_RX_BUF_SIZE(pp->pkt_size), DMA_FROM_DEVICE);
 
+               if (!skb)
+                       goto err_drop_frame;
+
                rcvd_pkts++;
                rcvd_bytes += rx_bytes;
 
@@ -3191,6 +3197,7 @@ static void mvneta_conf_mbus_windows(struct mvneta_port *pp,
        }
 
        mvreg_write(pp, MVNETA_BASE_ADDR_ENABLE, win_enable);
+       mvreg_write(pp, MVNETA_ACCESS_PROTECT_ENABLE, win_protect);
 }
 
 /* Power up the port */
@@ -3250,6 +3257,7 @@ static int mvneta_probe(struct platform_device *pdev)
        char hw_mac_addr[ETH_ALEN];
        const char *mac_from;
        const char *managed;
+       int tx_csum_limit;
        int phy_mode;
        int err;
        int cpu;
@@ -3350,8 +3358,21 @@ static int mvneta_probe(struct platform_device *pdev)
                }
        }
 
-       if (of_device_is_compatible(dn, "marvell,armada-370-neta"))
-               pp->tx_csum_limit = 1600;
+       if (!of_property_read_u32(dn, "tx-csum-limit", &tx_csum_limit)) {
+               if (tx_csum_limit < 0 ||
+                   tx_csum_limit > MVNETA_TX_CSUM_MAX_SIZE) {
+                       tx_csum_limit = MVNETA_TX_CSUM_DEF_SIZE;
+                       dev_info(&pdev->dev,
+                                "Wrong TX csum limit in DT, set to %dB\n",
+                                MVNETA_TX_CSUM_DEF_SIZE);
+               }
+       } else if (of_device_is_compatible(dn, "marvell,armada-370-neta")) {
+               tx_csum_limit = MVNETA_TX_CSUM_DEF_SIZE;
+       } else {
+               tx_csum_limit = MVNETA_TX_CSUM_MAX_SIZE;
+       }
+
+       pp->tx_csum_limit = tx_csum_limit;
 
        pp->tx_ring_size = MVNETA_MAX_TXD;
        pp->rx_ring_size = MVNETA_MAX_RXD;
index 2177e56ed0be7d18ee40d2428b69003bd6f8cca5..d48d5793407d9ec729fe8548a049a2506d02a934 100644 (file)
@@ -1010,7 +1010,7 @@ static int mlx4_MAD_IFC_wrapper(struct mlx4_dev *dev, int slave,
                if (!(smp->mgmt_class == IB_MGMT_CLASS_SUBN_LID_ROUTED &&
                      smp->method == IB_MGMT_METHOD_GET) || network_view) {
                        mlx4_err(dev, "Unprivileged slave %d is trying to execute a Subnet MGMT MAD, class 0x%x, method 0x%x, view=%s for attr 0x%x. Rejecting\n",
-                                slave, smp->method, smp->mgmt_class,
+                                slave, smp->mgmt_class, smp->method,
                                 network_view ? "Network" : "Host",
                                 be16_to_cpu(smp->attr_id));
                        return -EPERM;
index b159ef8303cc3e65d1e374367d19ca590d934901..057665180f13f3d9980eac2b807793675df16021 100644 (file)
@@ -1326,7 +1326,7 @@ static int lpc_eth_drv_probe(struct platform_device *pdev)
        /* Get platform resources */
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        irq = platform_get_irq(pdev, 0);
-       if ((!res) || (irq < 0) || (irq >= NR_IRQS)) {
+       if (!res || irq < 0) {
                dev_err(&pdev->dev, "error getting resources.\n");
                ret = -ENXIO;
                goto err_exit;
index ee8d1ec61fabaffe081e777d70fd1b381990fbea..ed5da4d476684d502a7d83469ee83566635d3d46 100644 (file)
@@ -1225,7 +1225,7 @@ static int ravb_open(struct net_device *ndev)
        /* Device init */
        error = ravb_dmac_init(ndev);
        if (error)
-               goto out_free_irq;
+               goto out_free_irq2;
        ravb_emac_init(ndev);
 
        /* Initialise PTP Clock driver */
@@ -1243,9 +1243,11 @@ static int ravb_open(struct net_device *ndev)
 out_ptp_stop:
        /* Stop PTP Clock driver */
        ravb_ptp_stop(ndev);
+out_free_irq2:
+       if (priv->chip_id == RCAR_GEN3)
+               free_irq(priv->emac_irq, ndev);
 out_free_irq:
        free_irq(ndev->irq, ndev);
-       free_irq(priv->emac_irq, ndev);
 out_napi_off:
        napi_disable(&priv->napi[RAVB_NC]);
        napi_disable(&priv->napi[RAVB_BE]);
index 7f6f4a4fcc708973af0aa48418bedaad984ef5fd..58c05acc2aabbdf63419874605ae11af298471ca 100644 (file)
@@ -299,16 +299,17 @@ static int sti_dwmac_parse_data(struct sti_dwmac *dwmac,
        if (IS_PHY_IF_MODE_GBIT(dwmac->interface)) {
                const char *rs;
 
+               dwmac->tx_retime_src = TX_RETIME_SRC_CLKGEN;
+
                err = of_property_read_string(np, "st,tx-retime-src", &rs);
                if (err < 0) {
                        dev_warn(dev, "Use internal clock source\n");
-                       dwmac->tx_retime_src = TX_RETIME_SRC_CLKGEN;
-               } else if (!strcasecmp(rs, "clk_125")) {
-                       dwmac->tx_retime_src = TX_RETIME_SRC_CLK_125;
-               } else if (!strcasecmp(rs, "txclk")) {
-                       dwmac->tx_retime_src = TX_RETIME_SRC_TXCLK;
+               } else {
+                       if (!strcasecmp(rs, "clk_125"))
+                               dwmac->tx_retime_src = TX_RETIME_SRC_CLK_125;
+                       else if (!strcasecmp(rs, "txclk"))
+                               dwmac->tx_retime_src = TX_RETIME_SRC_TXCLK;
                }
-
                dwmac->speed = SPEED_1000;
        }
 
index 64d8aa4e0cad6420bcb1fa4cd827ad823ba3601d..3c6549aee11dee5cf13c92c90c5b4b7a8618f375 100644 (file)
@@ -185,7 +185,7 @@ static void stmmac_clk_csr_set(struct stmmac_priv *priv)
                        priv->clk_csr = STMMAC_CSR_100_150M;
                else if ((clk_rate >= CSR_F_150M) && (clk_rate < CSR_F_250M))
                        priv->clk_csr = STMMAC_CSR_150_250M;
-               else if ((clk_rate >= CSR_F_250M) && (clk_rate < CSR_F_300M))
+               else if ((clk_rate >= CSR_F_250M) && (clk_rate <= CSR_F_300M))
                        priv->clk_csr = STMMAC_CSR_250_300M;
        }
 }
@@ -2232,6 +2232,12 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit)
 
                        frame_len = priv->hw->desc->get_rx_frame_len(p, coe);
 
+                       /*  check if frame_len fits the preallocated memory */
+                       if (frame_len > priv->dma_buf_sz) {
+                               priv->dev->stats.rx_length_errors++;
+                               break;
+                       }
+
                        /* ACS is set; GMAC core strips PAD/FCS for IEEE 802.3
                         * Type frames (LLC/LLC-SNAP)
                         */
@@ -3102,6 +3108,7 @@ int stmmac_resume(struct net_device *ndev)
        init_dma_desc_rings(ndev, GFP_ATOMIC);
        stmmac_hw_setup(ndev, false);
        stmmac_init_tx_coalesce(priv);
+       stmmac_set_rx_mode(ndev);
 
        napi_enable(&priv->napi);
 
index ebf6abc4853f300392677614d6f45be0f95e8fca..bba670c42e3749483bf2218ad2da6b3b4c8d0587 100644 (file)
@@ -138,7 +138,6 @@ int stmmac_mdio_reset(struct mii_bus *bus)
 
 #ifdef CONFIG_OF
        if (priv->device->of_node) {
-               int reset_gpio, active_low;
 
                if (data->reset_gpio < 0) {
                        struct device_node *np = priv->device->of_node;
@@ -154,24 +153,23 @@ int stmmac_mdio_reset(struct mii_bus *bus)
                                                "snps,reset-active-low");
                        of_property_read_u32_array(np,
                                "snps,reset-delays-us", data->delays, 3);
-               }
 
-               reset_gpio = data->reset_gpio;
-               active_low = data->active_low;
+                       if (gpio_request(data->reset_gpio, "mdio-reset"))
+                               return 0;
+               }
 
-               if (!gpio_request(reset_gpio, "mdio-reset")) {
-                       gpio_direction_output(reset_gpio, active_low ? 1 : 0);
-                       if (data->delays[0])
-                               msleep(DIV_ROUND_UP(data->delays[0], 1000));
+               gpio_direction_output(data->reset_gpio,
+                                     data->active_low ? 1 : 0);
+               if (data->delays[0])
+                       msleep(DIV_ROUND_UP(data->delays[0], 1000));
 
-                       gpio_set_value(reset_gpio, active_low ? 0 : 1);
-                       if (data->delays[1])
-                               msleep(DIV_ROUND_UP(data->delays[1], 1000));
+               gpio_set_value(data->reset_gpio, data->active_low ? 0 : 1);
+               if (data->delays[1])
+                       msleep(DIV_ROUND_UP(data->delays[1], 1000));
 
-                       gpio_set_value(reset_gpio, active_low ? 1 : 0);
-                       if (data->delays[2])
-                               msleep(DIV_ROUND_UP(data->delays[2], 1000));
-               }
+               gpio_set_value(data->reset_gpio, data->active_low ? 1 : 0);
+               if (data->delays[2])
+                       msleep(DIV_ROUND_UP(data->delays[2], 1000));
        }
 #endif
 
index c08be62bceba6f2e2eb59e0da7ac9c3bdbe61813..1562ab4151e192a079fc2a54dec7f8c101bcd109 100644 (file)
@@ -78,6 +78,9 @@ static int cpsw_am33xx_cm_get_macid(struct device *dev, u16 offset, int slave,
 
 int ti_cm_get_macid(struct device *dev, int slave, u8 *mac_addr)
 {
+       if (of_machine_is_compatible("ti,dm8148"))
+               return cpsw_am33xx_cm_get_macid(dev, 0x630, slave, mac_addr);
+
        if (of_machine_is_compatible("ti,am33xx"))
                return cpsw_am33xx_cm_get_macid(dev, 0x630, slave, mac_addr);
 
index 54036ae0a388c9a34cbb92fc832980fc1e584dc2..0fc521941c718dbcdea487a18a900984ad176ea5 100644 (file)
@@ -498,7 +498,7 @@ static void macvtap_sock_write_space(struct sock *sk)
        wait_queue_head_t *wqueue;
 
        if (!sock_writeable(sk) ||
-           !test_and_clear_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags))
+           !test_and_clear_bit(SOCKWQ_ASYNC_NOSPACE, &sk->sk_socket->flags))
                return;
 
        wqueue = sk_sleep(sk);
@@ -585,7 +585,7 @@ static unsigned int macvtap_poll(struct file *file, poll_table * wait)
                mask |= POLLIN | POLLRDNORM;
 
        if (sock_writeable(&q->sk) ||
-           (!test_and_set_bit(SOCK_ASYNC_NOSPACE, &q->sock.flags) &&
+           (!test_and_set_bit(SOCKWQ_ASYNC_NOSPACE, &q->sock.flags) &&
             sock_writeable(&q->sk)))
                mask |= POLLOUT | POLLWRNORM;
 
index 07a6119121c38922aa50b3241e95d4604435a051..3ce5d9514623ce210ba9f8b13a113b0ef4c91165 100644 (file)
@@ -614,7 +614,7 @@ static struct mdio_device_id __maybe_unused broadcom_tbl[] = {
        { PHY_ID_BCM5461, 0xfffffff0 },
        { PHY_ID_BCM54616S, 0xfffffff0 },
        { PHY_ID_BCM5464, 0xfffffff0 },
-       { PHY_ID_BCM5482, 0xfffffff0 },
+       { PHY_ID_BCM5481, 0xfffffff0 },
        { PHY_ID_BCM5482, 0xfffffff0 },
        { PHY_ID_BCM50610, 0xfffffff0 },
        { PHY_ID_BCM50610M, 0xfffffff0 },
index 48ce6ef400fe7fdda6ae78a9a22943b2307c1c8b..47cd306dbb3c4909ae95feb586f0b89198126995 100644 (file)
@@ -448,7 +448,8 @@ int phy_mii_ioctl(struct phy_device *phydev, struct ifreq *ifr, int cmd)
                mdiobus_write(phydev->bus, mii_data->phy_id,
                              mii_data->reg_num, val);
 
-               if (mii_data->reg_num == MII_BMCR &&
+               if (mii_data->phy_id == phydev->addr &&
+                   mii_data->reg_num == MII_BMCR &&
                    val & BMCR_RESET)
                        return phy_init_hw(phydev);
 
index b1878faea3974f6ae984763109edae78c4cd3342..f0db770e8b2f9655be8d3c3000a9395f945284e2 100644 (file)
@@ -1040,7 +1040,7 @@ static unsigned int tun_chr_poll(struct file *file, poll_table *wait)
                mask |= POLLIN | POLLRDNORM;
 
        if (sock_writeable(sk) ||
-           (!test_and_set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags) &&
+           (!test_and_set_bit(SOCKWQ_ASYNC_NOSPACE, &sk->sk_socket->flags) &&
             sock_writeable(sk)))
                mask |= POLLOUT | POLLWRNORM;
 
@@ -1488,7 +1488,7 @@ static void tun_sock_write_space(struct sock *sk)
        if (!sock_writeable(sk))
                return;
 
-       if (!test_and_clear_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags))
+       if (!test_and_clear_bit(SOCKWQ_ASYNC_NOSPACE, &sk->sk_socket->flags))
                return;
 
        wqueue = sk_sleep(sk);
index a187f08113ecbb77612dd11a2611d4649d79c47d..3b1ba823776842445b5d5b6a709c58208c357f2b 100644 (file)
@@ -691,7 +691,6 @@ static void cdc_ncm_free(struct cdc_ncm_ctx *ctx)
 
 int cdc_ncm_bind_common(struct usbnet *dev, struct usb_interface *intf, u8 data_altsetting, int drvflags)
 {
-       const struct usb_cdc_union_desc *union_desc = NULL;
        struct cdc_ncm_ctx *ctx;
        struct usb_driver *driver;
        u8 *buf;
@@ -725,15 +724,16 @@ int cdc_ncm_bind_common(struct usbnet *dev, struct usb_interface *intf, u8 data_
        /* parse through descriptors associated with control interface */
        cdc_parse_cdc_header(&hdr, intf, buf, len);
 
-       ctx->data = usb_ifnum_to_if(dev->udev,
-                                   hdr.usb_cdc_union_desc->bSlaveInterface0);
+       if (hdr.usb_cdc_union_desc)
+               ctx->data = usb_ifnum_to_if(dev->udev,
+                                           hdr.usb_cdc_union_desc->bSlaveInterface0);
        ctx->ether_desc = hdr.usb_cdc_ether_desc;
        ctx->func_desc = hdr.usb_cdc_ncm_desc;
        ctx->mbim_desc = hdr.usb_cdc_mbim_desc;
        ctx->mbim_extended_desc = hdr.usb_cdc_mbim_extended_desc;
 
        /* some buggy devices have an IAD but no CDC Union */
-       if (!union_desc && intf->intf_assoc && intf->intf_assoc->bInterfaceCount == 2) {
+       if (!hdr.usb_cdc_union_desc && intf->intf_assoc && intf->intf_assoc->bInterfaceCount == 2) {
                ctx->data = usb_ifnum_to_if(dev->udev, intf->cur_altsetting->desc.bInterfaceNumber + 1);
                dev_dbg(&intf->dev, "CDC Union missing - got slave from IAD\n");
        }
index 34799eaace41bcdb93cfa4c1ed76af31ae052ef3..9a5be8b851867e53f7427ba31f7a089ad02562fd 100644 (file)
@@ -725,6 +725,7 @@ static const struct usb_device_id products[] = {
        {QMI_FIXED_INTF(0x2357, 0x9000, 4)},    /* TP-LINK MA260 */
        {QMI_FIXED_INTF(0x1bc7, 0x1200, 5)},    /* Telit LE920 */
        {QMI_FIXED_INTF(0x1bc7, 0x1201, 2)},    /* Telit LE920 */
+       {QMI_FIXED_INTF(0x1c9e, 0x9b01, 3)},    /* XS Stick W100-2 from 4G Systems */
        {QMI_FIXED_INTF(0x0b3c, 0xc000, 4)},    /* Olivetti Olicard 100 */
        {QMI_FIXED_INTF(0x0b3c, 0xc001, 4)},    /* Olivetti Olicard 120 */
        {QMI_FIXED_INTF(0x0b3c, 0xc002, 4)},    /* Olivetti Olicard 140 */
index d8838dedb7a4cd06f54e2fa8a522b6c4bb15091e..f94ab786088fc8fd7f848edeaedd4d2aff160606 100644 (file)
@@ -140,6 +140,12 @@ struct virtnet_info {
 
        /* CPU hot plug notifier */
        struct notifier_block nb;
+
+       /* Control VQ buffers: protected by the rtnl lock */
+       struct virtio_net_ctrl_hdr ctrl_hdr;
+       virtio_net_ctrl_ack ctrl_status;
+       u8 ctrl_promisc;
+       u8 ctrl_allmulti;
 };
 
 struct padded_vnet_hdr {
@@ -976,31 +982,30 @@ static bool virtnet_send_command(struct virtnet_info *vi, u8 class, u8 cmd,
                                 struct scatterlist *out)
 {
        struct scatterlist *sgs[4], hdr, stat;
-       struct virtio_net_ctrl_hdr ctrl;
-       virtio_net_ctrl_ack status = ~0;
        unsigned out_num = 0, tmp;
 
        /* Caller should know better */
        BUG_ON(!virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_VQ));
 
-       ctrl.class = class;
-       ctrl.cmd = cmd;
+       vi->ctrl_status = ~0;
+       vi->ctrl_hdr.class = class;
+       vi->ctrl_hdr.cmd = cmd;
        /* Add header */
-       sg_init_one(&hdr, &ctrl, sizeof(ctrl));
+       sg_init_one(&hdr, &vi->ctrl_hdr, sizeof(vi->ctrl_hdr));
        sgs[out_num++] = &hdr;
 
        if (out)
                sgs[out_num++] = out;
 
        /* Add return status. */
-       sg_init_one(&stat, &status, sizeof(status));
+       sg_init_one(&stat, &vi->ctrl_status, sizeof(vi->ctrl_status));
        sgs[out_num] = &stat;
 
        BUG_ON(out_num + 1 > ARRAY_SIZE(sgs));
        virtqueue_add_sgs(vi->cvq, sgs, out_num, 1, vi, GFP_ATOMIC);
 
        if (unlikely(!virtqueue_kick(vi->cvq)))
-               return status == VIRTIO_NET_OK;
+               return vi->ctrl_status == VIRTIO_NET_OK;
 
        /* Spin for a response, the kick causes an ioport write, trapping
         * into the hypervisor, so the request should be handled immediately.
@@ -1009,7 +1014,7 @@ static bool virtnet_send_command(struct virtnet_info *vi, u8 class, u8 cmd,
               !virtqueue_is_broken(vi->cvq))
                cpu_relax();
 
-       return status == VIRTIO_NET_OK;
+       return vi->ctrl_status == VIRTIO_NET_OK;
 }
 
 static int virtnet_set_mac_address(struct net_device *dev, void *p)
@@ -1151,7 +1156,6 @@ static void virtnet_set_rx_mode(struct net_device *dev)
 {
        struct virtnet_info *vi = netdev_priv(dev);
        struct scatterlist sg[2];
-       u8 promisc, allmulti;
        struct virtio_net_ctrl_mac *mac_data;
        struct netdev_hw_addr *ha;
        int uc_count;
@@ -1163,22 +1167,22 @@ static void virtnet_set_rx_mode(struct net_device *dev)
        if (!virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_RX))
                return;
 
-       promisc = ((dev->flags & IFF_PROMISC) != 0);
-       allmulti = ((dev->flags & IFF_ALLMULTI) != 0);
+       vi->ctrl_promisc = ((dev->flags & IFF_PROMISC) != 0);
+       vi->ctrl_allmulti = ((dev->flags & IFF_ALLMULTI) != 0);
 
-       sg_init_one(sg, &promisc, sizeof(promisc));
+       sg_init_one(sg, &vi->ctrl_promisc, sizeof(vi->ctrl_promisc));
 
        if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_RX,
                                  VIRTIO_NET_CTRL_RX_PROMISC, sg))
                dev_warn(&dev->dev, "Failed to %sable promisc mode.\n",
-                        promisc ? "en" : "dis");
+                        vi->ctrl_promisc ? "en" : "dis");
 
-       sg_init_one(sg, &allmulti, sizeof(allmulti));
+       sg_init_one(sg, &vi->ctrl_allmulti, sizeof(vi->ctrl_allmulti));
 
        if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_RX,
                                  VIRTIO_NET_CTRL_RX_ALLMULTI, sg))
                dev_warn(&dev->dev, "Failed to %sable allmulti mode.\n",
-                        allmulti ? "en" : "dis");
+                        vi->ctrl_allmulti ? "en" : "dis");
 
        uc_count = netdev_uc_count(dev);
        mc_count = netdev_mc_count(dev);
index 899ea42881970bb7e579d091696ef9ca1f9aa896..417903715437ebda5b07a859effdca86a62d196b 100644 (file)
@@ -587,6 +587,12 @@ vmxnet3_rq_alloc_rx_buf(struct vmxnet3_rx_queue *rq, u32 ring_idx,
                                                &adapter->pdev->dev,
                                                rbi->skb->data, rbi->len,
                                                PCI_DMA_FROMDEVICE);
+                               if (dma_mapping_error(&adapter->pdev->dev,
+                                                     rbi->dma_addr)) {
+                                       dev_kfree_skb_any(rbi->skb);
+                                       rq->stats.rx_buf_alloc_failure++;
+                                       break;
+                               }
                        } else {
                                /* rx buffer skipped by the device */
                        }
@@ -605,13 +611,18 @@ vmxnet3_rq_alloc_rx_buf(struct vmxnet3_rx_queue *rq, u32 ring_idx,
                                                &adapter->pdev->dev,
                                                rbi->page, 0, PAGE_SIZE,
                                                PCI_DMA_FROMDEVICE);
+                               if (dma_mapping_error(&adapter->pdev->dev,
+                                                     rbi->dma_addr)) {
+                                       put_page(rbi->page);
+                                       rq->stats.rx_buf_alloc_failure++;
+                                       break;
+                               }
                        } else {
                                /* rx buffers skipped by the device */
                        }
                        val = VMXNET3_RXD_BTYPE_BODY << VMXNET3_RXD_BTYPE_SHIFT;
                }
 
-               BUG_ON(rbi->dma_addr == 0);
                gd->rxd.addr = cpu_to_le64(rbi->dma_addr);
                gd->dword[2] = cpu_to_le32((!ring->gen << VMXNET3_RXD_GEN_SHIFT)
                                           | val | rbi->len);
@@ -655,7 +666,7 @@ vmxnet3_append_frag(struct sk_buff *skb, struct Vmxnet3_RxCompDesc *rcd,
 }
 
 
-static void
+static int
 vmxnet3_map_pkt(struct sk_buff *skb, struct vmxnet3_tx_ctx *ctx,
                struct vmxnet3_tx_queue *tq, struct pci_dev *pdev,
                struct vmxnet3_adapter *adapter)
@@ -715,6 +726,8 @@ vmxnet3_map_pkt(struct sk_buff *skb, struct vmxnet3_tx_ctx *ctx,
                tbi->dma_addr = dma_map_single(&adapter->pdev->dev,
                                skb->data + buf_offset, buf_size,
                                PCI_DMA_TODEVICE);
+               if (dma_mapping_error(&adapter->pdev->dev, tbi->dma_addr))
+                       return -EFAULT;
 
                tbi->len = buf_size;
 
@@ -755,6 +768,8 @@ vmxnet3_map_pkt(struct sk_buff *skb, struct vmxnet3_tx_ctx *ctx,
                        tbi->dma_addr = skb_frag_dma_map(&adapter->pdev->dev, frag,
                                                         buf_offset, buf_size,
                                                         DMA_TO_DEVICE);
+                       if (dma_mapping_error(&adapter->pdev->dev, tbi->dma_addr))
+                               return -EFAULT;
 
                        tbi->len = buf_size;
 
@@ -782,6 +797,8 @@ vmxnet3_map_pkt(struct sk_buff *skb, struct vmxnet3_tx_ctx *ctx,
        /* set the last buf_info for the pkt */
        tbi->skb = skb;
        tbi->sop_idx = ctx->sop_txd - tq->tx_ring.base;
+
+       return 0;
 }
 
 
@@ -1020,7 +1037,8 @@ vmxnet3_tq_xmit(struct sk_buff *skb, struct vmxnet3_tx_queue *tq,
        }
 
        /* fill tx descs related to addr & len */
-       vmxnet3_map_pkt(skb, &ctx, tq, adapter->pdev, adapter);
+       if (vmxnet3_map_pkt(skb, &ctx, tq, adapter->pdev, adapter))
+               goto unlock_drop_pkt;
 
        /* setup the EOP desc */
        ctx.eop_txd->dword[3] = cpu_to_le32(VMXNET3_TXD_CQ | VMXNET3_TXD_EOP);
@@ -1231,6 +1249,7 @@ vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq,
                struct vmxnet3_rx_buf_info *rbi;
                struct sk_buff *skb, *new_skb = NULL;
                struct page *new_page = NULL;
+               dma_addr_t new_dma_addr;
                int num_to_alloc;
                struct Vmxnet3_RxDesc *rxd;
                u32 idx, ring_idx;
@@ -1287,6 +1306,21 @@ vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq,
                                skip_page_frags = true;
                                goto rcd_done;
                        }
+                       new_dma_addr = dma_map_single(&adapter->pdev->dev,
+                                                     new_skb->data, rbi->len,
+                                                     PCI_DMA_FROMDEVICE);
+                       if (dma_mapping_error(&adapter->pdev->dev,
+                                             new_dma_addr)) {
+                               dev_kfree_skb(new_skb);
+                               /* Skb allocation failed, do not handover this
+                                * skb to stack. Reuse it. Drop the existing pkt
+                                */
+                               rq->stats.rx_buf_alloc_failure++;
+                               ctx->skb = NULL;
+                               rq->stats.drop_total++;
+                               skip_page_frags = true;
+                               goto rcd_done;
+                       }
 
                        dma_unmap_single(&adapter->pdev->dev, rbi->dma_addr,
                                         rbi->len,
@@ -1303,9 +1337,7 @@ vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq,
 
                        /* Immediate refill */
                        rbi->skb = new_skb;
-                       rbi->dma_addr = dma_map_single(&adapter->pdev->dev,
-                                                      rbi->skb->data, rbi->len,
-                                                      PCI_DMA_FROMDEVICE);
+                       rbi->dma_addr = new_dma_addr;
                        rxd->addr = cpu_to_le64(rbi->dma_addr);
                        rxd->len = rbi->len;
                        if (adapter->version == 2 &&
@@ -1348,6 +1380,19 @@ vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq,
                                        skip_page_frags = true;
                                        goto rcd_done;
                                }
+                               new_dma_addr = dma_map_page(&adapter->pdev->dev
+                                                       , rbi->page,
+                                                       0, PAGE_SIZE,
+                                                       PCI_DMA_FROMDEVICE);
+                               if (dma_mapping_error(&adapter->pdev->dev,
+                                                     new_dma_addr)) {
+                                       put_page(new_page);
+                                       rq->stats.rx_buf_alloc_failure++;
+                                       dev_kfree_skb(ctx->skb);
+                                       ctx->skb = NULL;
+                                       skip_page_frags = true;
+                                       goto rcd_done;
+                               }
 
                                dma_unmap_page(&adapter->pdev->dev,
                                               rbi->dma_addr, rbi->len,
@@ -1357,10 +1402,7 @@ vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq,
 
                                /* Immediate refill */
                                rbi->page = new_page;
-                               rbi->dma_addr = dma_map_page(&adapter->pdev->dev
-                                                       , rbi->page,
-                                                       0, PAGE_SIZE,
-                                                       PCI_DMA_FROMDEVICE);
+                               rbi->dma_addr = new_dma_addr;
                                rxd->addr = cpu_to_le64(rbi->dma_addr);
                                rxd->len = rbi->len;
                        }
@@ -2167,7 +2209,8 @@ vmxnet3_set_mc(struct net_device *netdev)
                                                        PCI_DMA_TODEVICE);
                        }
 
-                       if (new_table_pa) {
+                       if (!dma_mapping_error(&adapter->pdev->dev,
+                                              new_table_pa)) {
                                new_mode |= VMXNET3_RXM_MCAST;
                                rxConf->mfTablePA = cpu_to_le64(new_table_pa);
                        } else {
@@ -3075,6 +3118,11 @@ vmxnet3_probe_device(struct pci_dev *pdev,
        adapter->adapter_pa = dma_map_single(&adapter->pdev->dev, adapter,
                                             sizeof(struct vmxnet3_adapter),
                                             PCI_DMA_TODEVICE);
+       if (dma_mapping_error(&adapter->pdev->dev, adapter->adapter_pa)) {
+               dev_err(&pdev->dev, "Failed to map dma\n");
+               err = -EFAULT;
+               goto err_dma_map;
+       }
        adapter->shared = dma_alloc_coherent(
                                &adapter->pdev->dev,
                                sizeof(struct Vmxnet3_DriverShared),
@@ -3233,6 +3281,7 @@ err_alloc_queue_desc:
 err_alloc_shared:
        dma_unmap_single(&adapter->pdev->dev, adapter->adapter_pa,
                         sizeof(struct vmxnet3_adapter), PCI_DMA_TODEVICE);
+err_dma_map:
        free_netdev(netdev);
        return err;
 }
index 92fa3e1ea65cca564907a43a78a859b6063f7f65..4f9748457f5a722658e5cfb01b6cbcc0f488d14f 100644 (file)
@@ -907,7 +907,6 @@ static int vrf_newlink(struct net *src_net, struct net_device *dev,
                       struct nlattr *tb[], struct nlattr *data[])
 {
        struct net_vrf *vrf = netdev_priv(dev);
-       int err;
 
        if (!data || !data[IFLA_VRF_TABLE])
                return -EINVAL;
@@ -916,15 +915,7 @@ static int vrf_newlink(struct net *src_net, struct net_device *dev,
 
        dev->priv_flags |= IFF_L3MDEV_MASTER;
 
-       err = register_netdevice(dev);
-       if (err < 0)
-               goto out_fail;
-
-       return 0;
-
-out_fail:
-       free_netdev(dev);
-       return err;
+       return register_netdevice(dev);
 }
 
 static size_t vrf_nl_getsize(const struct net_device *dev)
index e92aaf61590109430aa6b9b6cd100b7d35daf90b..89541cc90e877b476bf6d1fc973d4393bc01acc7 100644 (file)
@@ -1075,11 +1075,10 @@ static int fr_add_pvc(struct net_device *frad, unsigned int dlci, int type)
 
        used = pvc_is_used(pvc);
 
-       if (type == ARPHRD_ETHER) {
+       if (type == ARPHRD_ETHER)
                dev = alloc_netdev(0, "pvceth%d", NET_NAME_UNKNOWN,
                                   ether_setup);
-               dev->priv_flags &= ~IFF_TX_SKB_SHARING;
-       } else
+       else
                dev = alloc_netdev(0, "pvc%d", NET_NAME_UNKNOWN, pvc_setup);
 
        if (!dev) {
@@ -1088,9 +1087,10 @@ static int fr_add_pvc(struct net_device *frad, unsigned int dlci, int type)
                return -ENOBUFS;
        }
 
-       if (type == ARPHRD_ETHER)
+       if (type == ARPHRD_ETHER) {
+               dev->priv_flags &= ~IFF_TX_SKB_SHARING;
                eth_hw_addr_random(dev);
-       else {
+       else {
                *(__be16*)dev->dev_addr = htons(dlci);
                dlci_to_q922(dev->broadcast, dlci);
        }
index 5c47b011a9d7f3000a27d4c81d3dc75e5f855129..cd39025d2abf5923f49e83adb08bb8de88373cb5 100644 (file)
@@ -549,16 +549,12 @@ static void x25_asy_receive_buf(struct tty_struct *tty,
 
 static int x25_asy_open_tty(struct tty_struct *tty)
 {
-       struct x25_asy *sl = tty->disc_data;
+       struct x25_asy *sl;
        int err;
 
        if (tty->ops->write == NULL)
                return -EOPNOTSUPP;
 
-       /* First make sure we're not already connected. */
-       if (sl && sl->magic == X25_ASY_MAGIC)
-               return -EEXIST;
-
        /* OK.  Find a free X.25 channel to use. */
        sl = x25_asy_alloc();
        if (sl == NULL)
index aa9bd92ac4edf7e5b78229a136ca499f8f7c15e3..0947cc271e693feaf73b3ae25d0478d2fa529ff1 100644 (file)
@@ -51,6 +51,7 @@ MODULE_PARM_DESC(rawmode, "Use raw 802.11 frame datapath");
 static const struct ath10k_hw_params ath10k_hw_params_list[] = {
        {
                .id = QCA988X_HW_2_0_VERSION,
+               .dev_id = QCA988X_2_0_DEVICE_ID,
                .name = "qca988x hw2.0",
                .patch_load_addr = QCA988X_HW_2_0_PATCH_LOAD_ADDR,
                .uart_pin = 7,
@@ -69,6 +70,25 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
        },
        {
                .id = QCA6174_HW_2_1_VERSION,
+               .dev_id = QCA6164_2_1_DEVICE_ID,
+               .name = "qca6164 hw2.1",
+               .patch_load_addr = QCA6174_HW_2_1_PATCH_LOAD_ADDR,
+               .uart_pin = 6,
+               .otp_exe_param = 0,
+               .channel_counters_freq_hz = 88000,
+               .max_probe_resp_desc_thres = 0,
+               .fw = {
+                       .dir = QCA6174_HW_2_1_FW_DIR,
+                       .fw = QCA6174_HW_2_1_FW_FILE,
+                       .otp = QCA6174_HW_2_1_OTP_FILE,
+                       .board = QCA6174_HW_2_1_BOARD_DATA_FILE,
+                       .board_size = QCA6174_BOARD_DATA_SZ,
+                       .board_ext_size = QCA6174_BOARD_EXT_DATA_SZ,
+               },
+       },
+       {
+               .id = QCA6174_HW_2_1_VERSION,
+               .dev_id = QCA6174_2_1_DEVICE_ID,
                .name = "qca6174 hw2.1",
                .patch_load_addr = QCA6174_HW_2_1_PATCH_LOAD_ADDR,
                .uart_pin = 6,
@@ -86,6 +106,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
        },
        {
                .id = QCA6174_HW_3_0_VERSION,
+               .dev_id = QCA6174_2_1_DEVICE_ID,
                .name = "qca6174 hw3.0",
                .patch_load_addr = QCA6174_HW_3_0_PATCH_LOAD_ADDR,
                .uart_pin = 6,
@@ -103,6 +124,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
        },
        {
                .id = QCA6174_HW_3_2_VERSION,
+               .dev_id = QCA6174_2_1_DEVICE_ID,
                .name = "qca6174 hw3.2",
                .patch_load_addr = QCA6174_HW_3_0_PATCH_LOAD_ADDR,
                .uart_pin = 6,
@@ -121,6 +143,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
        },
        {
                .id = QCA99X0_HW_2_0_DEV_VERSION,
+               .dev_id = QCA99X0_2_0_DEVICE_ID,
                .name = "qca99x0 hw2.0",
                .patch_load_addr = QCA99X0_HW_2_0_PATCH_LOAD_ADDR,
                .uart_pin = 7,
@@ -139,10 +162,31 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
        },
        {
                .id = QCA9377_HW_1_0_DEV_VERSION,
+               .dev_id = QCA9377_1_0_DEVICE_ID,
                .name = "qca9377 hw1.0",
                .patch_load_addr = QCA9377_HW_1_0_PATCH_LOAD_ADDR,
-               .uart_pin = 7,
+               .uart_pin = 6,
                .otp_exe_param = 0,
+               .channel_counters_freq_hz = 88000,
+               .max_probe_resp_desc_thres = 0,
+               .fw = {
+                       .dir = QCA9377_HW_1_0_FW_DIR,
+                       .fw = QCA9377_HW_1_0_FW_FILE,
+                       .otp = QCA9377_HW_1_0_OTP_FILE,
+                       .board = QCA9377_HW_1_0_BOARD_DATA_FILE,
+                       .board_size = QCA9377_BOARD_DATA_SZ,
+                       .board_ext_size = QCA9377_BOARD_EXT_DATA_SZ,
+               },
+       },
+       {
+               .id = QCA9377_HW_1_1_DEV_VERSION,
+               .dev_id = QCA9377_1_0_DEVICE_ID,
+               .name = "qca9377 hw1.1",
+               .patch_load_addr = QCA9377_HW_1_0_PATCH_LOAD_ADDR,
+               .uart_pin = 6,
+               .otp_exe_param = 0,
+               .channel_counters_freq_hz = 88000,
+               .max_probe_resp_desc_thres = 0,
                .fw = {
                        .dir = QCA9377_HW_1_0_FW_DIR,
                        .fw = QCA9377_HW_1_0_FW_FILE,
@@ -1263,7 +1307,8 @@ static int ath10k_init_hw_params(struct ath10k *ar)
        for (i = 0; i < ARRAY_SIZE(ath10k_hw_params_list); i++) {
                hw_params = &ath10k_hw_params_list[i];
 
-               if (hw_params->id == ar->target_version)
+               if (hw_params->id == ar->target_version &&
+                   hw_params->dev_id == ar->dev_id)
                        break;
        }
 
index 018c64f4fd25b8cf1ab8db0f3b21e65962a5f45e..858d75f49a9ffe5b1ea9e511d834bd3a5815e3de 100644 (file)
@@ -636,6 +636,7 @@ struct ath10k {
 
        struct ath10k_hw_params {
                u32 id;
+               u16 dev_id;
                const char *name;
                u32 patch_load_addr;
                int uart_pin;
index 39966a05c1cc20f5b69e7111d5ddb711a070c5e9..713c2bcea17825f701b2be37a9cf82badef11caf 100644 (file)
 
 #define ATH10K_FW_DIR                  "ath10k"
 
+#define QCA988X_2_0_DEVICE_ID   (0x003c)
+#define QCA6164_2_1_DEVICE_ID   (0x0041)
+#define QCA6174_2_1_DEVICE_ID   (0x003e)
+#define QCA99X0_2_0_DEVICE_ID   (0x0040)
+#define QCA9377_1_0_DEVICE_ID   (0x0042)
+
 /* QCA988X 1.0 definitions (unsupported) */
 #define QCA988X_HW_1_0_CHIP_ID_REV     0x0
 
 #define QCA6174_HW_3_0_VERSION         0x05020000
 #define QCA6174_HW_3_2_VERSION         0x05030000
 
+/* QCA9377 target BMI version signatures */
+#define QCA9377_HW_1_0_DEV_VERSION     0x05020000
+#define QCA9377_HW_1_1_DEV_VERSION     0x05020001
+
 enum qca6174_pci_rev {
        QCA6174_PCI_REV_1_1 = 0x11,
        QCA6174_PCI_REV_1_3 = 0x13,
@@ -60,6 +70,11 @@ enum qca6174_chip_id_rev {
        QCA6174_HW_3_2_CHIP_ID_REV = 10,
 };
 
+enum qca9377_chip_id_rev {
+       QCA9377_HW_1_0_CHIP_ID_REV = 0x0,
+       QCA9377_HW_1_1_CHIP_ID_REV = 0x1,
+};
+
 #define QCA6174_HW_2_1_FW_DIR          "ath10k/QCA6174/hw2.1"
 #define QCA6174_HW_2_1_FW_FILE         "firmware.bin"
 #define QCA6174_HW_2_1_OTP_FILE                "otp.bin"
@@ -85,8 +100,6 @@ enum qca6174_chip_id_rev {
 #define QCA99X0_HW_2_0_PATCH_LOAD_ADDR 0x1234
 
 /* QCA9377 1.0 definitions */
-#define QCA9377_HW_1_0_DEV_VERSION     0x05020001
-#define QCA9377_HW_1_0_CHIP_ID_REV     0x1
 #define QCA9377_HW_1_0_FW_DIR          ATH10K_FW_DIR "/QCA9377/hw1.0"
 #define QCA9377_HW_1_0_FW_FILE         "firmware.bin"
 #define QCA9377_HW_1_0_OTP_FILE        "otp.bin"
index a7411fe90cc43ebcef7590538cb3d6cb73a6a13a..95a55405ebf0d1f8348cbfa54f567e780c7dfc13 100644 (file)
@@ -4225,7 +4225,7 @@ static int ath10k_config(struct ieee80211_hw *hw, u32 changed)
 
 static u32 get_nss_from_chainmask(u16 chain_mask)
 {
-       if ((chain_mask & 0x15) == 0x15)
+       if ((chain_mask & 0xf) == 0xf)
                return 4;
        else if ((chain_mask & 0x7) == 0x7)
                return 3;
index 3fca200b986ca75baa0de2568d36460be709d834..930785a724e1e50705d55e6051d9f53c595ef5ed 100644 (file)
@@ -57,12 +57,6 @@ MODULE_PARM_DESC(reset_mode, "0: auto, 1: warm only (default: 0)");
 #define ATH10K_PCI_TARGET_WAIT 3000
 #define ATH10K_PCI_NUM_WARM_RESET_ATTEMPTS 3
 
-#define QCA988X_2_0_DEVICE_ID  (0x003c)
-#define QCA6164_2_1_DEVICE_ID  (0x0041)
-#define QCA6174_2_1_DEVICE_ID  (0x003e)
-#define QCA99X0_2_0_DEVICE_ID  (0x0040)
-#define QCA9377_1_0_DEVICE_ID  (0x0042)
-
 static const struct pci_device_id ath10k_pci_id_table[] = {
        { PCI_VDEVICE(ATHEROS, QCA988X_2_0_DEVICE_ID) }, /* PCI-E QCA988X V2 */
        { PCI_VDEVICE(ATHEROS, QCA6164_2_1_DEVICE_ID) }, /* PCI-E QCA6164 V2.1 */
@@ -92,7 +86,9 @@ static const struct ath10k_pci_supp_chip ath10k_pci_supp_chips[] = {
        { QCA6174_2_1_DEVICE_ID, QCA6174_HW_3_2_CHIP_ID_REV },
 
        { QCA99X0_2_0_DEVICE_ID, QCA99X0_HW_2_0_CHIP_ID_REV },
+
        { QCA9377_1_0_DEVICE_ID, QCA9377_HW_1_0_CHIP_ID_REV },
+       { QCA9377_1_0_DEVICE_ID, QCA9377_HW_1_1_CHIP_ID_REV },
 };
 
 static void ath10k_pci_buffer_cleanup(struct ath10k *ar);
@@ -111,8 +107,9 @@ static void ath10k_pci_htc_tx_cb(struct ath10k_ce_pipe *ce_state);
 static void ath10k_pci_htc_rx_cb(struct ath10k_ce_pipe *ce_state);
 static void ath10k_pci_htt_tx_cb(struct ath10k_ce_pipe *ce_state);
 static void ath10k_pci_htt_rx_cb(struct ath10k_ce_pipe *ce_state);
+static void ath10k_pci_htt_htc_rx_cb(struct ath10k_ce_pipe *ce_state);
 
-static const struct ce_attr host_ce_config_wlan[] = {
+static struct ce_attr host_ce_config_wlan[] = {
        /* CE0: host->target HTC control and raw streams */
        {
                .flags = CE_ATTR_FLAGS,
@@ -128,7 +125,7 @@ static const struct ce_attr host_ce_config_wlan[] = {
                .src_nentries = 0,
                .src_sz_max = 2048,
                .dest_nentries = 512,
-               .recv_cb = ath10k_pci_htc_rx_cb,
+               .recv_cb = ath10k_pci_htt_htc_rx_cb,
        },
 
        /* CE2: target->host WMI */
@@ -217,7 +214,7 @@ static const struct ce_attr host_ce_config_wlan[] = {
 };
 
 /* Target firmware's Copy Engine configuration. */
-static const struct ce_pipe_config target_ce_config_wlan[] = {
+static struct ce_pipe_config target_ce_config_wlan[] = {
        /* CE0: host->target HTC control and raw streams */
        {
                .pipenum = __cpu_to_le32(0),
@@ -330,7 +327,7 @@ static const struct ce_pipe_config target_ce_config_wlan[] = {
  * This table is derived from the CE_PCI TABLE, above.
  * It is passed to the Target at startup for use by firmware.
  */
-static const struct service_to_pipe target_service_to_ce_map_wlan[] = {
+static struct service_to_pipe target_service_to_ce_map_wlan[] = {
        {
                __cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_DATA_VO),
                __cpu_to_le32(PIPEDIR_OUT),     /* out = UL = host -> target */
@@ -1208,6 +1205,16 @@ static void ath10k_pci_htc_rx_cb(struct ath10k_ce_pipe *ce_state)
        ath10k_pci_process_rx_cb(ce_state, ath10k_htc_rx_completion_handler);
 }
 
+static void ath10k_pci_htt_htc_rx_cb(struct ath10k_ce_pipe *ce_state)
+{
+       /* CE4 polling needs to be done whenever CE pipe which transports
+        * HTT Rx (target->host) is processed.
+        */
+       ath10k_ce_per_engine_service(ce_state->ar, 4);
+
+       ath10k_pci_process_rx_cb(ce_state, ath10k_htc_rx_completion_handler);
+}
+
 /* Called by lower (CE) layer when a send to HTT Target completes. */
 static void ath10k_pci_htt_tx_cb(struct ath10k_ce_pipe *ce_state)
 {
@@ -2027,6 +2034,29 @@ static int ath10k_pci_init_config(struct ath10k *ar)
        return 0;
 }
 
+static void ath10k_pci_override_ce_config(struct ath10k *ar)
+{
+       struct ce_attr *attr;
+       struct ce_pipe_config *config;
+
+       /* For QCA6174 we're overriding the Copy Engine 5 configuration,
+        * since it is currently used for other feature.
+        */
+
+       /* Override Host's Copy Engine 5 configuration */
+       attr = &host_ce_config_wlan[5];
+       attr->src_sz_max = 0;
+       attr->dest_nentries = 0;
+
+       /* Override Target firmware's Copy Engine configuration */
+       config = &target_ce_config_wlan[5];
+       config->pipedir = __cpu_to_le32(PIPEDIR_OUT);
+       config->nbytes_max = __cpu_to_le32(2048);
+
+       /* Map from service/endpoint to Copy Engine */
+       target_service_to_ce_map_wlan[15].pipenum = __cpu_to_le32(1);
+}
+
 static int ath10k_pci_alloc_pipes(struct ath10k *ar)
 {
        struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
@@ -3020,6 +3050,9 @@ static int ath10k_pci_probe(struct pci_dev *pdev,
                goto err_core_destroy;
        }
 
+       if (QCA_REV_6174(ar))
+               ath10k_pci_override_ce_config(ar);
+
        ret = ath10k_pci_alloc_pipes(ar);
        if (ret) {
                ath10k_err(ar, "failed to allocate copy engine pipes: %d\n",
index 1a73c7a1da77d0e0fe16fbdc6fb866d6c65226ee..bf88ec3a65fab3e04aab4398185236bdb955126b 100644 (file)
@@ -69,7 +69,7 @@
 #include "iwl-agn-hw.h"
 
 /* Highest firmware API version supported */
-#define IWL7260_UCODE_API_MAX  17
+#define IWL7260_UCODE_API_MAX  19
 
 /* Oldest version we won't warn about */
 #define IWL7260_UCODE_API_OK   13
index 0116e5a4c39389ac4123100bf1486d96c11ad10a..9bcc0bf937d8810f42da44656cf6bc7d11df4f5a 100644 (file)
@@ -69,7 +69,7 @@
 #include "iwl-agn-hw.h"
 
 /* Highest firmware API version supported */
-#define IWL8000_UCODE_API_MAX  17
+#define IWL8000_UCODE_API_MAX  19
 
 /* Oldest version we won't warn about */
 #define IWL8000_UCODE_API_OK   13
index 85ae902df7c08d9d1d0ad4611e7947ace08bf0f7..29ae58ebf223fa82be3e072ea4ac000e62d54884 100644 (file)
@@ -309,9 +309,9 @@ static void iwl_mvm_wowlan_program_keys(struct ieee80211_hw *hw,
         * to transmit packets to the AP, i.e. the PTK.
         */
        if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) {
-               key->hw_key_idx = 0;
                mvm->ptk_ivlen = key->iv_len;
                mvm->ptk_icvlen = key->icv_len;
+               ret = iwl_mvm_set_sta_key(mvm, vif, sta, key, 0);
        } else {
                /*
                 * firmware only supports TSC/RSC for a single key,
@@ -319,12 +319,11 @@ static void iwl_mvm_wowlan_program_keys(struct ieee80211_hw *hw,
                 * with new ones -- this relies on mac80211 doing
                 * list_add_tail().
                 */
-               key->hw_key_idx = 1;
                mvm->gtk_ivlen = key->iv_len;
                mvm->gtk_icvlen = key->icv_len;
+               ret = iwl_mvm_set_sta_key(mvm, vif, sta, key, 1);
        }
 
-       ret = iwl_mvm_set_sta_key(mvm, vif, sta, key, true);
        data->error = ret != 0;
 out_unlock:
        mutex_unlock(&mvm->mutex);
@@ -772,9 +771,6 @@ static int iwl_mvm_switch_to_d3(struct iwl_mvm *mvm)
         */
        set_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status);
 
-       /* We reprogram keys and shouldn't allocate new key indices */
-       memset(mvm->fw_key_table, 0, sizeof(mvm->fw_key_table));
-
        mvm->ptk_ivlen = 0;
        mvm->ptk_icvlen = 0;
        mvm->ptk_ivlen = 0;
index 1fb684693040eac8130cf62c348b0bf96dd4f005..e88afac51c5d69fe5d6c8f4e032cdcf95f48a168 100644 (file)
@@ -2941,6 +2941,7 @@ static int iwl_mvm_mac_set_key(struct ieee80211_hw *hw,
 {
        struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
        int ret;
+       u8 key_offset;
 
        if (iwlwifi_mod_params.sw_crypto) {
                IWL_DEBUG_MAC80211(mvm, "leave - hwcrypto disabled\n");
@@ -3006,10 +3007,14 @@ static int iwl_mvm_mac_set_key(struct ieee80211_hw *hw,
                        break;
                }
 
+               /* in HW restart reuse the index, otherwise request a new one */
+               if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status))
+                       key_offset = key->hw_key_idx;
+               else
+                       key_offset = STA_KEY_IDX_INVALID;
+
                IWL_DEBUG_MAC80211(mvm, "set hwcrypto key\n");
-               ret = iwl_mvm_set_sta_key(mvm, vif, sta, key,
-                                         test_bit(IWL_MVM_STATUS_IN_HW_RESTART,
-                                                  &mvm->status));
+               ret = iwl_mvm_set_sta_key(mvm, vif, sta, key, key_offset);
                if (ret) {
                        IWL_WARN(mvm, "set key failed\n");
                        /*
index 300a249486e4df2398738b62c53a7870f87a757b..354acbde088e9e6fad0927a9ef73787ab235558c 100644 (file)
@@ -1201,7 +1201,8 @@ static int iwl_mvm_set_fw_key_idx(struct iwl_mvm *mvm)
        return max_offs;
 }
 
-static u8 iwl_mvm_get_key_sta_id(struct ieee80211_vif *vif,
+static u8 iwl_mvm_get_key_sta_id(struct iwl_mvm *mvm,
+                                struct ieee80211_vif *vif,
                                 struct ieee80211_sta *sta)
 {
        struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
@@ -1218,8 +1219,21 @@ static u8 iwl_mvm_get_key_sta_id(struct ieee80211_vif *vif,
         * station ID, then use AP's station ID.
         */
        if (vif->type == NL80211_IFTYPE_STATION &&
-           mvmvif->ap_sta_id != IWL_MVM_STATION_COUNT)
-               return mvmvif->ap_sta_id;
+           mvmvif->ap_sta_id != IWL_MVM_STATION_COUNT) {
+               u8 sta_id = mvmvif->ap_sta_id;
+
+               sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[sta_id],
+                                               lockdep_is_held(&mvm->mutex));
+               /*
+                * It is possible that the 'sta' parameter is NULL,
+                * for example when a GTK is removed - the sta_id will then
+                * be the AP ID, and no station was passed by mac80211.
+                */
+               if (IS_ERR_OR_NULL(sta))
+                       return IWL_MVM_STATION_COUNT;
+
+               return sta_id;
+       }
 
        return IWL_MVM_STATION_COUNT;
 }
@@ -1227,7 +1241,8 @@ static u8 iwl_mvm_get_key_sta_id(struct ieee80211_vif *vif,
 static int iwl_mvm_send_sta_key(struct iwl_mvm *mvm,
                                struct iwl_mvm_sta *mvm_sta,
                                struct ieee80211_key_conf *keyconf, bool mcast,
-                               u32 tkip_iv32, u16 *tkip_p1k, u32 cmd_flags)
+                               u32 tkip_iv32, u16 *tkip_p1k, u32 cmd_flags,
+                               u8 key_offset)
 {
        struct iwl_mvm_add_sta_key_cmd cmd = {};
        __le16 key_flags;
@@ -1269,7 +1284,7 @@ static int iwl_mvm_send_sta_key(struct iwl_mvm *mvm,
        if (mcast)
                key_flags |= cpu_to_le16(STA_KEY_MULTICAST);
 
-       cmd.key_offset = keyconf->hw_key_idx;
+       cmd.key_offset = key_offset;
        cmd.key_flags = key_flags;
        cmd.sta_id = sta_id;
 
@@ -1360,6 +1375,7 @@ static int __iwl_mvm_set_sta_key(struct iwl_mvm *mvm,
                                 struct ieee80211_vif *vif,
                                 struct ieee80211_sta *sta,
                                 struct ieee80211_key_conf *keyconf,
+                                u8 key_offset,
                                 bool mcast)
 {
        struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta);
@@ -1375,17 +1391,17 @@ static int __iwl_mvm_set_sta_key(struct iwl_mvm *mvm,
                ieee80211_get_key_rx_seq(keyconf, 0, &seq);
                ieee80211_get_tkip_rx_p1k(keyconf, addr, seq.tkip.iv32, p1k);
                ret = iwl_mvm_send_sta_key(mvm, mvm_sta, keyconf, mcast,
-                                          seq.tkip.iv32, p1k, 0);
+                                          seq.tkip.iv32, p1k, 0, key_offset);
                break;
        case WLAN_CIPHER_SUITE_CCMP:
        case WLAN_CIPHER_SUITE_WEP40:
        case WLAN_CIPHER_SUITE_WEP104:
                ret = iwl_mvm_send_sta_key(mvm, mvm_sta, keyconf, mcast,
-                                          0, NULL, 0);
+                                          0, NULL, 0, key_offset);
                break;
        default:
                ret = iwl_mvm_send_sta_key(mvm, mvm_sta, keyconf, mcast,
-                                          0, NULL, 0);
+                                          0, NULL, 0, key_offset);
        }
 
        return ret;
@@ -1433,7 +1449,7 @@ int iwl_mvm_set_sta_key(struct iwl_mvm *mvm,
                        struct ieee80211_vif *vif,
                        struct ieee80211_sta *sta,
                        struct ieee80211_key_conf *keyconf,
-                       bool have_key_offset)
+                       u8 key_offset)
 {
        bool mcast = !(keyconf->flags & IEEE80211_KEY_FLAG_PAIRWISE);
        u8 sta_id;
@@ -1443,7 +1459,7 @@ int iwl_mvm_set_sta_key(struct iwl_mvm *mvm,
        lockdep_assert_held(&mvm->mutex);
 
        /* Get the station id from the mvm local station table */
-       sta_id = iwl_mvm_get_key_sta_id(vif, sta);
+       sta_id = iwl_mvm_get_key_sta_id(mvm, vif, sta);
        if (sta_id == IWL_MVM_STATION_COUNT) {
                IWL_ERR(mvm, "Failed to find station id\n");
                return -EINVAL;
@@ -1470,18 +1486,25 @@ int iwl_mvm_set_sta_key(struct iwl_mvm *mvm,
        if (WARN_ON_ONCE(iwl_mvm_sta_from_mac80211(sta)->vif != vif))
                return -EINVAL;
 
-       if (!have_key_offset) {
-               /*
-                * The D3 firmware hardcodes the PTK offset to 0, so we have to
-                * configure it there. As a result, this workaround exists to
-                * let the caller set the key offset (hw_key_idx), see d3.c.
-                */
-               keyconf->hw_key_idx = iwl_mvm_set_fw_key_idx(mvm);
-               if (keyconf->hw_key_idx == STA_KEY_IDX_INVALID)
+       /* If the key_offset is not pre-assigned, we need to find a
+        * new offset to use.  In normal cases, the offset is not
+        * pre-assigned, but during HW_RESTART we want to reuse the
+        * same indices, so we pass them when this function is called.
+        *
+        * In D3 entry, we need to hardcoded the indices (because the
+        * firmware hardcodes the PTK offset to 0).  In this case, we
+        * need to make sure we don't overwrite the hw_key_idx in the
+        * keyconf structure, because otherwise we cannot configure
+        * the original ones back when resuming.
+        */
+       if (key_offset == STA_KEY_IDX_INVALID) {
+               key_offset  = iwl_mvm_set_fw_key_idx(mvm);
+               if (key_offset == STA_KEY_IDX_INVALID)
                        return -ENOSPC;
+               keyconf->hw_key_idx = key_offset;
        }
 
-       ret = __iwl_mvm_set_sta_key(mvm, vif, sta, keyconf, mcast);
+       ret = __iwl_mvm_set_sta_key(mvm, vif, sta, keyconf, key_offset, mcast);
        if (ret) {
                __clear_bit(keyconf->hw_key_idx, mvm->fw_key_table);
                goto end;
@@ -1495,7 +1518,8 @@ int iwl_mvm_set_sta_key(struct iwl_mvm *mvm,
         */
        if (keyconf->cipher == WLAN_CIPHER_SUITE_WEP40 ||
            keyconf->cipher == WLAN_CIPHER_SUITE_WEP104) {
-               ret = __iwl_mvm_set_sta_key(mvm, vif, sta, keyconf, !mcast);
+               ret = __iwl_mvm_set_sta_key(mvm, vif, sta, keyconf,
+                                           key_offset, !mcast);
                if (ret) {
                        __clear_bit(keyconf->hw_key_idx, mvm->fw_key_table);
                        __iwl_mvm_remove_sta_key(mvm, sta_id, keyconf, mcast);
@@ -1521,7 +1545,7 @@ int iwl_mvm_remove_sta_key(struct iwl_mvm *mvm,
        lockdep_assert_held(&mvm->mutex);
 
        /* Get the station id from the mvm local station table */
-       sta_id = iwl_mvm_get_key_sta_id(vif, sta);
+       sta_id = iwl_mvm_get_key_sta_id(mvm, vif, sta);
 
        IWL_DEBUG_WEP(mvm, "mvm remove dynamic key: idx=%d sta=%d\n",
                      keyconf->keyidx, sta_id);
@@ -1547,24 +1571,6 @@ int iwl_mvm_remove_sta_key(struct iwl_mvm *mvm,
                return 0;
        }
 
-       /*
-        * It is possible that the 'sta' parameter is NULL, and thus
-        * there is a need to retrieve the sta from the local station table,
-        * for example when a GTK is removed (where the sta_id will then be
-        * the AP ID, and no station was passed by mac80211.)
-        */
-       if (!sta) {
-               sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[sta_id],
-                                               lockdep_is_held(&mvm->mutex));
-               if (!sta) {
-                       IWL_ERR(mvm, "Invalid station id\n");
-                       return -EINVAL;
-               }
-       }
-
-       if (WARN_ON_ONCE(iwl_mvm_sta_from_mac80211(sta)->vif != vif))
-               return -EINVAL;
-
        ret = __iwl_mvm_remove_sta_key(mvm, sta_id, keyconf, mcast);
        if (ret)
                return ret;
@@ -1584,7 +1590,7 @@ void iwl_mvm_update_tkip_key(struct iwl_mvm *mvm,
                             u16 *phase1key)
 {
        struct iwl_mvm_sta *mvm_sta;
-       u8 sta_id = iwl_mvm_get_key_sta_id(vif, sta);
+       u8 sta_id = iwl_mvm_get_key_sta_id(mvm, vif, sta);
        bool mcast = !(keyconf->flags & IEEE80211_KEY_FLAG_PAIRWISE);
 
        if (WARN_ON_ONCE(sta_id == IWL_MVM_STATION_COUNT))
@@ -1602,7 +1608,7 @@ void iwl_mvm_update_tkip_key(struct iwl_mvm *mvm,
 
        mvm_sta = iwl_mvm_sta_from_mac80211(sta);
        iwl_mvm_send_sta_key(mvm, mvm_sta, keyconf, mcast,
-                            iv32, phase1key, CMD_ASYNC);
+                            iv32, phase1key, CMD_ASYNC, keyconf->hw_key_idx);
        rcu_read_unlock();
 }
 
index eedb215eba3f6efd08f2ca387de80e46ec39bfb2..0631cc0a6d3c908d71c93270a15679270272c6c7 100644 (file)
@@ -365,8 +365,8 @@ int iwl_mvm_rm_sta_id(struct iwl_mvm *mvm,
 int iwl_mvm_set_sta_key(struct iwl_mvm *mvm,
                        struct ieee80211_vif *vif,
                        struct ieee80211_sta *sta,
-                       struct ieee80211_key_conf *key,
-                       bool have_key_offset);
+                       struct ieee80211_key_conf *keyconf,
+                       u8 key_offset);
 int iwl_mvm_remove_sta_key(struct iwl_mvm *mvm,
                           struct ieee80211_vif *vif,
                           struct ieee80211_sta *sta,
index 644b58bc5226c52b3cdee0a24b9a392c25e8ac02..639761fb2bfb2f8a1dbd5925984e6ad0c15f9587 100644 (file)
@@ -423,14 +423,21 @@ static const struct pci_device_id iwl_hw_card_ids[] = {
 /* 8000 Series */
        {IWL_PCI_DEVICE(0x24F3, 0x0010, iwl8260_2ac_cfg)},
        {IWL_PCI_DEVICE(0x24F3, 0x1010, iwl8260_2ac_cfg)},
+       {IWL_PCI_DEVICE(0x24F3, 0x0130, iwl8260_2ac_cfg)},
+       {IWL_PCI_DEVICE(0x24F3, 0x1130, iwl8260_2ac_cfg)},
+       {IWL_PCI_DEVICE(0x24F3, 0x0132, iwl8260_2ac_cfg)},
+       {IWL_PCI_DEVICE(0x24F3, 0x1132, iwl8260_2ac_cfg)},
        {IWL_PCI_DEVICE(0x24F3, 0x0110, iwl8260_2ac_cfg)},
+       {IWL_PCI_DEVICE(0x24F3, 0x01F0, iwl8260_2ac_cfg)},
+       {IWL_PCI_DEVICE(0x24F3, 0x0012, iwl8260_2ac_cfg)},
+       {IWL_PCI_DEVICE(0x24F3, 0x1012, iwl8260_2ac_cfg)},
        {IWL_PCI_DEVICE(0x24F3, 0x1110, iwl8260_2ac_cfg)},
        {IWL_PCI_DEVICE(0x24F3, 0x0050, iwl8260_2ac_cfg)},
        {IWL_PCI_DEVICE(0x24F3, 0x0250, iwl8260_2ac_cfg)},
        {IWL_PCI_DEVICE(0x24F3, 0x1050, iwl8260_2ac_cfg)},
        {IWL_PCI_DEVICE(0x24F3, 0x0150, iwl8260_2ac_cfg)},
+       {IWL_PCI_DEVICE(0x24F3, 0x1150, iwl8260_2ac_cfg)},
        {IWL_PCI_DEVICE(0x24F4, 0x0030, iwl8260_2ac_cfg)},
-       {IWL_PCI_DEVICE(0x24F4, 0x1130, iwl8260_2ac_cfg)},
        {IWL_PCI_DEVICE(0x24F4, 0x1030, iwl8260_2ac_cfg)},
        {IWL_PCI_DEVICE(0x24F3, 0xC010, iwl8260_2ac_cfg)},
        {IWL_PCI_DEVICE(0x24F3, 0xC110, iwl8260_2ac_cfg)},
@@ -438,18 +445,28 @@ static const struct pci_device_id iwl_hw_card_ids[] = {
        {IWL_PCI_DEVICE(0x24F3, 0xC050, iwl8260_2ac_cfg)},
        {IWL_PCI_DEVICE(0x24F3, 0xD050, iwl8260_2ac_cfg)},
        {IWL_PCI_DEVICE(0x24F3, 0x8010, iwl8260_2ac_cfg)},
+       {IWL_PCI_DEVICE(0x24F3, 0x8110, iwl8260_2ac_cfg)},
        {IWL_PCI_DEVICE(0x24F3, 0x9010, iwl8260_2ac_cfg)},
+       {IWL_PCI_DEVICE(0x24F3, 0x9110, iwl8260_2ac_cfg)},
        {IWL_PCI_DEVICE(0x24F4, 0x8030, iwl8260_2ac_cfg)},
        {IWL_PCI_DEVICE(0x24F4, 0x9030, iwl8260_2ac_cfg)},
+       {IWL_PCI_DEVICE(0x24F3, 0x8130, iwl8260_2ac_cfg)},
+       {IWL_PCI_DEVICE(0x24F3, 0x9130, iwl8260_2ac_cfg)},
+       {IWL_PCI_DEVICE(0x24F3, 0x8132, iwl8260_2ac_cfg)},
+       {IWL_PCI_DEVICE(0x24F3, 0x9132, iwl8260_2ac_cfg)},
        {IWL_PCI_DEVICE(0x24F3, 0x8050, iwl8260_2ac_cfg)},
+       {IWL_PCI_DEVICE(0x24F3, 0x8150, iwl8260_2ac_cfg)},
        {IWL_PCI_DEVICE(0x24F3, 0x9050, iwl8260_2ac_cfg)},
+       {IWL_PCI_DEVICE(0x24F3, 0x9150, iwl8260_2ac_cfg)},
        {IWL_PCI_DEVICE(0x24F3, 0x0004, iwl8260_2n_cfg)},
+       {IWL_PCI_DEVICE(0x24F3, 0x0044, iwl8260_2n_cfg)},
        {IWL_PCI_DEVICE(0x24F5, 0x0010, iwl4165_2ac_cfg)},
        {IWL_PCI_DEVICE(0x24F6, 0x0030, iwl4165_2ac_cfg)},
        {IWL_PCI_DEVICE(0x24F3, 0x0810, iwl8260_2ac_cfg)},
        {IWL_PCI_DEVICE(0x24F3, 0x0910, iwl8260_2ac_cfg)},
        {IWL_PCI_DEVICE(0x24F3, 0x0850, iwl8260_2ac_cfg)},
        {IWL_PCI_DEVICE(0x24F3, 0x0950, iwl8260_2ac_cfg)},
+       {IWL_PCI_DEVICE(0x24F3, 0x0930, iwl8260_2ac_cfg)},
 #endif /* CONFIG_IWLMVM */
 
        {0}
index 6e9418ed90c289bee5b7f2dfc478f847dfc7ca68..bbb789f8990b10944d0a8eed60c7700af2a4121e 100644 (file)
@@ -2272,7 +2272,7 @@ void rtl8821ae_enable_interrupt(struct ieee80211_hw *hw)
        struct rtl_priv *rtlpriv = rtl_priv(hw);
        struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
 
-       if (!rtlpci->int_clear)
+       if (rtlpci->int_clear)
                rtl8821ae_clear_interrupt(hw);/*clear it here first*/
 
        rtl_write_dword(rtlpriv, REG_HIMR, rtlpci->irq_mask[0] & 0xFFFFFFFF);
index 8ee141a55bc5cc6b566e79dde58cdb05583e7fdf..142bdff4ed605b6e148cdbac588f80020b2c76c9 100644 (file)
@@ -448,7 +448,7 @@ MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 1)\n");
 MODULE_PARM_DESC(msi, "Set to 1 to use MSI interrupts mode (default 1)\n");
 MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)");
 MODULE_PARM_DESC(disable_watchdog, "Set to 1 to disable the watchdog (default 0)\n");
-MODULE_PARM_DESC(int_clear, "Set to 1 to disable interrupt clear before set (default 0)\n");
+MODULE_PARM_DESC(int_clear, "Set to 0 to disable interrupt clear before set (default 1)\n");
 
 static SIMPLE_DEV_PM_OPS(rtlwifi_pm_ops, rtl_pci_suspend, rtl_pci_resume);
 
index 219dc206fa5f24dc6fdffb3a2a6ec17df20d5281..a5fe239525868b1b86ec2d5337cfdb5e324424d6 100644 (file)
@@ -1,4 +1,5 @@
 
 obj-$(CONFIG_BLK_DEV_NVME)     += nvme.o
 
-nvme-y         += pci.o scsi.o lightnvm.o
+lightnvm-$(CONFIG_NVM) := lightnvm.o
+nvme-y         += pci.o scsi.o $(lightnvm-y)
index e0b7b95813bc98e1fc7f25fd422fad87690ec2e4..15f2acb4d5cd4937ee350e7daaf67f1b8ec56ad6 100644 (file)
@@ -22,8 +22,6 @@
 
 #include "nvme.h"
 
-#ifdef CONFIG_NVM
-
 #include <linux/nvme.h>
 #include <linux/bitops.h>
 #include <linux/lightnvm.h>
@@ -93,7 +91,7 @@ struct nvme_nvm_l2ptbl {
        __le16                  cdw14[6];
 };
 
-struct nvme_nvm_bbtbl {
+struct nvme_nvm_getbbtbl {
        __u8                    opcode;
        __u8                    flags;
        __u16                   command_id;
@@ -101,10 +99,23 @@ struct nvme_nvm_bbtbl {
        __u64                   rsvd[2];
        __le64                  prp1;
        __le64                  prp2;
-       __le32                  prp1_len;
-       __le32                  prp2_len;
-       __le32                  lbb;
-       __u32                   rsvd11[3];
+       __le64                  spba;
+       __u32                   rsvd4[4];
+};
+
+struct nvme_nvm_setbbtbl {
+       __u8                    opcode;
+       __u8                    flags;
+       __u16                   command_id;
+       __le32                  nsid;
+       __le64                  rsvd[2];
+       __le64                  prp1;
+       __le64                  prp2;
+       __le64                  spba;
+       __le16                  nlb;
+       __u8                    value;
+       __u8                    rsvd3;
+       __u32                   rsvd4[3];
 };
 
 struct nvme_nvm_erase_blk {
@@ -129,8 +140,8 @@ struct nvme_nvm_command {
                struct nvme_nvm_hb_rw hb_rw;
                struct nvme_nvm_ph_rw ph_rw;
                struct nvme_nvm_l2ptbl l2p;
-               struct nvme_nvm_bbtbl get_bb;
-               struct nvme_nvm_bbtbl set_bb;
+               struct nvme_nvm_getbbtbl get_bb;
+               struct nvme_nvm_setbbtbl set_bb;
                struct nvme_nvm_erase_blk erase;
        };
 };
@@ -142,11 +153,13 @@ struct nvme_nvm_id_group {
        __u8                    num_ch;
        __u8                    num_lun;
        __u8                    num_pln;
+       __u8                    rsvd1;
        __le16                  num_blk;
        __le16                  num_pg;
        __le16                  fpg_sz;
        __le16                  csecs;
        __le16                  sos;
+       __le16                  rsvd2;
        __le32                  trdt;
        __le32                  trdm;
        __le32                  tprt;
@@ -154,8 +167,9 @@ struct nvme_nvm_id_group {
        __le32                  tbet;
        __le32                  tbem;
        __le32                  mpos;
+       __le32                  mccap;
        __le16                  cpar;
-       __u8                    reserved[913];
+       __u8                    reserved[906];
 } __packed;
 
 struct nvme_nvm_addr_format {
@@ -178,15 +192,28 @@ struct nvme_nvm_id {
        __u8                    ver_id;
        __u8                    vmnt;
        __u8                    cgrps;
-       __u8                    res[5];
+       __u8                    res;
        __le32                  cap;
        __le32                  dom;
        struct nvme_nvm_addr_format ppaf;
-       __u8                    ppat;
-       __u8                    resv[223];
+       __u8                    resv[228];
        struct nvme_nvm_id_group groups[4];
 } __packed;
 
+struct nvme_nvm_bb_tbl {
+       __u8    tblid[4];
+       __le16  verid;
+       __le16  revid;
+       __le32  rvsd1;
+       __le32  tblks;
+       __le32  tfact;
+       __le32  tgrown;
+       __le32  tdresv;
+       __le32  thresv;
+       __le32  rsvd2[8];
+       __u8    blk[0];
+};
+
 /*
  * Check we didn't inadvertently grow the command struct
  */
@@ -195,12 +222,14 @@ static inline void _nvme_nvm_check_size(void)
        BUILD_BUG_ON(sizeof(struct nvme_nvm_identity) != 64);
        BUILD_BUG_ON(sizeof(struct nvme_nvm_hb_rw) != 64);
        BUILD_BUG_ON(sizeof(struct nvme_nvm_ph_rw) != 64);
-       BUILD_BUG_ON(sizeof(struct nvme_nvm_bbtbl) != 64);
+       BUILD_BUG_ON(sizeof(struct nvme_nvm_getbbtbl) != 64);
+       BUILD_BUG_ON(sizeof(struct nvme_nvm_setbbtbl) != 64);
        BUILD_BUG_ON(sizeof(struct nvme_nvm_l2ptbl) != 64);
        BUILD_BUG_ON(sizeof(struct nvme_nvm_erase_blk) != 64);
        BUILD_BUG_ON(sizeof(struct nvme_nvm_id_group) != 960);
        BUILD_BUG_ON(sizeof(struct nvme_nvm_addr_format) != 128);
        BUILD_BUG_ON(sizeof(struct nvme_nvm_id) != 4096);
+       BUILD_BUG_ON(sizeof(struct nvme_nvm_bb_tbl) != 512);
 }
 
 static int init_grps(struct nvm_id *nvm_id, struct nvme_nvm_id *nvme_nvm_id)
@@ -234,6 +263,7 @@ static int init_grps(struct nvm_id *nvm_id, struct nvme_nvm_id *nvme_nvm_id)
                dst->tbet = le32_to_cpu(src->tbet);
                dst->tbem = le32_to_cpu(src->tbem);
                dst->mpos = le32_to_cpu(src->mpos);
+               dst->mccap = le32_to_cpu(src->mccap);
 
                dst->cpar = le16_to_cpu(src->cpar);
        }
@@ -241,9 +271,10 @@ static int init_grps(struct nvm_id *nvm_id, struct nvme_nvm_id *nvme_nvm_id)
        return 0;
 }
 
-static int nvme_nvm_identity(struct request_queue *q, struct nvm_id *nvm_id)
+static int nvme_nvm_identity(struct nvm_dev *nvmdev, struct nvm_id *nvm_id)
 {
-       struct nvme_ns *ns = q->queuedata;
+       struct nvme_ns *ns = nvmdev->q->queuedata;
+       struct nvme_dev *dev = ns->dev;
        struct nvme_nvm_id *nvme_nvm_id;
        struct nvme_nvm_command c = {};
        int ret;
@@ -256,8 +287,8 @@ static int nvme_nvm_identity(struct request_queue *q, struct nvm_id *nvm_id)
        if (!nvme_nvm_id)
                return -ENOMEM;
 
-       ret = nvme_submit_sync_cmd(q, (struct nvme_command *)&c, nvme_nvm_id,
-                                               sizeof(struct nvme_nvm_id));
+       ret = nvme_submit_sync_cmd(dev->admin_q, (struct nvme_command *)&c,
+                               nvme_nvm_id, sizeof(struct nvme_nvm_id));
        if (ret) {
                ret = -EIO;
                goto out;
@@ -268,6 +299,8 @@ static int nvme_nvm_identity(struct request_queue *q, struct nvm_id *nvm_id)
        nvm_id->cgrps = nvme_nvm_id->cgrps;
        nvm_id->cap = le32_to_cpu(nvme_nvm_id->cap);
        nvm_id->dom = le32_to_cpu(nvme_nvm_id->dom);
+       memcpy(&nvm_id->ppaf, &nvme_nvm_id->ppaf,
+                                       sizeof(struct nvme_nvm_addr_format));
 
        ret = init_grps(nvm_id, nvme_nvm_id);
 out:
@@ -275,13 +308,13 @@ out:
        return ret;
 }
 
-static int nvme_nvm_get_l2p_tbl(struct request_queue *q, u64 slba, u32 nlb,
+static int nvme_nvm_get_l2p_tbl(struct nvm_dev *nvmdev, u64 slba, u32 nlb,
                                nvm_l2p_update_fn *update_l2p, void *priv)
 {
-       struct nvme_ns *ns = q->queuedata;
+       struct nvme_ns *ns = nvmdev->q->queuedata;
        struct nvme_dev *dev = ns->dev;
        struct nvme_nvm_command c = {};
-       u32 len = queue_max_hw_sectors(q) << 9;
+       u32 len = queue_max_hw_sectors(dev->admin_q) << 9;
        u32 nlb_pr_rq = len / sizeof(u64);
        u64 cmd_slba = slba;
        void *entries;
@@ -299,8 +332,8 @@ static int nvme_nvm_get_l2p_tbl(struct request_queue *q, u64 slba, u32 nlb,
                c.l2p.slba = cpu_to_le64(cmd_slba);
                c.l2p.nlb = cpu_to_le32(cmd_nlb);
 
-               ret = nvme_submit_sync_cmd(q, (struct nvme_command *)&c,
-                                                               entries, len);
+               ret = nvme_submit_sync_cmd(dev->admin_q,
+                               (struct nvme_command *)&c, entries, len);
                if (ret) {
                        dev_err(dev->dev, "L2P table transfer failed (%d)\n",
                                                                        ret);
@@ -322,43 +355,84 @@ out:
        return ret;
 }
 
-static int nvme_nvm_get_bb_tbl(struct request_queue *q, int lunid,
-                               unsigned int nr_blocks,
-                               nvm_bb_update_fn *update_bbtbl, void *priv)
+static int nvme_nvm_get_bb_tbl(struct nvm_dev *nvmdev, struct ppa_addr ppa,
+                               int nr_blocks, nvm_bb_update_fn *update_bbtbl,
+                               void *priv)
 {
+       struct request_queue *q = nvmdev->q;
        struct nvme_ns *ns = q->queuedata;
        struct nvme_dev *dev = ns->dev;
        struct nvme_nvm_command c = {};
-       void *bb_bitmap;
-       u16 bb_bitmap_size;
+       struct nvme_nvm_bb_tbl *bb_tbl;
+       int tblsz = sizeof(struct nvme_nvm_bb_tbl) + nr_blocks;
        int ret = 0;
 
        c.get_bb.opcode = nvme_nvm_admin_get_bb_tbl;
        c.get_bb.nsid = cpu_to_le32(ns->ns_id);
-       c.get_bb.lbb = cpu_to_le32(lunid);
-       bb_bitmap_size = ((nr_blocks >> 15) + 1) * PAGE_SIZE;
-       bb_bitmap = kmalloc(bb_bitmap_size, GFP_KERNEL);
-       if (!bb_bitmap)
-               return -ENOMEM;
+       c.get_bb.spba = cpu_to_le64(ppa.ppa);
 
-       bitmap_zero(bb_bitmap, nr_blocks);
+       bb_tbl = kzalloc(tblsz, GFP_KERNEL);
+       if (!bb_tbl)
+               return -ENOMEM;
 
-       ret = nvme_submit_sync_cmd(q, (struct nvme_command *)&c, bb_bitmap,
-                                                               bb_bitmap_size);
+       ret = nvme_submit_sync_cmd(dev->admin_q, (struct nvme_command *)&c,
+                                                               bb_tbl, tblsz);
        if (ret) {
                dev_err(dev->dev, "get bad block table failed (%d)\n", ret);
                ret = -EIO;
                goto out;
        }
 
-       ret = update_bbtbl(lunid, bb_bitmap, nr_blocks, priv);
+       if (bb_tbl->tblid[0] != 'B' || bb_tbl->tblid[1] != 'B' ||
+               bb_tbl->tblid[2] != 'L' || bb_tbl->tblid[3] != 'T') {
+               dev_err(dev->dev, "bbt format mismatch\n");
+               ret = -EINVAL;
+               goto out;
+       }
+
+       if (le16_to_cpu(bb_tbl->verid) != 1) {
+               ret = -EINVAL;
+               dev_err(dev->dev, "bbt version not supported\n");
+               goto out;
+       }
+
+       if (le32_to_cpu(bb_tbl->tblks) != nr_blocks) {
+               ret = -EINVAL;
+               dev_err(dev->dev, "bbt unsuspected blocks returned (%u!=%u)",
+                                       le32_to_cpu(bb_tbl->tblks), nr_blocks);
+               goto out;
+       }
+
+       ppa = dev_to_generic_addr(nvmdev, ppa);
+       ret = update_bbtbl(ppa, nr_blocks, bb_tbl->blk, priv);
        if (ret) {
                ret = -EINTR;
                goto out;
        }
 
 out:
-       kfree(bb_bitmap);
+       kfree(bb_tbl);
+       return ret;
+}
+
+static int nvme_nvm_set_bb_tbl(struct nvm_dev *nvmdev, struct nvm_rq *rqd,
+                                                               int type)
+{
+       struct nvme_ns *ns = nvmdev->q->queuedata;
+       struct nvme_dev *dev = ns->dev;
+       struct nvme_nvm_command c = {};
+       int ret = 0;
+
+       c.set_bb.opcode = nvme_nvm_admin_set_bb_tbl;
+       c.set_bb.nsid = cpu_to_le32(ns->ns_id);
+       c.set_bb.spba = cpu_to_le64(rqd->ppa_addr.ppa);
+       c.set_bb.nlb = cpu_to_le16(rqd->nr_pages - 1);
+       c.set_bb.value = type;
+
+       ret = nvme_submit_sync_cmd(dev->admin_q, (struct nvme_command *)&c,
+                                                               NULL, 0);
+       if (ret)
+               dev_err(dev->dev, "set bad block table failed (%d)\n", ret);
        return ret;
 }
 
@@ -381,7 +455,7 @@ static void nvme_nvm_end_io(struct request *rq, int error)
        struct nvm_rq *rqd = rq->end_io_data;
        struct nvm_dev *dev = rqd->dev;
 
-       if (dev->mt->end_io(rqd, error))
+       if (dev->mt && dev->mt->end_io(rqd, error))
                pr_err("nvme: err status: %x result: %lx\n",
                                rq->errors, (unsigned long)rq->special);
 
@@ -389,8 +463,9 @@ static void nvme_nvm_end_io(struct request *rq, int error)
        blk_mq_free_request(rq);
 }
 
-static int nvme_nvm_submit_io(struct request_queue *q, struct nvm_rq *rqd)
+static int nvme_nvm_submit_io(struct nvm_dev *dev, struct nvm_rq *rqd)
 {
+       struct request_queue *q = dev->q;
        struct nvme_ns *ns = q->queuedata;
        struct request *rq;
        struct bio *bio = rqd->bio;
@@ -428,8 +503,9 @@ static int nvme_nvm_submit_io(struct request_queue *q, struct nvm_rq *rqd)
        return 0;
 }
 
-static int nvme_nvm_erase_block(struct request_queue *q, struct nvm_rq *rqd)
+static int nvme_nvm_erase_block(struct nvm_dev *dev, struct nvm_rq *rqd)
 {
+       struct request_queue *q = dev->q;
        struct nvme_ns *ns = q->queuedata;
        struct nvme_nvm_command c = {};
 
@@ -441,9 +517,9 @@ static int nvme_nvm_erase_block(struct request_queue *q, struct nvm_rq *rqd)
        return nvme_submit_sync_cmd(q, (struct nvme_command *)&c, NULL, 0);
 }
 
-static void *nvme_nvm_create_dma_pool(struct request_queue *q, char *name)
+static void *nvme_nvm_create_dma_pool(struct nvm_dev *nvmdev, char *name)
 {
-       struct nvme_ns *ns = q->queuedata;
+       struct nvme_ns *ns = nvmdev->q->queuedata;
        struct nvme_dev *dev = ns->dev;
 
        return dma_pool_create(name, dev->dev, PAGE_SIZE, PAGE_SIZE, 0);
@@ -456,7 +532,7 @@ static void nvme_nvm_destroy_dma_pool(void *pool)
        dma_pool_destroy(dma_pool);
 }
 
-static void *nvme_nvm_dev_dma_alloc(struct request_queue *q, void *pool,
+static void *nvme_nvm_dev_dma_alloc(struct nvm_dev *dev, void *pool,
                                    gfp_t mem_flags, dma_addr_t *dma_handler)
 {
        return dma_pool_alloc(pool, mem_flags, dma_handler);
@@ -474,6 +550,7 @@ static struct nvm_dev_ops nvme_nvm_dev_ops = {
        .get_l2p_tbl            = nvme_nvm_get_l2p_tbl,
 
        .get_bb_tbl             = nvme_nvm_get_bb_tbl,
+       .set_bb_tbl             = nvme_nvm_set_bb_tbl,
 
        .submit_io              = nvme_nvm_submit_io,
        .erase_block            = nvme_nvm_erase_block,
@@ -496,31 +573,27 @@ void nvme_nvm_unregister(struct request_queue *q, char *disk_name)
        nvm_unregister(disk_name);
 }
 
+/* move to shared place when used in multiple places. */
+#define PCI_VENDOR_ID_CNEX 0x1d1d
+#define PCI_DEVICE_ID_CNEX_WL 0x2807
+#define PCI_DEVICE_ID_CNEX_QEMU 0x1f1f
+
 int nvme_nvm_ns_supported(struct nvme_ns *ns, struct nvme_id_ns *id)
 {
        struct nvme_dev *dev = ns->dev;
        struct pci_dev *pdev = to_pci_dev(dev->dev);
 
        /* QEMU NVMe simulator - PCI ID + Vendor specific bit */
-       if (pdev->vendor == PCI_VENDOR_ID_INTEL && pdev->device == 0x5845 &&
+       if (pdev->vendor == PCI_VENDOR_ID_CNEX &&
+                               pdev->device == PCI_DEVICE_ID_CNEX_QEMU &&
                                                        id->vs[0] == 0x1)
                return 1;
 
        /* CNEX Labs - PCI ID + Vendor specific bit */
-       if (pdev->vendor == 0x1d1d && pdev->device == 0x2807 &&
+       if (pdev->vendor == PCI_VENDOR_ID_CNEX &&
+                               pdev->device == PCI_DEVICE_ID_CNEX_WL &&
                                                        id->vs[0] == 0x1)
                return 1;
 
        return 0;
 }
-#else
-int nvme_nvm_register(struct request_queue *q, char *disk_name)
-{
-       return 0;
-}
-void nvme_nvm_unregister(struct request_queue *q, char *disk_name) {};
-int nvme_nvm_ns_supported(struct nvme_ns *ns, struct nvme_id_ns *id)
-{
-       return 0;
-}
-#endif /* CONFIG_NVM */
index fdb4e5bad9ac73c59c67e70100aba411d124ab2e..044253dca30a433549a37ec7e28c3a6c161d38a5 100644 (file)
@@ -136,8 +136,22 @@ int nvme_sg_io(struct nvme_ns *ns, struct sg_io_hdr __user *u_hdr);
 int nvme_sg_io32(struct nvme_ns *ns, unsigned long arg);
 int nvme_sg_get_version_num(int __user *ip);
 
+#ifdef CONFIG_NVM
 int nvme_nvm_ns_supported(struct nvme_ns *ns, struct nvme_id_ns *id);
 int nvme_nvm_register(struct request_queue *q, char *disk_name);
 void nvme_nvm_unregister(struct request_queue *q, char *disk_name);
+#else
+static inline int nvme_nvm_register(struct request_queue *q, char *disk_name)
+{
+       return 0;
+}
+
+static inline void nvme_nvm_unregister(struct request_queue *q, char *disk_name) {};
+
+static inline int nvme_nvm_ns_supported(struct nvme_ns *ns, struct nvme_id_ns *id)
+{
+       return 0;
+}
+#endif /* CONFIG_NVM */
 
 #endif /* _NVME_H */
index 8187df20469535023ae9966aecfb1542260b4270..9e294ff4e652a2bb8daa9e3f4a94cc09e8bb8b88 100644 (file)
@@ -896,19 +896,28 @@ static int nvme_queue_rq(struct blk_mq_hw_ctx *hctx,
                        goto retry_cmd;
                }
                if (blk_integrity_rq(req)) {
-                       if (blk_rq_count_integrity_sg(req->q, req->bio) != 1)
+                       if (blk_rq_count_integrity_sg(req->q, req->bio) != 1) {
+                               dma_unmap_sg(dev->dev, iod->sg, iod->nents,
+                                               dma_dir);
                                goto error_cmd;
+                       }
 
                        sg_init_table(iod->meta_sg, 1);
                        if (blk_rq_map_integrity_sg(
-                                       req->q, req->bio, iod->meta_sg) != 1)
+                                       req->q, req->bio, iod->meta_sg) != 1) {
+                               dma_unmap_sg(dev->dev, iod->sg, iod->nents,
+                                               dma_dir);
                                goto error_cmd;
+                       }
 
                        if (rq_data_dir(req))
                                nvme_dif_remap(req, nvme_dif_prep);
 
-                       if (!dma_map_sg(nvmeq->q_dmadev, iod->meta_sg, 1, dma_dir))
+                       if (!dma_map_sg(nvmeq->q_dmadev, iod->meta_sg, 1, dma_dir)) {
+                               dma_unmap_sg(dev->dev, iod->sg, iod->nents,
+                                               dma_dir);
                                goto error_cmd;
+                       }
                }
        }
 
@@ -968,7 +977,8 @@ static void __nvme_process_cq(struct nvme_queue *nvmeq, unsigned int *tag)
        if (head == nvmeq->cq_head && phase == nvmeq->cq_phase)
                return;
 
-       writel(head, nvmeq->q_db + nvmeq->dev->db_stride);
+       if (likely(nvmeq->cq_vector >= 0))
+               writel(head, nvmeq->q_db + nvmeq->dev->db_stride);
        nvmeq->cq_head = head;
        nvmeq->cq_phase = phase;
 
@@ -1727,9 +1737,13 @@ static int nvme_configure_admin_queue(struct nvme_dev *dev)
        u32 aqa;
        u64 cap = lo_hi_readq(&dev->bar->cap);
        struct nvme_queue *nvmeq;
-       unsigned page_shift = PAGE_SHIFT;
+       /*
+        * default to a 4K page size, with the intention to update this
+        * path in the future to accomodate architectures with differing
+        * kernel and IO page sizes.
+        */
+       unsigned page_shift = 12;
        unsigned dev_page_min = NVME_CAP_MPSMIN(cap) + 12;
-       unsigned dev_page_max = NVME_CAP_MPSMAX(cap) + 12;
 
        if (page_shift < dev_page_min) {
                dev_err(dev->dev,
@@ -1738,13 +1752,6 @@ static int nvme_configure_admin_queue(struct nvme_dev *dev)
                                1 << page_shift);
                return -ENODEV;
        }
-       if (page_shift > dev_page_max) {
-               dev_info(dev->dev,
-                               "Device maximum page size (%u) smaller than "
-                               "host (%u); enabling work-around\n",
-                               1 << dev_page_max, 1 << page_shift);
-               page_shift = dev_page_max;
-       }
 
        dev->subsystem = readl(&dev->bar->vs) >= NVME_VS(1, 1) ?
                                                NVME_CAP_NSSRC(cap) : 0;
@@ -2268,7 +2275,7 @@ static void nvme_alloc_ns(struct nvme_dev *dev, unsigned nsid)
        if (dev->max_hw_sectors) {
                blk_queue_max_hw_sectors(ns->queue, dev->max_hw_sectors);
                blk_queue_max_segments(ns->queue,
-                       ((dev->max_hw_sectors << 9) / dev->page_size) + 1);
+                       (dev->max_hw_sectors / (dev->page_size >> 9)) + 1);
        }
        if (dev->stripe_size)
                blk_queue_chunk_sectors(ns->queue, dev->stripe_size >> 9);
@@ -2701,6 +2708,18 @@ static int nvme_dev_map(struct nvme_dev *dev)
        dev->q_depth = min_t(int, NVME_CAP_MQES(cap) + 1, NVME_Q_DEPTH);
        dev->db_stride = 1 << NVME_CAP_STRIDE(cap);
        dev->dbs = ((void __iomem *)dev->bar) + 4096;
+
+       /*
+        * Temporary fix for the Apple controller found in the MacBook8,1 and
+        * some MacBook7,1 to avoid controller resets and data loss.
+        */
+       if (pdev->vendor == PCI_VENDOR_ID_APPLE && pdev->device == 0x2001) {
+               dev->q_depth = 2;
+               dev_warn(dev->dev, "detected Apple NVMe controller, set "
+                       "queue depth=%u to work around controller resets\n",
+                       dev->q_depth);
+       }
+
        if (readl(&dev->bar->vs) >= NVME_VS(1, 2))
                dev->cmb = nvme_map_cmb(dev);
 
@@ -2787,6 +2806,10 @@ static void nvme_del_queue_end(struct nvme_queue *nvmeq)
 {
        struct nvme_delq_ctx *dq = nvmeq->cmdinfo.ctx;
        nvme_put_dq(dq);
+
+       spin_lock_irq(&nvmeq->q_lock);
+       nvme_process_cq(nvmeq);
+       spin_unlock_irq(&nvmeq->q_lock);
 }
 
 static int adapter_async_del_queue(struct nvme_queue *nvmeq, u8 opcode,
index cd53fe4a0c8684900a94fb4bee76f9bd668e3837..9582c5703b3c905486da173d08a2f986883bda26 100644 (file)
@@ -485,9 +485,10 @@ static int of_translate_one(struct device_node *parent, struct of_bus *bus,
        int rone;
        u64 offset = OF_BAD_ADDR;
 
-       /* Normally, an absence of a "ranges" property means we are
+       /*
+        * Normally, an absence of a "ranges" property means we are
         * crossing a non-translatable boundary, and thus the addresses
-        * below the current not cannot be converted to CPU physical ones.
+        * below the current cannot be converted to CPU physical ones.
         * Unfortunately, while this is very clear in the spec, it's not
         * what Apple understood, and they do have things like /uni-n or
         * /ht nodes with no "ranges" property and a lot of perfectly
index d2430298a309a86d3f2110623d3728b9dedb228f..655f79db7899ffd0628714d51203847630a8075c 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/kernel.h>
 #include <linux/initrd.h>
 #include <linux/memblock.h>
+#include <linux/mutex.h>
 #include <linux/of.h>
 #include <linux/of_fdt.h>
 #include <linux/of_reserved_mem.h>
@@ -436,6 +437,8 @@ static void *kernel_tree_alloc(u64 size, u64 align)
        return kzalloc(size, GFP_KERNEL);
 }
 
+static DEFINE_MUTEX(of_fdt_unflatten_mutex);
+
 /**
  * of_fdt_unflatten_tree - create tree of device_nodes from flat blob
  *
@@ -447,7 +450,9 @@ static void *kernel_tree_alloc(u64 size, u64 align)
 void of_fdt_unflatten_tree(const unsigned long *blob,
                        struct device_node **mynodes)
 {
+       mutex_lock(&of_fdt_unflatten_mutex);
        __unflatten_device_tree(blob, mynodes, &kernel_tree_alloc);
+       mutex_unlock(&of_fdt_unflatten_mutex);
 }
 EXPORT_SYMBOL_GPL(of_fdt_unflatten_tree);
 
@@ -1041,7 +1046,7 @@ void __init __weak early_init_dt_add_memory_arch(u64 base, u64 size)
 int __init __weak early_init_dt_reserve_memory_arch(phys_addr_t base,
                                        phys_addr_t size, bool nomap)
 {
-       pr_err("Reserved memory not supported, ignoring range 0x%pa - 0x%pa%s\n",
+       pr_err("Reserved memory not supported, ignoring range %pa - %pa%s\n",
                  &base, &size, nomap ? " (nomap)" : "");
        return -ENOSYS;
 }
index 902b89be7217137726be7eb1ab19263c0372635a..4fa916dffc91924a0354c3c779ae5bf41cb79cec 100644 (file)
@@ -53,7 +53,7 @@ EXPORT_SYMBOL_GPL(irq_of_parse_and_map);
  * Returns a pointer to the interrupt parent node, or NULL if the interrupt
  * parent could not be determined.
  */
-static struct device_node *of_irq_find_parent(struct device_node *child)
+struct device_node *of_irq_find_parent(struct device_node *child)
 {
        struct device_node *p;
        const __be32 *parp;
@@ -77,6 +77,7 @@ static struct device_node *of_irq_find_parent(struct device_node *child)
 
        return p;
 }
+EXPORT_SYMBOL_GPL(of_irq_find_parent);
 
 /**
  * of_irq_parse_raw - Low level interrupt tree parsing
index be77e75c587db95c55a51e556f228f97810e051c..1a3556a9e9ea126b451b2a3c68e0407135af242f 100644 (file)
@@ -206,7 +206,13 @@ static int __init __rmem_cmp(const void *a, const void *b)
 {
        const struct reserved_mem *ra = a, *rb = b;
 
-       return ra->base - rb->base;
+       if (ra->base < rb->base)
+               return -1;
+
+       if (ra->base > rb->base)
+               return 1;
+
+       return 0;
 }
 
 static void __init __rmem_check_for_overlap(void)
index 761e77bfce5d2f43f251ebb74f82245d52c5f5f3..e56f1569f6c396f8c29448e9adb26214e26ba9fc 100644 (file)
@@ -104,7 +104,11 @@ iommu_coalesce_chunks(struct ioc *ioc, struct device *dev,
        struct scatterlist *contig_sg;     /* contig chunk head */
        unsigned long dma_offset, dma_len; /* start/len of DMA stream */
        unsigned int n_mappings = 0;
-       unsigned int max_seg_size = dma_get_max_seg_size(dev);
+       unsigned int max_seg_size = min(dma_get_max_seg_size(dev),
+                                       (unsigned)DMA_CHUNK_SIZE);
+       unsigned int max_seg_boundary = dma_get_seg_boundary(dev) + 1;
+       if (max_seg_boundary)   /* check if the addition above didn't overflow */
+               max_seg_size = min(max_seg_size, max_seg_boundary);
 
        while (nents > 0) {
 
@@ -138,14 +142,11 @@ iommu_coalesce_chunks(struct ioc *ioc, struct device *dev,
 
                        /*
                        ** First make sure current dma stream won't
-                       ** exceed DMA_CHUNK_SIZE if we coalesce the
+                       ** exceed max_seg_size if we coalesce the
                        ** next entry.
                        */   
-                       if(unlikely(ALIGN(dma_len + dma_offset + startsg->length,
-                                           IOVP_SIZE) > DMA_CHUNK_SIZE))
-                               break;
-
-                       if (startsg->length + dma_len > max_seg_size)
+                       if (unlikely(ALIGN(dma_len + dma_offset + startsg->length, IOVP_SIZE) >
+                                    max_seg_size))
                                break;
 
                        /*
index e5dda38bdde5e1735a50b4de9fcd2cd6307d13c5..99da549d5d06a067b58d3bbe08c39041a9d90605 100644 (file)
 #define TLP_CFG_DW2(bus, devfn, offset)        \
                                (((bus) << 24) | ((devfn) << 16) | (offset))
 #define TLP_REQ_ID(bus, devfn)         (((bus) << 8) | (devfn))
+#define TLP_COMP_STATUS(s)             (((s) >> 12) & 7)
 #define TLP_HDR_SIZE                   3
 #define TLP_LOOP                       500
+#define RP_DEVFN                       0
 
 #define INTX_NUM                       4
 
@@ -166,34 +168,41 @@ static bool altera_pcie_valid_config(struct altera_pcie *pcie,
 
 static int tlp_read_packet(struct altera_pcie *pcie, u32 *value)
 {
-       u8 loop;
+       int i;
        bool sop = 0;
        u32 ctrl;
        u32 reg0, reg1;
+       u32 comp_status = 1;
 
        /*
         * Minimum 2 loops to read TLP headers and 1 loop to read data
         * payload.
         */
-       for (loop = 0; loop < TLP_LOOP; loop++) {
+       for (i = 0; i < TLP_LOOP; i++) {
                ctrl = cra_readl(pcie, RP_RXCPL_STATUS);
                if ((ctrl & RP_RXCPL_SOP) || (ctrl & RP_RXCPL_EOP) || sop) {
                        reg0 = cra_readl(pcie, RP_RXCPL_REG0);
                        reg1 = cra_readl(pcie, RP_RXCPL_REG1);
 
-                       if (ctrl & RP_RXCPL_SOP)
+                       if (ctrl & RP_RXCPL_SOP) {
                                sop = true;
+                               comp_status = TLP_COMP_STATUS(reg1);
+                       }
 
                        if (ctrl & RP_RXCPL_EOP) {
+                               if (comp_status)
+                                       return PCIBIOS_DEVICE_NOT_FOUND;
+
                                if (value)
                                        *value = reg0;
+
                                return PCIBIOS_SUCCESSFUL;
                        }
                }
                udelay(5);
        }
 
-       return -ENOENT;
+       return PCIBIOS_DEVICE_NOT_FOUND;
 }
 
 static void tlp_write_packet(struct altera_pcie *pcie, u32 *headers,
@@ -233,7 +242,7 @@ static int tlp_cfg_dword_read(struct altera_pcie *pcie, u8 bus, u32 devfn,
        else
                headers[0] = TLP_CFG_DW0(TLP_FMTTYPE_CFGRD1);
 
-       headers[1] = TLP_CFG_DW1(TLP_REQ_ID(pcie->root_bus_nr, devfn),
+       headers[1] = TLP_CFG_DW1(TLP_REQ_ID(pcie->root_bus_nr, RP_DEVFN),
                                        TLP_READ_TAG, byte_en);
        headers[2] = TLP_CFG_DW2(bus, devfn, where);
 
@@ -253,7 +262,7 @@ static int tlp_cfg_dword_write(struct altera_pcie *pcie, u8 bus, u32 devfn,
        else
                headers[0] = TLP_CFG_DW0(TLP_FMTTYPE_CFGWR1);
 
-       headers[1] = TLP_CFG_DW1(TLP_REQ_ID(pcie->root_bus_nr, devfn),
+       headers[1] = TLP_CFG_DW1(TLP_REQ_ID(pcie->root_bus_nr, RP_DEVFN),
                                        TLP_WRITE_TAG, byte_en);
        headers[2] = TLP_CFG_DW2(bus, devfn, where);
 
@@ -458,7 +467,7 @@ static int altera_pcie_init_irq_domain(struct altera_pcie *pcie)
        struct device_node *node = dev->of_node;
 
        /* Setup INTx */
-       pcie->irq_domain = irq_domain_add_linear(node, INTX_NUM,
+       pcie->irq_domain = irq_domain_add_linear(node, INTX_NUM + 1,
                                        &intx_domain_ops, pcie);
        if (!pcie->irq_domain) {
                dev_err(dev, "Failed to get a INTx IRQ domain\n");
index 540f077c37eae7b59b983c31fa6ddce51d8bda6e..02a7452bdf235cf52731b3a822066c27d33e8a76 100644 (file)
@@ -440,7 +440,6 @@ int dw_pcie_host_init(struct pcie_port *pp)
                                         ret, pp->io);
                                continue;
                        }
-                       pp->io_base = pp->io->start;
                        break;
                case IORESOURCE_MEM:
                        pp->mem = win->res;
index 35457ecd8e70f4d6f856573f45f8bbc2991d1f6d..163671a4f798dfc18bb24f3490ad7138753efac1 100644 (file)
@@ -111,7 +111,7 @@ static struct pcie_host_ops hisi_pcie_host_ops = {
        .link_up = hisi_pcie_link_up,
 };
 
-static int __init hisi_add_pcie_port(struct pcie_port *pp,
+static int hisi_add_pcie_port(struct pcie_port *pp,
                                     struct platform_device *pdev)
 {
        int ret;
@@ -139,7 +139,7 @@ static int __init hisi_add_pcie_port(struct pcie_port *pp,
        return 0;
 }
 
-static int __init hisi_pcie_probe(struct platform_device *pdev)
+static int hisi_pcie_probe(struct platform_device *pdev)
 {
        struct hisi_pcie *hisi_pcie;
        struct pcie_port *pp;
index 53e463244bb7e35ac368ff088a4976c2153fce3d..7eaa4c87fec71c8dd792ccffc919b322711d91dd 100644 (file)
@@ -54,7 +54,7 @@ static int pci_msi_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
        struct irq_domain *domain;
 
        domain = pci_msi_get_domain(dev);
-       if (domain)
+       if (domain && irq_domain_is_hierarchy(domain))
                return pci_msi_domain_alloc_irqs(domain, dev, nvec, type);
 
        return arch_setup_msi_irqs(dev, nvec, type);
@@ -65,7 +65,7 @@ static void pci_msi_teardown_msi_irqs(struct pci_dev *dev)
        struct irq_domain *domain;
 
        domain = pci_msi_get_domain(dev);
-       if (domain)
+       if (domain && irq_domain_is_hierarchy(domain))
                pci_msi_domain_free_irqs(domain, dev);
        else
                arch_teardown_msi_irqs(dev);
index 4446fcb5effd347d87fb6314473297acc4558769..d7ffd66814bb51c14cbdf849fcd6a0a33f30dba7 100644 (file)
@@ -1146,9 +1146,21 @@ static int pci_pm_runtime_suspend(struct device *dev)
        pci_dev->state_saved = false;
        pci_dev->no_d3cold = false;
        error = pm->runtime_suspend(dev);
-       suspend_report_result(pm->runtime_suspend, error);
-       if (error)
+       if (error) {
+               /*
+                * -EBUSY and -EAGAIN is used to request the runtime PM core
+                * to schedule a new suspend, so log the event only with debug
+                * log level.
+                */
+               if (error == -EBUSY || error == -EAGAIN)
+                       dev_dbg(dev, "can't suspend now (%pf returned %d)\n",
+                               pm->runtime_suspend, error);
+               else
+                       dev_err(dev, "can't suspend (%pf returned %d)\n",
+                               pm->runtime_suspend, error);
+
                return error;
+       }
        if (!pci_dev->d3cold_allowed)
                pci_dev->no_d3cold = true;
 
index 92618686604cb9d314aa1e6bf833363cfbaaa1b5..eead54cd01b2bfad6a5514f53067429e616db6b7 100644 (file)
@@ -216,7 +216,10 @@ static ssize_t numa_node_store(struct device *dev,
        if (ret)
                return ret;
 
-       if (node >= MAX_NUMNODES || !node_online(node))
+       if ((node < 0 && node != NUMA_NO_NODE) || node >= MAX_NUMNODES)
+               return -EINVAL;
+
+       if (node != NUMA_NO_NODE && !node_online(node))
                return -EINVAL;
 
        add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK);
index fd2f03fa53f33a34977fc8713fd8cf6759cad2d5..d390fc1475eccf9f77491b5b401a823067b2995b 100644 (file)
@@ -337,6 +337,4 @@ static inline int pci_dev_specific_reset(struct pci_dev *dev, int probe)
 }
 #endif
 
-struct pci_host_bridge *pci_find_host_bridge(struct pci_bus *bus);
-
 #endif /* DRIVERS_PCI_H */
index b422e4ed73f4266f7a8d13db4ec1096395163fc3..312c78b27a3206c813c85912e14b570ffa43a0a6 100644 (file)
@@ -5,8 +5,6 @@
 config PINCTRL
        bool
 
-if PINCTRL
-
 menu "Pin controllers"
        depends on PINCTRL
 
@@ -274,5 +272,3 @@ config PINCTRL_TB10X
        select GPIOLIB
 
 endmenu
-
-endif
index 88a7fac11bd499f72c831b91f0f6c05bd29b19f7..acaf84cadca3fcac638656638a3ea8310011c6da 100644 (file)
@@ -538,8 +538,10 @@ static int imx1_pinctrl_parse_functions(struct device_node *np,
                func->groups[i] = child->name;
                grp = &info->groups[grp_index++];
                ret = imx1_pinctrl_parse_groups(child, grp, info, i++);
-               if (ret == -ENOMEM)
+               if (ret == -ENOMEM) {
+                       of_node_put(child);
                        return ret;
+               }
        }
 
        return 0;
@@ -582,8 +584,10 @@ static int imx1_pinctrl_parse_dt(struct platform_device *pdev,
 
        for_each_child_of_node(np, child) {
                ret = imx1_pinctrl_parse_functions(child, info, ifunc++);
-               if (ret == -ENOMEM)
+               if (ret == -ENOMEM) {
+                       of_node_put(child);
                        return -ENOMEM;
+               }
        }
 
        return 0;
index f307f1d27d646fcd3954a9d497528fffbf16dc2b..5c717275a7fa805f370cdd68815e64f8982b142b 100644 (file)
@@ -747,7 +747,7 @@ static int mtk_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
        reg_addr =  mtk_get_port(pctl, offset) + pctl->devdata->dir_offset;
        bit = BIT(offset & 0xf);
        regmap_read(pctl->regmap1, reg_addr, &read_val);
-       return !!(read_val & bit);
+       return !(read_val & bit);
 }
 
 static int mtk_gpio_get(struct gpio_chip *chip, unsigned offset)
@@ -757,12 +757,8 @@ static int mtk_gpio_get(struct gpio_chip *chip, unsigned offset)
        unsigned int read_val = 0;
        struct mtk_pinctrl *pctl = dev_get_drvdata(chip->dev);
 
-       if (mtk_gpio_get_direction(chip, offset))
-               reg_addr = mtk_get_port(pctl, offset) +
-                       pctl->devdata->dout_offset;
-       else
-               reg_addr = mtk_get_port(pctl, offset) +
-                       pctl->devdata->din_offset;
+       reg_addr = mtk_get_port(pctl, offset) +
+               pctl->devdata->din_offset;
 
        bit = BIT(offset & 0xf);
        regmap_read(pctl->regmap1, reg_addr, &read_val);
@@ -997,6 +993,7 @@ static struct gpio_chip mtk_gpio_chip = {
        .owner                  = THIS_MODULE,
        .request                = gpiochip_generic_request,
        .free                   = gpiochip_generic_free,
+       .get_direction          = mtk_gpio_get_direction,
        .direction_input        = mtk_gpio_direction_input,
        .direction_output       = mtk_gpio_direction_output,
        .get                    = mtk_gpio_get,
index d809c9eaa3231817512bdda858ad208d0f1138e4..19a3c3bc2f1f7213d31ea8f23ef56b815031a3a0 100644 (file)
@@ -672,7 +672,7 @@ static int pm8xxx_gpio_probe(struct platform_device *pdev)
                return -ENOMEM;
 
        pctrl->dev = &pdev->dev;
-       pctrl->npins = (unsigned)of_device_get_match_data(&pdev->dev);
+       pctrl->npins = (unsigned long)of_device_get_match_data(&pdev->dev);
 
        pctrl->regmap = dev_get_regmap(pdev->dev.parent, NULL);
        if (!pctrl->regmap) {
index 8982027de8e8b528f026f38d58ccdf692901635c..b868ef1766a0910e50dbfe43b80e650cea19739f 100644 (file)
@@ -763,7 +763,7 @@ static int pm8xxx_mpp_probe(struct platform_device *pdev)
                return -ENOMEM;
 
        pctrl->dev = &pdev->dev;
-       pctrl->npins = (unsigned)of_device_get_match_data(&pdev->dev);
+       pctrl->npins = (unsigned long)of_device_get_match_data(&pdev->dev);
 
        pctrl->regmap = dev_get_regmap(pdev->dev.parent, NULL);
        if (!pctrl->regmap) {
index e7deb51de7dc4fd4c76bc1b7483ac2127e1da850..9842bb1067969701a8879b3de481f3da6d2349a7 100644 (file)
        PORT_GP_12(5, fn, sfx)
 
 #undef _GP_DATA
-#define _GP_DATA(bank, pin, name, sfx)                                 \
+#define _GP_DATA(bank, pin, name, sfx, cfg)                            \
        PINMUX_DATA(name##_DATA, name##_FN, name##_IN, name##_OUT)
 
-#define _GP_INOUTSEL(bank, pin, name, sfx)     name##_IN, name##_OUT
-#define _GP_INDT(bank, pin, name, sfx)         name##_DATA
+#define _GP_INOUTSEL(bank, pin, name, sfx, cfg)        name##_IN, name##_OUT
+#define _GP_INDT(bank, pin, name, sfx, cfg)    name##_DATA
 #define GP_INOUTSEL(bank)      PORT_GP_32_REV(bank, _GP_INOUTSEL, unused)
 #define GP_INDT(bank)          PORT_GP_32_REV(bank, _GP_INDT, unused)
 
index 8b3130f22b42b334ff0d22718e46484012fb2c2b..9e03d158f4119133f09b0979d8b5b70e1ae63c06 100644 (file)
@@ -1478,6 +1478,8 @@ module_init(remoteproc_init);
 
 static void __exit remoteproc_exit(void)
 {
+       ida_destroy(&rproc_dev_index);
+
        rproc_exit_debugfs();
 }
 module_exit(remoteproc_exit);
index 9d30809bb407174214e1be674b323b0dd88c0a8e..916af5096f57b93b7f7e148d28716329b31c7be6 100644 (file)
@@ -156,7 +156,7 @@ rproc_recovery_write(struct file *filp, const char __user *user_buf,
        char buf[10];
        int ret;
 
-       if (count > sizeof(buf))
+       if (count < 1 || count > sizeof(buf))
                return count;
 
        ret = copy_from_user(buf, user_buf, count);
index 188006c55ce0708771709199b183aff93c16c3b1..aa705bb4748c08ac302d45775ef698cf26c69d5b 100644 (file)
@@ -15,9 +15,6 @@
 #include <linux/i2c.h>
 #include <linux/init.h>
 #include <linux/module.h>
-#include <linux/of_device.h>
-#include <linux/of_irq.h>
-#include <linux/pm_wakeirq.h>
 #include <linux/rtc/ds1307.h>
 #include <linux/rtc.h>
 #include <linux/slab.h>
@@ -117,7 +114,6 @@ struct ds1307 {
 #define HAS_ALARM      1               /* bit 1 == irq claimed */
        struct i2c_client       *client;
        struct rtc_device       *rtc;
-       int                     wakeirq;
        s32 (*read_block_data)(const struct i2c_client *client, u8 command,
                               u8 length, u8 *values);
        s32 (*write_block_data)(const struct i2c_client *client, u8 command,
@@ -1138,7 +1134,10 @@ read_rtc:
                                bin2bcd(tmp));
        }
 
-       device_set_wakeup_capable(&client->dev, want_irq);
+       if (want_irq) {
+               device_set_wakeup_capable(&client->dev, true);
+               set_bit(HAS_ALARM, &ds1307->flags);
+       }
        ds1307->rtc = devm_rtc_device_register(&client->dev, client->name,
                                rtc_ops, THIS_MODULE);
        if (IS_ERR(ds1307->rtc)) {
@@ -1146,43 +1145,19 @@ read_rtc:
        }
 
        if (want_irq) {
-               struct device_node *node = client->dev.of_node;
-
                err = devm_request_threaded_irq(&client->dev,
                                                client->irq, NULL, irq_handler,
                                                IRQF_SHARED | IRQF_ONESHOT,
                                                ds1307->rtc->name, client);
                if (err) {
                        client->irq = 0;
+                       device_set_wakeup_capable(&client->dev, false);
+                       clear_bit(HAS_ALARM, &ds1307->flags);
                        dev_err(&client->dev, "unable to request IRQ!\n");
-                       goto no_irq;
-               }
-
-               set_bit(HAS_ALARM, &ds1307->flags);
-               dev_dbg(&client->dev, "got IRQ %d\n", client->irq);
-
-               /* Currently supported by OF code only! */
-               if (!node)
-                       goto no_irq;
-
-               err = of_irq_get(node, 1);
-               if (err <= 0) {
-                       if (err == -EPROBE_DEFER)
-                               goto exit;
-                       goto no_irq;
-               }
-               ds1307->wakeirq = err;
-
-               err = dev_pm_set_dedicated_wake_irq(&client->dev,
-                                                   ds1307->wakeirq);
-               if (err) {
-                       dev_err(&client->dev, "unable to setup wakeIRQ %d!\n",
-                               err);
-                       goto exit;
-               }
+               } else
+                       dev_dbg(&client->dev, "got IRQ %d\n", client->irq);
        }
 
-no_irq:
        if (chip->nvram_size) {
 
                ds1307->nvram = devm_kzalloc(&client->dev,
@@ -1226,9 +1201,6 @@ static int ds1307_remove(struct i2c_client *client)
 {
        struct ds1307 *ds1307 = i2c_get_clientdata(client);
 
-       if (ds1307->wakeirq)
-               dev_pm_clear_wake_irq(&client->dev);
-
        if (test_and_clear_bit(HAS_NVRAM, &ds1307->flags))
                sysfs_remove_bin_file(&client->dev.kobj, ds1307->nvram);
 
index 5f692ae4074959e019a74eb0c81405cb2869195c..64eed87d34a87840d5da60d267383589541e1d73 100644 (file)
@@ -364,6 +364,7 @@ config SCSI_HPSA
        tristate "HP Smart Array SCSI driver"
        depends on PCI && SCSI
        select CHECK_SIGNATURE
+       select SCSI_SAS_ATTRS
        help
          This driver supports HP Smart Array Controllers (circa 2009).
          It is a SCSI alternative to the cciss driver, which is a block
@@ -499,6 +500,7 @@ config SCSI_ADVANSYS
        tristate "AdvanSys SCSI support"
        depends on SCSI
        depends on ISA || EISA || PCI
+       depends on ISA_DMA_API || !ISA
        help
          This is a driver for all SCSI host adapters manufactured by
          AdvanSys. It is documented in the kernel source in
index 519f9a4b3dadf39c07be7e61f20fc2481cddbd02..febbd83e2ecd9d6a6984500eb8cc02d6690c3984 100644 (file)
@@ -7803,7 +7803,7 @@ adv_build_req(struct asc_board *boardp, struct scsi_cmnd *scp,
                return ASC_BUSY;
        }
        scsiqp->sense_addr = cpu_to_le32(sense_addr);
-       scsiqp->sense_len = cpu_to_le32(SCSI_SENSE_BUFFERSIZE);
+       scsiqp->sense_len = SCSI_SENSE_BUFFERSIZE;
 
        /* Build ADV_SCSI_REQ_Q */
 
index 323982fd00c3ba985dfb59bf04b6eff04f86e9b7..82ac1cd818ac18e1310ba2abaede9c8b262f9976 100644 (file)
@@ -333,6 +333,17 @@ static void scsi_host_dev_release(struct device *dev)
                kfree(queuedata);
        }
 
+       if (shost->shost_state == SHOST_CREATED) {
+               /*
+                * Free the shost_dev device name here if scsi_host_alloc()
+                * and scsi_host_put() have been called but neither
+                * scsi_host_add() nor scsi_host_remove() has been called.
+                * This avoids that the memory allocated for the shost_dev
+                * name is leaked.
+                */
+               kfree(dev_name(&shost->shost_dev));
+       }
+
        scsi_destroy_command_freelist(shost);
        if (shost_use_blk_mq(shost)) {
                if (shost->tag_set.tags)
index 6a8f95808ee0f92027796651a6254e6c9382ca5a..a3860367b568aa06adf4290bf84717458c241e77 100644 (file)
@@ -8671,7 +8671,7 @@ static void hpsa_disable_rld_caching(struct ctlr_info *h)
        if ((rc != 0)  || (c->err_info->CommandStatus != 0))
                goto errout;
 
-       if (*options && HPSA_DIAG_OPTS_DISABLE_RLD_CACHING)
+       if (*options & HPSA_DIAG_OPTS_DISABLE_RLD_CACHING)
                goto out;
 
 errout:
index 29061467cc174e118848dd44244ff28bb198deb3..b736dbc8048530e6c2c8dae2a8f7e1aac896ce10 100644 (file)
@@ -71,3 +71,12 @@ config SCSI_MPT3SAS_MAX_SGE
        MAX_PHYS_SEGMENTS in most kernels.  However in SuSE kernels this
        can be 256. However, it may decreased down to 16.  Decreasing this
        parameter will reduce memory requirements on a per controller instance.
+
+config SCSI_MPT2SAS
+       tristate "Legacy MPT2SAS config option"
+       default n
+       select SCSI_MPT3SAS
+       depends on PCI && SCSI
+       ---help---
+       Dummy config option for backwards compatiblity: configure the MPT3SAS
+       driver instead.
index d95206b7e1167861531d2cd29c9ef27e7da82c25..9ab77b06434d19a61a92bb771aef0e70da0f31d8 100644 (file)
@@ -3905,8 +3905,7 @@ scsih_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *scmd)
         * We do not expose raid functionality to upper layer for warpdrive.
         */
        if (!ioc->is_warpdrive && !scsih_is_raid(&scmd->device->sdev_gendev)
-           && (sas_device_priv_data->flags & MPT_DEVICE_TLR_ON) &&
-           scmd->cmd_len != 32)
+           && sas_is_tlr_enabled(scmd->device) && scmd->cmd_len != 32)
                mpi_control |= MPI2_SCSIIO_CONTROL_TLR_ON;
 
        smid = mpt3sas_base_get_smid_scsiio(ioc, ioc->scsi_io_cb_idx, scmd);
index 90fdf0e859e31fd9e72352d2ed19a889061e6ed4..675e7fab0796e4c1ebfc3e7e77aa109592a25c02 100644 (file)
@@ -758,7 +758,7 @@ mvs_store_interrupt_coalescing(struct device *cdev,
                        struct device_attribute *attr,
                        const char *buffer, size_t size)
 {
-       int val = 0;
+       unsigned int val = 0;
        struct mvs_info *mvi = NULL;
        struct Scsi_Host *shost = class_to_shost(cdev);
        struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost);
@@ -766,7 +766,7 @@ mvs_store_interrupt_coalescing(struct device *cdev,
        if (buffer == NULL)
                return size;
 
-       if (sscanf(buffer, "%d", &val) != 1)
+       if (sscanf(buffer, "%u", &val) != 1)
                return -EINVAL;
 
        if (val >= 0x10000) {
index eb0cc5475c451860d56c6f74679ce026f3808710..b6b4cfdd76201d76f26ca4a99c60aa49ec6b4c69 100644 (file)
@@ -433,7 +433,7 @@ qla82xx_pci_get_crb_addr_2M(struct qla_hw_data *ha, ulong off_in,
        if (off_in < QLA82XX_PCI_CRBSPACE)
                return -1;
 
-       *off_out = (void __iomem *)(off_in - QLA82XX_PCI_CRBSPACE);
+       off_in -= QLA82XX_PCI_CRBSPACE;
 
        /* Try direct map */
        m = &crb_128M_2M_map[CRB_BLK(off_in)].sub_block[CRB_SUBBLK(off_in)];
@@ -443,6 +443,7 @@ qla82xx_pci_get_crb_addr_2M(struct qla_hw_data *ha, ulong off_in,
                return 0;
        }
        /* Not in direct map, use crb window */
+       *off_out = (void __iomem *)off_in;
        return 1;
 }
 
index 3ba2e9564b9a78f000c234fa1be7bb05e24eaebd..81af294f15a7d4deb557b162dc51ca676df9618a 100644 (file)
@@ -902,7 +902,7 @@ static ssize_t tcm_qla2xxx_tpg_fabric_prot_type_show(struct config_item *item,
        return sprintf(page, "%d\n", tpg->tpg_attrib.fabric_prot_type);
 }
 
-CONFIGFS_ATTR_WO(tcm_qla2xxx_tpg_, enable);
+CONFIGFS_ATTR(tcm_qla2xxx_tpg_, enable);
 CONFIGFS_ATTR_RO(tcm_qla2xxx_tpg_, dynamic_sessions);
 CONFIGFS_ATTR(tcm_qla2xxx_tpg_, fabric_prot_type);
 
index dfcc45bb03b1f30e808e611a567c2f76cc734d3c..d09d60293c272663b5b9b84f27ce2fab3e61a6aa 100644 (file)
@@ -465,8 +465,9 @@ static const struct opcode_info_t opcode_info_arr[SDEB_I_LAST_ELEMENT + 1] = {
             0} },
        {0, 0, 0, F_INV_OP | FF_RESPOND, NULL, NULL, /* MAINT OUT */
            {0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
-       {0, 0, 0, F_INV_OP | FF_RESPOND, NULL, NULL, /* VERIFY */
-           {0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
+       {0, 0x2f, 0, F_D_OUT_MAYBE | FF_DIRECT_IO, NULL, NULL, /* VERIFY(10) */
+           {10,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc7,
+            0, 0, 0, 0, 0, 0} },
        {1, 0x7f, 0x9, F_SA_HIGH | F_D_IN | FF_DIRECT_IO, resp_read_dt0,
            vl_iarr, {32,  0xc7, 0, 0, 0, 0, 0x1f, 0x18, 0x0, 0x9, 0xfe, 0,
                      0xff, 0xff, 0xff, 0xff} },/* VARIABLE LENGTH, READ(32) */
@@ -477,8 +478,8 @@ static const struct opcode_info_t opcode_info_arr[SDEB_I_LAST_ELEMENT + 1] = {
            {10,  0x13, 0xff, 0xff, 0, 0, 0, 0xff, 0xff, 0xc7, 0, 0, 0, 0, 0,
             0} },
 /* 20 */
-       {0, 0, 0, F_INV_OP | FF_RESPOND, NULL, NULL, /* ALLOW REMOVAL */
-           {0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
+       {0, 0x1e, 0, 0, NULL, NULL, /* ALLOW REMOVAL */
+           {6,  0, 0, 0, 0x3, 0xc7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
        {0, 0x1, 0, 0, resp_start_stop, NULL, /* REWIND ?? */
            {6,  0x1, 0, 0, 0, 0xc7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
        {0, 0, 0, F_INV_OP | FF_RESPOND, NULL, NULL, /* ATA_PT */
index 83245391e956bc6f351a668473debeba6121b71b..054923e3393c6f2dffd0959fea6ee610ecf177ac 100644 (file)
@@ -701,9 +701,12 @@ static int scsi_probe_lun(struct scsi_device *sdev, unsigned char *inq_result,
         * strings.
         */
        if (sdev->inquiry_len < 36) {
-               sdev_printk(KERN_INFO, sdev,
-                           "scsi scan: INQUIRY result too short (%d),"
-                           " using 36\n", sdev->inquiry_len);
+               if (!sdev->host->short_inquiry) {
+                       shost_printk(KERN_INFO, sdev->host,
+                                   "scsi scan: INQUIRY result too short (%d),"
+                                   " using 36\n", sdev->inquiry_len);
+                       sdev->host->short_inquiry = 1;
+               }
                sdev->inquiry_len = 36;
        }
 
index 8d2312239ae0cda01238ae549f0ae8007de233ea..21930c9ac9cd90caf6e5386b4495992fb3f8542d 100644 (file)
@@ -1102,6 +1102,14 @@ void __scsi_remove_device(struct scsi_device *sdev)
 {
        struct device *dev = &sdev->sdev_gendev;
 
+       /*
+        * This cleanup path is not reentrant and while it is impossible
+        * to get a new reference with scsi_device_get() someone can still
+        * hold a previously acquired one.
+        */
+       if (sdev->sdev_state == SDEV_DEL)
+               return;
+
        if (sdev->is_visible) {
                if (scsi_device_set_state(sdev, SDEV_CANCEL) != 0)
                        return;
@@ -1110,7 +1118,9 @@ void __scsi_remove_device(struct scsi_device *sdev)
                device_unregister(&sdev->sdev_dev);
                transport_remove_device(dev);
                scsi_dh_remove_device(sdev);
-       }
+               device_del(dev);
+       } else
+               put_device(&sdev->sdev_dev);
 
        /*
         * Stop accepting new requests and wait until all queuecommand() and
@@ -1121,16 +1131,6 @@ void __scsi_remove_device(struct scsi_device *sdev)
        blk_cleanup_queue(sdev->request_queue);
        cancel_work_sync(&sdev->requeue_work);
 
-       /*
-        * Remove the device after blk_cleanup_queue() has been called such
-        * a possible bdi_register() call with the same name occurs after
-        * blk_cleanup_queue() has called bdi_destroy().
-        */
-       if (sdev->is_visible)
-               device_del(dev);
-       else
-               put_device(&sdev->sdev_dev);
-
        if (sdev->host->hostt->slave_destroy)
                sdev->host->hostt->slave_destroy(sdev);
        transport_destroy_device(dev);
index 54519804c46a57b99ce680ee665b4fe28dd91148..3d22fc3e3c1a7ba6df90665f59cf10e8d38ef715 100644 (file)
@@ -638,11 +638,24 @@ static void sd_config_discard(struct scsi_disk *sdkp, unsigned int mode)
        unsigned int max_blocks = 0;
 
        q->limits.discard_zeroes_data = 0;
-       q->limits.discard_alignment = sdkp->unmap_alignment *
-               logical_block_size;
-       q->limits.discard_granularity =
-               max(sdkp->physical_block_size,
-                   sdkp->unmap_granularity * logical_block_size);
+
+       /*
+        * When LBPRZ is reported, discard alignment and granularity
+        * must be fixed to the logical block size. Otherwise the block
+        * layer will drop misaligned portions of the request which can
+        * lead to data corruption. If LBPRZ is not set, we honor the
+        * device preference.
+        */
+       if (sdkp->lbprz) {
+               q->limits.discard_alignment = 0;
+               q->limits.discard_granularity = 1;
+       } else {
+               q->limits.discard_alignment = sdkp->unmap_alignment *
+                       logical_block_size;
+               q->limits.discard_granularity =
+                       max(sdkp->physical_block_size,
+                           sdkp->unmap_granularity * logical_block_size);
+       }
 
        sdkp->provisioning_mode = mode;
 
@@ -2321,11 +2334,8 @@ got_data:
                }
        }
 
-       if (sdkp->capacity > 0xffffffff) {
+       if (sdkp->capacity > 0xffffffff)
                sdp->use_16_for_rw = 1;
-               sdkp->max_xfer_blocks = SD_MAX_XFER_BLOCKS;
-       } else
-               sdkp->max_xfer_blocks = SD_DEF_XFER_BLOCKS;
 
        /* Rescale capacity to 512-byte units */
        if (sector_size == 4096)
@@ -2642,7 +2652,6 @@ static void sd_read_block_limits(struct scsi_disk *sdkp)
 {
        unsigned int sector_sz = sdkp->device->sector_size;
        const int vpd_len = 64;
-       u32 max_xfer_length;
        unsigned char *buffer = kmalloc(vpd_len, GFP_KERNEL);
 
        if (!buffer ||
@@ -2650,14 +2659,11 @@ static void sd_read_block_limits(struct scsi_disk *sdkp)
            scsi_get_vpd_page(sdkp->device, 0xb0, buffer, vpd_len))
                goto out;
 
-       max_xfer_length = get_unaligned_be32(&buffer[8]);
-       if (max_xfer_length)
-               sdkp->max_xfer_blocks = max_xfer_length;
-
        blk_queue_io_min(sdkp->disk->queue,
                         get_unaligned_be16(&buffer[6]) * sector_sz);
-       blk_queue_io_opt(sdkp->disk->queue,
-                        get_unaligned_be32(&buffer[12]) * sector_sz);
+
+       sdkp->max_xfer_blocks = get_unaligned_be32(&buffer[8]);
+       sdkp->opt_xfer_blocks = get_unaligned_be32(&buffer[12]);
 
        if (buffer[3] == 0x3c) {
                unsigned int lba_count, desc_count;
@@ -2806,6 +2812,11 @@ static int sd_try_extended_inquiry(struct scsi_device *sdp)
        return 0;
 }
 
+static inline u32 logical_to_sectors(struct scsi_device *sdev, u32 blocks)
+{
+       return blocks << (ilog2(sdev->sector_size) - 9);
+}
+
 /**
  *     sd_revalidate_disk - called the first time a new disk is seen,
  *     performs disk spin up, read_capacity, etc.
@@ -2815,8 +2826,9 @@ static int sd_revalidate_disk(struct gendisk *disk)
 {
        struct scsi_disk *sdkp = scsi_disk(disk);
        struct scsi_device *sdp = sdkp->device;
+       struct request_queue *q = sdkp->disk->queue;
        unsigned char *buffer;
-       unsigned int max_xfer;
+       unsigned int dev_max, rw_max;
 
        SCSI_LOG_HLQUEUE(3, sd_printk(KERN_INFO, sdkp,
                                      "sd_revalidate_disk\n"));
@@ -2864,11 +2876,26 @@ static int sd_revalidate_disk(struct gendisk *disk)
         */
        sd_set_flush_flag(sdkp);
 
-       max_xfer = sdkp->max_xfer_blocks;
-       max_xfer <<= ilog2(sdp->sector_size) - 9;
+       /* Initial block count limit based on CDB TRANSFER LENGTH field size. */
+       dev_max = sdp->use_16_for_rw ? SD_MAX_XFER_BLOCKS : SD_DEF_XFER_BLOCKS;
+
+       /* Some devices report a maximum block count for READ/WRITE requests. */
+       dev_max = min_not_zero(dev_max, sdkp->max_xfer_blocks);
+       q->limits.max_dev_sectors = logical_to_sectors(sdp, dev_max);
+
+       /*
+        * Use the device's preferred I/O size for reads and writes
+        * unless the reported value is unreasonably large (or garbage).
+        */
+       if (sdkp->opt_xfer_blocks && sdkp->opt_xfer_blocks <= dev_max &&
+           sdkp->opt_xfer_blocks <= SD_DEF_XFER_BLOCKS)
+               rw_max = q->limits.io_opt =
+                       logical_to_sectors(sdp, sdkp->opt_xfer_blocks);
+       else
+               rw_max = BLK_DEF_MAX_SECTORS;
 
-       sdkp->disk->queue->limits.max_sectors =
-               min_not_zero(queue_max_hw_sectors(sdkp->disk->queue), max_xfer);
+       /* Combine with controller limits */
+       q->limits.max_sectors = min(rw_max, queue_max_hw_sectors(q));
 
        set_capacity(disk, sdkp->capacity);
        sd_config_write_same(sdkp);
index 63ba5ca7f9a16b21735c1283c2a17df40a7ee06c..5f2a84aff29fb9cbd003e5bbe6996355a5c07075 100644 (file)
@@ -67,6 +67,7 @@ struct scsi_disk {
        atomic_t        openers;
        sector_t        capacity;       /* size in 512-byte sectors */
        u32             max_xfer_blocks;
+       u32             opt_xfer_blocks;
        u32             max_ws_blocks;
        u32             max_unmap_blocks;
        u32             unmap_granularity;
index e0a1e52a04e736b35dc2b03371a72fc0590b85b1..2e522951b619740b08a712695dfca31962b16de0 100644 (file)
@@ -4083,6 +4083,7 @@ static int create_one_cdev(struct scsi_tape *tape, int mode, int rew)
        }
        cdev->owner = THIS_MODULE;
        cdev->ops = &st_fops;
+       STm->cdevs[rew] = cdev;
 
        error = cdev_add(cdev, cdev_devno, 1);
        if (error) {
@@ -4091,7 +4092,6 @@ static int create_one_cdev(struct scsi_tape *tape, int mode, int rew)
                pr_err("st%d: Device not attached.\n", dev_num);
                goto out_free;
        }
-       STm->cdevs[rew] = cdev;
 
        i = mode << (4 - ST_NBR_MODE_BITS);
        snprintf(name, 10, "%s%s%s", rew ? "n" : "",
@@ -4110,8 +4110,9 @@ static int create_one_cdev(struct scsi_tape *tape, int mode, int rew)
        return 0;
 out_free:
        cdev_del(STm->cdevs[rew]);
-       STm->cdevs[rew] = NULL;
 out:
+       STm->cdevs[rew] = NULL;
+       STm->devs[rew] = NULL;
        return error;
 }
 
index 9d5068248aa0486f147bbbc90f1f2ac495ad0378..0a4ea809a61b0cddb37fd6fc2b72e6047a343bf4 100644 (file)
@@ -23,6 +23,7 @@ config MTK_PMIC_WRAP
 config MTK_SCPSYS
        bool "MediaTek SCPSYS Support"
        depends on ARCH_MEDIATEK || COMPILE_TEST
+       default ARM64 && ARCH_MEDIATEK
        select REGMAP
        select MTK_INFRACFG
        select PM_GENERIC_DOMAINS if PM
index f3a0b6a4b54ef8093f2dbbabbcdd7c07de1cddbe..8c03a80b482ddac7c1e22ac4178772f7d29819ff 100644 (file)
@@ -1179,7 +1179,7 @@ static int knav_queue_setup_link_ram(struct knav_device *kdev)
 
                block++;
                if (!block->size)
-                       return 0;
+                       continue;
 
                dev_dbg(kdev->dev, "linkram1: phys:%x, virt:%p, size:%x\n",
                        block->phys, block->virt, block->size);
@@ -1519,9 +1519,9 @@ static int knav_queue_load_pdsp(struct knav_device *kdev,
 
        for (i = 0; i < ARRAY_SIZE(knav_acc_firmwares); i++) {
                if (knav_acc_firmwares[i]) {
-                       ret = request_firmware(&fw,
-                                              knav_acc_firmwares[i],
-                                              kdev->dev);
+                       ret = request_firmware_direct(&fw,
+                                                     knav_acc_firmwares[i],
+                                                     kdev->dev);
                        if (!ret) {
                                found = true;
                                break;
index 06858e04ec59a8f2e290c398f6f06e2d1b15e28a..bf9a610e5b898106af79e49a586d7ad4061ef4e0 100644 (file)
@@ -562,8 +562,8 @@ static int bcm63xx_spi_probe(struct platform_device *pdev)
                goto out_clk_disable;
        }
 
-       dev_info(dev, "at 0x%08x (irq %d, FIFOs size %d)\n",
-                r->start, irq, bs->fifo_size);
+       dev_info(dev, "at %pr (irq %d, FIFOs size %d)\n",
+                r, irq, bs->fifo_size);
 
        return 0;
 
index 563954a614242718bd125f16f9a3549f783346b8..7840067062a8daf950f4de9a07e232f1482c9485 100644 (file)
@@ -410,7 +410,7 @@ static int mtk_spi_setup(struct spi_device *spi)
        if (!spi->controller_data)
                spi->controller_data = (void *)&mtk_default_chip_info;
 
-       if (mdata->dev_comp->need_pad_sel)
+       if (mdata->dev_comp->need_pad_sel && gpio_is_valid(spi->cs_gpio))
                gpio_direction_output(spi->cs_gpio, !(spi->mode & SPI_CS_HIGH));
 
        return 0;
@@ -632,13 +632,23 @@ static int mtk_spi_probe(struct platform_device *pdev)
                        goto err_put_master;
                }
 
-               for (i = 0; i < master->num_chipselect; i++) {
-                       ret = devm_gpio_request(&pdev->dev, master->cs_gpios[i],
-                                               dev_name(&pdev->dev));
-                       if (ret) {
-                               dev_err(&pdev->dev,
-                                       "can't get CS GPIO %i\n", i);
-                               goto err_put_master;
+               if (!master->cs_gpios && master->num_chipselect > 1) {
+                       dev_err(&pdev->dev,
+                               "cs_gpios not specified and num_chipselect > 1\n");
+                       ret = -EINVAL;
+                       goto err_put_master;
+               }
+
+               if (master->cs_gpios) {
+                       for (i = 0; i < master->num_chipselect; i++) {
+                               ret = devm_gpio_request(&pdev->dev,
+                                                       master->cs_gpios[i],
+                                                       dev_name(&pdev->dev));
+                               if (ret) {
+                                       dev_err(&pdev->dev,
+                                               "can't get CS GPIO %i\n", i);
+                                       goto err_put_master;
+                               }
                        }
                }
        }
index 94af80676684e4708d373e1551b8a6c46ea118fa..5e5fd77e27119d6ceb8d64f657884ab4ef9f3759 100644 (file)
@@ -1171,19 +1171,31 @@ err_no_rxchan:
 static int pl022_dma_autoprobe(struct pl022 *pl022)
 {
        struct device *dev = &pl022->adev->dev;
+       struct dma_chan *chan;
+       int err;
 
        /* automatically configure DMA channels from platform, normally using DT */
-       pl022->dma_rx_channel = dma_request_slave_channel(dev, "rx");
-       if (!pl022->dma_rx_channel)
+       chan = dma_request_slave_channel_reason(dev, "rx");
+       if (IS_ERR(chan)) {
+               err = PTR_ERR(chan);
                goto err_no_rxchan;
+       }
+
+       pl022->dma_rx_channel = chan;
 
-       pl022->dma_tx_channel = dma_request_slave_channel(dev, "tx");
-       if (!pl022->dma_tx_channel)
+       chan = dma_request_slave_channel_reason(dev, "tx");
+       if (IS_ERR(chan)) {
+               err = PTR_ERR(chan);
                goto err_no_txchan;
+       }
+
+       pl022->dma_tx_channel = chan;
 
        pl022->dummypage = kmalloc(PAGE_SIZE, GFP_KERNEL);
-       if (!pl022->dummypage)
+       if (!pl022->dummypage) {
+               err = -ENOMEM;
                goto err_no_dummypage;
+       }
 
        return 0;
 
@@ -1194,7 +1206,7 @@ err_no_txchan:
        dma_release_channel(pl022->dma_rx_channel);
        pl022->dma_rx_channel = NULL;
 err_no_rxchan:
-       return -ENODEV;
+       return err;
 }
                
 static void terminate_dma(struct pl022 *pl022)
@@ -2236,6 +2248,10 @@ static int pl022_probe(struct amba_device *adev, const struct amba_id *id)
 
        /* Get DMA channels, try autoconfiguration first */
        status = pl022_dma_autoprobe(pl022);
+       if (status == -EPROBE_DEFER) {
+               dev_dbg(dev, "deferring probe to get DMA channel\n");
+               goto err_no_irq;
+       }
 
        /* If that failed, use channels from platform_info */
        if (status == 0)
index e2415be209d5a77e9224add30db37d65244fabda..2b0a8ec3affb87333f8bdb2e9a2d9ad95855d4c1 100644 (file)
@@ -376,6 +376,7 @@ static void spi_drv_shutdown(struct device *dev)
 
 /**
  * __spi_register_driver - register a SPI driver
+ * @owner: owner module of the driver to register
  * @sdrv: the driver to register
  * Context: can sleep
  *
@@ -2130,6 +2131,7 @@ static int __spi_validate(struct spi_device *spi, struct spi_message *message)
         * Set transfer tx_nbits and rx_nbits as single transfer default
         * (SPI_NBITS_SINGLE) if it is not set for this transfer.
         */
+       message->frame_length = 0;
        list_for_each_entry(xfer, &message->transfers, transfer_list) {
                message->frame_length += xfer->len;
                if (!xfer->bits_per_word)
index 8f3ac37bfe12e71cb9b0f2e936664ffe7ba20737..64d8c87209605cbfebbed27378adf9fd9a244bcb 100644 (file)
@@ -25,5 +25,13 @@ ion/
    exposes existing cma regions and doesn't reserve unecessarily memory when
    booting a system which doesn't use ion.
 
+sync framework:
+ - remove CONFIG_SW_SYNC_USER, it is used only for testing/debugging and
+ should not be upstreamed.
+ - port CONFIG_SW_SYNC_USER tests interfaces to use debugfs somehow
+ - port libsync tests to kselftest
+ - clean up and ABI check for security issues
+ - move it to drivers/base/dma-buf
+
 Please send patches to Greg Kroah-Hartman <greg@kroah.com> and Cc:
 Arve HjønnevÃ¥g <arve@android.com> and Riley Andrews <riandrews@android.com>
index 3f2a3d611e4bea033b7943085f4fef747112be89..5bb1283d19cd2c0b697d11cd2b03dbaa71ca57b7 100644 (file)
@@ -831,14 +831,14 @@ static struct miscdevice ashmem_misc = {
 
 static int __init ashmem_init(void)
 {
-       int ret;
+       int ret = -ENOMEM;
 
        ashmem_area_cachep = kmem_cache_create("ashmem_area_cache",
                                               sizeof(struct ashmem_area),
                                               0, 0, NULL);
        if (unlikely(!ashmem_area_cachep)) {
                pr_err("failed to create slab cache\n");
-               return -ENOMEM;
+               goto out;
        }
 
        ashmem_range_cachep = kmem_cache_create("ashmem_range_cache",
@@ -846,13 +846,13 @@ static int __init ashmem_init(void)
                                                0, 0, NULL);
        if (unlikely(!ashmem_range_cachep)) {
                pr_err("failed to create slab cache\n");
-               return -ENOMEM;
+               goto out_free1;
        }
 
        ret = misc_register(&ashmem_misc);
        if (unlikely(ret)) {
                pr_err("failed to register misc device!\n");
-               return ret;
+               goto out_free2;
        }
 
        register_shrinker(&ashmem_shrinker);
@@ -860,5 +860,12 @@ static int __init ashmem_init(void)
        pr_info("initialized\n");
 
        return 0;
+
+out_free2:
+       kmem_cache_destroy(ashmem_range_cachep);
+out_free1:
+       kmem_cache_destroy(ashmem_area_cachep);
+out:
+       return ret;
 }
 device_initcall(ashmem_init);
index 3452346244922d1211b674087641c1009b2c3e0b..19c1572f1525ef5c506f1505dbe48ecb04b819cd 100644 (file)
@@ -33,3 +33,10 @@ config ION_TEGRA
        help
          Choose this option if you wish to use ion on an nVidia Tegra.
 
+config ION_HISI
+       tristate "Ion for Hisilicon"
+       depends on ARCH_HISI && ION
+       help
+         Choose this option if you wish to use ion on Hisilicon Platform.
+
+source "drivers/staging/android/ion/hisilicon/Kconfig"
index b56fd2bf2b4f4853a56aac29958afdf4bf77b5b5..18cc2aa593c2cec07ad6f3a232518b766a9d6dd3 100644 (file)
@@ -7,4 +7,5 @@ endif
 
 obj-$(CONFIG_ION_DUMMY) += ion_dummy_driver.o
 obj-$(CONFIG_ION_TEGRA) += tegra/
+obj-$(CONFIG_ION_HISI) += hisilicon/
 
diff --git a/drivers/staging/android/ion/hisilicon/Kconfig b/drivers/staging/android/ion/hisilicon/Kconfig
new file mode 100644 (file)
index 0000000..2b4bd07
--- /dev/null
@@ -0,0 +1,5 @@
+config HI6220_ION
+        bool "Hi6220 ION Driver"
+        depends on ARCH_HISI && ION
+        help
+          Build the Hisilicon Hi6220 ion driver.
diff --git a/drivers/staging/android/ion/hisilicon/Makefile b/drivers/staging/android/ion/hisilicon/Makefile
new file mode 100644 (file)
index 0000000..2a89414
--- /dev/null
@@ -0,0 +1 @@
+obj-$(CONFIG_HI6220_ION) += hi6220_ion.o
diff --git a/drivers/staging/android/ion/hisilicon/hi6220_ion.c b/drivers/staging/android/ion/hisilicon/hi6220_ion.c
new file mode 100644 (file)
index 0000000..e3c07b2
--- /dev/null
@@ -0,0 +1,223 @@
+/*
+ * Hisilicon Hi6220 ION Driver
+ *
+ * Copyright (c) 2015 Hisilicon Limited.
+ *
+ * Author: Chen Feng <puck.chen@hisilicon.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#define pr_fmt(fmt) "Ion: " fmt
+
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/of.h>
+#include <linux/mm.h>
+#include "../ion_priv.h"
+#include "../ion.h"
+
+struct hi6220_ion_type_table {
+       const char *name;
+       enum ion_heap_type type;
+};
+
+static struct hi6220_ion_type_table ion_type_table[] = {
+       {"ion_system", ION_HEAP_TYPE_SYSTEM},
+       {"ion_system_contig", ION_HEAP_TYPE_SYSTEM_CONTIG},
+       {"ion_carveout", ION_HEAP_TYPE_CARVEOUT},
+       {"ion_chunk", ION_HEAP_TYPE_CHUNK},
+       {"ion_dma", ION_HEAP_TYPE_DMA},
+       {"ion_custom", ION_HEAP_TYPE_CUSTOM},
+};
+
+static struct ion_device *idev;
+static int num_heaps;
+static struct ion_heap **heaps;
+static struct ion_platform_heap **heaps_data;
+
+static int get_type_by_name(const char *name, enum ion_heap_type *type)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(ion_type_table); i++) {
+               if (strncmp(name, ion_type_table[i].name, strlen(name)))
+                       continue;
+
+               *type = ion_type_table[i].type;
+               return 0;
+       }
+
+       return -EINVAL;
+}
+
+static int hi6220_set_platform_data(struct platform_device *pdev)
+{
+       unsigned int base;
+       unsigned int size;
+       unsigned int id;
+       const char *heap_name;
+       const char *type_name;
+       enum ion_heap_type type;
+       int ret;
+       struct device_node *np;
+       struct ion_platform_heap *p_data;
+       const struct device_node *dt_node = pdev->dev.of_node;
+       int index = 0;
+
+       for_each_child_of_node(dt_node, np)
+               num_heaps++;
+
+       heaps_data = devm_kzalloc(&pdev->dev,
+                                 sizeof(struct ion_platform_heap *) *
+                                 num_heaps,
+                                 GFP_KERNEL);
+       if (!heaps_data)
+               return -ENOMEM;
+
+       for_each_child_of_node(dt_node, np) {
+               ret = of_property_read_string(np, "heap-name", &heap_name);
+               if (ret < 0) {
+                       pr_err("check the name of node %s\n", np->name);
+                       continue;
+               }
+
+               ret = of_property_read_u32(np, "heap-id", &id);
+               if (ret < 0) {
+                       pr_err("check the id %s\n", np->name);
+                       continue;
+               }
+
+               ret = of_property_read_u32(np, "heap-base", &base);
+               if (ret < 0) {
+                       pr_err("check the base of node %s\n", np->name);
+                       continue;
+               }
+
+               ret = of_property_read_u32(np, "heap-size", &size);
+               if (ret < 0) {
+                       pr_err("check the size of node %s\n", np->name);
+                       continue;
+               }
+
+               ret = of_property_read_string(np, "heap-type", &type_name);
+               if (ret < 0) {
+                       pr_err("check the type of node %s\n", np->name);
+                       continue;
+               }
+
+               ret = get_type_by_name(type_name, &type);
+               if (ret < 0) {
+                       pr_err("type name error %s!\n", type_name);
+                       continue;
+               }
+               pr_info("heap index %d : name %s base 0x%x size 0x%x id %d type %d\n",
+                       index, heap_name, base, size, id, type);
+
+               p_data = devm_kzalloc(&pdev->dev,
+                                     sizeof(struct ion_platform_heap),
+                                     GFP_KERNEL);
+               if (!p_data)
+                       return -ENOMEM;
+
+               p_data->name = heap_name;
+               p_data->base = base;
+               p_data->size = size;
+               p_data->id = id;
+               p_data->type = type;
+
+               heaps_data[index] = p_data;
+               index++;
+       }
+       return 0;
+}
+
+static int hi6220_ion_probe(struct platform_device *pdev)
+{
+       int i;
+       int err;
+       static struct ion_platform_heap *p_heap;
+
+       idev = ion_device_create(NULL);
+       err = hi6220_set_platform_data(pdev);
+       if (err) {
+               pr_err("ion set platform data error!\n");
+               goto err_free_idev;
+       }
+       heaps = devm_kzalloc(&pdev->dev,
+                            sizeof(struct ion_heap *) * num_heaps,
+                            GFP_KERNEL);
+       if (!heaps) {
+               err = -ENOMEM;
+               goto err_free_idev;
+       }
+
+       /*
+        * create the heaps as specified in the dts file
+        */
+       for (i = 0; i < num_heaps; i++) {
+               p_heap = heaps_data[i];
+               heaps[i] = ion_heap_create(p_heap);
+               if (IS_ERR_OR_NULL(heaps[i])) {
+                       err = PTR_ERR(heaps[i]);
+                       goto err_free_heaps;
+               }
+
+               ion_device_add_heap(idev, heaps[i]);
+
+               pr_info("%s: adding heap %s of type %d with %lx@%lx\n",
+                       __func__, p_heap->name, p_heap->type,
+                       p_heap->base, (unsigned long)p_heap->size);
+       }
+       return err;
+
+err_free_heaps:
+       for (i = 0; i < num_heaps; ++i) {
+               ion_heap_destroy(heaps[i]);
+               heaps[i] = NULL;
+       }
+err_free_idev:
+       ion_device_destroy(idev);
+
+       return err;
+}
+
+static int hi6220_ion_remove(struct platform_device *pdev)
+{
+       int i;
+
+       for (i = 0; i < num_heaps; i++) {
+               ion_heap_destroy(heaps[i]);
+               heaps[i] = NULL;
+       }
+       ion_device_destroy(idev);
+
+       return 0;
+}
+
+static const struct of_device_id hi6220_ion_match_table[] = {
+       {.compatible = "hisilicon,hi6220-ion"},
+       {},
+};
+
+static struct platform_driver hi6220_ion_driver = {
+       .probe = hi6220_ion_probe,
+       .remove = hi6220_ion_remove,
+       .driver = {
+               .name = "ion-hi6220",
+               .of_match_table = hi6220_ion_match_table,
+       },
+};
+
+static int __init hi6220_ion_init(void)
+{
+       int ret;
+
+       ret = platform_driver_register(&hi6220_ion_driver);
+       return ret;
+}
+
+subsys_initcall(hi6220_ion_init);
index e0c1acb2ba69c49b674ca9ec1827842a75e9b7f8..ed43796b5b582ddee27c86d659aa6503faee4de3 100644 (file)
@@ -188,7 +188,7 @@ static void fence_check_cb_func(struct fence *f, struct fence_cb *cb)
 }
 
 /* TODO: implement a create which takes more that one sync_pt */
-struct sync_fence *sync_fence_create(const char *name, struct sync_pt *pt)
+struct sync_fence *sync_fence_create_dma(const char *name, struct fence *pt)
 {
        struct sync_fence *fence;
 
@@ -199,16 +199,21 @@ struct sync_fence *sync_fence_create(const char *name, struct sync_pt *pt)
        fence->num_fences = 1;
        atomic_set(&fence->status, 1);
 
-       fence->cbs[0].sync_pt = &pt->base;
+       fence->cbs[0].sync_pt = pt;
        fence->cbs[0].fence = fence;
-       if (fence_add_callback(&pt->base, &fence->cbs[0].cb,
-                              fence_check_cb_func))
+       if (fence_add_callback(pt, &fence->cbs[0].cb, fence_check_cb_func))
                atomic_dec(&fence->status);
 
        sync_fence_debug_add(fence);
 
        return fence;
 }
+EXPORT_SYMBOL(sync_fence_create_dma);
+
+struct sync_fence *sync_fence_create(const char *name, struct sync_pt *pt)
+{
+       return sync_fence_create_dma(name, &pt->base);
+}
 EXPORT_SYMBOL(sync_fence_create);
 
 struct sync_fence *sync_fence_fdget(int fd)
@@ -519,12 +524,10 @@ static const struct fence_ops android_fence_ops = {
 static void sync_fence_free(struct kref *kref)
 {
        struct sync_fence *fence = container_of(kref, struct sync_fence, kref);
-       int i, status = atomic_read(&fence->status);
+       int i;
 
        for (i = 0; i < fence->num_fences; ++i) {
-               if (status)
-                       fence_remove_callback(fence->cbs[i].sync_pt,
-                                             &fence->cbs[i].cb);
+               fence_remove_callback(fence->cbs[i].sync_pt, &fence->cbs[i].cb);
                fence_put(fence->cbs[i].sync_pt);
        }
 
index 61f8a3aede96ead8641b00c74aa8bbd38a1f00a7..afa0752275a722ed69f6161f3e79ed1b21082ad0 100644 (file)
@@ -254,6 +254,16 @@ void sync_pt_free(struct sync_pt *pt);
  */
 struct sync_fence *sync_fence_create(const char *name, struct sync_pt *pt);
 
+/**
+ * sync_fence_create_dma() - creates a sync fence from dma-fence
+ * @name:      name of fence to create
+ * @pt:        dma-fence to add to the fence
+ *
+ * Creates a fence containg @pt.  Once this is called, the fence takes
+ * ownership of @pt.
+ */
+struct sync_fence *sync_fence_create_dma(const char *name, struct fence *pt);
+
 /*
  * API for sync_fence consumers
  */
index 91ed2c4cff45b1d42e8679cdb4fbcf0682d10789..f45d13cdd42b902f32543e37fbf2173cb0cb6dba 100644 (file)
@@ -82,36 +82,42 @@ static const char *sync_status_str(int status)
        return "error";
 }
 
-static void sync_print_pt(struct seq_file *s, struct sync_pt *pt, bool fence)
+static void sync_print_pt(struct seq_file *s, struct fence *pt, bool fence)
 {
        int status = 1;
-       struct sync_timeline *parent = sync_pt_parent(pt);
 
-       if (fence_is_signaled_locked(&pt->base))
-               status = pt->base.status;
+       if (fence_is_signaled_locked(pt))
+               status = pt->status;
 
        seq_printf(s, "  %s%spt %s",
-                  fence ? parent->name : "",
+                  fence && pt->ops->get_timeline_name ?
+                  pt->ops->get_timeline_name(pt) : "",
                   fence ? "_" : "",
                   sync_status_str(status));
 
        if (status <= 0) {
                struct timespec64 ts64 =
-                       ktime_to_timespec64(pt->base.timestamp);
+                       ktime_to_timespec64(pt->timestamp);
 
                seq_printf(s, "@%lld.%09ld", (s64)ts64.tv_sec, ts64.tv_nsec);
        }
 
-       if (parent->ops->timeline_value_str &&
-           parent->ops->pt_value_str) {
+       if ((!fence || pt->ops->timeline_value_str) &&
+           pt->ops->fence_value_str) {
                char value[64];
+               bool success;
 
-               parent->ops->pt_value_str(pt, value, sizeof(value));
-               seq_printf(s, ": %s", value);
-               if (fence) {
-                       parent->ops->timeline_value_str(parent, value,
-                                                   sizeof(value));
-                       seq_printf(s, " / %s", value);
+               pt->ops->fence_value_str(pt, value, sizeof(value));
+               success = strlen(value);
+
+               if (success)
+                       seq_printf(s, ": %s", value);
+
+               if (success && fence) {
+                       pt->ops->timeline_value_str(pt, value, sizeof(value));
+
+                       if (strlen(value))
+                               seq_printf(s, " / %s", value);
                }
        }
 
@@ -138,7 +144,7 @@ static void sync_print_obj(struct seq_file *s, struct sync_timeline *obj)
        list_for_each(pos, &obj->child_list_head) {
                struct sync_pt *pt =
                        container_of(pos, struct sync_pt, child_list);
-               sync_print_pt(s, pt, false);
+               sync_print_pt(s, &pt->base, false);
        }
        spin_unlock_irqrestore(&obj->child_list_lock, flags);
 }
@@ -153,11 +159,7 @@ static void sync_print_fence(struct seq_file *s, struct sync_fence *fence)
                   sync_status_str(atomic_read(&fence->status)));
 
        for (i = 0; i < fence->num_fences; ++i) {
-               struct sync_pt *pt =
-                       container_of(fence->cbs[i].sync_pt,
-                                    struct sync_pt, base);
-
-               sync_print_pt(s, pt, true);
+               sync_print_pt(s, fence->cbs[i].sync_pt, true);
        }
 
        spin_lock_irqsave(&fence->wq.lock, flags);
index 945c85a10793074cb7ec246d0ebc16f5eef30f8b..e7255f811611cff32c52a0caf88ab024c955c232 100644 (file)
@@ -772,6 +772,14 @@ config COMEDI_ADV_PCI1724
          To compile this driver as a module, choose M here: the module will be
          called adv_pci1724.
 
+config COMEDI_ADV_PCI1760
+       tristate "Advantech PCI-1760 support"
+       ---help---
+         Enable support for Advantech PCI-1760 board.
+
+         To compile this driver as a module, choose M here: the module will be
+         called adv_pci1760.
+
 config COMEDI_ADV_PCI_DIO
        tristate "Advantech PCI DIO card support"
        select COMEDI_8254
@@ -779,8 +787,8 @@ config COMEDI_ADV_PCI_DIO
        ---help---
          Enable support for Advantech PCI DIO cards
          PCI-1730, PCI-1733, PCI-1734, PCI-1735U, PCI-1736UP, PCI-1739U,
-         PCI-1750, PCI-1751, PCI-1752, PCI-1753/E, PCI-1754, PCI-1756,
-         PCI-1760 and PCI-1762
+         PCI-1750, PCI-1751, PCI-1752, PCI-1753/E, PCI-1754, PCI-1756 and
+         PCI-1762
 
          To compile this driver as a module, choose M here: the module will be
          called adv_pci_dio.
index 66edda190b75cd8ebf04c30030fa9675ceaf385e..83bd309d011b9f6cd07ea3ddb97059c9c96f017f 100644 (file)
@@ -1,20 +1,20 @@
 /*
   include/comedi.h (installed as /usr/include/comedi.h)
   header file for comedi
-
   COMEDI - Linux Control and Measurement Device Interface
   Copyright (C) 1998-2001 David A. Schleef <ds@schleef.org>
-
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU Lesser General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.
-
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
-*/
* include/comedi.h (installed as /usr/include/comedi.h)
* header file for comedi
+ *
* COMEDI - Linux Control and Measurement Device Interface
* Copyright (C) 1998-2001 David A. Schleef <ds@schleef.org>
+ *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
+ */
 
 #ifndef _COMEDI_H
 #define _COMEDI_H
@@ -28,9 +28,9 @@
 #define COMEDI_MAJOR 98
 
 /*
  maximum number of minor devices.  This can be increased, although
  kernel structures are currently statically allocated, thus you
  don't want this to be much more than you actually use.
* maximum number of minor devices.  This can be increased, although
* kernel structures are currently statically allocated, thus you
* don't want this to be much more than you actually use.
  */
 #define COMEDI_NDEVICES 16
 
 /* packs and unpacks a channel/range number */
 
 #define CR_PACK(chan, rng, aref)                                       \
-       ((((aref)&0x3)<<24) | (((rng)&0xff)<<16) | (chan))
+       ((((aref) & 0x3) << 24) | (((rng) & 0xff) << 16) | (chan))
 #define CR_PACK_FLAGS(chan, range, aref, flags)                                \
        (CR_PACK(chan, range, aref) | ((flags) & CR_FLAGS_MASK))
 
-#define CR_CHAN(a)     ((a)&0xffff)
-#define CR_RANGE(a)    (((a)>>16)&0xff)
-#define CR_AREF(a)     (((a)>>24)&0x03)
+#define CR_CHAN(a)     ((a) & 0xffff)
+#define CR_RANGE(a)    (((a) >> 16) & 0xff)
+#define CR_AREF(a)     (((a) >> 24) & 0x03)
 
 #define CR_FLAGS_MASK  0xfc000000
-#define CR_ALT_FILTER  (1<<26)
+#define CR_ALT_FILTER  (1 << 26)
 #define CR_DITHER      CR_ALT_FILTER
 #define CR_DEGLITCH    CR_ALT_FILTER
-#define CR_ALT_SOURCE  (1<<27)
-#define CR_EDGE                (1<<30)
-#define CR_INVERT      (1<<31)
+#define CR_ALT_SOURCE  (1 << 27)
+#define CR_EDGE                (1 << 30)
+#define CR_INVERT      (1 << 31)
 
 #define AREF_GROUND    0x00    /* analog ref = analog ground */
 #define AREF_COMMON    0x01    /* analog ref = analog common */
 
 #define INSN_READ              (0 | INSN_MASK_READ)
 #define INSN_WRITE             (1 | INSN_MASK_WRITE)
-#define INSN_BITS              (2 | INSN_MASK_READ|INSN_MASK_WRITE)
-#define INSN_CONFIG            (3 | INSN_MASK_READ|INSN_MASK_WRITE)
-#define INSN_GTOD              (4 | INSN_MASK_READ|INSN_MASK_SPECIAL)
-#define INSN_WAIT              (5 | INSN_MASK_WRITE|INSN_MASK_SPECIAL)
-#define INSN_INTTRIG           (6 | INSN_MASK_WRITE|INSN_MASK_SPECIAL)
+#define INSN_BITS              (2 | INSN_MASK_READ | INSN_MASK_WRITE)
+#define INSN_CONFIG            (3 | INSN_MASK_READ | INSN_MASK_WRITE)
+#define INSN_GTOD              (4 | INSN_MASK_READ | INSN_MASK_SPECIAL)
+#define INSN_WAIT              (5 | INSN_MASK_WRITE | INSN_MASK_SPECIAL)
+#define INSN_INTTRIG           (6 | INSN_MASK_WRITE | INSN_MASK_SPECIAL)
 
 /* trigger flags */
 /* These flags are used in comedi_trig structures */
@@ -279,7 +279,8 @@ enum configuration_ids {
        INSN_CONFIG_SET_OTHER_SRC = 2005, /* Set other source */
        /* INSN_CONFIG_GET_OTHER_SRC = 2006,*//* Get other source */
        /* Get size in bytes of subdevice's on-board fifos used during
-        * streaming input/output */
+        * streaming input/output
+        */
        INSN_CONFIG_GET_HARDWARE_BUFFER_SIZE = 2006,
        INSN_CONFIG_SET_COUNTER_MODE = 4097,
        /* INSN_CONFIG_8254_SET_MODE is deprecated */
@@ -292,7 +293,8 @@ enum configuration_ids {
        INSN_CONFIG_PWM_GET_PERIOD = 5001,      /* gets frequency */
        INSN_CONFIG_GET_PWM_STATUS = 5002,      /* is it running? */
        /* sets H bridge: duty cycle and sign bit for a relay at the
-        * same time */
+        * same time
+        */
        INSN_CONFIG_PWM_SET_H_BRIDGE = 5003,
        /* gets H bridge data: duty cycle and the sign bit */
        INSN_CONFIG_PWM_GET_H_BRIDGE = 5004
@@ -502,13 +504,13 @@ struct comedi_bufinfo {
 
 /* range stuff */
 
-#define __RANGE(a, b)  ((((a)&0xffff)<<16)|((b)&0xffff))
+#define __RANGE(a, b)  ((((a) & 0xffff) << 16) | ((b) & 0xffff))
 
-#define RANGE_OFFSET(a)                (((a)>>16)&0xffff)
-#define RANGE_LENGTH(b)                ((b)&0xffff)
+#define RANGE_OFFSET(a)                (((a) >> 16) & 0xffff)
+#define RANGE_LENGTH(b)                ((b) & 0xffff)
 
-#define RF_UNIT(flags)         ((flags)&0xff)
-#define RF_EXTERNAL            (1<<8)
+#define RF_UNIT(flags)         ((flags) & 0xff)
+#define RF_EXTERNAL            (1 << 8)
 
 #define UNIT_volt              0
 #define UNIT_mA                        1
@@ -521,23 +523,22 @@ struct comedi_bufinfo {
 /**********************************************************/
 
 /*
-  8254 specific configuration.
-
-  It supports two config commands:
-
-  0 ID: INSN_CONFIG_SET_COUNTER_MODE
-  1 8254 Mode
-    I8254_MODE0, I8254_MODE1, ..., I8254_MODE5
-    OR'ed with:
-    I8254_BCD, I8254_BINARY
-
-  0 ID: INSN_CONFIG_8254_READ_STATUS
-  1 <-- Status byte returned here.
-    B7 = Output
-    B6 = NULL Count
-    B5 - B0 Current mode.
-
-*/
+ * 8254 specific configuration.
+ *
+ * It supports two config commands:
+ *
+ * 0 ID: INSN_CONFIG_SET_COUNTER_MODE
+ * 1 8254 Mode
+ * I8254_MODE0, I8254_MODE1, ..., I8254_MODE5
+ * OR'ed with:
+ * I8254_BCD, I8254_BINARY
+ *
+ * 0 ID: INSN_CONFIG_8254_READ_STATUS
+ * 1 <-- Status byte returned here.
+ * B7 = Output
+ * B6 = NULL Count
+ * B5 - B0 Current mode.
+ */
 
 enum i8254_mode {
        I8254_MODE0 = (0 << 1), /* Interrupt on terminal count */
@@ -545,18 +546,20 @@ enum i8254_mode {
        I8254_MODE2 = (2 << 1), /* Rate generator */
        I8254_MODE3 = (3 << 1), /* Square wave mode */
        I8254_MODE4 = (4 << 1), /* Software triggered strobe */
-       I8254_MODE5 = (5 << 1), /* Hardware triggered strobe
-                                * (retriggerable) */
-       I8254_BCD = 1,          /* use binary-coded decimal instead of binary
-                                * (pretty useless) */
+       /* Hardware triggered strobe (retriggerable) */
+       I8254_MODE5 = (5 << 1),
+       /* Use binary-coded decimal instead of binary (pretty useless) */
+       I8254_BCD = 1,
        I8254_BINARY = 0
 };
 
 #define NI_USUAL_PFI_SELECT(x) (((x) < 10) ? (0x1 + (x)) : (0xb + (x)))
 #define NI_USUAL_RTSI_SELECT(x)        (((x) < 7) ? (0xb + (x)) : 0x1b)
 
-/* mode bits for NI general-purpose counters, set with
- * INSN_CONFIG_SET_COUNTER_MODE */
+/*
+ * mode bits for NI general-purpose counters, set with
+ * INSN_CONFIG_SET_COUNTER_MODE
+ */
 #define NI_GPCT_COUNTING_MODE_SHIFT 16
 #define NI_GPCT_INDEX_PHASE_BITSHIFT 20
 #define NI_GPCT_COUNTING_DIRECTION_SHIFT 24
@@ -624,8 +627,10 @@ enum ni_gpct_mode_bits {
        NI_GPCT_INVERT_OUTPUT_BIT = 0x20000000
 };
 
-/* Bits for setting a clock source with
- * INSN_CONFIG_SET_CLOCK_SRC when using NI general-purpose counters. */
+/*
+ * Bits for setting a clock source with
+ * INSN_CONFIG_SET_CLOCK_SRC when using NI general-purpose counters.
+ */
 enum ni_gpct_clock_source_bits {
        NI_GPCT_CLOCK_SRC_SELECT_MASK = 0x3f,
        NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS = 0x0,
@@ -656,9 +661,11 @@ enum ni_gpct_clock_source_bits {
 /* no pfi on NI 660x */
 #define NI_GPCT_PFI_CLOCK_SRC_BITS(x)          (0x20 + (x))
 
-/* Possibilities for setting a gate source with
-INSN_CONFIG_SET_GATE_SRC when using NI general-purpose counters.
-May be bitwise-or'd with CR_EDGE or CR_INVERT. */
+/*
+ * Possibilities for setting a gate source with
+ * INSN_CONFIG_SET_GATE_SRC when using NI general-purpose counters.
+ * May be bitwise-or'd with CR_EDGE or CR_INVERT.
+ */
 enum ni_gpct_gate_select {
        /* m-series gates */
        NI_GPCT_TIMESTAMP_MUX_GATE_SELECT = 0x0,
@@ -675,9 +682,11 @@ enum ni_gpct_gate_select {
        /* more gates for 660x "second gate" */
        NI_GPCT_UP_DOWN_PIN_i_GATE_SELECT = 0x201,
        NI_GPCT_SELECTED_GATE_GATE_SELECT = 0x21e,
-       /* m-series "second gate" sources are unknown,
+       /*
+        * m-series "second gate" sources are unknown,
         * we should add them here with an offset of 0x300 when
-        * known. */
+        * known.
+        */
        NI_GPCT_DISABLED_GATE_SELECT = 0x8000,
 };
 
@@ -686,8 +695,10 @@ enum ni_gpct_gate_select {
 #define NI_GPCT_PFI_GATE_SELECT(x)             NI_USUAL_PFI_SELECT(x)
 #define NI_GPCT_UP_DOWN_PIN_GATE_SELECT(x)     (0x202 + (x))
 
-/* Possibilities for setting a source with
-INSN_CONFIG_SET_OTHER_SRC when using NI general-purpose counters. */
+/*
+ * Possibilities for setting a source with
+ * INSN_CONFIG_SET_OTHER_SRC when using NI general-purpose counters.
+ */
 enum ni_gpct_other_index {
        NI_GPCT_SOURCE_ENCODER_A,
        NI_GPCT_SOURCE_ENCODER_B,
@@ -702,18 +713,24 @@ enum ni_gpct_other_select {
 
 #define NI_GPCT_PFI_OTHER_SELECT(x)    NI_USUAL_PFI_SELECT(x)
 
-/* start sources for ni general-purpose counters for use with
-INSN_CONFIG_ARM */
+/*
+ * start sources for ni general-purpose counters for use with
+ * INSN_CONFIG_ARM
+ */
 enum ni_gpct_arm_source {
        NI_GPCT_ARM_IMMEDIATE = 0x0,
-       NI_GPCT_ARM_PAIRED_IMMEDIATE = 0x1, /* Start both the counter
-                                            * and the adjacent paired
-                                            * counter simultaneously */
-       /* NI doesn't document bits for selecting hardware arm triggers.
+       /*
+        * Start both the counter and the adjacent pared
+        * counter simultaneously
+        */
+       NI_GPCT_ARM_PAIRED_IMMEDIATE = 0x1,
+       /*
+        * NI doesn't document bits for selecting hardware arm triggers.
         * If the NI_GPCT_ARM_UNKNOWN bit is set, we will pass the least
         * significant bits (3 bits for 660x or 5 bits for m-series)
         * through to the hardware.  This will at least allow someone to
-        * figure out what the bits do later. */
+        * figure out what the bits do later.
+        */
        NI_GPCT_ARM_UNKNOWN = 0x1000,
 };
 
@@ -728,8 +745,10 @@ enum ni_gpct_filter_select {
        NI_GPCT_FILTER_2x_TIMEBASE_3 = 0x6
 };
 
-/* PFI digital filtering options for ni m-series for use with
- * INSN_CONFIG_FILTER. */
+/*
+ * PFI digital filtering options for ni m-series for use with
+ * INSN_CONFIG_FILTER.
+ */
 enum ni_pfi_filter_select {
        NI_PFI_FILTER_OFF = 0x0,
        NI_PFI_FILTER_125ns = 0x1,
@@ -740,9 +759,11 @@ enum ni_pfi_filter_select {
 /* master clock sources for ni mio boards and INSN_CONFIG_SET_CLOCK_SRC */
 enum ni_mio_clock_source {
        NI_MIO_INTERNAL_CLOCK = 0,
-       NI_MIO_RTSI_CLOCK = 1,  /* doesn't work for m-series, use
-                                  NI_MIO_PLL_RTSI_CLOCK() */
-       /* the NI_MIO_PLL_* sources are m-series only */
+       /*
+        * Doesn't work for m-series, use NI_MIO_PLL_RTSI_CLOCK()
+        * the NI_MIO_PLL_* sources are m-series only
+        */
+       NI_MIO_RTSI_CLOCK = 1,
        NI_MIO_PLL_PXI_STAR_TRIGGER_CLOCK = 2,
        NI_MIO_PLL_PXI10_CLOCK = 3,
        NI_MIO_PLL_RTSI0_CLOCK = 4
@@ -750,9 +771,11 @@ enum ni_mio_clock_source {
 
 #define NI_MIO_PLL_RTSI_CLOCK(x)       (NI_MIO_PLL_RTSI0_CLOCK + (x))
 
-/* Signals which can be routed to an NI RTSI pin with INSN_CONFIG_SET_ROUTING.
- The numbers assigned are not arbitrary, they correspond to the bits required
- to program the board. */
+/*
+ * Signals which can be routed to an NI RTSI pin with INSN_CONFIG_SET_ROUTING.
+ * The numbers assigned are not arbitrary, they correspond to the bits required
+ * to program the board.
+ */
 enum ni_rtsi_routing {
        NI_RTSI_OUTPUT_ADR_START1 = 0,
        NI_RTSI_OUTPUT_ADR_START2 = 1,
@@ -763,17 +786,19 @@ enum ni_rtsi_routing {
        NI_RTSI_OUTPUT_G_GATE0 = 6,
        NI_RTSI_OUTPUT_RGOUT0 = 7,
        NI_RTSI_OUTPUT_RTSI_BRD_0 = 8,
-       NI_RTSI_OUTPUT_RTSI_OSC = 12    /* pre-m-series always have RTSI
-                                        * clock on line 7 */
+       /* Pre-m-series always have RTSI clock on line 7 */
+       NI_RTSI_OUTPUT_RTSI_OSC = 12
 };
 
 #define NI_RTSI_OUTPUT_RTSI_BRD(x)     (NI_RTSI_OUTPUT_RTSI_BRD_0 + (x))
 
-/* Signals which can be routed to an NI PFI pin on an m-series board with
+/*
+ * Signals which can be routed to an NI PFI pin on an m-series board with
  * INSN_CONFIG_SET_ROUTING.  These numbers are also returned by
  * INSN_CONFIG_GET_ROUTING on pre-m-series boards, even though their routing
  * cannot be changed.  The numbers assigned are not arbitrary, they correspond
- * to the bits required to program the board. */
+ * to the bits required to program the board.
+ */
 enum ni_pfi_routing {
        NI_PFI_OUTPUT_PFI_DEFAULT = 0,
        NI_PFI_OUTPUT_AI_START1 = 1,
@@ -803,20 +828,24 @@ enum ni_pfi_routing {
 
 #define NI_PFI_OUTPUT_RTSI(x)          (NI_PFI_OUTPUT_RTSI0 + (x))
 
-/* Signals which can be routed to output on a NI PFI pin on a 660x board
- with INSN_CONFIG_SET_ROUTING.  The numbers assigned are
- not arbitrary, they correspond to the bits required
- to program the board.  Lines 0 to 7 can only be set to
- NI_660X_PFI_OUTPUT_DIO.  Lines 32 to 39 can only be set to
- NI_660X_PFI_OUTPUT_COUNTER. */
+/*
+ * Signals which can be routed to output on a NI PFI pin on a 660x board
+ * with INSN_CONFIG_SET_ROUTING.  The numbers assigned are
+ * not arbitrary, they correspond to the bits required
+ * to program the board.  Lines 0 to 7 can only be set to
+ * NI_660X_PFI_OUTPUT_DIO.  Lines 32 to 39 can only be set to
+ * NI_660X_PFI_OUTPUT_COUNTER.
+ */
 enum ni_660x_pfi_routing {
        NI_660X_PFI_OUTPUT_COUNTER = 1, /* counter */
        NI_660X_PFI_OUTPUT_DIO = 2,     /* static digital output */
 };
 
-/* NI External Trigger lines.  These values are not arbitrary, but are related
+/*
+ * NI External Trigger lines.  These values are not arbitrary, but are related
  * to the bits required to program the board (offset by 1 for historical
- * reasons). */
+ * reasons).
+ */
 #define NI_EXT_PFI(x)                  (NI_USUAL_PFI_SELECT(x) - 1)
 #define NI_EXT_RTSI(x)                 (NI_USUAL_RTSI_SELECT(x) - 1)
 
@@ -827,9 +856,11 @@ enum comedi_counter_status_flags {
        COMEDI_COUNTER_TERMINAL_COUNT = 0x4,
 };
 
-/* Clock sources for CDIO subdevice on NI m-series boards.  Used as the
+/*
+ * Clock sources for CDIO subdevice on NI m-series boards.  Used as the
  * scan_begin_arg for a comedi_command. These sources may also be bitwise-or'd
- * with CR_INVERT to change polarity. */
+ * with CR_INVERT to change polarity.
+ */
 enum ni_m_series_cdio_scan_begin_src {
        NI_CDIO_SCAN_BEGIN_SRC_GROUND = 0,
        NI_CDIO_SCAN_BEGIN_SRC_AI_START = 18,
@@ -846,38 +877,50 @@ enum ni_m_series_cdio_scan_begin_src {
 #define NI_CDIO_SCAN_BEGIN_SRC_PFI(x)  NI_USUAL_PFI_SELECT(x)
 #define NI_CDIO_SCAN_BEGIN_SRC_RTSI(x) NI_USUAL_RTSI_SELECT(x)
 
-/* scan_begin_src for scan_begin_arg==TRIG_EXT with analog output command on NI
+/*
+ * scan_begin_src for scan_begin_arg==TRIG_EXT with analog output command on NI
  * boards.  These scan begin sources can also be bitwise-or'd with CR_INVERT to
- * change polarity. */
+ * change polarity.
+ */
 #define NI_AO_SCAN_BEGIN_SRC_PFI(x)    NI_USUAL_PFI_SELECT(x)
 #define NI_AO_SCAN_BEGIN_SRC_RTSI(x)   NI_USUAL_RTSI_SELECT(x)
 
-/* Bits for setting a clock source with
- * INSN_CONFIG_SET_CLOCK_SRC when using NI frequency output subdevice. */
+/*
+ * Bits for setting a clock source with
+ * INSN_CONFIG_SET_CLOCK_SRC when using NI frequency output subdevice.
+ */
 enum ni_freq_out_clock_source_bits {
        NI_FREQ_OUT_TIMEBASE_1_DIV_2_CLOCK_SRC, /* 10 MHz */
        NI_FREQ_OUT_TIMEBASE_2_CLOCK_SRC        /* 100 KHz */
 };
 
-/* Values for setting a clock source with INSN_CONFIG_SET_CLOCK_SRC for
- * 8254 counter subdevices on Amplicon DIO boards (amplc_dio200 driver). */
+/*
+ * Values for setting a clock source with INSN_CONFIG_SET_CLOCK_SRC for
+ * 8254 counter subdevices on Amplicon DIO boards (amplc_dio200 driver).
+ */
 enum amplc_dio_clock_source {
-       AMPLC_DIO_CLK_CLKN,     /* per channel external clock
-                                  input/output pin (pin is only an
-                                  input when clock source set to this
-                                  value, otherwise it is an output) */
+       /*
+        * Per channel external clock
+        * input/output pin (pin is only an
+        * input when clock source set to this value,
+        * otherwise it is an output)
+        */
+       AMPLC_DIO_CLK_CLKN,
        AMPLC_DIO_CLK_10MHZ,    /* 10 MHz internal clock */
        AMPLC_DIO_CLK_1MHZ,     /* 1 MHz internal clock */
        AMPLC_DIO_CLK_100KHZ,   /* 100 kHz internal clock */
        AMPLC_DIO_CLK_10KHZ,    /* 10 kHz internal clock */
        AMPLC_DIO_CLK_1KHZ,     /* 1 kHz internal clock */
-       AMPLC_DIO_CLK_OUTNM1,   /* output of preceding counter channel
-                                  (for channel 0, preceding counter
-                                  channel is channel 2 on preceding
-                                  counter subdevice, for first counter
-                                  subdevice, preceding counter
-                                  subdevice is the last counter
-                                  subdevice) */
+       /*
+        * Output of preceding counter channel
+        * (for channel 0, preceding counter
+        * channel is channel 2 on preceding
+        * counter subdevice, for first counter
+        * subdevice, preceding counter
+        * subdevice is the last counter
+        * subdevice)
+        */
+       AMPLC_DIO_CLK_OUTNM1,
        AMPLC_DIO_CLK_EXT,      /* per chip external input pin */
        /* the following are "enhanced" clock sources for PCIe models */
        AMPLC_DIO_CLK_VCC,      /* clock input HIGH */
@@ -886,35 +929,39 @@ enum amplc_dio_clock_source {
        AMPLC_DIO_CLK_20MHZ     /* 20 MHz internal clock */
 };
 
-/* Values for setting a clock source with INSN_CONFIG_SET_CLOCK_SRC for
- * timer subdevice on some Amplicon DIO PCIe boards (amplc_dio200 driver). */
+/*
+ * Values for setting a clock source with INSN_CONFIG_SET_CLOCK_SRC for
+ * timer subdevice on some Amplicon DIO PCIe boards (amplc_dio200 driver).
+ */
 enum amplc_dio_ts_clock_src {
        AMPLC_DIO_TS_CLK_1GHZ,  /* 1 ns period with 20 ns granularity */
        AMPLC_DIO_TS_CLK_1MHZ,  /* 1 us period */
        AMPLC_DIO_TS_CLK_1KHZ   /* 1 ms period */
 };
 
-/* Values for setting a gate source with INSN_CONFIG_SET_GATE_SRC for
- * 8254 counter subdevices on Amplicon DIO boards (amplc_dio200 driver). */
+/*
+ * Values for setting a gate source with INSN_CONFIG_SET_GATE_SRC for
+ * 8254 counter subdevices on Amplicon DIO boards (amplc_dio200 driver).
+ */
 enum amplc_dio_gate_source {
        AMPLC_DIO_GAT_VCC,      /* internal high logic level */
        AMPLC_DIO_GAT_GND,      /* internal low logic level */
        AMPLC_DIO_GAT_GATN,     /* per channel external gate input */
-       AMPLC_DIO_GAT_NOUTNM2,  /* negated output of counter channel
-                                  minus 2 (for channels 0 or 1,
-                                  channel minus 2 is channel 1 or 2 on
-                                  the preceding counter subdevice, for
-                                  the first counter subdevice the
-                                  preceding counter subdevice is the
-                                  last counter subdevice) */
+       /*
+        * negated output of counter channel minus 2
+        * (for channels 0 or 1, channel minus 2 is channel 1 or 2 on
+        * the preceding counter subdevice, for the first counter subdevice
+        * the preceding counter subdevice is the last counter subdevice)
+        */
+       AMPLC_DIO_GAT_NOUTNM2,
        AMPLC_DIO_GAT_RESERVED4,
        AMPLC_DIO_GAT_RESERVED5,
        AMPLC_DIO_GAT_RESERVED6,
        AMPLC_DIO_GAT_RESERVED7,
        /* the following are "enhanced" gate sources for PCIe models */
        AMPLC_DIO_GAT_NGATN = 6, /* negated per channel gate input */
-       AMPLC_DIO_GAT_OUTNM2,   /* non-negated output of counter
-                                  channel minus 2 */
+       /* non-negated output of counter channel minus 2 */
+       AMPLC_DIO_GAT_OUTNM2,
        AMPLC_DIO_GAT_PAT_PRESENT, /* "pattern present" signal */
        AMPLC_DIO_GAT_PAT_OCCURRED, /* "pattern occurred" latched */
        AMPLC_DIO_GAT_PAT_GONE, /* "pattern gone away" latched */
index 7b4af519e17e1a92e9b6d594ea95fad753af5a36..d57fadef47fcf8e8b363e3002690d606c8bdf16b 100644 (file)
@@ -2303,11 +2303,13 @@ static ssize_t comedi_write(struct file *file, const char __user *buf,
 {
        struct comedi_subdevice *s;
        struct comedi_async *async;
-       int n, m, count = 0, retval = 0;
+       unsigned int n, m;
+       ssize_t count = 0;
+       int retval = 0;
        DECLARE_WAITQUEUE(wait, current);
        struct comedi_file *cfp = file->private_data;
        struct comedi_device *dev = cfp->dev;
-       bool on_wait_queue = false;
+       bool become_nonbusy = false;
        bool attach_locked;
        unsigned int old_detach_count;
 
@@ -2329,74 +2331,33 @@ static ssize_t comedi_write(struct file *file, const char __user *buf,
        }
 
        async = s->async;
-
-       if (!s->busy || !nbytes)
-               goto out;
-       if (s->busy != file) {
-               retval = -EACCES;
-               goto out;
-       }
-       if (!(async->cmd.flags & CMDF_WRITE)) {
+       if (s->busy != file || !(async->cmd.flags & CMDF_WRITE)) {
                retval = -EINVAL;
                goto out;
        }
 
        add_wait_queue(&async->wait_head, &wait);
-       on_wait_queue = true;
-       while (nbytes > 0 && !retval) {
+       while (count == 0 && !retval) {
                unsigned runflags;
+               unsigned int wp, n1, n2;
 
                set_current_state(TASK_INTERRUPTIBLE);
 
                runflags = comedi_get_subdevice_runflags(s);
                if (!comedi_is_runflags_running(runflags)) {
-                       if (count == 0) {
-                               struct comedi_subdevice *new_s;
-
-                               if (comedi_is_runflags_in_error(runflags))
-                                       retval = -EPIPE;
-                               else
-                                       retval = 0;
-                               /*
-                                * To avoid deadlock, cannot acquire dev->mutex
-                                * while dev->attach_lock is held.  Need to
-                                * remove task from the async wait queue before
-                                * releasing dev->attach_lock, as it might not
-                                * be valid afterwards.
-                                */
-                               remove_wait_queue(&async->wait_head, &wait);
-                               on_wait_queue = false;
-                               up_read(&dev->attach_lock);
-                               attach_locked = false;
-                               mutex_lock(&dev->mutex);
-                               /*
-                                * Become non-busy unless things have changed
-                                * behind our back.  Checking dev->detach_count
-                                * is unchanged ought to be sufficient (unless
-                                * there have been 2**32 detaches in the
-                                * meantime!), but check the subdevice pointer
-                                * as well just in case.
-                                */
-                               new_s = comedi_file_write_subdevice(file);
-                               if (dev->attached &&
-                                   old_detach_count == dev->detach_count &&
-                                   s == new_s && new_s->async == async)
-                                       do_become_nonbusy(dev, s);
-                               mutex_unlock(&dev->mutex);
-                       }
+                       if (comedi_is_runflags_in_error(runflags))
+                               retval = -EPIPE;
+                       if (retval || nbytes)
+                               become_nonbusy = true;
                        break;
                }
+               if (nbytes == 0)
+                       break;
 
-               n = nbytes;
-
-               m = n;
-               if (async->buf_write_ptr + m > async->prealloc_bufsz)
-                       m = async->prealloc_bufsz - async->buf_write_ptr;
+               /* Allocate all free buffer space. */
                comedi_buf_write_alloc(s, async->prealloc_bufsz);
-               if (m > comedi_buf_write_n_allocated(s))
-                       m = comedi_buf_write_n_allocated(s);
-               if (m < n)
-                       n = m;
+               m = comedi_buf_write_n_allocated(s);
+               n = min_t(size_t, m, nbytes);
 
                if (n == 0) {
                        if (file->f_flags & O_NONBLOCK) {
@@ -2408,21 +2369,22 @@ static ssize_t comedi_write(struct file *file, const char __user *buf,
                                retval = -ERESTARTSYS;
                                break;
                        }
-                       if (!s->busy)
-                               break;
-                       if (s->busy != file) {
-                               retval = -EACCES;
-                               break;
-                       }
-                       if (!(async->cmd.flags & CMDF_WRITE)) {
+                       if (s->busy != file ||
+                           !(async->cmd.flags & CMDF_WRITE)) {
                                retval = -EINVAL;
                                break;
                        }
                        continue;
                }
 
-               m = copy_from_user(async->prealloc_buf + async->buf_write_ptr,
-                                  buf, n);
+               wp = async->buf_write_ptr;
+               n1 = min(n, async->prealloc_bufsz - wp);
+               n2 = n - n1;
+               m = copy_from_user(async->prealloc_buf + wp, buf, n1);
+               if (m)
+                       m += n2;
+               else if (n2)
+                       m = copy_from_user(async->prealloc_buf, buf + n1, n2);
                if (m) {
                        n -= m;
                        retval = -EFAULT;
@@ -2433,12 +2395,38 @@ static ssize_t comedi_write(struct file *file, const char __user *buf,
                nbytes -= n;
 
                buf += n;
-               break;          /* makes device work like a pipe */
        }
-out:
-       if (on_wait_queue)
-               remove_wait_queue(&async->wait_head, &wait);
+       remove_wait_queue(&async->wait_head, &wait);
        set_current_state(TASK_RUNNING);
+       if (become_nonbusy && count == 0) {
+               struct comedi_subdevice *new_s;
+
+               /*
+                * To avoid deadlock, cannot acquire dev->mutex
+                * while dev->attach_lock is held.
+                */
+               up_read(&dev->attach_lock);
+               attach_locked = false;
+               mutex_lock(&dev->mutex);
+               /*
+                * Check device hasn't become detached behind our back.
+                * Checking dev->detach_count is unchanged ought to be
+                * sufficient (unless there have been 2**32 detaches in the
+                * meantime!), but check the subdevice pointer as well just in
+                * case.
+                *
+                * Also check the subdevice is still in a suitable state to
+                * become non-busy in case it changed behind our back.
+                */
+               new_s = comedi_file_write_subdevice(file);
+               if (dev->attached && old_detach_count == dev->detach_count &&
+                   s == new_s && new_s->async == async && s->busy == file &&
+                   (async->cmd.flags & CMDF_WRITE) &&
+                   !comedi_is_subdevice_running(s))
+                       do_become_nonbusy(dev, s);
+               mutex_unlock(&dev->mutex);
+       }
+out:
        if (attach_locked)
                up_read(&dev->attach_lock);
 
index 56baf852ecf5ddc1dc26773739ef8b92b379d8af..f9b56396e161cccd3c0f42fe016abd6438ff6278 100644 (file)
@@ -1,20 +1,20 @@
 /*
   linux/include/comedilib.h
   header file for kcomedilib
-
   COMEDI - Linux Control and Measurement Device Interface
   Copyright (C) 1998-2001 David A. Schleef <ds@schleef.org>
-
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.
-
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
-*/
comedilib.h
* Header file for kcomedilib
+ *
* COMEDI - Linux Control and Measurement Device Interface
* Copyright (C) 1998-2001 David A. Schleef <ds@schleef.org>
+ *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
+ */
 
 #ifndef _LINUX_COMEDILIB_H
 #define _LINUX_COMEDILIB_H
index 94c179bea71ef41a1fced9cbabdadef1107506ed..0c8cfa738727ee052307bfaceae12a4892882914 100644 (file)
@@ -81,6 +81,7 @@ obj-$(CONFIG_COMEDI_ADV_PCI1710)      += adv_pci1710.o
 obj-$(CONFIG_COMEDI_ADV_PCI1720)       += adv_pci1720.o
 obj-$(CONFIG_COMEDI_ADV_PCI1723)       += adv_pci1723.o
 obj-$(CONFIG_COMEDI_ADV_PCI1724)       += adv_pci1724.o
+obj-$(CONFIG_COMEDI_ADV_PCI1760)       += adv_pci1760.o
 obj-$(CONFIG_COMEDI_ADV_PCI_DIO)       += adv_pci_dio.o
 obj-$(CONFIG_COMEDI_AMPLC_DIO200_PCI)  += amplc_dio200_pci.o
 obj-$(CONFIG_COMEDI_AMPLC_PC236_PCI)   += amplc_pci236.o
index 45d7f42312ec3da8576e905e7a2f8fe3ebdecc7f..2c1b6de30da8c4d74e085aaeac64d1c376c53a9f 100644 (file)
 #define PCI171X_AD_DATA_REG    0x00    /* R:   A/D data */
 #define PCI171X_SOFTTRG_REG    0x00    /* W:   soft trigger for A/D */
 #define PCI171X_RANGE_REG      0x02    /* W:   A/D gain/range register */
+#define PCI171X_RANGE_DIFF     BIT(5)
+#define PCI171X_RANGE_UNI      BIT(4)
+#define PCI171X_RANGE_GAIN(x)  (((x) & 0x7) << 0)
 #define PCI171X_MUX_REG                0x04    /* W:   A/D multiplexor control */
+#define PCI171X_MUX_CHANH(x)   (((x) & 0xf) << 8)
+#define PCI171X_MUX_CHANL(x)   (((x) & 0xf) << 0)
+#define PCI171X_MUX_CHAN(x)    (PCI171X_MUX_CHANH(x) | PCI171X_MUX_CHANL(x))
 #define PCI171X_STATUS_REG     0x06    /* R:   status register */
 #define PCI171X_STATUS_IRQ     BIT(11) /* 1=IRQ occurred */
 #define PCI171X_STATUS_FF      BIT(10) /* 1=FIFO is full, fatal error */
 #define PCI171X_CLRFIFO_REG    0x09    /* W:   clear FIFO */
 #define PCI171X_DA_REG(x)      (0x0a + ((x) * 2)) /* W:   D/A register */
 #define PCI171X_DAREF_REG      0x0e    /* W:   D/A reference control */
+#define PCI171X_DAREF(c, r)    (((r) & 0x3) << ((c) * 2))
+#define PCI171X_DAREF_MASK(c)  PCI171X_DAREF((c), 0x3)
 #define PCI171X_DI_REG         0x10    /* R:   digital inputs */
 #define PCI171X_DO_REG         0x10    /* W:   digital outputs */
 #define PCI171X_TIMER_BASE     0x18    /* R/W: 8254 timer */
 
-static const struct comedi_lrange range_pci1710_3 = {
+static const struct comedi_lrange pci1710_ai_range = {
        9, {
-               BIP_RANGE(5),
-               BIP_RANGE(2.5),
-               BIP_RANGE(1.25),
-               BIP_RANGE(0.625),
-               BIP_RANGE(10),
-               UNI_RANGE(10),
-               UNI_RANGE(5),
-               UNI_RANGE(2.5),
-               UNI_RANGE(1.25)
+               BIP_RANGE(5),           /* gain 1   (0x00) */
+               BIP_RANGE(2.5),         /* gain 2   (0x01) */
+               BIP_RANGE(1.25),        /* gain 4   (0x02) */
+               BIP_RANGE(0.625),       /* gain 8   (0x03) */
+               BIP_RANGE(10),          /* gain 0.5 (0x04) */
+               UNI_RANGE(10),          /* gain 1   (0x00 | UNI) */
+               UNI_RANGE(5),           /* gain 2   (0x01 | UNI) */
+               UNI_RANGE(2.5),         /* gain 4   (0x02 | UNI) */
+               UNI_RANGE(1.25)         /* gain 8   (0x03 | UNI) */
        }
 };
 
-static const char range_codes_pci1710_3[] = { 0x00, 0x01, 0x02, 0x03, 0x04,
-                                             0x10, 0x11, 0x12, 0x13 };
-
-static const struct comedi_lrange range_pci1710hg = {
+static const struct comedi_lrange pci1710hg_ai_range = {
        12, {
-               BIP_RANGE(5),
-               BIP_RANGE(0.5),
-               BIP_RANGE(0.05),
-               BIP_RANGE(0.005),
-               BIP_RANGE(10),
-               BIP_RANGE(1),
-               BIP_RANGE(0.1),
-               BIP_RANGE(0.01),
-               UNI_RANGE(10),
-               UNI_RANGE(1),
-               UNI_RANGE(0.1),
-               UNI_RANGE(0.01)
+               BIP_RANGE(5),           /* gain 1    (0x00) */
+               BIP_RANGE(0.5),         /* gain 10   (0x01) */
+               BIP_RANGE(0.05),        /* gain 100  (0x02) */
+               BIP_RANGE(0.005),       /* gain 1000 (0x03) */
+               BIP_RANGE(10),          /* gain 0.5  (0x04) */
+               BIP_RANGE(1),           /* gain 5    (0x05) */
+               BIP_RANGE(0.1),         /* gain 50   (0x06) */
+               BIP_RANGE(0.01),        /* gain 500  (0x07) */
+               UNI_RANGE(10),          /* gain 1    (0x00 | UNI) */
+               UNI_RANGE(1),           /* gain 10   (0x01 | UNI) */
+               UNI_RANGE(0.1),         /* gain 100  (0x02 | UNI) */
+               UNI_RANGE(0.01)         /* gain 1000 (0x03 | UNI) */
        }
 };
 
-static const char range_codes_pci1710hg[] = { 0x00, 0x01, 0x02, 0x03, 0x04,
-                                             0x05, 0x06, 0x07, 0x10, 0x11,
-                                             0x12, 0x13 };
-
-static const struct comedi_lrange range_pci17x1 = {
+static const struct comedi_lrange pci1711_ai_range = {
        5, {
-               BIP_RANGE(10),
-               BIP_RANGE(5),
-               BIP_RANGE(2.5),
-               BIP_RANGE(1.25),
-               BIP_RANGE(0.625)
+               BIP_RANGE(10),          /* gain 1  (0x00) */
+               BIP_RANGE(5),           /* gain 2  (0x01) */
+               BIP_RANGE(2.5),         /* gain 4  (0x02) */
+               BIP_RANGE(1.25),        /* gain 8  (0x03) */
+               BIP_RANGE(0.625)        /* gain 16 (0x04) */
        }
 };
 
-static const char range_codes_pci17x1[] = { 0x00, 0x01, 0x02, 0x03, 0x04 };
-
 static const struct comedi_lrange pci171x_ao_range = {
-       2, {
-               UNI_RANGE(5),
-               UNI_RANGE(10)
+       3, {
+               UNI_RANGE(5),           /* internal -5V ref */
+               UNI_RANGE(10),          /* internal -10V ref */
+               RANGE_ext(0, 1)         /* external -Vref (+/-10V max) */
        }
 };
 
@@ -129,71 +129,39 @@ enum pci1710_boardid {
 };
 
 struct boardtype {
-       const char *name;       /*  board name */
-       int n_aichan;           /*  num of A/D chans */
-       const struct comedi_lrange *rangelist_ai;       /*  rangelist for A/D */
-       const char *rangecode_ai;       /*  range codes for programming */
+       const char *name;
+       const struct comedi_lrange *ai_range;
+       unsigned int is_pci1711:1;
        unsigned int is_pci1713:1;
-       unsigned int has_irq:1;
-       unsigned int has_large_fifo:1;  /* 4K or 1K FIFO */
-       unsigned int has_diff_ai:1;
        unsigned int has_ao:1;
-       unsigned int has_di_do:1;
-       unsigned int has_counter:1;
 };
 
 static const struct boardtype boardtypes[] = {
        [BOARD_PCI1710] = {
                .name           = "pci1710",
-               .n_aichan       = 16,
-               .rangelist_ai   = &range_pci1710_3,
-               .rangecode_ai   = range_codes_pci1710_3,
-               .has_irq        = 1,
-               .has_large_fifo = 1,
-               .has_diff_ai    = 1,
+               .ai_range       = &pci1710_ai_range,
                .has_ao         = 1,
-               .has_di_do      = 1,
-               .has_counter    = 1,
        },
        [BOARD_PCI1710HG] = {
                .name           = "pci1710hg",
-               .n_aichan       = 16,
-               .rangelist_ai   = &range_pci1710hg,
-               .rangecode_ai   = range_codes_pci1710hg,
-               .has_irq        = 1,
-               .has_large_fifo = 1,
-               .has_diff_ai    = 1,
+               .ai_range       = &pci1710hg_ai_range,
                .has_ao         = 1,
-               .has_di_do      = 1,
-               .has_counter    = 1,
        },
        [BOARD_PCI1711] = {
                .name           = "pci1711",
-               .n_aichan       = 16,
-               .rangelist_ai   = &range_pci17x1,
-               .rangecode_ai   = range_codes_pci17x1,
-               .has_irq        = 1,
+               .ai_range       = &pci1711_ai_range,
+               .is_pci1711     = 1,
                .has_ao         = 1,
-               .has_di_do      = 1,
-               .has_counter    = 1,
        },
        [BOARD_PCI1713] = {
                .name           = "pci1713",
-               .n_aichan       = 32,
-               .rangelist_ai   = &range_pci1710_3,
-               .rangecode_ai   = range_codes_pci1710_3,
+               .ai_range       = &pci1710_ai_range,
                .is_pci1713     = 1,
-               .has_irq        = 1,
-               .has_large_fifo = 1,
-               .has_diff_ai    = 1,
        },
        [BOARD_PCI1731] = {
                .name           = "pci1731",
-               .n_aichan       = 16,
-               .rangelist_ai   = &range_pci17x1,
-               .rangecode_ai   = range_codes_pci17x1,
-               .has_irq        = 1,
-               .has_di_do      = 1,
+               .ai_range       = &pci1711_ai_range,
+               .is_pci1711     = 1,
        },
 };
 
@@ -201,14 +169,15 @@ struct pci1710_private {
        unsigned int max_samples;
        unsigned int ctrl;      /* control register value */
        unsigned int ctrl_ext;  /* used to switch from TRIG_EXT to TRIG_xxx */
-       unsigned int mux_ext;   /* used to set the channel interval to scan */
+       unsigned int mux_scan;  /* used to set the channel interval to scan */
        unsigned char ai_et;
        unsigned int act_chanlist[32];  /*  list of scanned channel */
        unsigned char saved_seglen;     /* len of the non-repeating chanlist */
        unsigned char da_ranges;        /*  copy of D/A outpit range register */
+       unsigned char unipolar_gain;    /* adjust for unipolar gain codes */
 };
 
-static int pci171x_ai_check_chanlist(struct comedi_device *dev,
+static int pci1710_ai_check_chanlist(struct comedi_device *dev,
                                     struct comedi_subdevice *s,
                                     struct comedi_cmd *cmd)
 {
@@ -274,13 +243,12 @@ static int pci171x_ai_check_chanlist(struct comedi_device *dev,
        return 0;
 }
 
-static void pci171x_ai_setup_chanlist(struct comedi_device *dev,
+static void pci1710_ai_setup_chanlist(struct comedi_device *dev,
                                      struct comedi_subdevice *s,
                                      unsigned int *chanlist,
                                      unsigned int n_chan,
                                      unsigned int seglen)
 {
-       const struct boardtype *board = dev->board_ptr;
        struct pci1710_private *devpriv = dev->private;
        unsigned int first_chan = CR_CHAN(chanlist[0]);
        unsigned int last_chan = CR_CHAN(chanlist[seglen - 1]);
@@ -290,14 +258,18 @@ static void pci171x_ai_setup_chanlist(struct comedi_device *dev,
                unsigned int chan = CR_CHAN(chanlist[i]);
                unsigned int range = CR_RANGE(chanlist[i]);
                unsigned int aref = CR_AREF(chanlist[i]);
-               unsigned int rangeval;
+               unsigned int rangeval = 0;
 
-               rangeval = board->rangecode_ai[range];
                if (aref == AREF_DIFF)
-                       rangeval |= 0x0020;
+                       rangeval |= PCI171X_RANGE_DIFF;
+               if (comedi_range_is_unipolar(s, range)) {
+                       rangeval |= PCI171X_RANGE_UNI;
+                       range -= devpriv->unipolar_gain;
+               }
+               rangeval |= PCI171X_RANGE_GAIN(range);
 
                /* select channel and set range */
-               outw(chan | (chan << 8), dev->iobase + PCI171X_MUX_REG);
+               outw(PCI171X_MUX_CHAN(chan), dev->iobase + PCI171X_MUX_REG);
                outw(rangeval, dev->iobase + PCI171X_RANGE_REG);
 
                devpriv->act_chanlist[i] = chan;
@@ -306,11 +278,12 @@ static void pci171x_ai_setup_chanlist(struct comedi_device *dev,
                devpriv->act_chanlist[i] = CR_CHAN(chanlist[i]);
 
        /* select channel interval to scan */
-       devpriv->mux_ext = first_chan | (last_chan << 8);
-       outw(devpriv->mux_ext, dev->iobase + PCI171X_MUX_REG);
+       devpriv->mux_scan = PCI171X_MUX_CHANL(first_chan) |
+                           PCI171X_MUX_CHANH(last_chan);
+       outw(devpriv->mux_scan, dev->iobase + PCI171X_MUX_REG);
 }
 
-static int pci171x_ai_eoc(struct comedi_device *dev,
+static int pci1710_ai_eoc(struct comedi_device *dev,
                          struct comedi_subdevice *s,
                          struct comedi_insn *insn,
                          unsigned long context)
@@ -323,7 +296,7 @@ static int pci171x_ai_eoc(struct comedi_device *dev,
        return -EBUSY;
 }
 
-static int pci171x_ai_read_sample(struct comedi_device *dev,
+static int pci1710_ai_read_sample(struct comedi_device *dev,
                                  struct comedi_subdevice *s,
                                  unsigned int cur_chan,
                                  unsigned int *val)
@@ -352,7 +325,7 @@ static int pci171x_ai_read_sample(struct comedi_device *dev,
        return 0;
 }
 
-static int pci171x_ai_insn_read(struct comedi_device *dev,
+static int pci1710_ai_insn_read(struct comedi_device *dev,
                                struct comedi_subdevice *s,
                                struct comedi_insn *insn,
                                unsigned int *data)
@@ -361,13 +334,14 @@ static int pci171x_ai_insn_read(struct comedi_device *dev,
        int ret = 0;
        int i;
 
-       devpriv->ctrl &= PCI171X_CTRL_CNT0;
-       devpriv->ctrl |= PCI171X_CTRL_SW;       /*  set software trigger */
+       /* enable software trigger */
+       devpriv->ctrl |= PCI171X_CTRL_SW;
        outw(devpriv->ctrl, dev->iobase + PCI171X_CTRL_REG);
+
        outb(0, dev->iobase + PCI171X_CLRFIFO_REG);
        outb(0, dev->iobase + PCI171X_CLRINT_REG);
 
-       pci171x_ai_setup_chanlist(dev, s, &insn->chanspec, 1, 1);
+       pci1710_ai_setup_chanlist(dev, s, &insn->chanspec, 1, 1);
 
        for (i = 0; i < insn->n; i++) {
                unsigned int val;
@@ -375,81 +349,40 @@ static int pci171x_ai_insn_read(struct comedi_device *dev,
                /* start conversion */
                outw(0, dev->iobase + PCI171X_SOFTTRG_REG);
 
-               ret = comedi_timeout(dev, s, insn, pci171x_ai_eoc, 0);
+               ret = comedi_timeout(dev, s, insn, pci1710_ai_eoc, 0);
                if (ret)
                        break;
 
-               ret = pci171x_ai_read_sample(dev, s, 0, &val);
+               ret = pci1710_ai_read_sample(dev, s, 0, &val);
                if (ret)
                        break;
 
                data[i] = val;
        }
 
+       /* disable software trigger */
+       devpriv->ctrl &= ~PCI171X_CTRL_SW;
+       outw(devpriv->ctrl, dev->iobase + PCI171X_CTRL_REG);
+
        outb(0, dev->iobase + PCI171X_CLRFIFO_REG);
        outb(0, dev->iobase + PCI171X_CLRINT_REG);
 
        return ret ? ret : insn->n;
 }
 
-static int pci171x_ao_insn_write(struct comedi_device *dev,
-                                struct comedi_subdevice *s,
-                                struct comedi_insn *insn,
-                                unsigned int *data)
-{
-       struct pci1710_private *devpriv = dev->private;
-       unsigned int chan = CR_CHAN(insn->chanspec);
-       unsigned int range = CR_RANGE(insn->chanspec);
-       unsigned int val = s->readback[chan];
-       int i;
-
-       devpriv->da_ranges &= ~(1 << (chan << 1));
-       devpriv->da_ranges |= (range << (chan << 1));
-       outw(devpriv->da_ranges, dev->iobase + PCI171X_DAREF_REG);
-
-       for (i = 0; i < insn->n; i++) {
-               val = data[i];
-               outw(val, dev->iobase + PCI171X_DA_REG(chan));
-       }
-
-       s->readback[chan] = val;
-
-       return insn->n;
-}
-
-static int pci171x_di_insn_bits(struct comedi_device *dev,
-                               struct comedi_subdevice *s,
-                               struct comedi_insn *insn,
-                               unsigned int *data)
-{
-       data[1] = inw(dev->iobase + PCI171X_DI_REG);
-
-       return insn->n;
-}
-
-static int pci171x_do_insn_bits(struct comedi_device *dev,
-                               struct comedi_subdevice *s,
-                               struct comedi_insn *insn,
-                               unsigned int *data)
-{
-       if (comedi_dio_update_state(s, data))
-               outw(s->state, dev->iobase + PCI171X_DO_REG);
-
-       data[1] = s->state;
-
-       return insn->n;
-}
-
-static int pci171x_ai_cancel(struct comedi_device *dev,
+static int pci1710_ai_cancel(struct comedi_device *dev,
                             struct comedi_subdevice *s)
 {
        struct pci1710_private *devpriv = dev->private;
 
-       devpriv->ctrl &= PCI171X_CTRL_CNT0;
-       devpriv->ctrl |= PCI171X_CTRL_SW;
-       /* reset any operations */
+       /* disable A/D triggers and interrupt sources */
+       devpriv->ctrl &= PCI171X_CTRL_CNT0;     /* preserve counter 0 clk src */
        outw(devpriv->ctrl, dev->iobase + PCI171X_CTRL_REG);
+
+       /* disable pacer */
        comedi_8254_pacer_enable(dev->pacer, 1, 2, false);
+
+       /* clear A/D FIFO and any pending interrutps */
        outb(0, dev->iobase + PCI171X_CLRFIFO_REG);
        outb(0, dev->iobase + PCI171X_CLRINT_REG);
 
@@ -480,7 +413,7 @@ static void pci1710_handle_every_sample(struct comedi_device *dev,
        outb(0, dev->iobase + PCI171X_CLRINT_REG);
 
        for (; !(inw(dev->iobase + PCI171X_STATUS_REG) & PCI171X_STATUS_FE);) {
-               ret = pci171x_ai_read_sample(dev, s, s->async->cur_chan, &val);
+               ret = pci1710_ai_read_sample(dev, s, s->async->cur_chan, &val);
                if (ret) {
                        s->async->events |= COMEDI_CB_ERROR;
                        break;
@@ -524,7 +457,7 @@ static void pci1710_handle_fifo(struct comedi_device *dev,
                unsigned int val;
                int ret;
 
-               ret = pci171x_ai_read_sample(dev, s, s->async->cur_chan, &val);
+               ret = pci1710_ai_read_sample(dev, s, s->async->cur_chan, &val);
                if (ret) {
                        s->async->events |= COMEDI_CB_ERROR;
                        break;
@@ -543,7 +476,7 @@ static void pci1710_handle_fifo(struct comedi_device *dev,
        outb(0, dev->iobase + PCI171X_CLRINT_REG);
 }
 
-static irqreturn_t interrupt_service_pci1710(int irq, void *d)
+static irqreturn_t pci1710_irq_handler(int irq, void *d)
 {
        struct comedi_device *dev = d;
        struct pci1710_private *devpriv = dev->private;
@@ -569,7 +502,7 @@ static irqreturn_t interrupt_service_pci1710(int irq, void *d)
                outb(0, dev->iobase + PCI171X_CLRFIFO_REG);
                outb(0, dev->iobase + PCI171X_CLRINT_REG);
                /* no sample on this interrupt; reset the channel interval */
-               outw(devpriv->mux_ext, dev->iobase + PCI171X_MUX_REG);
+               outw(devpriv->mux_scan, dev->iobase + PCI171X_MUX_REG);
                outw(devpriv->ctrl, dev->iobase + PCI171X_CTRL_REG);
                comedi_8254_pacer_enable(dev->pacer, 1, 2, true);
                return IRQ_HANDLED;
@@ -585,12 +518,12 @@ static irqreturn_t interrupt_service_pci1710(int irq, void *d)
        return IRQ_HANDLED;
 }
 
-static int pci171x_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
+static int pci1710_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 {
        struct pci1710_private *devpriv = dev->private;
        struct comedi_cmd *cmd = &s->async->cmd;
 
-       pci171x_ai_setup_chanlist(dev, s, cmd->chanlist, cmd->chanlist_len,
+       pci1710_ai_setup_chanlist(dev, s, cmd->chanlist, cmd->chanlist_len,
                                  devpriv->saved_seglen);
 
        outb(0, dev->iobase + PCI171X_CLRFIFO_REG);
@@ -626,7 +559,7 @@ static int pci171x_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
        return 0;
 }
 
-static int pci171x_ai_cmdtest(struct comedi_device *dev,
+static int pci1710_ai_cmdtest(struct comedi_device *dev,
                              struct comedi_subdevice *s,
                              struct comedi_cmd *cmd)
 {
@@ -690,7 +623,7 @@ static int pci171x_ai_cmdtest(struct comedi_device *dev,
 
        /* Step 5: check channel list */
 
-       err |= pci171x_ai_check_chanlist(dev, s, cmd);
+       err |= pci1710_ai_check_chanlist(dev, s, cmd);
 
        if (err)
                return 5;
@@ -698,7 +631,55 @@ static int pci171x_ai_cmdtest(struct comedi_device *dev,
        return 0;
 }
 
-static int pci171x_insn_counter_config(struct comedi_device *dev,
+static int pci1710_ao_insn_write(struct comedi_device *dev,
+                                struct comedi_subdevice *s,
+                                struct comedi_insn *insn,
+                                unsigned int *data)
+{
+       struct pci1710_private *devpriv = dev->private;
+       unsigned int chan = CR_CHAN(insn->chanspec);
+       unsigned int range = CR_RANGE(insn->chanspec);
+       unsigned int val = s->readback[chan];
+       int i;
+
+       devpriv->da_ranges &= ~PCI171X_DAREF_MASK(chan);
+       devpriv->da_ranges |= PCI171X_DAREF(chan, range);
+       outw(devpriv->da_ranges, dev->iobase + PCI171X_DAREF_REG);
+
+       for (i = 0; i < insn->n; i++) {
+               val = data[i];
+               outw(val, dev->iobase + PCI171X_DA_REG(chan));
+       }
+
+       s->readback[chan] = val;
+
+       return insn->n;
+}
+
+static int pci1710_di_insn_bits(struct comedi_device *dev,
+                               struct comedi_subdevice *s,
+                               struct comedi_insn *insn,
+                               unsigned int *data)
+{
+       data[1] = inw(dev->iobase + PCI171X_DI_REG);
+
+       return insn->n;
+}
+
+static int pci1710_do_insn_bits(struct comedi_device *dev,
+                               struct comedi_subdevice *s,
+                               struct comedi_insn *insn,
+                               unsigned int *data)
+{
+       if (comedi_dio_update_state(s, data))
+               outw(s->state, dev->iobase + PCI171X_DO_REG);
+
+       data[1] = s->state;
+
+       return insn->n;
+}
+
+static int pci1710_counter_insn_config(struct comedi_device *dev,
                                       struct comedi_subdevice *s,
                                       struct comedi_insn *insn,
                                       unsigned int *data)
@@ -725,7 +706,7 @@ static int pci171x_insn_counter_config(struct comedi_device *dev,
                        data[2] = 0;
                } else {
                        data[1] = 0;
-                       data[2] = I8254_OSC_BASE_10MHZ;
+                       data[2] = I8254_OSC_BASE_1MHZ;
                }
                break;
        default:
@@ -735,29 +716,29 @@ static int pci171x_insn_counter_config(struct comedi_device *dev,
        return insn->n;
 }
 
-static int pci1710_reset(struct comedi_device *dev)
+static void pci1710_reset(struct comedi_device *dev)
 {
        const struct boardtype *board = dev->board_ptr;
-       struct pci1710_private *devpriv = dev->private;
 
-       /* Software trigger, CNT0=external */
-       devpriv->ctrl = PCI171X_CTRL_SW | PCI171X_CTRL_CNT0;
-       /* reset any operations */
-       outw(devpriv->ctrl, dev->iobase + PCI171X_CTRL_REG);
+       /*
+        * Disable A/D triggers and interrupt sources, set counter 0
+        * to use internal 1 MHz clock.
+        */
+       outw(0, dev->iobase + PCI171X_CTRL_REG);
+
+       /* clear A/D FIFO and any pending interrutps */
        outb(0, dev->iobase + PCI171X_CLRFIFO_REG);
        outb(0, dev->iobase + PCI171X_CLRINT_REG);
-       devpriv->da_ranges = 0;
+
        if (board->has_ao) {
                /* set DACs to 0..5V and outputs to 0V */
-               outb(devpriv->da_ranges, dev->iobase + PCI171X_DAREF_REG);
+               outb(0, dev->iobase + PCI171X_DAREF_REG);
                outw(0, dev->iobase + PCI171X_DA_REG(0));
                outw(0, dev->iobase + PCI171X_DA_REG(1));
        }
-       outw(0, dev->iobase + PCI171X_DO_REG);  /*  digital outputs to 0 */
-       outb(0, dev->iobase + PCI171X_CLRFIFO_REG);
-       outb(0, dev->iobase + PCI171X_CLRINT_REG);
 
-       return 0;
+       /* set digital outputs to 0 */
+       outw(0, dev->iobase + PCI171X_DO_REG);
 }
 
 static int pci1710_auto_attach(struct comedi_device *dev,
@@ -768,6 +749,7 @@ static int pci1710_auto_attach(struct comedi_device *dev,
        struct pci1710_private *devpriv;
        struct comedi_subdevice *s;
        int ret, subdev, n_subdevices;
+       int i;
 
        if (context < ARRAY_SIZE(boardtypes))
                board = &boardtypes[context];
@@ -790,15 +772,16 @@ static int pci1710_auto_attach(struct comedi_device *dev,
        if (!dev->pacer)
                return -ENOMEM;
 
-       n_subdevices = 0;
-       if (board->n_aichan)
-               n_subdevices++;
+       n_subdevices = 1;       /* all boards have analog inputs */
        if (board->has_ao)
                n_subdevices++;
-       if (board->has_di_do)
-               n_subdevices += 2;
-       if (board->has_counter)
-               n_subdevices++;
+       if (!board->is_pci1713) {
+               /*
+                * All other boards have digital inputs and outputs as
+                * well as a user counter.
+                */
+               n_subdevices += 3;
+       }
 
        ret = comedi_alloc_subdevices(dev, n_subdevices);
        if (ret)
@@ -806,8 +789,8 @@ static int pci1710_auto_attach(struct comedi_device *dev,
 
        pci1710_reset(dev);
 
-       if (board->has_irq && pcidev->irq) {
-               ret = request_irq(pcidev->irq, interrupt_service_pci1710,
+       if (pcidev->irq) {
+               ret = request_irq(pcidev->irq, pci1710_irq_handler,
                                  IRQF_SHARED, dev->board_name, dev);
                if (ret == 0)
                        dev->irq = pcidev->irq;
@@ -815,95 +798,89 @@ static int pci1710_auto_attach(struct comedi_device *dev,
 
        subdev = 0;
 
-       if (board->n_aichan) {
-               s = &dev->subdevices[subdev];
-               s->type         = COMEDI_SUBD_AI;
-               s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_GROUND;
-               if (board->has_diff_ai)
-                       s->subdev_flags |= SDF_DIFF;
-               s->n_chan       = board->n_aichan;
-               s->maxdata      = 0x0fff;
-               s->range_table  = board->rangelist_ai;
-               s->insn_read    = pci171x_ai_insn_read;
-               if (dev->irq) {
-                       dev->read_subdev = s;
-                       s->subdev_flags |= SDF_CMD_READ;
-                       s->len_chanlist = s->n_chan;
-                       s->do_cmdtest   = pci171x_ai_cmdtest;
-                       s->do_cmd       = pci171x_ai_cmd;
-                       s->cancel       = pci171x_ai_cancel;
+       /* Analog Input subdevice */
+       s = &dev->subdevices[subdev++];
+       s->type         = COMEDI_SUBD_AI;
+       s->subdev_flags = SDF_READABLE | SDF_GROUND;
+       if (!board->is_pci1711)
+               s->subdev_flags |= SDF_DIFF;
+       s->n_chan       = board->is_pci1713 ? 32 : 16;
+       s->maxdata      = 0x0fff;
+       s->range_table  = board->ai_range;
+       s->insn_read    = pci1710_ai_insn_read;
+       if (dev->irq) {
+               dev->read_subdev = s;
+               s->subdev_flags |= SDF_CMD_READ;
+               s->len_chanlist = s->n_chan;
+               s->do_cmdtest   = pci1710_ai_cmdtest;
+               s->do_cmd       = pci1710_ai_cmd;
+               s->cancel       = pci1710_ai_cancel;
+       }
+
+       /* find the value needed to adjust for unipolar gain codes */
+       for (i = 0; i < s->range_table->length; i++) {
+               if (comedi_range_is_unipolar(s, i)) {
+                       devpriv->unipolar_gain = i;
+                       break;
                }
-               subdev++;
        }
 
        if (board->has_ao) {
-               s = &dev->subdevices[subdev];
+               /* Analog Output subdevice */
+               s = &dev->subdevices[subdev++];
                s->type         = COMEDI_SUBD_AO;
-               s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON;
+               s->subdev_flags = SDF_WRITABLE | SDF_GROUND;
                s->n_chan       = 2;
                s->maxdata      = 0x0fff;
                s->range_table  = &pci171x_ao_range;
-               s->insn_write   = pci171x_ao_insn_write;
+               s->insn_write   = pci1710_ao_insn_write;
 
                ret = comedi_alloc_subdev_readback(s);
                if (ret)
                        return ret;
-
-               subdev++;
        }
 
-       if (board->has_di_do) {
-               s = &dev->subdevices[subdev];
+       if (!board->is_pci1713) {
+               /* Digital Input subdevice */
+               s = &dev->subdevices[subdev++];
                s->type         = COMEDI_SUBD_DI;
                s->subdev_flags = SDF_READABLE;
                s->n_chan       = 16;
                s->maxdata      = 1;
                s->range_table  = &range_digital;
-               s->insn_bits    = pci171x_di_insn_bits;
-               subdev++;
+               s->insn_bits    = pci1710_di_insn_bits;
 
-               s = &dev->subdevices[subdev];
+               /* Digital Output subdevice */
+               s = &dev->subdevices[subdev++];
                s->type         = COMEDI_SUBD_DO;
                s->subdev_flags = SDF_WRITABLE;
                s->n_chan       = 16;
                s->maxdata      = 1;
                s->range_table  = &range_digital;
-               s->insn_bits    = pci171x_do_insn_bits;
-               subdev++;
-       }
+               s->insn_bits    = pci1710_do_insn_bits;
 
-       /* Counter subdevice (8254) */
-       if (board->has_counter) {
-               s = &dev->subdevices[subdev];
+               /* Counter subdevice (8254) */
+               s = &dev->subdevices[subdev++];
                comedi_8254_subdevice_init(s, dev->pacer);
 
-               dev->pacer->insn_config = pci171x_insn_counter_config;
+               dev->pacer->insn_config = pci1710_counter_insn_config;
 
                /* counters 1 and 2 are used internally for the pacer */
                comedi_8254_set_busy(dev->pacer, 1, true);
                comedi_8254_set_busy(dev->pacer, 2, true);
-
-               subdev++;
        }
 
        /* max_samples is half the FIFO size (2 bytes/sample) */
-       devpriv->max_samples = (board->has_large_fifo) ? 2048 : 512;
+       devpriv->max_samples = (board->is_pci1711) ? 512 : 2048;
 
        return 0;
 }
 
-static void pci1710_detach(struct comedi_device *dev)
-{
-       if (dev->iobase)
-               pci1710_reset(dev);
-       comedi_pci_detach(dev);
-}
-
 static struct comedi_driver adv_pci1710_driver = {
        .driver_name    = "adv_pci1710",
        .module         = THIS_MODULE,
        .auto_attach    = pci1710_auto_attach,
-       .detach         = pci1710_detach,
+       .detach         = comedi_pci_detach,
 };
 
 static int adv_pci1710_pci_probe(struct pci_dev *dev,
diff --git a/drivers/staging/comedi/drivers/adv_pci1760.c b/drivers/staging/comedi/drivers/adv_pci1760.c
new file mode 100644 (file)
index 0000000..d7dd1e5
--- /dev/null
@@ -0,0 +1,432 @@
+/*
+ * COMEDI driver for the Advantech PCI-1760
+ * Copyright (C) 2015 H Hartley Sweeten <hsweeten@visionengravers.com>
+ *
+ * Based on the pci1760 support in the adv_pci_dio driver written by:
+ *     Michal Dobes <dobes@tesnet.cz>
+ *
+ * COMEDI - Linux Control and Measurement Device Interface
+ * Copyright (C) 2000 David A. Schleef <ds@schleef.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+/*
+ * Driver: adv_pci1760
+ * Description: Advantech PCI-1760 Relay & Isolated Digital Input Card
+ * Devices: [Advantech] PCI-1760 (adv_pci1760)
+ * Author: H Hartley Sweeten <hsweeten@visionengravers.com>
+ * Updated: Fri, 13 Nov 2015 12:34:00 -0700
+ * Status: untested
+ *
+ * Configuration Options: not applicable, uses PCI auto config
+ */
+
+#include <linux/module.h>
+
+#include "../comedi_pci.h"
+
+/*
+ * PCI-1760 Register Map
+ *
+ * Outgoing Mailbox Bytes
+ * OMB3: Not used (must be 0)
+ * OMB2: The command code to the PCI-1760
+ * OMB1: The hi byte of the parameter for the command in OMB2
+ * OMB0: The lo byte of the parameter for the command in OMB2
+ *
+ * Incoming Mailbox Bytes
+ * IMB3: The Isolated Digital Input status (updated every 100us)
+ * IMB2: The current command (matches OMB2 when command is successful)
+ * IMB1: The hi byte of the feedback data for the command in OMB2
+ * IMB0: The lo byte of the feedback data for the command in OMB2
+ *
+ * Interrupt Control/Status
+ * INTCSR3: Not used (must be 0)
+ * INTCSR2: The interrupt status (read only)
+ * INTCSR1: Interrupt enable/disable
+ * INTCSR0: Not used (must be 0)
+ */
+#define PCI1760_OMB_REG(x)             (0x0c + (x))
+#define PCI1760_IMB_REG(x)             (0x1c + (x))
+#define PCI1760_INTCSR_REG(x)          (0x38 + (x))
+#define PCI1760_INTCSR1_IRQ_ENA                BIT(5)
+#define PCI1760_INTCSR2_OMB_IRQ                BIT(0)
+#define PCI1760_INTCSR2_IMB_IRQ                BIT(1)
+#define PCI1760_INTCSR2_IRQ_STATUS     BIT(6)
+#define PCI1760_INTCSR2_IRQ_ASSERTED   BIT(7)
+
+/* PCI-1760 command codes */
+#define PCI1760_CMD_CLR_IMB2           0x00    /* Clears IMB2 */
+#define PCI1760_CMD_SET_DO             0x01    /* Set output state */
+#define PCI1760_CMD_GET_DO             0x02    /* Read output status */
+#define PCI1760_CMD_GET_STATUS         0x03    /* Read current status */
+#define PCI1760_CMD_GET_FW_VER         0x0e    /* Read firware version */
+#define PCI1760_CMD_GET_HW_VER         0x0f    /* Read hardware version */
+#define PCI1760_CMD_SET_PWM_HI(x)      (0x10 + (x) * 2) /* Set "hi" period */
+#define PCI1760_CMD_SET_PWM_LO(x)      (0x11 + (x) * 2) /* Set "lo" period */
+#define PCI1760_CMD_SET_PWM_CNT(x)     (0x14 + (x)) /* Set burst count */
+#define PCI1760_CMD_ENA_PWM            0x1f    /* Enable PWM outputs */
+#define PCI1760_CMD_ENA_FILT           0x20    /* Enable input filter */
+#define PCI1760_CMD_ENA_PAT_MATCH      0x21    /* Enable input pattern match */
+#define PCI1760_CMD_SET_PAT_MATCH      0x22    /* Set input pattern match */
+#define PCI1760_CMD_ENA_RISE_EDGE      0x23    /* Enable input rising edge */
+#define PCI1760_CMD_ENA_FALL_EDGE      0x24    /* Enable input falling edge */
+#define PCI1760_CMD_ENA_CNT            0x28    /* Enable counter */
+#define PCI1760_CMD_RST_CNT            0x29    /* Reset counter */
+#define PCI1760_CMD_ENA_CNT_OFLOW      0x2a    /* Enable counter overflow */
+#define PCI1760_CMD_ENA_CNT_MATCH      0x2b    /* Enable counter match */
+#define PCI1760_CMD_SET_CNT_EDGE       0x2c    /* Set counter edge */
+#define PCI1760_CMD_GET_CNT            0x2f    /* Reads counter value */
+#define PCI1760_CMD_SET_HI_SAMP(x)     (0x30 + (x)) /* Set "hi" sample time */
+#define PCI1760_CMD_SET_LO_SAMP(x)     (0x38 + (x)) /* Set "lo" sample time */
+#define PCI1760_CMD_SET_CNT(x)         (0x40 + (x)) /* Set counter reset val */
+#define PCI1760_CMD_SET_CNT_MATCH(x)   (0x48 + (x)) /* Set counter match val */
+#define PCI1760_CMD_GET_INT_FLAGS      0x60    /* Read interrupt flags */
+#define PCI1760_CMD_GET_INT_FLAGS_MATCH        BIT(0)
+#define PCI1760_CMD_GET_INT_FLAGS_COS  BIT(1)
+#define PCI1760_CMD_GET_INT_FLAGS_OFLOW        BIT(2)
+#define PCI1760_CMD_GET_OS             0x61    /* Read edge change flags */
+#define PCI1760_CMD_GET_CNT_STATUS     0x62    /* Read counter oflow/match */
+
+#define PCI1760_CMD_TIMEOUT            250     /* 250 usec timeout */
+#define PCI1760_CMD_RETRIES            3       /* limit number of retries */
+
+#define PCI1760_PWM_TIMEBASE           100000  /* 1 unit = 100 usec */
+
+static int pci1760_send_cmd(struct comedi_device *dev,
+                           unsigned char cmd, unsigned short val)
+{
+       unsigned long timeout;
+
+       /* send the command and parameter */
+       outb(val & 0xff, dev->iobase + PCI1760_OMB_REG(0));
+       outb((val >> 8) & 0xff, dev->iobase + PCI1760_OMB_REG(1));
+       outb(cmd, dev->iobase + PCI1760_OMB_REG(2));
+       outb(0, dev->iobase + PCI1760_OMB_REG(3));
+
+       /* datasheet says to allow up to 250 usec for the command to complete */
+       timeout = jiffies + usecs_to_jiffies(PCI1760_CMD_TIMEOUT);
+       do {
+               if (inb(dev->iobase + PCI1760_IMB_REG(2)) == cmd) {
+                       /* command success; return the feedback data */
+                       return inb(dev->iobase + PCI1760_IMB_REG(0)) |
+                              (inb(dev->iobase + PCI1760_IMB_REG(1)) << 8);
+               }
+               cpu_relax();
+       } while (time_before(jiffies, timeout));
+
+       return -EBUSY;
+}
+
+static int pci1760_cmd(struct comedi_device *dev,
+                      unsigned char cmd, unsigned short val)
+{
+       int repeats;
+       int ret;
+
+       /* send PCI1760_CMD_CLR_IMB2 between identical commands */
+       if (inb(dev->iobase + PCI1760_IMB_REG(2)) == cmd) {
+               ret = pci1760_send_cmd(dev, PCI1760_CMD_CLR_IMB2, 0);
+               if (ret < 0) {
+                       /* timeout? try it once more */
+                       ret = pci1760_send_cmd(dev, PCI1760_CMD_CLR_IMB2, 0);
+                       if (ret < 0)
+                               return -ETIMEDOUT;
+               }
+       }
+
+       /* datasheet says to keep retrying the command */
+       for (repeats = 0; repeats < PCI1760_CMD_RETRIES; repeats++) {
+               ret = pci1760_send_cmd(dev, cmd, val);
+               if (ret >= 0)
+                       return ret;
+       }
+
+       /* command failed! */
+       return -ETIMEDOUT;
+}
+
+static int pci1760_di_insn_bits(struct comedi_device *dev,
+                               struct comedi_subdevice *s,
+                               struct comedi_insn *insn,
+                               unsigned int *data)
+{
+       data[1] = inb(dev->iobase + PCI1760_IMB_REG(3));
+
+       return insn->n;
+}
+
+static int pci1760_do_insn_bits(struct comedi_device *dev,
+                               struct comedi_subdevice *s,
+                               struct comedi_insn *insn,
+                               unsigned int *data)
+{
+       int ret;
+
+       if (comedi_dio_update_state(s, data)) {
+               ret = pci1760_cmd(dev, PCI1760_CMD_SET_DO, s->state);
+               if (ret < 0)
+                       return ret;
+       }
+
+       data[1] = s->state;
+
+       return insn->n;
+}
+
+static int pci1760_pwm_ns_to_div(unsigned int flags, unsigned int ns)
+{
+       unsigned int divisor;
+
+       switch (flags) {
+       case CMDF_ROUND_NEAREST:
+               divisor = DIV_ROUND_CLOSEST(ns, PCI1760_PWM_TIMEBASE);
+               break;
+       case CMDF_ROUND_UP:
+               divisor = DIV_ROUND_UP(ns, PCI1760_PWM_TIMEBASE);
+               break;
+       case CMDF_ROUND_DOWN:
+               divisor = ns / PCI1760_PWM_TIMEBASE;
+       default:
+               return -EINVAL;
+       }
+
+       if (divisor < 1)
+               divisor = 1;
+       if (divisor > 0xffff)
+               divisor = 0xffff;
+
+       return divisor;
+}
+
+static int pci1760_pwm_enable(struct comedi_device *dev,
+                             unsigned int chan, bool enable)
+{
+       int ret;
+
+       ret = pci1760_cmd(dev, PCI1760_CMD_GET_STATUS, PCI1760_CMD_ENA_PWM);
+       if (ret < 0)
+               return ret;
+
+       if (enable)
+               ret |= BIT(chan);
+       else
+               ret &= ~BIT(chan);
+
+       return pci1760_cmd(dev, PCI1760_CMD_ENA_PWM, ret);
+}
+
+static int pci1760_pwm_insn_config(struct comedi_device *dev,
+                                  struct comedi_subdevice *s,
+                                  struct comedi_insn *insn,
+                                  unsigned int *data)
+{
+       unsigned int chan = CR_CHAN(insn->chanspec);
+       int hi_div;
+       int lo_div;
+       int ret;
+
+       switch (data[0]) {
+       case INSN_CONFIG_ARM:
+               ret = pci1760_pwm_enable(dev, chan, false);
+               if (ret < 0)
+                       return ret;
+
+               if (data[1] > 0xffff)
+                       return -EINVAL;
+               ret = pci1760_cmd(dev, PCI1760_CMD_SET_PWM_CNT(chan), data[1]);
+               if (ret < 0)
+                       return ret;
+
+               ret = pci1760_pwm_enable(dev, chan, true);
+               if (ret < 0)
+                       return ret;
+               break;
+       case INSN_CONFIG_DISARM:
+               ret = pci1760_pwm_enable(dev, chan, false);
+               if (ret < 0)
+                       return ret;
+               break;
+       case INSN_CONFIG_PWM_OUTPUT:
+               ret = pci1760_pwm_enable(dev, chan, false);
+               if (ret < 0)
+                       return ret;
+
+               hi_div = pci1760_pwm_ns_to_div(data[1], data[2]);
+               lo_div = pci1760_pwm_ns_to_div(data[3], data[4]);
+               if (hi_div < 0 || lo_div < 0)
+                       return -EINVAL;
+               if ((hi_div * PCI1760_PWM_TIMEBASE) != data[2] ||
+                   (lo_div * PCI1760_PWM_TIMEBASE) != data[4]) {
+                       data[2] = hi_div * PCI1760_PWM_TIMEBASE;
+                       data[4] = lo_div * PCI1760_PWM_TIMEBASE;
+                       return -EAGAIN;
+               }
+               ret = pci1760_cmd(dev, PCI1760_CMD_SET_PWM_HI(chan), hi_div);
+               if (ret < 0)
+                       return ret;
+               ret = pci1760_cmd(dev, PCI1760_CMD_SET_PWM_LO(chan), lo_div);
+               if (ret < 0)
+                       return ret;
+               break;
+       case INSN_CONFIG_GET_PWM_OUTPUT:
+               hi_div = pci1760_cmd(dev, PCI1760_CMD_GET_STATUS,
+                                    PCI1760_CMD_SET_PWM_HI(chan));
+               lo_div = pci1760_cmd(dev, PCI1760_CMD_GET_STATUS,
+                                    PCI1760_CMD_SET_PWM_LO(chan));
+               if (hi_div < 0 || lo_div < 0)
+                       return -ETIMEDOUT;
+
+               data[1] = hi_div * PCI1760_PWM_TIMEBASE;
+               data[2] = lo_div * PCI1760_PWM_TIMEBASE;
+               break;
+       case INSN_CONFIG_GET_PWM_STATUS:
+               ret = pci1760_cmd(dev, PCI1760_CMD_GET_STATUS,
+                                 PCI1760_CMD_ENA_PWM);
+               if (ret < 0)
+                       return ret;
+
+               data[1] = (ret & BIT(chan)) ? 1 : 0;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return insn->n;
+}
+
+static void pci1760_reset(struct comedi_device *dev)
+{
+       int i;
+
+       /* disable interrupts (intcsr2 is read-only) */
+       outb(0, dev->iobase + PCI1760_INTCSR_REG(0));
+       outb(0, dev->iobase + PCI1760_INTCSR_REG(1));
+       outb(0, dev->iobase + PCI1760_INTCSR_REG(3));
+
+       /* disable counters */
+       pci1760_cmd(dev, PCI1760_CMD_ENA_CNT, 0);
+
+       /* disable overflow interrupts */
+       pci1760_cmd(dev, PCI1760_CMD_ENA_CNT_OFLOW, 0);
+
+       /* disable match */
+       pci1760_cmd(dev, PCI1760_CMD_ENA_CNT_MATCH, 0);
+
+       /* set match and counter reset values */
+       for (i = 0; i < 8; i++) {
+               pci1760_cmd(dev, PCI1760_CMD_SET_CNT_MATCH(i), 0x8000);
+               pci1760_cmd(dev, PCI1760_CMD_SET_CNT(i), 0x0000);
+       }
+
+       /* reset counters to reset values */
+       pci1760_cmd(dev, PCI1760_CMD_RST_CNT, 0xff);
+
+       /* set counter count edges */
+       pci1760_cmd(dev, PCI1760_CMD_SET_CNT_EDGE, 0);
+
+       /* disable input filters */
+       pci1760_cmd(dev, PCI1760_CMD_ENA_FILT, 0);
+
+       /* disable pattern matching */
+       pci1760_cmd(dev, PCI1760_CMD_ENA_PAT_MATCH, 0);
+
+       /* set pattern match value */
+       pci1760_cmd(dev, PCI1760_CMD_SET_PAT_MATCH, 0);
+}
+
+static int pci1760_auto_attach(struct comedi_device *dev,
+                              unsigned long context)
+{
+       struct pci_dev *pcidev = comedi_to_pci_dev(dev);
+       struct comedi_subdevice *s;
+       int ret;
+
+       ret = comedi_pci_enable(dev);
+       if (ret)
+               return ret;
+       dev->iobase = pci_resource_start(pcidev, 0);
+
+       pci1760_reset(dev);
+
+       ret = comedi_alloc_subdevices(dev, 4);
+       if (ret)
+               return ret;
+
+       /* Digital Input subdevice */
+       s = &dev->subdevices[0];
+       s->type         = COMEDI_SUBD_DI;
+       s->subdev_flags = SDF_READABLE;
+       s->n_chan       = 8;
+       s->maxdata      = 1;
+       s->range_table  = &range_digital;
+       s->insn_bits    = pci1760_di_insn_bits;
+
+       /* Digital Output subdevice */
+       s = &dev->subdevices[1];
+       s->type         = COMEDI_SUBD_DO;
+       s->subdev_flags = SDF_WRITABLE;
+       s->n_chan       = 8;
+       s->maxdata      = 1;
+       s->range_table  = &range_digital;
+       s->insn_bits    = pci1760_do_insn_bits;
+
+       /* get the current state of the outputs */
+       ret = pci1760_cmd(dev, PCI1760_CMD_GET_DO, 0);
+       if (ret < 0)
+               return ret;
+       s->state        = ret;
+
+       /* PWM subdevice */
+       s = &dev->subdevices[2];
+       s->type         = COMEDI_SUBD_PWM;
+       s->subdev_flags = SDF_PWM_COUNTER;
+       s->n_chan       = 2;
+       s->insn_config  = pci1760_pwm_insn_config;
+
+       /* Counter subdevice */
+       s = &dev->subdevices[3];
+       s->type         = COMEDI_SUBD_UNUSED;
+
+       return 0;
+}
+
+static struct comedi_driver pci1760_driver = {
+       .driver_name    = "adv_pci1760",
+       .module         = THIS_MODULE,
+       .auto_attach    = pci1760_auto_attach,
+       .detach         = comedi_pci_detach,
+};
+
+static int pci1760_pci_probe(struct pci_dev *dev,
+                            const struct pci_device_id *id)
+{
+       return comedi_pci_auto_config(dev, &pci1760_driver, id->driver_data);
+}
+
+static const struct pci_device_id pci1760_pci_table[] = {
+       { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1760) },
+       { 0 }
+};
+MODULE_DEVICE_TABLE(pci, pci1760_pci_table);
+
+static struct pci_driver pci1760_pci_driver = {
+       .name           = "adv_pci1760",
+       .id_table       = pci1760_pci_table,
+       .probe          = pci1760_pci_probe,
+       .remove         = comedi_pci_auto_unconfig,
+};
+module_comedi_pci_driver(pci1760_driver, pci1760_pci_driver);
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi driver for Advantech PCI-1760");
+MODULE_LICENSE("GPL");
index f1b3c5aa8d794786951377ad301bdf1d61d32335..620cec13d74cd044dc5d99e6680c5e12b016df22 100644 (file)
@@ -4,30 +4,21 @@
  * Author: Michal Dobes <dobes@tesnet.cz>
  *
  *  Hardware driver for Advantech PCI DIO cards.
-*/
-/*
-Driver: adv_pci_dio
-Description: Advantech PCI-1730, PCI-1733, PCI-1734, PCI-1735U,
-       PCI-1736UP, PCI-1739U, PCI-1750, PCI-1751, PCI-1752,
-       PCI-1753/E, PCI-1754, PCI-1756, PCI-1760, PCI-1762
-Author: Michal Dobes <dobes@tesnet.cz>
-Devices: [Advantech] PCI-1730 (adv_pci_dio), PCI-1733,
-  PCI-1734, PCI-1735U, PCI-1736UP, PCI-1739U, PCI-1750,
-  PCI-1751, PCI-1752, PCI-1753,
-  PCI-1753+PCI-1753E, PCI-1754, PCI-1756,
-  PCI-1760, PCI-1762
-Status: untested
-Updated: Mon, 09 Jan 2012 12:40:46 +0000
-
-This driver supports now only insn interface for DI/DO/DIO.
+ */
 
-Configuration options:
-  [0] - PCI bus of device (optional)
-  [1] - PCI slot of device (optional)
-       If bus/slot is not specified, the first available PCI
-       device will be used.
-
-*/
+/*
+ * Driver: adv_pci_dio
+ * Description: Advantech Digital I/O Cards
+ * Devices: [Advantech] PCI-1730 (adv_pci_dio), PCI-1733,
+ *   PCI-1734, PCI-1735U, PCI-1736UP, PCI-1739U, PCI-1750,
+ *   PCI-1751, PCI-1752, PCI-1753, PCI-1753+PCI-1753E,
+ *   PCI-1754, PCI-1756, PCI-1762
+ * Author: Michal Dobes <dobes@tesnet.cz>
+ * Updated: Mon, 09 Jan 2012 12:40:46 +0000
+ * Status: untested
+ *
+ * Configuration Options: not applicable, uses PCI auto config
+ */
 
 #include <linux/module.h>
 #include <linux/delay.h>
@@ -37,403 +28,199 @@ Configuration options:
 #include "8255.h"
 #include "comedi_8254.h"
 
-/* hardware types of the cards */
-enum hw_cards_id {
-       TYPE_PCI1730, TYPE_PCI1733, TYPE_PCI1734, TYPE_PCI1735, TYPE_PCI1736,
-       TYPE_PCI1739,
-       TYPE_PCI1750,
-       TYPE_PCI1751,
-       TYPE_PCI1752,
-       TYPE_PCI1753, TYPE_PCI1753E,
-       TYPE_PCI1754, TYPE_PCI1756,
-       TYPE_PCI1760,
-       TYPE_PCI1762
-};
-
-/* which I/O instructions to use */
-enum hw_io_access {
-       IO_8b, IO_16b
-};
-
-#define MAX_DI_SUBDEVS 2       /* max number of DI subdevices per card */
-#define MAX_DO_SUBDEVS 2       /* max number of DO subdevices per card */
-#define MAX_DIO_SUBDEVG        2       /* max number of DIO subdevices group per
-                                * card */
-
-#define PCIDIO_MAINREG    2    /* main I/O region for all Advantech cards? */
-
-/* Register offset definitions */
-/*  Advantech PCI-1730/3/4 */
-#define PCI1730_IDI       0    /* R:   Isolated digital input  0-15 */
-#define PCI1730_IDO       0    /* W:   Isolated digital output 0-15 */
-#define PCI1730_DI        2    /* R:   Digital input  0-15 */
-#define PCI1730_DO        2    /* W:   Digital output 0-15 */
-#define PCI1733_IDI       0    /* R:   Isolated digital input  0-31 */
-#define        PCI1730_3_INT_EN        0x08    /* R/W: enable/disable interrupts */
-#define        PCI1730_3_INT_RF        0x0c    /* R/W: set falling/raising edge for
-                                        * interrupts */
-#define        PCI1730_3_INT_CLR       0x10    /* R/W: clear interrupts */
-#define PCI1734_IDO       0    /* W:   Isolated digital output 0-31 */
-#define PCI173x_BOARDID           4    /* R:   Board I/D switch for 1730/3/4 */
-
-/* Advantech PCI-1735U */
-#define PCI1735_DI        0    /* R:   Digital input  0-31 */
-#define PCI1735_DO        0    /* W:   Digital output 0-31 */
-#define PCI1735_C8254     4    /* R/W: 8254 counter */
-#define PCI1735_BOARDID           8    /* R:   Board I/D switch for 1735U */
-
-/*  Advantech PCI-1736UP */
-#define PCI1736_IDI        0   /* R:   Isolated digital input  0-15 */
-#define PCI1736_IDO        0   /* W:   Isolated digital output 0-15 */
-#define PCI1736_3_INT_EN        0x08   /* R/W: enable/disable interrupts */
-#define PCI1736_3_INT_RF        0x0c   /* R/W: set falling/raising edge for
-                                        * interrupts */
-#define PCI1736_3_INT_CLR       0x10   /* R/W: clear interrupts */
-#define PCI1736_BOARDID    4   /* R:   Board I/D switch for 1736UP */
-#define PCI1736_MAINREG    0   /* Normal register (2) doesn't work */
+/*
+ * Register offset definitions
+ */
 
-/* Advantech PCI-1739U */
-#define PCI1739_DIO       0    /* R/W: begin of 8255 registers block */
-#define PCI1739_ICR      32    /* W:   Interrupt control register */
-#define PCI1739_ISR      32    /* R:   Interrupt status register */
-#define PCI1739_BOARDID           8    /* R:   Board I/D switch for 1739U */
+/* PCI-1730, PCI-1733, PCI-1736 interrupt control registers */
+#define PCI173X_INT_EN_REG     0x08    /* R/W: enable/disable */
+#define PCI173X_INT_RF_REG     0x0c    /* R/W: falling/rising edge */
+#define PCI173X_INT_CLR_REG    0x10    /* R/W: clear */
 
-/*  Advantech PCI-1750 */
-#define PCI1750_IDI       0    /* R:   Isolated digital input  0-15 */
-#define PCI1750_IDO       0    /* W:   Isolated digital output 0-15 */
-#define PCI1750_ICR      32    /* W:   Interrupt control register */
-#define PCI1750_ISR      32    /* R:   Interrupt status register */
+/* PCI-1739U, PCI-1750, PCI1751 interrupt control registers */
+#define PCI1750_INT_REG                0x20    /* R/W: status/control */
 
-/*  Advantech PCI-1751/3/3E */
-#define PCI1751_DIO       0    /* R/W: begin of 8255 registers block */
-#define PCI1751_CNT      24    /* R/W: begin of 8254 registers block */
-#define PCI1751_ICR      32    /* W:   Interrupt control register */
-#define PCI1751_ISR      32    /* R:   Interrupt status register */
-#define PCI1753_DIO       0    /* R/W: begin of 8255 registers block */
-#define PCI1753_ICR0     16    /* R/W: Interrupt control register group 0 */
-#define PCI1753_ICR1     17    /* R/W: Interrupt control register group 1 */
-#define PCI1753_ICR2     18    /* R/W: Interrupt control register group 2 */
-#define PCI1753_ICR3     19    /* R/W: Interrupt control register group 3 */
-#define PCI1753E_DIO     32    /* R/W: begin of 8255 registers block */
-#define PCI1753E_ICR0    48    /* R/W: Interrupt control register group 0 */
-#define PCI1753E_ICR1    49    /* R/W: Interrupt control register group 1 */
-#define PCI1753E_ICR2    50    /* R/W: Interrupt control register group 2 */
-#define PCI1753E_ICR3    51    /* R/W: Interrupt control register group 3 */
+/* PCI-1753, PCI-1753E interrupt control registers */
+#define PCI1753_INT_REG(x)     (0x10 + (x)) /* R/W: control group 0 to 3 */
+#define PCI1753E_INT_REG(x)    (0x30 + (x)) /* R/W: control group 0 to 3 */
 
-/*  Advantech PCI-1752/4/6 */
-#define PCI1752_IDO       0    /* R/W: Digital output  0-31 */
-#define PCI1752_IDO2      4    /* R/W: Digital output 32-63 */
-#define PCI1754_IDI       0    /* R:   Digital input   0-31 */
-#define PCI1754_IDI2      4    /* R:   Digital input  32-64 */
-#define PCI1756_IDI       0    /* R:   Digital input   0-31 */
-#define PCI1756_IDO       4    /* R/W: Digital output  0-31 */
-#define PCI1754_6_ICR0 0x08    /* R/W: Interrupt control register group 0 */
-#define PCI1754_6_ICR1 0x0a    /* R/W: Interrupt control register group 1 */
-#define PCI1754_ICR2   0x0c    /* R/W: Interrupt control register group 2 */
-#define PCI1754_ICR3   0x0e    /* R/W: Interrupt control register group 3 */
-#define PCI1752_6_CFC  0x12    /* R/W: set/read channel freeze function */
-#define PCI175x_BOARDID        0x10    /* R:   Board I/D switch for 1752/4/6 */
+/* PCI-1754, PCI-1756 interrupt control registers */
+#define PCI1754_INT_REG(x)     (0x08 + (x) * 2) /* R/W: control group 0 to 3 */
 
-/*  Advantech PCI-1762 registers */
-#define PCI1762_RO        0    /* R/W: Relays status/output */
-#define PCI1762_IDI       2    /* R:   Isolated input status */
-#define PCI1762_BOARDID           4    /* R:   Board I/D switch */
-#define PCI1762_ICR       6    /* W:   Interrupt control register */
-#define PCI1762_ISR       6    /* R:   Interrupt status register */
+/* PCI-1752, PCI-1756 special registers */
+#define PCI1752_CFC_REG                0x12    /* R/W: channel freeze function */
 
-/*  Advantech PCI-1760 registers */
-#define OMB0           0x0c    /* W:   Mailbox outgoing registers */
-#define OMB1           0x0d
-#define OMB2           0x0e
-#define OMB3           0x0f
-#define IMB0           0x1c    /* R:   Mailbox incoming registers */
-#define IMB1           0x1d
-#define IMB2           0x1e
-#define IMB3           0x1f
-#define INTCSR0                0x38    /* R/W: Interrupt control registers */
-#define INTCSR1                0x39
-#define INTCSR2                0x3a
-#define INTCSR3                0x3b
+/* PCI-1762 interrupt control registers */
+#define PCI1762_INT_REG                0x06    /* R/W: status/control */
 
-/*  PCI-1760 mailbox commands */
-#define CMD_ClearIMB2          0x00    /* Clear IMB2 status and return actual
-                                        * DI status in IMB3 */
-#define CMD_SetRelaysOutput    0x01    /* Set relay output from OMB0 */
-#define CMD_GetRelaysStatus    0x02    /* Get relay status to IMB0 */
-#define CMD_ReadCurrentStatus  0x07    /* Read the current status of the
-                                        * register in OMB0, result in IMB0 */
-#define CMD_ReadFirmwareVersion        0x0e    /* Read the firmware ver., result in
-                                        * IMB1.IMB0 */
-#define CMD_ReadHardwareVersion        0x0f    /* Read the hardware ver., result in
-                                        * IMB1.IMB0 */
-#define CMD_EnableIDIFilters   0x20    /* Enable IDI filters based on bits in
-                                        * OMB0 */
-#define CMD_EnableIDIPatternMatch 0x21 /* Enable IDI pattern match based on
-                                        * bits in OMB0 */
-#define CMD_SetIDIPatternMatch 0x22    /* Enable IDI pattern match based on
-                                        * bits in OMB0 */
-#define CMD_EnableIDICounters  0x28    /* Enable IDI counters based on bits in
-                                        * OMB0 */
-#define CMD_ResetIDICounters   0x29    /* Reset IDI counters based on bits in
-                                        * OMB0 to its reset values */
-#define CMD_OverflowIDICounters        0x2a    /* Enable IDI counters overflow
-                                        * interrupts  based on bits in OMB0 */
-#define CMD_MatchIntIDICounters        0x2b    /* Enable IDI counters match value
-                                        * interrupts  based on bits in OMB0 */
-#define CMD_EdgeIDICounters    0x2c    /* Set IDI up counters count edge (bit=0
-                                        * - rising, =1 - falling) */
-#define CMD_GetIDICntCurValue  0x2f    /* Read IDI{OMB0} up counter current
-                                        * value */
-#define CMD_SetIDI0CntResetValue 0x40  /* Set IDI0 Counter Reset Value
-                                        * 256*OMB1+OMB0 */
-#define CMD_SetIDI1CntResetValue 0x41  /* Set IDI1 Counter Reset Value
-                                        * 256*OMB1+OMB0 */
-#define CMD_SetIDI2CntResetValue 0x42  /* Set IDI2 Counter Reset Value
-                                        * 256*OMB1+OMB0 */
-#define CMD_SetIDI3CntResetValue 0x43  /* Set IDI3 Counter Reset Value
-                                        * 256*OMB1+OMB0 */
-#define CMD_SetIDI4CntResetValue 0x44  /* Set IDI4 Counter Reset Value
-                                        * 256*OMB1+OMB0 */
-#define CMD_SetIDI5CntResetValue 0x45  /* Set IDI5 Counter Reset Value
-                                        * 256*OMB1+OMB0 */
-#define CMD_SetIDI6CntResetValue 0x46  /* Set IDI6 Counter Reset Value
-                                        * 256*OMB1+OMB0 */
-#define CMD_SetIDI7CntResetValue 0x47  /* Set IDI7 Counter Reset Value
-                                        * 256*OMB1+OMB0 */
-#define CMD_SetIDI0CntMatchValue 0x48  /* Set IDI0 Counter Match Value
-                                        * 256*OMB1+OMB0 */
-#define CMD_SetIDI1CntMatchValue 0x49  /* Set IDI1 Counter Match Value
-                                        * 256*OMB1+OMB0 */
-#define CMD_SetIDI2CntMatchValue 0x4a  /* Set IDI2 Counter Match Value
-                                        * 256*OMB1+OMB0 */
-#define CMD_SetIDI3CntMatchValue 0x4b  /* Set IDI3 Counter Match Value
-                                        * 256*OMB1+OMB0 */
-#define CMD_SetIDI4CntMatchValue 0x4c  /* Set IDI4 Counter Match Value
-                                        * 256*OMB1+OMB0 */
-#define CMD_SetIDI5CntMatchValue 0x4d  /* Set IDI5 Counter Match Value
-                                        * 256*OMB1+OMB0 */
-#define CMD_SetIDI6CntMatchValue 0x4e  /* Set IDI6 Counter Match Value
-                                        * 256*OMB1+OMB0 */
-#define CMD_SetIDI7CntMatchValue 0x4f  /* Set IDI7 Counter Match Value
-                                        * 256*OMB1+OMB0 */
+/* maximum number of subdevice descriptions in the boardinfo */
+#define PCI_DIO_MAX_DI_SUBDEVS 2       /* 2 x 8/16/32 input channels max */
+#define PCI_DIO_MAX_DO_SUBDEVS 2       /* 2 x 8/16/32 output channels max */
+#define PCI_DIO_MAX_DIO_SUBDEVG        2       /* 2 x any number of 8255 devices max */
 
-#define OMBCMD_RETRY   0x03    /* 3 times try request before error */
+enum pci_dio_boardid {
+       TYPE_PCI1730,
+       TYPE_PCI1733,
+       TYPE_PCI1734,
+       TYPE_PCI1735,
+       TYPE_PCI1736,
+       TYPE_PCI1739,
+       TYPE_PCI1750,
+       TYPE_PCI1751,
+       TYPE_PCI1752,
+       TYPE_PCI1753,
+       TYPE_PCI1753E,
+       TYPE_PCI1754,
+       TYPE_PCI1756,
+       TYPE_PCI1762
+};
 
 struct diosubd_data {
-       int chans;              /*  num of chans */
-       int addr;               /*  PCI address ofset */
-       int regs;               /*  number of registers to read or 8255
-                                   subdevices */
-       unsigned int specflags; /*  addon subdevice flags */
+       int chans;              /*  num of chans or 8255 devices */
+       unsigned long addr;     /*  PCI address ofset */
 };
 
 struct dio_boardtype {
        const char *name;       /*  board name */
-       int main_pci_region;    /*  main I/O PCI region */
-       enum hw_cards_id cardtype;
        int nsubdevs;
-       struct diosubd_data sdi[MAX_DI_SUBDEVS];        /*  DI chans */
-       struct diosubd_data sdo[MAX_DO_SUBDEVS];        /*  DO chans */
-       struct diosubd_data sdio[MAX_DIO_SUBDEVG];      /*  DIO 8255 chans */
-       struct diosubd_data boardid;    /*  card supports board ID switch */
+       struct diosubd_data sdi[PCI_DIO_MAX_DI_SUBDEVS];
+       struct diosubd_data sdo[PCI_DIO_MAX_DO_SUBDEVS];
+       struct diosubd_data sdio[PCI_DIO_MAX_DIO_SUBDEVG];
+       unsigned long id_reg;
        unsigned long timer_regbase;
-       enum hw_io_access io_access;
+       unsigned int is_16bit:1;
 };
 
 static const struct dio_boardtype boardtypes[] = {
        [TYPE_PCI1730] = {
                .name           = "pci1730",
-               .main_pci_region = PCIDIO_MAINREG,
-               .cardtype       = TYPE_PCI1730,
                .nsubdevs       = 5,
-               .sdi[0]         = { 16, PCI1730_DI, 2, 0, },
-               .sdi[1]         = { 16, PCI1730_IDI, 2, 0, },
-               .sdo[0]         = { 16, PCI1730_DO, 2, 0, },
-               .sdo[1]         = { 16, PCI1730_IDO, 2, 0, },
-               .boardid        = { 4, PCI173x_BOARDID, 1, SDF_INTERNAL, },
-               .io_access      = IO_8b,
+               .sdi[0]         = { 16, 0x02, },        /* DI 0-15 */
+               .sdi[1]         = { 16, 0x00, },        /* ISO DI 0-15 */
+               .sdo[0]         = { 16, 0x02, },        /* DO 0-15 */
+               .sdo[1]         = { 16, 0x00, },        /* ISO DO 0-15 */
+               .id_reg         = 0x04,
        },
        [TYPE_PCI1733] = {
                .name           = "pci1733",
-               .main_pci_region = PCIDIO_MAINREG,
-               .cardtype       = TYPE_PCI1733,
                .nsubdevs       = 2,
-               .sdi[1]         = { 32, PCI1733_IDI, 4, 0, },
-               .boardid        = { 4, PCI173x_BOARDID, 1, SDF_INTERNAL, },
-               .io_access      = IO_8b,
+               .sdi[1]         = { 32, 0x00, },        /* ISO DI 0-31 */
+               .id_reg         = 0x04,
        },
        [TYPE_PCI1734] = {
                .name           = "pci1734",
-               .main_pci_region = PCIDIO_MAINREG,
-               .cardtype       = TYPE_PCI1734,
                .nsubdevs       = 2,
-               .sdo[1]         = { 32, PCI1734_IDO, 4, 0, },
-               .boardid        = { 4, PCI173x_BOARDID, 1, SDF_INTERNAL, },
-               .io_access      = IO_8b,
+               .sdo[1]         = { 32, 0x00, },        /* ISO DO 0-31 */
+               .id_reg         = 0x04,
        },
        [TYPE_PCI1735] = {
                .name           = "pci1735",
-               .main_pci_region = PCIDIO_MAINREG,
-               .cardtype       = TYPE_PCI1735,
                .nsubdevs       = 4,
-               .sdi[0]         = { 32, PCI1735_DI, 4, 0, },
-               .sdo[0]         = { 32, PCI1735_DO, 4, 0, },
-               .boardid        = { 4, PCI1735_BOARDID, 1, SDF_INTERNAL, },
-               .timer_regbase  = PCI1735_C8254,
-               .io_access      = IO_8b,
+               .sdi[0]         = { 32, 0x00, },        /* DI 0-31 */
+               .sdo[0]         = { 32, 0x00, },        /* DO 0-31 */
+               .id_reg         = 0x08,
+               .timer_regbase  = 0x04,
        },
        [TYPE_PCI1736] = {
                .name           = "pci1736",
-               .main_pci_region = PCI1736_MAINREG,
-               .cardtype       = TYPE_PCI1736,
                .nsubdevs       = 3,
-               .sdi[1]         = { 16, PCI1736_IDI, 2, 0, },
-               .sdo[1]         = { 16, PCI1736_IDO, 2, 0, },
-               .boardid        = { 4, PCI1736_BOARDID, 1, SDF_INTERNAL, },
-               .io_access      = IO_8b,
+               .sdi[1]         = { 16, 0x00, },        /* ISO DI 0-15 */
+               .sdo[1]         = { 16, 0x00, },        /* ISO DO 0-15 */
+               .id_reg         = 0x04,
        },
        [TYPE_PCI1739] = {
                .name           = "pci1739",
-               .main_pci_region = PCIDIO_MAINREG,
-               .cardtype       = TYPE_PCI1739,
-               .nsubdevs       = 2,
-               .sdio[0]        = { 48, PCI1739_DIO, 2, 0, },
-               .io_access      = IO_8b,
+               .nsubdevs       = 3,
+               .sdio[0]        = { 2, 0x00, },         /* 8255 DIO */
+               .id_reg         = 0x08,
        },
        [TYPE_PCI1750] = {
                .name           = "pci1750",
-               .main_pci_region = PCIDIO_MAINREG,
-               .cardtype       = TYPE_PCI1750,
                .nsubdevs       = 2,
-               .sdi[1]         = { 16, PCI1750_IDI, 2, 0, },
-               .sdo[1]         = { 16, PCI1750_IDO, 2, 0, },
-               .io_access      = IO_8b,
+               .sdi[1]         = { 16, 0x00, },        /* ISO DI 0-15 */
+               .sdo[1]         = { 16, 0x00, },        /* ISO DO 0-15 */
        },
        [TYPE_PCI1751] = {
                .name           = "pci1751",
-               .main_pci_region = PCIDIO_MAINREG,
-               .cardtype       = TYPE_PCI1751,
                .nsubdevs       = 3,
-               .sdio[0]        = { 48, PCI1751_DIO, 2, 0, },
-               .timer_regbase  = PCI1751_CNT,
-               .io_access      = IO_8b,
+               .sdio[0]        = { 2, 0x00, },         /* 8255 DIO */
+               .timer_regbase  = 0x18,
        },
        [TYPE_PCI1752] = {
                .name           = "pci1752",
-               .main_pci_region = PCIDIO_MAINREG,
-               .cardtype       = TYPE_PCI1752,
                .nsubdevs       = 3,
-               .sdo[0]         = { 32, PCI1752_IDO, 2, 0, },
-               .sdo[1]         = { 32, PCI1752_IDO2, 2, 0, },
-               .boardid        = { 4, PCI175x_BOARDID, 1, SDF_INTERNAL, },
-               .io_access      = IO_16b,
+               .sdo[0]         = { 32, 0x00, },        /* DO 0-31 */
+               .sdo[1]         = { 32, 0x04, },        /* DO 32-63 */
+               .id_reg         = 0x10,
+               .is_16bit       = 1,
        },
        [TYPE_PCI1753] = {
                .name           = "pci1753",
-               .main_pci_region = PCIDIO_MAINREG,
-               .cardtype       = TYPE_PCI1753,
                .nsubdevs       = 4,
-               .sdio[0]        = { 96, PCI1753_DIO, 4, 0, },
-               .io_access      = IO_8b,
+               .sdio[0]        = { 4, 0x00, },         /* 8255 DIO */
        },
        [TYPE_PCI1753E] = {
                .name           = "pci1753e",
-               .main_pci_region = PCIDIO_MAINREG,
-               .cardtype       = TYPE_PCI1753E,
                .nsubdevs       = 8,
-               .sdio[0]        = { 96, PCI1753_DIO, 4, 0, },
-               .sdio[1]        = { 96, PCI1753E_DIO, 4, 0, },
-               .io_access      = IO_8b,
+               .sdio[0]        = { 4, 0x00, },         /* 8255 DIO */
+               .sdio[1]        = { 4, 0x20, },         /* 8255 DIO */
        },
        [TYPE_PCI1754] = {
                .name           = "pci1754",
-               .main_pci_region = PCIDIO_MAINREG,
-               .cardtype       = TYPE_PCI1754,
                .nsubdevs       = 3,
-               .sdi[0]         = { 32, PCI1754_IDI, 2, 0, },
-               .sdi[1]         = { 32, PCI1754_IDI2, 2, 0, },
-               .boardid        = { 4, PCI175x_BOARDID, 1, SDF_INTERNAL, },
-               .io_access      = IO_16b,
+               .sdi[0]         = { 32, 0x00, },        /* DI 0-31 */
+               .sdi[1]         = { 32, 0x04, },        /* DI 32-63 */
+               .id_reg         = 0x10,
+               .is_16bit       = 1,
        },
        [TYPE_PCI1756] = {
                .name           = "pci1756",
-               .main_pci_region = PCIDIO_MAINREG,
-               .cardtype       = TYPE_PCI1756,
                .nsubdevs       = 3,
-               .sdi[1]         = { 32, PCI1756_IDI, 2, 0, },
-               .sdo[1]         = { 32, PCI1756_IDO, 2, 0, },
-               .boardid        = { 4, PCI175x_BOARDID, 1, SDF_INTERNAL, },
-               .io_access      = IO_16b,
-       },
-       [TYPE_PCI1760] = {
-               /* This card has its own 'attach' */
-               .name           = "pci1760",
-               .main_pci_region = 0,
-               .cardtype       = TYPE_PCI1760,
-               .nsubdevs       = 4,
-               .io_access      = IO_8b,
+               .sdi[1]         = { 32, 0x00, },        /* DI 0-31 */
+               .sdo[1]         = { 32, 0x04, },        /* DO 0-31 */
+               .id_reg         = 0x10,
+               .is_16bit       = 1,
        },
        [TYPE_PCI1762] = {
                .name           = "pci1762",
-               .main_pci_region = PCIDIO_MAINREG,
-               .cardtype       = TYPE_PCI1762,
                .nsubdevs       = 3,
-               .sdi[1]         = { 16, PCI1762_IDI, 1, 0, },
-               .sdo[1]         = { 16, PCI1762_RO, 1, 0, },
-               .boardid        = { 4, PCI1762_BOARDID, 1, SDF_INTERNAL, },
-               .io_access      = IO_16b,
+               .sdi[1]         = { 16, 0x02, },        /* ISO DI 0-15 */
+               .sdo[1]         = { 16, 0x00, },        /* ISO DO 0-15 */
+               .id_reg         = 0x04,
+               .is_16bit       = 1,
        },
 };
 
-struct pci_dio_private {
-       char GlobalIrqEnabled;  /*  1= any IRQ source is enabled */
-       /*  PCI-1760 specific data */
-       unsigned char IDICntEnable;     /* counter's counting enable status */
-       unsigned char IDICntOverEnable; /* counter's overflow interrupts enable
-                                        * status */
-       unsigned char IDICntMatchEnable;        /* counter's match interrupts
-                                                * enable status */
-       unsigned char IDICntEdge;       /* counter's count edge value
-                                        * (bit=0 - rising, =1 - falling) */
-       unsigned short CntResValue[8];  /*  counters' reset value */
-       unsigned short CntMatchValue[8]; /*  counters' match interrupt value */
-       unsigned char IDIFiltersEn; /*  IDI's digital filters enable status */
-       unsigned char IDIPatMatchEn;    /*  IDI's pattern match enable status */
-       unsigned char IDIPatMatchValue; /*  IDI's pattern match value */
-       unsigned short IDIFiltrLow[8];  /*  IDI's filter value low signal */
-       unsigned short IDIFiltrHigh[8]; /*  IDI's filter value high signal */
-};
-
-/*
-==============================================================================
-*/
 static int pci_dio_insn_bits_di_b(struct comedi_device *dev,
                                  struct comedi_subdevice *s,
-                                 struct comedi_insn *insn, unsigned int *data)
+                                 struct comedi_insn *insn,
+                                 unsigned int *data)
 {
-       const struct diosubd_data *d = (const struct diosubd_data *)s->private;
-       int i;
+       unsigned long reg = (unsigned long)s->private;
+       unsigned long iobase = dev->iobase + reg;
 
-       data[1] = 0;
-       for (i = 0; i < d->regs; i++)
-               data[1] |= inb(dev->iobase + d->addr + i) << (8 * i);
+       data[1] = inb(iobase);
+       if (s->n_chan > 8)
+               data[1] |= (inb(iobase + 1) << 8);
+       if (s->n_chan > 16)
+               data[1] |= (inb(iobase + 2) << 16);
+       if (s->n_chan > 24)
+               data[1] |= (inb(iobase + 3) << 24);
 
        return insn->n;
 }
 
-/*
-==============================================================================
-*/
 static int pci_dio_insn_bits_di_w(struct comedi_device *dev,
                                  struct comedi_subdevice *s,
-                                 struct comedi_insn *insn, unsigned int *data)
+                                 struct comedi_insn *insn,
+                                 unsigned int *data)
 {
-       const struct diosubd_data *d = (const struct diosubd_data *)s->private;
-       int i;
+       unsigned long reg = (unsigned long)s->private;
+       unsigned long iobase = dev->iobase + reg;
 
-       data[1] = 0;
-       for (i = 0; i < d->regs; i++)
-               data[1] |= inw(dev->iobase + d->addr + 2 * i) << (16 * i);
+       data[1] = inw(iobase);
+       if (s->n_chan > 16)
+               data[1] |= (inw(iobase + 2) << 16);
 
        return insn->n;
 }
@@ -443,13 +230,17 @@ static int pci_dio_insn_bits_do_b(struct comedi_device *dev,
                                  struct comedi_insn *insn,
                                  unsigned int *data)
 {
-       const struct diosubd_data *d = (const struct diosubd_data *)s->private;
-       int i;
+       unsigned long reg = (unsigned long)s->private;
+       unsigned long iobase = dev->iobase + reg;
 
        if (comedi_dio_update_state(s, data)) {
-               for (i = 0; i < d->regs; i++)
-                       outb((s->state >> (8 * i)) & 0xff,
-                            dev->iobase + d->addr + i);
+               outb(s->state & 0xff, iobase);
+               if (s->n_chan > 8)
+                       outb((s->state >> 8) & 0xff, iobase + 1);
+               if (s->n_chan > 16)
+                       outb((s->state >> 16) & 0xff, iobase + 2);
+               if (s->n_chan > 24)
+                       outb((s->state >> 24) & 0xff, iobase + 3);
        }
 
        data[1] = s->state;
@@ -462,13 +253,13 @@ static int pci_dio_insn_bits_do_w(struct comedi_device *dev,
                                  struct comedi_insn *insn,
                                  unsigned int *data)
 {
-       const struct diosubd_data *d = (const struct diosubd_data *)s->private;
-       int i;
+       unsigned long reg = (unsigned long)s->private;
+       unsigned long iobase = dev->iobase + reg;
 
        if (comedi_dio_update_state(s, data)) {
-               for (i = 0; i < d->regs; i++)
-                       outw((s->state >> (16 * i)) & 0xffff,
-                            dev->iobase + d->addr + 2 * i);
+               outw(s->state & 0xffff, iobase);
+               if (s->n_chan > 16)
+                       outw((s->state >> 16) & 0xffff, iobase + 2);
        }
 
        data[1] = s->state;
@@ -476,510 +267,64 @@ static int pci_dio_insn_bits_do_w(struct comedi_device *dev,
        return insn->n;
 }
 
-/*
-==============================================================================
-*/
-static int pci1760_unchecked_mbxrequest(struct comedi_device *dev,
-                                       unsigned char *omb, unsigned char *imb,
-                                       int repeats)
-{
-       int cnt, tout, ok = 0;
-
-       for (cnt = 0; cnt < repeats; cnt++) {
-               outb(omb[0], dev->iobase + OMB0);
-               outb(omb[1], dev->iobase + OMB1);
-               outb(omb[2], dev->iobase + OMB2);
-               outb(omb[3], dev->iobase + OMB3);
-               for (tout = 0; tout < 251; tout++) {
-                       imb[2] = inb(dev->iobase + IMB2);
-                       if (imb[2] == omb[2]) {
-                               imb[0] = inb(dev->iobase + IMB0);
-                               imb[1] = inb(dev->iobase + IMB1);
-                               imb[3] = inb(dev->iobase + IMB3);
-                               ok = 1;
-                               break;
-                       }
-                       udelay(1);
-               }
-               if (ok)
-                       return 0;
-       }
-
-       dev_err(dev->class_dev, "PCI-1760 mailbox request timeout!\n");
-       return -ETIME;
-}
-
-static int pci1760_clear_imb2(struct comedi_device *dev)
-{
-       unsigned char omb[4] = { 0x0, 0x0, CMD_ClearIMB2, 0x0 };
-       unsigned char imb[4];
-       /* check if imb2 is already clear */
-       if (inb(dev->iobase + IMB2) == CMD_ClearIMB2)
-               return 0;
-       return pci1760_unchecked_mbxrequest(dev, omb, imb, OMBCMD_RETRY);
-}
-
-static int pci1760_mbxrequest(struct comedi_device *dev,
-                             unsigned char *omb, unsigned char *imb)
-{
-       if (omb[2] == CMD_ClearIMB2) {
-               dev_err(dev->class_dev,
-                       "bug! this function should not be used for CMD_ClearIMB2 command\n");
-               return -EINVAL;
-       }
-       if (inb(dev->iobase + IMB2) == omb[2]) {
-               int retval;
-
-               retval = pci1760_clear_imb2(dev);
-               if (retval < 0)
-                       return retval;
-       }
-       return pci1760_unchecked_mbxrequest(dev, omb, imb, OMBCMD_RETRY);
-}
-
-/*
-==============================================================================
-*/
-static int pci1760_insn_bits_di(struct comedi_device *dev,
-                               struct comedi_subdevice *s,
-                               struct comedi_insn *insn, unsigned int *data)
+static int pci_dio_reset(struct comedi_device *dev, unsigned long cardtype)
 {
-       data[1] = inb(dev->iobase + IMB3);
+       /* disable channel freeze function on the PCI-1752/1756 boards */
+       if (cardtype == TYPE_PCI1752 || cardtype == TYPE_PCI1756)
+               outw(0, dev->iobase + PCI1752_CFC_REG);
 
-       return insn->n;
-}
-
-static int pci1760_insn_bits_do(struct comedi_device *dev,
-                               struct comedi_subdevice *s,
-                               struct comedi_insn *insn,
-                               unsigned int *data)
-{
-       int ret;
-       unsigned char omb[4] = {
-               0x00,
-               0x00,
-               CMD_SetRelaysOutput,
-               0x00
-       };
-       unsigned char imb[4];
-
-       if (comedi_dio_update_state(s, data)) {
-               omb[0] = s->state;
-               ret = pci1760_mbxrequest(dev, omb, imb);
-               if (!ret)
-                       return ret;
-       }
-
-       data[1] = s->state;
-
-       return insn->n;
-}
-
-/*
-==============================================================================
-*/
-static int pci1760_insn_cnt_read(struct comedi_device *dev,
-                                struct comedi_subdevice *s,
-                                struct comedi_insn *insn, unsigned int *data)
-{
-       int ret, n;
-       unsigned char omb[4] = {
-               CR_CHAN(insn->chanspec) & 0x07,
-               0x00,
-               CMD_GetIDICntCurValue,
-               0x00
-       };
-       unsigned char imb[4];
-
-       for (n = 0; n < insn->n; n++) {
-               ret = pci1760_mbxrequest(dev, omb, imb);
-               if (!ret)
-                       return ret;
-               data[n] = (imb[1] << 8) + imb[0];
-       }
-
-       return n;
-}
-
-/*
-==============================================================================
-*/
-static int pci1760_insn_cnt_write(struct comedi_device *dev,
-                                 struct comedi_subdevice *s,
-                                 struct comedi_insn *insn, unsigned int *data)
-{
-       struct pci_dio_private *devpriv = dev->private;
-       int ret;
-       unsigned char chan = CR_CHAN(insn->chanspec) & 0x07;
-       unsigned char bitmask = 1 << chan;
-       unsigned char omb[4] = {
-               data[0] & 0xff,
-               (data[0] >> 8) & 0xff,
-               CMD_SetIDI0CntResetValue + chan,
-               0x00
-       };
-       unsigned char imb[4];
-
-       /* Set reset value if different */
-       if (devpriv->CntResValue[chan] != (data[0] & 0xffff)) {
-               ret = pci1760_mbxrequest(dev, omb, imb);
-               if (!ret)
-                       return ret;
-               devpriv->CntResValue[chan] = data[0] & 0xffff;
-       }
-
-       omb[0] = bitmask;       /*  reset counter to it reset value */
-       omb[2] = CMD_ResetIDICounters;
-       ret = pci1760_mbxrequest(dev, omb, imb);
-       if (!ret)
-               return ret;
-
-       /*  start counter if it don't run */
-       if (!(bitmask & devpriv->IDICntEnable)) {
-               omb[0] = bitmask;
-               omb[2] = CMD_EnableIDICounters;
-               ret = pci1760_mbxrequest(dev, omb, imb);
-               if (!ret)
-                       return ret;
-               devpriv->IDICntEnable |= bitmask;
-       }
-       return 1;
-}
-
-/*
-==============================================================================
-*/
-static int pci1760_reset(struct comedi_device *dev)
-{
-       struct pci_dio_private *devpriv = dev->private;
-       int i;
-       unsigned char omb[4] = { 0x00, 0x00, 0x00, 0x00 };
-       unsigned char imb[4];
-
-       outb(0, dev->iobase + INTCSR0); /*  disable IRQ */
-       outb(0, dev->iobase + INTCSR1);
-       outb(0, dev->iobase + INTCSR2);
-       outb(0, dev->iobase + INTCSR3);
-       devpriv->GlobalIrqEnabled = 0;
-
-       omb[0] = 0x00;
-       omb[2] = CMD_SetRelaysOutput;   /*  reset relay outputs */
-       pci1760_mbxrequest(dev, omb, imb);
-
-       omb[0] = 0x00;
-       omb[2] = CMD_EnableIDICounters; /*  disable IDI up counters */
-       pci1760_mbxrequest(dev, omb, imb);
-       devpriv->IDICntEnable = 0;
-
-       omb[0] = 0x00;
-       omb[2] = CMD_OverflowIDICounters; /* disable counters overflow
-                                          * interrupts */
-       pci1760_mbxrequest(dev, omb, imb);
-       devpriv->IDICntOverEnable = 0;
-
-       omb[0] = 0x00;
-       omb[2] = CMD_MatchIntIDICounters; /* disable counters match value
-                                          * interrupts */
-       pci1760_mbxrequest(dev, omb, imb);
-       devpriv->IDICntMatchEnable = 0;
-
-       omb[0] = 0x00;
-       omb[1] = 0x80;
-       for (i = 0; i < 8; i++) {       /*  set IDI up counters match value */
-               omb[2] = CMD_SetIDI0CntMatchValue + i;
-               pci1760_mbxrequest(dev, omb, imb);
-               devpriv->CntMatchValue[i] = 0x8000;
-       }
-
-       omb[0] = 0x00;
-       omb[1] = 0x00;
-       for (i = 0; i < 8; i++) {       /*  set IDI up counters reset value */
-               omb[2] = CMD_SetIDI0CntResetValue + i;
-               pci1760_mbxrequest(dev, omb, imb);
-               devpriv->CntResValue[i] = 0x0000;
-       }
-
-       omb[0] = 0xff;
-       omb[2] = CMD_ResetIDICounters; /* reset IDI up counters to reset
-                                       * values */
-       pci1760_mbxrequest(dev, omb, imb);
-
-       omb[0] = 0x00;
-       omb[2] = CMD_EdgeIDICounters;   /*  set IDI up counters count edge */
-       pci1760_mbxrequest(dev, omb, imb);
-       devpriv->IDICntEdge = 0x00;
-
-       omb[0] = 0x00;
-       omb[2] = CMD_EnableIDIFilters;  /*  disable all digital in filters */
-       pci1760_mbxrequest(dev, omb, imb);
-       devpriv->IDIFiltersEn = 0x00;
-
-       omb[0] = 0x00;
-       omb[2] = CMD_EnableIDIPatternMatch;     /*  disable pattern matching */
-       pci1760_mbxrequest(dev, omb, imb);
-       devpriv->IDIPatMatchEn = 0x00;
-
-       omb[0] = 0x00;
-       omb[2] = CMD_SetIDIPatternMatch;        /*  set pattern match value */
-       pci1760_mbxrequest(dev, omb, imb);
-       devpriv->IDIPatMatchValue = 0x00;
-
-       return 0;
-}
-
-/*
-==============================================================================
-*/
-static int pci_dio_reset(struct comedi_device *dev)
-{
-       const struct dio_boardtype *board = dev->board_ptr;
-
-       switch (board->cardtype) {
+       /* disable and clear interrupts */
+       switch (cardtype) {
        case TYPE_PCI1730:
-               outb(0, dev->iobase + PCI1730_DO);      /*  clear outputs */
-               outb(0, dev->iobase + PCI1730_DO + 1);
-               outb(0, dev->iobase + PCI1730_IDO);
-               outb(0, dev->iobase + PCI1730_IDO + 1);
-               /* fallthrough */
        case TYPE_PCI1733:
-               /* disable interrupts */
-               outb(0, dev->iobase + PCI1730_3_INT_EN);
-               /* clear interrupts */
-               outb(0x0f, dev->iobase + PCI1730_3_INT_CLR);
-               /* set rising edge trigger */
-               outb(0, dev->iobase + PCI1730_3_INT_RF);
-               break;
-       case TYPE_PCI1734:
-               outb(0, dev->iobase + PCI1734_IDO);     /*  clear outputs */
-               outb(0, dev->iobase + PCI1734_IDO + 1);
-               outb(0, dev->iobase + PCI1734_IDO + 2);
-               outb(0, dev->iobase + PCI1734_IDO + 3);
-               break;
-       case TYPE_PCI1735:
-               outb(0, dev->iobase + PCI1735_DO);      /*  clear outputs */
-               outb(0, dev->iobase + PCI1735_DO + 1);
-               outb(0, dev->iobase + PCI1735_DO + 2);
-               outb(0, dev->iobase + PCI1735_DO + 3);
-               break;
-
        case TYPE_PCI1736:
-               outb(0, dev->iobase + PCI1736_IDO);
-               outb(0, dev->iobase + PCI1736_IDO + 1);
-               /* disable interrupts */
-               outb(0, dev->iobase + PCI1736_3_INT_EN);
-               /* clear interrupts */
-               outb(0x0f, dev->iobase + PCI1736_3_INT_CLR);
-               /* set rising edge trigger */
-               outb(0, dev->iobase + PCI1736_3_INT_RF);
+               outb(0, dev->iobase + PCI173X_INT_EN_REG);
+               outb(0x0f, dev->iobase + PCI173X_INT_CLR_REG);
+               outb(0, dev->iobase + PCI173X_INT_RF_REG);
                break;
-
        case TYPE_PCI1739:
-               /* disable & clear interrupts */
-               outb(0x88, dev->iobase + PCI1739_ICR);
-               break;
-
        case TYPE_PCI1750:
        case TYPE_PCI1751:
-               /* disable & clear interrupts */
-               outb(0x88, dev->iobase + PCI1750_ICR);
-               break;
-       case TYPE_PCI1752:
-               outw(0, dev->iobase + PCI1752_6_CFC); /* disable channel freeze
-                                                      * function */
-               outw(0, dev->iobase + PCI1752_IDO);     /*  clear outputs */
-               outw(0, dev->iobase + PCI1752_IDO + 2);
-               outw(0, dev->iobase + PCI1752_IDO2);
-               outw(0, dev->iobase + PCI1752_IDO2 + 2);
+               outb(0x88, dev->iobase + PCI1750_INT_REG);
                break;
-       case TYPE_PCI1753E:
-               outb(0x88, dev->iobase + PCI1753E_ICR0); /* disable & clear
-                                                         * interrupts */
-               outb(0x80, dev->iobase + PCI1753E_ICR1);
-               outb(0x80, dev->iobase + PCI1753E_ICR2);
-               outb(0x80, dev->iobase + PCI1753E_ICR3);
-               /* fallthrough */
        case TYPE_PCI1753:
-               outb(0x88, dev->iobase + PCI1753_ICR0); /* disable & clear
-                                                        * interrupts */
-               outb(0x80, dev->iobase + PCI1753_ICR1);
-               outb(0x80, dev->iobase + PCI1753_ICR2);
-               outb(0x80, dev->iobase + PCI1753_ICR3);
+       case TYPE_PCI1753E:
+               outb(0x88, dev->iobase + PCI1753_INT_REG(0));
+               outb(0x80, dev->iobase + PCI1753_INT_REG(1));
+               outb(0x80, dev->iobase + PCI1753_INT_REG(2));
+               outb(0x80, dev->iobase + PCI1753_INT_REG(3));
+               if (cardtype == TYPE_PCI1753E) {
+                       outb(0x88, dev->iobase + PCI1753E_INT_REG(0));
+                       outb(0x80, dev->iobase + PCI1753E_INT_REG(1));
+                       outb(0x80, dev->iobase + PCI1753E_INT_REG(2));
+                       outb(0x80, dev->iobase + PCI1753E_INT_REG(3));
+               }
                break;
        case TYPE_PCI1754:
-               outw(0x08, dev->iobase + PCI1754_6_ICR0); /* disable and clear
-                                                          * interrupts */
-               outw(0x08, dev->iobase + PCI1754_6_ICR1);
-               outw(0x08, dev->iobase + PCI1754_ICR2);
-               outw(0x08, dev->iobase + PCI1754_ICR3);
-               break;
        case TYPE_PCI1756:
-               outw(0, dev->iobase + PCI1752_6_CFC); /* disable channel freeze
-                                                      * function */
-               outw(0x08, dev->iobase + PCI1754_6_ICR0); /* disable and clear
-                                                          * interrupts */
-               outw(0x08, dev->iobase + PCI1754_6_ICR1);
-               outw(0, dev->iobase + PCI1756_IDO);     /*  clear outputs */
-               outw(0, dev->iobase + PCI1756_IDO + 2);
-               break;
-       case TYPE_PCI1760:
-               pci1760_reset(dev);
+               outw(0x08, dev->iobase + PCI1754_INT_REG(0));
+               outw(0x08, dev->iobase + PCI1754_INT_REG(1));
+               if (cardtype == TYPE_PCI1754) {
+                       outw(0x08, dev->iobase + PCI1754_INT_REG(2));
+                       outw(0x08, dev->iobase + PCI1754_INT_REG(3));
+               }
                break;
        case TYPE_PCI1762:
-               outw(0x0101, dev->iobase + PCI1762_ICR); /* disable & clear
-                                                         * interrupts */
-               break;
-       }
-
-       return 0;
-}
-
-/*
-==============================================================================
-*/
-static int pci1760_attach(struct comedi_device *dev)
-{
-       struct comedi_subdevice *s;
-
-       s = &dev->subdevices[0];
-       s->type = COMEDI_SUBD_DI;
-       s->subdev_flags = SDF_READABLE;
-       s->n_chan = 8;
-       s->maxdata = 1;
-       s->len_chanlist = 8;
-       s->range_table = &range_digital;
-       s->insn_bits = pci1760_insn_bits_di;
-
-       s = &dev->subdevices[1];
-       s->type = COMEDI_SUBD_DO;
-       s->subdev_flags = SDF_WRITABLE;
-       s->n_chan = 8;
-       s->maxdata = 1;
-       s->len_chanlist = 8;
-       s->range_table = &range_digital;
-       s->state = 0;
-       s->insn_bits = pci1760_insn_bits_do;
-
-       s = &dev->subdevices[2];
-       s->type = COMEDI_SUBD_TIMER;
-       s->subdev_flags = SDF_WRITABLE | SDF_LSAMPL;
-       s->n_chan = 2;
-       s->maxdata = 0xffffffff;
-       s->len_chanlist = 2;
-/*       s->insn_config=pci1760_insn_pwm_cfg; */
-
-       s = &dev->subdevices[3];
-       s->type = COMEDI_SUBD_COUNTER;
-       s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
-       s->n_chan = 8;
-       s->maxdata = 0xffff;
-       s->len_chanlist = 8;
-       s->insn_read = pci1760_insn_cnt_read;
-       s->insn_write = pci1760_insn_cnt_write;
-/*       s->insn_config=pci1760_insn_cnt_cfg; */
-
-       return 0;
-}
-
-/*
-==============================================================================
-*/
-static int pci_dio_add_di(struct comedi_device *dev,
-                         struct comedi_subdevice *s,
-                         const struct diosubd_data *d)
-{
-       const struct dio_boardtype *board = dev->board_ptr;
-
-       s->type = COMEDI_SUBD_DI;
-       s->subdev_flags = SDF_READABLE | d->specflags;
-       if (d->chans > 16)
-               s->subdev_flags |= SDF_LSAMPL;
-       s->n_chan = d->chans;
-       s->maxdata = 1;
-       s->len_chanlist = d->chans;
-       s->range_table = &range_digital;
-       switch (board->io_access) {
-       case IO_8b:
-               s->insn_bits = pci_dio_insn_bits_di_b;
-               break;
-       case IO_16b:
-               s->insn_bits = pci_dio_insn_bits_di_w;
-               break;
-       }
-       s->private = (void *)d;
-
-       return 0;
-}
-
-/*
-==============================================================================
-*/
-static int pci_dio_add_do(struct comedi_device *dev,
-                         struct comedi_subdevice *s,
-                         const struct diosubd_data *d)
-{
-       const struct dio_boardtype *board = dev->board_ptr;
-
-       s->type = COMEDI_SUBD_DO;
-       s->subdev_flags = SDF_WRITABLE;
-       if (d->chans > 16)
-               s->subdev_flags |= SDF_LSAMPL;
-       s->n_chan = d->chans;
-       s->maxdata = 1;
-       s->len_chanlist = d->chans;
-       s->range_table = &range_digital;
-       s->state = 0;
-       switch (board->io_access) {
-       case IO_8b:
-               s->insn_bits = pci_dio_insn_bits_do_b;
+               outw(0x0101, dev->iobase + PCI1762_INT_REG);
                break;
-       case IO_16b:
-               s->insn_bits = pci_dio_insn_bits_do_w;
+       default:
                break;
        }
-       s->private = (void *)d;
 
        return 0;
 }
 
-static unsigned long pci_dio_override_cardtype(struct pci_dev *pcidev,
-                                              unsigned long cardtype)
-{
-       /*
-        * Change cardtype from TYPE_PCI1753 to TYPE_PCI1753E if expansion
-        * board available.  Need to enable PCI device and request the main
-        * registers PCI BAR temporarily to perform the test.
-        */
-       if (cardtype != TYPE_PCI1753)
-               return cardtype;
-       if (pci_enable_device(pcidev) < 0)
-               return cardtype;
-       if (pci_request_region(pcidev, PCIDIO_MAINREG, "adv_pci_dio") == 0) {
-               /*
-                * This test is based on Advantech's "advdaq" driver source
-                * (which declares its module licence as "GPL" although the
-                * driver source does not include a "COPYING" file).
-                */
-               unsigned long reg =
-                       pci_resource_start(pcidev, PCIDIO_MAINREG) + 53;
-
-               outb(0x05, reg);
-               if ((inb(reg) & 0x07) == 0x02) {
-                       outb(0x02, reg);
-                       if ((inb(reg) & 0x07) == 0x05)
-                               cardtype = TYPE_PCI1753E;
-               }
-               pci_release_region(pcidev, PCIDIO_MAINREG);
-       }
-       pci_disable_device(pcidev);
-       return cardtype;
-}
-
 static int pci_dio_auto_attach(struct comedi_device *dev,
                               unsigned long context)
 {
        struct pci_dev *pcidev = comedi_to_pci_dev(dev);
        const struct dio_boardtype *board = NULL;
-       struct pci_dio_private *devpriv;
+       const struct diosubd_data *d;
        struct comedi_subdevice *s;
        int ret, subdev, i, j;
 
@@ -990,54 +335,93 @@ static int pci_dio_auto_attach(struct comedi_device *dev,
        dev->board_ptr = board;
        dev->board_name = board->name;
 
-       devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
-       if (!devpriv)
-               return -ENOMEM;
-
        ret = comedi_pci_enable(dev);
        if (ret)
                return ret;
-       dev->iobase = pci_resource_start(pcidev, board->main_pci_region);
+       if (context == TYPE_PCI1736)
+               dev->iobase = pci_resource_start(pcidev, 0);
+       else
+               dev->iobase = pci_resource_start(pcidev, 2);
+
+       pci_dio_reset(dev, context);
 
        ret = comedi_alloc_subdevices(dev, board->nsubdevs);
        if (ret)
                return ret;
 
        subdev = 0;
-       for (i = 0; i < MAX_DI_SUBDEVS; i++)
-               if (board->sdi[i].chans) {
-                       s = &dev->subdevices[subdev];
-                       pci_dio_add_di(dev, s, &board->sdi[i]);
-                       subdev++;
+       for (i = 0; i < PCI_DIO_MAX_DI_SUBDEVS; i++) {
+               d = &board->sdi[i];
+               if (d->chans) {
+                       s = &dev->subdevices[subdev++];
+                       s->type         = COMEDI_SUBD_DI;
+                       s->subdev_flags = SDF_READABLE;
+                       s->n_chan       = d->chans;
+                       s->maxdata      = 1;
+                       s->range_table  = &range_digital;
+                       s->insn_bits    = board->is_16bit
+                                               ? pci_dio_insn_bits_di_w
+                                               : pci_dio_insn_bits_di_b;
+                       s->private      = (void *)d->addr;
                }
+       }
 
-       for (i = 0; i < MAX_DO_SUBDEVS; i++)
-               if (board->sdo[i].chans) {
-                       s = &dev->subdevices[subdev];
-                       pci_dio_add_do(dev, s, &board->sdo[i]);
-                       subdev++;
+       for (i = 0; i < PCI_DIO_MAX_DO_SUBDEVS; i++) {
+               d = &board->sdo[i];
+               if (d->chans) {
+                       s = &dev->subdevices[subdev++];
+                       s->type         = COMEDI_SUBD_DO;
+                       s->subdev_flags = SDF_WRITABLE;
+                       s->n_chan       = d->chans;
+                       s->maxdata      = 1;
+                       s->range_table  = &range_digital;
+                       s->insn_bits    = board->is_16bit
+                                               ? pci_dio_insn_bits_do_w
+                                               : pci_dio_insn_bits_do_b;
+                       s->private      = (void *)d->addr;
+
+                       /* reset all outputs to 0 */
+                       if (board->is_16bit) {
+                               outw(0, dev->iobase + d->addr);
+                               if (s->n_chan > 16)
+                                       outw(0, dev->iobase + d->addr + 2);
+                       } else {
+                               outb(0, dev->iobase + d->addr);
+                               if (s->n_chan > 8)
+                                       outb(0, dev->iobase + d->addr + 1);
+                               if (s->n_chan > 16)
+                                       outb(0, dev->iobase + d->addr + 2);
+                               if (s->n_chan > 24)
+                                       outb(0, dev->iobase + d->addr + 3);
+                       }
                }
+       }
 
-       for (i = 0; i < MAX_DIO_SUBDEVG; i++)
-               for (j = 0; j < board->sdio[i].regs; j++) {
-                       s = &dev->subdevices[subdev];
+       for (i = 0; i < PCI_DIO_MAX_DIO_SUBDEVG; i++) {
+               d = &board->sdio[i];
+               for (j = 0; j < d->chans; j++) {
+                       s = &dev->subdevices[subdev++];
                        ret = subdev_8255_init(dev, s, NULL,
-                                              board->sdio[i].addr +
-                                              j * I8255_SIZE);
+                                              d->addr + j * I8255_SIZE);
                        if (ret)
                                return ret;
-                       subdev++;
                }
+       }
 
-       if (board->boardid.chans) {
-               s = &dev->subdevices[subdev];
-               s->type = COMEDI_SUBD_DI;
-               pci_dio_add_di(dev, s, &board->boardid);
-               subdev++;
+       if (board->id_reg) {
+               s = &dev->subdevices[subdev++];
+               s->type         = COMEDI_SUBD_DI;
+               s->subdev_flags = SDF_READABLE | SDF_INTERNAL;
+               s->n_chan       = 4;
+               s->maxdata      = 1;
+               s->range_table  = &range_digital;
+               s->insn_bits    = board->is_16bit ? pci_dio_insn_bits_di_w
+                                                 : pci_dio_insn_bits_di_b;
+               s->private      = (void *)board->id_reg;
        }
 
        if (board->timer_regbase) {
-               s = &dev->subdevices[subdev];
+               s = &dev->subdevices[subdev++];
 
                dev->pacer = comedi_8254_init(dev->iobase +
                                              board->timer_regbase,
@@ -1046,32 +430,50 @@ static int pci_dio_auto_attach(struct comedi_device *dev,
                        return -ENOMEM;
 
                comedi_8254_subdevice_init(s, dev->pacer);
-
-               subdev++;
        }
 
-       if (board->cardtype == TYPE_PCI1760)
-               pci1760_attach(dev);
-
-       pci_dio_reset(dev);
-
        return 0;
 }
 
-static void pci_dio_detach(struct comedi_device *dev)
-{
-       if (dev->iobase)
-               pci_dio_reset(dev);
-       comedi_pci_detach(dev);
-}
-
 static struct comedi_driver adv_pci_dio_driver = {
        .driver_name    = "adv_pci_dio",
        .module         = THIS_MODULE,
        .auto_attach    = pci_dio_auto_attach,
-       .detach         = pci_dio_detach,
+       .detach         = comedi_pci_detach,
 };
 
+static unsigned long pci_dio_override_cardtype(struct pci_dev *pcidev,
+                                              unsigned long cardtype)
+{
+       /*
+        * Change cardtype from TYPE_PCI1753 to TYPE_PCI1753E if expansion
+        * board available.  Need to enable PCI device and request the main
+        * registers PCI BAR temporarily to perform the test.
+        */
+       if (cardtype != TYPE_PCI1753)
+               return cardtype;
+       if (pci_enable_device(pcidev) < 0)
+               return cardtype;
+       if (pci_request_region(pcidev, 2, "adv_pci_dio") == 0) {
+               /*
+                * This test is based on Advantech's "advdaq" driver source
+                * (which declares its module licence as "GPL" although the
+                * driver source does not include a "COPYING" file).
+                */
+               unsigned long reg = pci_resource_start(pcidev, 2) + 53;
+
+               outb(0x05, reg);
+               if ((inb(reg) & 0x07) == 0x02) {
+                       outb(0x02, reg);
+                       if ((inb(reg) & 0x07) == 0x05)
+                               cardtype = TYPE_PCI1753E;
+               }
+               pci_release_region(pcidev, 2);
+       }
+       pci_disable_device(pcidev);
+       return cardtype;
+}
+
 static int adv_pci_dio_pci_probe(struct pci_dev *dev,
                                 const struct pci_device_id *id)
 {
@@ -1094,7 +496,6 @@ static const struct pci_device_id adv_pci_dio_pci_table[] = {
        { PCI_VDEVICE(ADVANTECH, 0x1753), TYPE_PCI1753 },
        { PCI_VDEVICE(ADVANTECH, 0x1754), TYPE_PCI1754 },
        { PCI_VDEVICE(ADVANTECH, 0x1756), TYPE_PCI1756 },
-       { PCI_VDEVICE(ADVANTECH, 0x1760), TYPE_PCI1760 },
        { PCI_VDEVICE(ADVANTECH, 0x1762), TYPE_PCI1762 },
        { 0 }
 };
@@ -1109,5 +510,5 @@ static struct pci_driver adv_pci_dio_pci_driver = {
 module_comedi_pci_driver(adv_pci_dio_driver, adv_pci_dio_pci_driver);
 
 MODULE_AUTHOR("Comedi http://www.comedi.org");
-MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_DESCRIPTION("Comedi driver for Advantech Digital I/O Cards");
 MODULE_LICENSE("GPL");
index b2f7679a01161f4fe6e02a58bfd79aa06a4de215..cac011fdd375d6e93033577738dfafa30c8f179a 100644 (file)
@@ -1022,14 +1022,17 @@ pci224_auto_attach(struct comedi_device *dev, unsigned long context_model)
        irq = pci_dev->irq;
 
        /* Allocate buffer to hold values for AO channel scan. */
-       devpriv->ao_scan_vals = kmalloc(sizeof(devpriv->ao_scan_vals[0]) *
-                                       board->ao_chans, GFP_KERNEL);
+       devpriv->ao_scan_vals = kmalloc_array(board->ao_chans,
+                                             sizeof(devpriv->ao_scan_vals[0]),
+                                             GFP_KERNEL);
        if (!devpriv->ao_scan_vals)
                return -ENOMEM;
 
        /* Allocate buffer to hold AO channel scan order. */
-       devpriv->ao_scan_order = kmalloc(sizeof(devpriv->ao_scan_order[0]) *
-                                        board->ao_chans, GFP_KERNEL);
+       devpriv->ao_scan_order =
+                               kmalloc_array(board->ao_chans,
+                                             sizeof(devpriv->ao_scan_order[0]),
+                                             GFP_KERNEL);
        if (!devpriv->ao_scan_order)
                return -ENOMEM;
 
index b00a36a5cb360e101a5ff5c13f7cf0fba492aef3..ccb37d1f0f8eeddc9e8495711da1c220e5c465ec 100644 (file)
 
 /* DAC registers */
 #define CB_DDA_DA_CTRL_REG             0x00       /* D/A Control Register  */
-#define CB_DDA_DA_CTRL_SU              (1 << 0)   /*  Simultaneous update  */
-#define CB_DDA_DA_CTRL_EN              (1 << 1)   /*  Enable specified DAC */
+#define CB_DDA_DA_CTRL_SU              BIT(0)   /*  Simultaneous update  */
+#define CB_DDA_DA_CTRL_EN              BIT(1)   /*  Enable specified DAC */
 #define CB_DDA_DA_CTRL_DAC(x)          ((x) << 2) /*  Specify DAC channel  */
 #define CB_DDA_DA_CTRL_RANGE2V5                (0 << 6)   /*  2.5V range           */
 #define CB_DDA_DA_CTRL_RANGE5V         (2 << 6)   /*  5V range             */
 #define CB_DDA_DA_CTRL_RANGE10V                (3 << 6)   /*  10V range            */
-#define CB_DDA_DA_CTRL_UNIP            (1 << 8)   /*  Unipolar range       */
+#define CB_DDA_DA_CTRL_UNIP            BIT(8)   /*  Unipolar range       */
 
 #define DACALIBRATION1 4       /*  D/A CALIBRATION REGISTER 1 */
 /* write bits */
index 15a4093efda13869c0be6be98429ff03fdf5cbd4..1bf8ddc6f07cb6e3155f7e22ed891a352a2b54e5 100644 (file)
@@ -75,8 +75,8 @@
 #define PARPORT_DATA_REG       0x00
 #define PARPORT_STATUS_REG     0x01
 #define PARPORT_CTRL_REG       0x02
-#define PARPORT_CTRL_IRQ_ENA   (1 << 4)
-#define PARPORT_CTRL_BIDIR_ENA (1 << 5)
+#define PARPORT_CTRL_IRQ_ENA   BIT(4)
+#define PARPORT_CTRL_BIDIR_ENA BIT(5)
 
 static int parport_data_reg_insn_bits(struct comedi_device *dev,
                                      struct comedi_subdevice *s,
index 62a817e4cd64582b14e3afe1c101066d89276695..84c62e25609435493838b85139b45867e5c7aaca 100644 (file)
 #define NI6527_DO_REG(x)               (0x03 + (x))
 #define NI6527_ID_REG                  0x06
 #define NI6527_CLR_REG                 0x07
-#define NI6527_CLR_EDGE                        (1 << 3)
-#define NI6527_CLR_OVERFLOW            (1 << 2)
-#define NI6527_CLR_FILT                        (1 << 1)
-#define NI6527_CLR_INTERVAL            (1 << 0)
+#define NI6527_CLR_EDGE                        BIT(3)
+#define NI6527_CLR_OVERFLOW            BIT(2)
+#define NI6527_CLR_FILT                        BIT(1)
+#define NI6527_CLR_INTERVAL            BIT(0)
 #define NI6527_CLR_IRQS                        (NI6527_CLR_EDGE | NI6527_CLR_OVERFLOW)
 #define NI6527_CLR_RESET_FILT          (NI6527_CLR_FILT | NI6527_CLR_INTERVAL)
 #define NI6527_FILT_INTERVAL_REG(x)    (0x08 + (x))
 #define NI6527_FILT_ENA_REG(x)         (0x0c + (x))
 #define NI6527_STATUS_REG              0x14
-#define NI6527_STATUS_IRQ              (1 << 2)
-#define NI6527_STATUS_OVERFLOW         (1 << 1)
-#define NI6527_STATUS_EDGE             (1 << 0)
+#define NI6527_STATUS_IRQ              BIT(2)
+#define NI6527_STATUS_OVERFLOW         BIT(1)
+#define NI6527_STATUS_EDGE             BIT(0)
 #define NI6527_CTRL_REG                        0x15
-#define NI6527_CTRL_FALLING            (1 << 4)
-#define NI6527_CTRL_RISING             (1 << 3)
-#define NI6527_CTRL_IRQ                        (1 << 2)
-#define NI6527_CTRL_OVERFLOW           (1 << 1)
-#define NI6527_CTRL_EDGE               (1 << 0)
+#define NI6527_CTRL_FALLING            BIT(4)
+#define NI6527_CTRL_RISING             BIT(3)
+#define NI6527_CTRL_IRQ                        BIT(2)
+#define NI6527_CTRL_OVERFLOW           BIT(1)
+#define NI6527_CTRL_EDGE               BIT(0)
 #define NI6527_CTRL_DISABLE_IRQS       0
 #define NI6527_CTRL_ENABLE_IRQS                (NI6527_CTRL_FALLING | \
                                         NI6527_CTRL_RISING | \
index 800d57426070409b27ebaebed6292cb77135d89b..251117be1205fc0b7401d71dcd083236a8b87917 100644 (file)
 /* Non-recurring Registers (8-bit except where noted) */
 #define NI_65XX_ID_REG                 0x00
 #define NI_65XX_CLR_REG                        0x01
-#define NI_65XX_CLR_WDOG_INT           (1 << 6)
-#define NI_65XX_CLR_WDOG_PING          (1 << 5)
-#define NI_65XX_CLR_WDOG_EXP           (1 << 4)
-#define NI_65XX_CLR_EDGE_INT           (1 << 3)
-#define NI_65XX_CLR_OVERFLOW_INT       (1 << 2)
+#define NI_65XX_CLR_WDOG_INT           BIT(6)
+#define NI_65XX_CLR_WDOG_PING          BIT(5)
+#define NI_65XX_CLR_WDOG_EXP           BIT(4)
+#define NI_65XX_CLR_EDGE_INT           BIT(3)
+#define NI_65XX_CLR_OVERFLOW_INT       BIT(2)
 #define NI_65XX_STATUS_REG             0x02
-#define NI_65XX_STATUS_WDOG_INT                (1 << 5)
-#define NI_65XX_STATUS_FALL_EDGE       (1 << 4)
-#define NI_65XX_STATUS_RISE_EDGE       (1 << 3)
-#define NI_65XX_STATUS_INT             (1 << 2)
-#define NI_65XX_STATUS_OVERFLOW_INT    (1 << 1)
-#define NI_65XX_STATUS_EDGE_INT                (1 << 0)
+#define NI_65XX_STATUS_WDOG_INT                BIT(5)
+#define NI_65XX_STATUS_FALL_EDGE       BIT(4)
+#define NI_65XX_STATUS_RISE_EDGE       BIT(3)
+#define NI_65XX_STATUS_INT             BIT(2)
+#define NI_65XX_STATUS_OVERFLOW_INT    BIT(1)
+#define NI_65XX_STATUS_EDGE_INT                BIT(0)
 #define NI_65XX_CTRL_REG               0x03
-#define NI_65XX_CTRL_WDOG_ENA          (1 << 5)
-#define NI_65XX_CTRL_FALL_EDGE_ENA     (1 << 4)
-#define NI_65XX_CTRL_RISE_EDGE_ENA     (1 << 3)
-#define NI_65XX_CTRL_INT_ENA           (1 << 2)
-#define NI_65XX_CTRL_OVERFLOW_ENA      (1 << 1)
-#define NI_65XX_CTRL_EDGE_ENA          (1 << 0)
+#define NI_65XX_CTRL_WDOG_ENA          BIT(5)
+#define NI_65XX_CTRL_FALL_EDGE_ENA     BIT(4)
+#define NI_65XX_CTRL_RISE_EDGE_ENA     BIT(3)
+#define NI_65XX_CTRL_INT_ENA           BIT(2)
+#define NI_65XX_CTRL_OVERFLOW_ENA      BIT(1)
+#define NI_65XX_CTRL_EDGE_ENA          BIT(0)
 #define NI_65XX_REV_REG                        0x04 /* 32-bit */
 #define NI_65XX_FILTER_REG             0x08 /* 32-bit */
 #define NI_65XX_RTSI_ROUTE_REG         0x0c /* 16-bit */
 #define NI_65XX_RTSI_WDOG_REG          0x10 /* 16-bit */
 #define NI_65XX_RTSI_TRIG_REG          0x12 /* 16-bit */
 #define NI_65XX_AUTO_CLK_SEL_REG       0x14 /* PXI-6528 only */
-#define NI_65XX_AUTO_CLK_SEL_STATUS    (1 << 1)
-#define NI_65XX_AUTO_CLK_SEL_DISABLE   (1 << 0)
+#define NI_65XX_AUTO_CLK_SEL_STATUS    BIT(1)
+#define NI_65XX_AUTO_CLK_SEL_DISABLE   BIT(0)
 #define NI_65XX_WDOG_CTRL_REG          0x15
-#define NI_65XX_WDOG_CTRL_ENA          (1 << 0)
+#define NI_65XX_WDOG_CTRL_ENA          BIT(0)
 #define NI_65XX_RTSI_CFG_REG           0x16
-#define NI_65XX_RTSI_CFG_RISE_SENSE    (1 << 2)
-#define NI_65XX_RTSI_CFG_FALL_SENSE    (1 << 1)
-#define NI_65XX_RTSI_CFG_SYNC_DETECT   (1 << 0)
+#define NI_65XX_RTSI_CFG_RISE_SENSE    BIT(2)
+#define NI_65XX_RTSI_CFG_FALL_SENSE    BIT(1)
+#define NI_65XX_RTSI_CFG_SYNC_DETECT   BIT(0)
 #define NI_65XX_WDOG_STATUS_REG                0x17
-#define NI_65XX_WDOG_STATUS_EXP                (1 << 0)
+#define NI_65XX_WDOG_STATUS_EXP                BIT(0)
 #define NI_65XX_WDOG_INTERVAL_REG      0x18 /* 32-bit */
 
 /* Recurring port registers (8-bit) */
 #define NI_65XX_PORT(x)                        ((x) * 0x10)
 #define NI_65XX_IO_DATA_REG(x)         (0x40 + NI_65XX_PORT(x))
 #define NI_65XX_IO_SEL_REG(x)          (0x41 + NI_65XX_PORT(x))
-#define NI_65XX_IO_SEL_OUTPUT          (0 << 0)
-#define NI_65XX_IO_SEL_INPUT           (1 << 0)
+#define NI_65XX_IO_SEL_OUTPUT          0
+#define NI_65XX_IO_SEL_INPUT           BIT(0)
 #define NI_65XX_RISE_EDGE_ENA_REG(x)   (0x42 + NI_65XX_PORT(x))
 #define NI_65XX_FALL_EDGE_ENA_REG(x)   (0x43 + NI_65XX_PORT(x))
 #define NI_65XX_FILTER_ENA(x)          (0x44 + NI_65XX_PORT(x))
@@ -613,7 +613,7 @@ static int ni_65xx_intr_insn_config(struct comedi_device *dev,
 
 /* ripped from mite.h and mite_setup2() to avoid mite dependency */
 #define MITE_IODWBSR   0xc0     /* IO Device Window Base Size Register */
-#define WENAB          (1 << 7) /* window enable */
+#define WENAB                  BIT(7) /* window enable */
 
 static int ni_65xx_mite_init(struct pci_dev *pcidev)
 {
index f4c580f65a896ccbf3100cfcdbbc15b17044e66f..3e72718801a9ea58d1dc6fbe44c97610d858fa01 100644 (file)
@@ -214,8 +214,9 @@ static int ni_670x_auto_attach(struct comedi_device *dev,
        if (s->n_chan == 32) {
                const struct comedi_lrange **range_table_list;
 
-               range_table_list = kmalloc(sizeof(struct comedi_lrange *) * 32,
-                                          GFP_KERNEL);
+               range_table_list = kmalloc_array(32,
+                                                sizeof(struct comedi_lrange *),
+                                                GFP_KERNEL);
                if (!range_table_list)
                        return -ENOMEM;
                s->range_table_list = range_table_list;
index cbb44fc6940bc6f57a49b5ce07521ac2f037144d..5e8130a7d6708b7a52afb81ef90da505e8a31bb0 100644 (file)
@@ -579,48 +579,54 @@ static inline unsigned ni_stc_dma_channel_select_bitfield(unsigned channel)
        return 0;
 }
 
-/* negative channel means no channel */
-static inline void ni_set_ai_dma_channel(struct comedi_device *dev, int channel)
+static inline void ni_set_ai_dma_channel(struct comedi_device *dev,
+                                        unsigned channel)
 {
-       unsigned bits = 0;
-
-       if (channel >= 0)
-               bits = ni_stc_dma_channel_select_bitfield(channel);
+       unsigned bits = ni_stc_dma_channel_select_bitfield(channel);
 
        ni_set_bitfield(dev, NI_E_DMA_AI_AO_SEL_REG,
                        NI_E_DMA_AI_SEL_MASK, NI_E_DMA_AI_SEL(bits));
 }
 
-/* negative channel means no channel */
-static inline void ni_set_ao_dma_channel(struct comedi_device *dev, int channel)
+static inline void ni_set_ai_dma_no_channel(struct comedi_device *dev)
 {
-       unsigned bits = 0;
+       ni_set_bitfield(dev, NI_E_DMA_AI_AO_SEL_REG, NI_E_DMA_AI_SEL_MASK, 0);
+}
 
-       if (channel >= 0)
-               bits = ni_stc_dma_channel_select_bitfield(channel);
+static inline void ni_set_ao_dma_channel(struct comedi_device *dev,
+                                        unsigned channel)
+{
+       unsigned bits = ni_stc_dma_channel_select_bitfield(channel);
 
        ni_set_bitfield(dev, NI_E_DMA_AI_AO_SEL_REG,
                        NI_E_DMA_AO_SEL_MASK, NI_E_DMA_AO_SEL(bits));
 }
 
-/* negative channel means no channel */
+static inline void ni_set_ao_dma_no_channel(struct comedi_device *dev)
+{
+       ni_set_bitfield(dev, NI_E_DMA_AI_AO_SEL_REG, NI_E_DMA_AO_SEL_MASK, 0);
+}
+
 static inline void ni_set_gpct_dma_channel(struct comedi_device *dev,
                                           unsigned gpct_index,
-                                          int channel)
+                                          unsigned channel)
 {
-       unsigned bits = 0;
-
-       if (channel >= 0)
-               bits = ni_stc_dma_channel_select_bitfield(channel);
+       unsigned bits = ni_stc_dma_channel_select_bitfield(channel);
 
        ni_set_bitfield(dev, NI_E_DMA_G0_G1_SEL_REG,
                        NI_E_DMA_G0_G1_SEL_MASK(gpct_index),
                        NI_E_DMA_G0_G1_SEL(gpct_index, bits));
 }
 
-/* negative mite_channel means no channel */
+static inline void ni_set_gpct_dma_no_channel(struct comedi_device *dev,
+                                             unsigned gpct_index)
+{
+       ni_set_bitfield(dev, NI_E_DMA_G0_G1_SEL_REG,
+                       NI_E_DMA_G0_G1_SEL_MASK(gpct_index), 0);
+}
+
 static inline void ni_set_cdo_dma_channel(struct comedi_device *dev,
-                                         int mite_channel)
+                                         unsigned mite_channel)
 {
        struct ni_private *devpriv = dev->private;
        unsigned long flags;
@@ -628,16 +634,26 @@ static inline void ni_set_cdo_dma_channel(struct comedi_device *dev,
 
        spin_lock_irqsave(&devpriv->soft_reg_copy_lock, flags);
        devpriv->cdio_dma_select_reg &= ~NI_M_CDIO_DMA_SEL_CDO_MASK;
-       if (mite_channel >= 0) {
-               /*
-                * XXX just guessing ni_stc_dma_channel_select_bitfield()
-                * returns the right bits, under the assumption the cdio dma
-                * selection works just like ai/ao/gpct.
-                * Definitely works for dma channels 0 and 1.
-                */
-               bits = ni_stc_dma_channel_select_bitfield(mite_channel);
-               devpriv->cdio_dma_select_reg |= NI_M_CDIO_DMA_SEL_CDO(bits);
-       }
+       /*
+        * XXX just guessing ni_stc_dma_channel_select_bitfield()
+        * returns the right bits, under the assumption the cdio dma
+        * selection works just like ai/ao/gpct.
+        * Definitely works for dma channels 0 and 1.
+        */
+       bits = ni_stc_dma_channel_select_bitfield(mite_channel);
+       devpriv->cdio_dma_select_reg |= NI_M_CDIO_DMA_SEL_CDO(bits);
+       ni_writeb(dev, devpriv->cdio_dma_select_reg, NI_M_CDIO_DMA_SEL_REG);
+       mmiowb();
+       spin_unlock_irqrestore(&devpriv->soft_reg_copy_lock, flags);
+}
+
+static inline void ni_set_cdo_dma_no_channel(struct comedi_device *dev)
+{
+       struct ni_private *devpriv = dev->private;
+       unsigned long flags;
+
+       spin_lock_irqsave(&devpriv->soft_reg_copy_lock, flags);
+       devpriv->cdio_dma_select_reg &= ~NI_M_CDIO_DMA_SEL_CDO_MASK;
        ni_writeb(dev, devpriv->cdio_dma_select_reg, NI_M_CDIO_DMA_SEL_REG);
        mmiowb();
        spin_unlock_irqrestore(&devpriv->soft_reg_copy_lock, flags);
@@ -745,7 +761,7 @@ static void ni_release_ai_mite_channel(struct comedi_device *dev)
 
        spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
        if (devpriv->ai_mite_chan) {
-               ni_set_ai_dma_channel(dev, -1);
+               ni_set_ai_dma_no_channel(dev);
                mite_release_channel(devpriv->ai_mite_chan);
                devpriv->ai_mite_chan = NULL;
        }
@@ -761,7 +777,7 @@ static void ni_release_ao_mite_channel(struct comedi_device *dev)
 
        spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
        if (devpriv->ao_mite_chan) {
-               ni_set_ao_dma_channel(dev, -1);
+               ni_set_ao_dma_no_channel(dev);
                mite_release_channel(devpriv->ao_mite_chan);
                devpriv->ao_mite_chan = NULL;
        }
@@ -781,7 +797,7 @@ static void ni_release_gpct_mite_channel(struct comedi_device *dev,
                struct mite_channel *mite_chan =
                    devpriv->counter_dev->counters[gpct_index].mite_chan;
 
-               ni_set_gpct_dma_channel(dev, gpct_index, -1);
+               ni_set_gpct_dma_no_channel(dev, gpct_index);
                ni_tio_set_mite_channel(&devpriv->
                                        counter_dev->counters[gpct_index],
                                        NULL);
@@ -799,7 +815,7 @@ static void ni_release_cdo_mite_channel(struct comedi_device *dev)
 
        spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
        if (devpriv->cdo_mite_chan) {
-               ni_set_cdo_dma_channel(dev, -1);
+               ni_set_cdo_dma_no_channel(dev);
                mite_release_channel(devpriv->cdo_mite_chan);
                devpriv->cdo_mite_chan = NULL;
        }
index 25706531b885489a3ff016a2b671429ff7e9e0a7..f5cd6d5004bdd9aa843502b7fd82681a54cf6d7d 100644 (file)
@@ -1,4 +1,5 @@
-/* plx9080.h
+/*
+ * plx9080.h
  *
  * Copyright (C) 2002,2003 Frank Mori Hess <fmhess@users.sourceforge.net>
  *
@@ -33,8 +34,10 @@ struct plx_dma_desc {
        __le32 local_start_addr;
        /* transfer_size is in bytes, only first 23 bits of register are used */
        __le32 transfer_size;
-       /* address of next descriptor (quad word aligned), plus some
-        * additional bits (see PLX_DMA0_DESCRIPTOR_REG) */
+       /*
+        * address of next descriptor (quad word aligned), plus some
+        * additional bits (see PLX_DMA0_DESCRIPTOR_REG)
+        */
        __le32 next;
 };
 
@@ -46,23 +49,31 @@ struct plx_dma_desc {
 **
 **********************************************************************/
 
-#define PLX_LAS0RNG_REG         0x0000 /* L, Local Addr Space 0 Range Register */
-#define PLX_LAS1RNG_REG         0x00f0 /* L, Local Addr Space 1 Range Register */
+/* L, Local Addr Space 0 Range Register */
+#define PLX_LAS0RNG_REG         0x0000
+/* L, Local Addr Space 1 Range Register */
+#define PLX_LAS1RNG_REG         0x00f0
 #define  LRNG_IO           0x00000001  /* Map to: 1=I/O, 0=Mem */
 #define  LRNG_ANY32        0x00000000  /* Locate anywhere in 32 bit */
 #define  LRNG_LT1MB        0x00000002  /* Locate in 1st meg */
 #define  LRNG_ANY64        0x00000004  /* Locate anywhere in 64 bit */
-#define  LRNG_MEM_MASK     0xfffffff0  /*  bits that specify range for memory io */
-#define  LRNG_IO_MASK     0xfffffffa   /*  bits that specify range for normal io */
-
-#define PLX_LAS0MAP_REG         0x0004 /* L, Local Addr Space 0 Remap Register */
-#define PLX_LAS1MAP_REG         0x00f4 /* L, Local Addr Space 1 Remap Register */
+/*  bits that specify range for memory io */
+#define  LRNG_MEM_MASK     0xfffffff0
+/*  bits that specify range for normal io */
+#define  LRNG_IO_MASK     0xfffffffa
+/* L, Local Addr Space 0 Remap Register */
+#define PLX_LAS0MAP_REG         0x0004
+/* L, Local Addr Space 1 Remap Register */
+#define PLX_LAS1MAP_REG         0x00f4
 #define  LMAP_EN           0x00000001  /* Enable slave decode */
-#define  LMAP_MEM_MASK     0xfffffff0  /*  bits that specify decode for memory io */
-#define  LMAP_IO_MASK     0xfffffffa   /*  bits that specify decode bits for normal io */
+/*  bits that specify decode for memory io */
+#define  LMAP_MEM_MASK     0xfffffff0
+/*  bits that specify decode bits for normal io */
+#define  LMAP_IO_MASK     0xfffffffa
 
-/* Mode/Arbitration Register.
-*/
+/*
+ * Mode/Arbitration Register.
+ */
 #define PLX_MARB_REG         0x8       /* L, Local Arbitration Register */
 #define PLX_DMAARB_REG      0xac
 enum marb_bits {
@@ -72,35 +83,45 @@ enum marb_bits {
        MARB_LPEN = 0x00020000, /* Pause Timer Enable */
        MARB_BREQ = 0x00040000, /* Local Bus BREQ Enable */
        MARB_DMA_PRIORITY_MASK = 0x00180000,
-       MARB_LBDS_GIVE_UP_BUS_MODE = 0x00200000,        /* local bus direct slave give up bus mode */
-       MARB_DS_LLOCK_ENABLE = 0x00400000,      /* direct slave LLOCKo# enable */
+       /* local bus direct slave give up bus mode */
+       MARB_LBDS_GIVE_UP_BUS_MODE = 0x00200000,
+       /* direct slave LLOCKo# enable */
+       MARB_DS_LLOCK_ENABLE = 0x00400000,
        MARB_PCI_REQUEST_MODE = 0x00800000,
        MARB_PCIv21_MODE = 0x01000000,  /* pci specification v2.1 mode */
        MARB_PCI_READ_NO_WRITE_MODE = 0x02000000,
        MARB_PCI_READ_WITH_WRITE_FLUSH_MODE = 0x04000000,
-       MARB_GATE_TIMER_WITH_BREQ = 0x08000000, /* gate local bus latency timer with BREQ */
+       /* gate local bus latency timer with BREQ */
+       MARB_GATE_TIMER_WITH_BREQ = 0x08000000,
        MARB_PCI_READ_NO_FLUSH_MODE = 0x10000000,
        MARB_USE_SUBSYSTEM_IDS = 0x20000000,
 };
 
 #define PLX_BIGEND_REG 0xc
 enum bigend_bits {
-       BIGEND_CONFIG = 0x1,    /* use big endian ordering for configuration register accesses */
+       /* use big endian ordering for configuration register accesses */
+       BIGEND_CONFIG = 0x1,
        BIGEND_DIRECT_MASTER = 0x2,
        BIGEND_DIRECT_SLAVE_LOCAL0 = 0x4,
        BIGEND_ROM = 0x8,
-       BIGEND_BYTE_LANE = 0x10,        /* use byte lane consisting of most significant bits instead of least significant */
+       /*
+        * use byte lane consisting of most significant bits instead of
+        * least significant
+        */
+       BIGEND_BYTE_LANE = 0x10,
        BIGEND_DIRECT_SLAVE_LOCAL1 = 0x20,
        BIGEND_DMA1 = 0x40,
        BIGEND_DMA0 = 0x80,
 };
 
-/* Note: The Expansion ROM  stuff is only relevant to the PC environment.
+/*
+** Note: The Expansion ROM  stuff is only relevant to the PC environment.
 **       This expansion ROM code is executed by the host CPU at boot time.
 **       For this reason no bit definitions are provided here.
-*/
+ */
 #define PLX_ROMRNG_REG         0x0010  /* L, Expn ROM Space Range Register */
-#define PLX_ROMMAP_REG         0x0014  /* L, Local Addr Space Range Register */
+/* L, Local Addr Space Range Register */
+#define PLX_ROMMAP_REG         0x0014
 
 #define PLX_REGION0_REG         0x0018 /* L, Local Bus Region 0 Descriptor */
 #define  RGN_WIDTH         0x00000002  /* Local bus width bits */
@@ -190,7 +211,8 @@ enum bigend_bits {
 #define  ICS_TA_DMA0       0x02000000  /* Target Abort - DMA #0 */
 #define  ICS_TA_DMA1       0x04000000  /* Target Abort - DMA #1 */
 #define  ICS_TA_RA         0x08000000  /* Target Abort - Retry Timeout */
-#define  ICS_MBIA(x)       (0x10000000 << ((x) & 0x3)) /*  mailbox x is active */
+/*  mailbox x is active */
+#define  ICS_MBIA(x)       (0x10000000 << ((x) & 0x3))
 
 #define PLX_CONTROL_REG        0x006C  /* L, EEPROM Cntl & PCI Cmd Codes */
 #define  CTL_RDMA          0x0000000E  /* DMA Read Command */
@@ -221,28 +243,38 @@ enum bigend_bits {
 #define  PLX_EN_BTERM_BIT      0x80    /*  enable BTERM# input */
 #define  PLX_DMA_LOCAL_BURST_EN_BIT    0x100   /*  enable local burst mode */
 #define  PLX_EN_CHAIN_BIT      0x200   /*  enables chaining */
-#define  PLX_EN_DMA_DONE_INTR_BIT      0x400   /*  enables interrupt on dma done */
-#define  PLX_LOCAL_ADDR_CONST_BIT      0x800   /*  hold local address constant (don't increment) */
-#define  PLX_DEMAND_MODE_BIT   0x1000  /*  enables demand-mode for dma transfer */
+/*  enables interrupt on dma done */
+#define  PLX_EN_DMA_DONE_INTR_BIT      0x400
+/*  hold local address constant (don't increment) */
+#define  PLX_LOCAL_ADDR_CONST_BIT      0x800
+/*  enables demand-mode for dma transfer */
+#define  PLX_DEMAND_MODE_BIT   0x1000
 #define  PLX_EOT_ENABLE_BIT    0x4000
 #define  PLX_STOP_MODE_BIT 0x8000
-#define  PLX_DMA_INTR_PCI_BIT  0x20000 /*  routes dma interrupt to pci bus (instead of local bus) */
+/*  routes dma interrupt to pci bus (instead of local bus) */
+#define  PLX_DMA_INTR_PCI_BIT  0x20000
 
-#define PLX_DMA0_PCI_ADDRESS_REG       0x84    /*  pci address that dma transfers start at */
+/*  pci address that dma transfers start at */
+#define PLX_DMA0_PCI_ADDRESS_REG       0x84
 #define PLX_DMA1_PCI_ADDRESS_REG       0x98
 
-#define PLX_DMA0_LOCAL_ADDRESS_REG     0x88    /*  local address that dma transfers start at */
+/*  local address that dma transfers start at */
+#define PLX_DMA0_LOCAL_ADDRESS_REG     0x88
 #define PLX_DMA1_LOCAL_ADDRESS_REG     0x9c
 
-#define PLX_DMA0_TRANSFER_SIZE_REG     0x8c    /*  number of bytes to transfer (first 23 bits) */
+/*  number of bytes to transfer (first 23 bits) */
+#define PLX_DMA0_TRANSFER_SIZE_REG     0x8c
 #define PLX_DMA1_TRANSFER_SIZE_REG     0xa0
 
 #define PLX_DMA0_DESCRIPTOR_REG        0x90    /*  descriptor pointer register */
 #define PLX_DMA1_DESCRIPTOR_REG        0xa4
-#define  PLX_DESC_IN_PCI_BIT   0x1     /*  descriptor is located in pci space (not local space) */
+/*  descriptor is located in pci space (not local space) */
+#define  PLX_DESC_IN_PCI_BIT   0x1
 #define  PLX_END_OF_CHAIN_BIT  0x2     /*  end of chain bit */
-#define  PLX_INTR_TERM_COUNT   0x4     /*  interrupt when this descriptor's transfer is finished */
-#define  PLX_XFER_LOCAL_TO_PCI 0x8     /*  transfer from local to pci bus (not pci to local) */
+/*  interrupt when this descriptor's transfer is finished */
+#define  PLX_INTR_TERM_COUNT   0x4
+/*  transfer from local to pci bus (not pci to local) */
+#define  PLX_XFER_LOCAL_TO_PCI 0x8
 
 #define PLX_DMA0_CS_REG        0xa8    /*  command status register */
 #define PLX_DMA1_CS_REG        0xa9
@@ -288,10 +320,11 @@ enum bigend_bits {
 #define MBX_STS_PCIRESET   0x00000100  /* Host issued PCI reset request */
 #define MBX_STS_BUSY       0x00000080  /* PUTS is in progress */
 #define MBX_STS_ERROR      0x00000040  /* PUTS has failed */
-#define MBX_STS_RESERVED   0x000000c0  /* Undefined -> status in transition.
-                                          We are in process of changing
-                                          bits; we SET Error bit before
-                                          RESET of Busy bit */
+/*
+ * Undefined -> status in transition. We are in process of changing bits;
+ * we SET Error bit before RESET of Busy bit
+ */
+#define MBX_STS_RESERVED   0x000000c0
 
 #define MBX_RESERVED_5     0x00000020  /* FYI: reserved/unused bit */
 #define MBX_RESERVED_4     0x00000010  /* FYI: reserved/unused bit */
@@ -320,12 +353,12 @@ enum bigend_bits {
 #define MBX_CMD_BSWAP_0    0x8c000000  /* use scheme 0 */
 #define MBX_CMD_BSWAP_1    0x8c000001  /* use scheme 1 */
 
-#define MBX_CMD_SETHMS     0x8d000000  /* setup host memory access window
-                                          size */
-#define MBX_CMD_SETHBA     0x8e000000  /* setup host memory access base
-                                          address */
-#define MBX_CMD_MGO        0x8f000000  /* perform memory setup and continue
-                                          (IE. Done) */
+/* setup host memory access window size */
+#define MBX_CMD_SETHMS     0x8d000000
+/* setup host memory access base address */
+#define MBX_CMD_SETHBA     0x8e000000
+/* perform memory setup and continue (IE. Done) */
+#define MBX_CMD_MGO        0x8f000000
 #define MBX_CMD_NOOP       0xFF000000  /* dummy, illegal command */
 
 /*****************************************/
@@ -348,7 +381,8 @@ enum bigend_bits {
 /***************************************/
 
 #define MBX_BTYPE_MASK          0x0000ffff     /* PUTS Board Type Register */
-#define MBX_BTYPE_FAMILY_MASK   0x0000ff00     /* PUTS Board Family Register */
+/* PUTS Board Family Register */
+#define MBX_BTYPE_FAMILY_MASK   0x0000ff00
 #define MBX_BTYPE_SUBTYPE_MASK  0x000000ff     /* PUTS Board Subtype */
 
 #define MBX_BTYPE_PLX9060       0x00000100     /* PLX family type */
@@ -378,12 +412,12 @@ enum bigend_bits {
 
 /* system allocates this many bytes for address mapping mailbox space */
 #define MBX_ADDR_SPACE_360 0x80        /* wanXL100s/200/400 */
-#define MBX_ADDR_MASK_360 (MBX_ADDR_SPACE_360-1)
+#define MBX_ADDR_MASK_360 (MBX_ADDR_SPACE_360 - 1)
 
 static inline int plx9080_abort_dma(void __iomem *iobase, unsigned int channel)
 {
        void __iomem *dma_cs_addr;
-       uint8_t dma_status;
+       u8 dma_status;
        const int timeout = 10000;
        unsigned int i;
 
index d70c979476274b9195940c8b0ac4ea160d71848f..c80527db9c194896d23130d3aeb2d405a6483e99 100644 (file)
@@ -37,7 +37,6 @@
 
 #include <linux/module.h>
 #include "../comedidev.h"
-#include <asm/byteorder.h>
 
 /*
  * Register I/O map
 #define S526_GPCT_LSB_REG(x)   (0x12 + ((x) * 8))
 #define S526_GPCT_MSB_REG(x)   (0x14 + ((x) * 8))
 #define S526_GPCT_MODE_REG(x)  (0x16 + ((x) * 8))
+#define S526_GPCT_MODE_COUT_SRC(x)     ((x) << 0)
+#define S526_GPCT_MODE_COUT_SRC_MASK   S526_GPCT_MODE_COUT_SRC(0x1)
+#define S526_GPCT_MODE_COUT_SRC_RCAP   S526_GPCT_MODE_COUT_SRC(0)
+#define S526_GPCT_MODE_COUT_SRC_RTGL   S526_GPCT_MODE_COUT_SRC(1)
+#define S526_GPCT_MODE_COUT_POL(x)     ((x) << 1)
+#define S526_GPCT_MODE_COUT_POL_MASK   S526_GPCT_MODE_COUT_POL(0x1)
+#define S526_GPCT_MODE_COUT_POL_NORM   S526_GPCT_MODE_COUT_POL(0)
+#define S526_GPCT_MODE_COUT_POL_INV    S526_GPCT_MODE_COUT_POL(1)
+#define S526_GPCT_MODE_AUTOLOAD(x)     ((x) << 2)
+#define S526_GPCT_MODE_AUTOLOAD_MASK   S526_GPCT_MODE_AUTOLOAD(0x7)
+#define S526_GPCT_MODE_AUTOLOAD_NONE   S526_GPCT_MODE_AUTOLOAD(0)
+/* these 3 bits can be OR'ed */
+#define S526_GPCT_MODE_AUTOLOAD_RO     S526_GPCT_MODE_AUTOLOAD(0x1)
+#define S526_GPCT_MODE_AUTOLOAD_IXFALL S526_GPCT_MODE_AUTOLOAD(0x2)
+#define S526_GPCT_MODE_AUTOLOAD_IXRISE S526_GPCT_MODE_AUTOLOAD(0x4)
+#define S526_GPCT_MODE_HWCTEN_SRC(x)   ((x) << 5)
+#define S526_GPCT_MODE_HWCTEN_SRC_MASK S526_GPCT_MODE_HWCTEN_SRC(0x3)
+#define S526_GPCT_MODE_HWCTEN_SRC_CEN  S526_GPCT_MODE_HWCTEN_SRC(0)
+#define S526_GPCT_MODE_HWCTEN_SRC_IX   S526_GPCT_MODE_HWCTEN_SRC(1)
+#define S526_GPCT_MODE_HWCTEN_SRC_IXRF S526_GPCT_MODE_HWCTEN_SRC(2)
+#define S526_GPCT_MODE_HWCTEN_SRC_NRCAP        S526_GPCT_MODE_HWCTEN_SRC(3)
+#define S526_GPCT_MODE_CTEN_CTRL(x)    ((x) << 7)
+#define S526_GPCT_MODE_CTEN_CTRL_MASK  S526_GPCT_MODE_CTEN_CTRL(0x3)
+#define S526_GPCT_MODE_CTEN_CTRL_DIS   S526_GPCT_MODE_CTEN_CTRL(0)
+#define S526_GPCT_MODE_CTEN_CTRL_ENA   S526_GPCT_MODE_CTEN_CTRL(1)
+#define S526_GPCT_MODE_CTEN_CTRL_HW    S526_GPCT_MODE_CTEN_CTRL(2)
+#define S526_GPCT_MODE_CTEN_CTRL_INVHW S526_GPCT_MODE_CTEN_CTRL(3)
+#define S526_GPCT_MODE_CLK_SRC(x)      ((x) << 9)
+#define S526_GPCT_MODE_CLK_SRC_MASK    S526_GPCT_MODE_CLK_SRC(0x3)
+/* if count direction control set to quadrature */
+#define S526_GPCT_MODE_CLK_SRC_QUADX1  S526_GPCT_MODE_CLK_SRC(0)
+#define S526_GPCT_MODE_CLK_SRC_QUADX2  S526_GPCT_MODE_CLK_SRC(1)
+#define S526_GPCT_MODE_CLK_SRC_QUADX4  S526_GPCT_MODE_CLK_SRC(2)
+#define S526_GPCT_MODE_CLK_SRC_QUADX4_ S526_GPCT_MODE_CLK_SRC(3)
+/* if count direction control set to software control */
+#define S526_GPCT_MODE_CLK_SRC_ARISE   S526_GPCT_MODE_CLK_SRC(0)
+#define S526_GPCT_MODE_CLK_SRC_AFALL   S526_GPCT_MODE_CLK_SRC(1)
+#define S526_GPCT_MODE_CLK_SRC_INT     S526_GPCT_MODE_CLK_SRC(2)
+#define S526_GPCT_MODE_CLK_SRC_INTHALF S526_GPCT_MODE_CLK_SRC(3)
+#define S526_GPCT_MODE_CT_DIR(x)       ((x) << 11)
+#define S526_GPCT_MODE_CT_DIR_MASK     S526_GPCT_MODE_CT_DIR(0x1)
+/* if count direction control set to software control */
+#define S526_GPCT_MODE_CT_DIR_UP       S526_GPCT_MODE_CT_DIR(0)
+#define S526_GPCT_MODE_CT_DIR_DOWN     S526_GPCT_MODE_CT_DIR(1)
+#define S526_GPCT_MODE_CTDIR_CTRL(x)   ((x) << 12)
+#define S526_GPCT_MODE_CTDIR_CTRL_MASK S526_GPCT_MODE_CTDIR_CTRL(0x1)
+#define S526_GPCT_MODE_CTDIR_CTRL_QUAD S526_GPCT_MODE_CTDIR_CTRL(0)
+#define S526_GPCT_MODE_CTDIR_CTRL_SOFT S526_GPCT_MODE_CTDIR_CTRL(1)
+#define S526_GPCT_MODE_LATCH_CTRL(x)   ((x) << 13)
+#define S526_GPCT_MODE_LATCH_CTRL_MASK S526_GPCT_MODE_LATCH_CTRL(0x1)
+#define S526_GPCT_MODE_LATCH_CTRL_READ S526_GPCT_MODE_LATCH_CTRL(0)
+#define S526_GPCT_MODE_LATCH_CTRL_EVENT        S526_GPCT_MODE_LATCH_CTRL(1)
+#define S526_GPCT_MODE_PR_SELECT(x)    ((x) << 14)
+#define S526_GPCT_MODE_PR_SELECT_MASK  S526_GPCT_MODE_PR_SELECT(0x1)
+#define S526_GPCT_MODE_PR_SELECT_PR0   S526_GPCT_MODE_PR_SELECT(0)
+#define S526_GPCT_MODE_PR_SELECT_PR1   S526_GPCT_MODE_PR_SELECT(1)
+/* Control/Status - R = readable, W = writeable, C = write 1 to clear */
 #define S526_GPCT_CTRL_REG(x)  (0x18 + ((x) * 8))
+#define S526_GPCT_CTRL_EV_STATUS(x)    ((x) << 0)              /* RC */
+#define S526_GPCT_CTRL_EV_STATUS_MASK  S526_GPCT_EV_STATUS(0xf)
+#define S526_GPCT_CTRL_EV_STATUS_NONE  S526_GPCT_EV_STATUS(0)
+/* these 4 bits can be OR'ed */
+#define S526_GPCT_CTRL_EV_STATUS_ECAP  S526_GPCT_EV_STATUS(0x1)
+#define S526_GPCT_CTRL_EV_STATUS_ICAPN S526_GPCT_EV_STATUS(0x2)
+#define S526_GPCT_CTRL_EV_STATUS_ICAPP S526_GPCT_EV_STATUS(0x4)
+#define S526_GPCT_CTRL_EV_STATUS_RCAP  S526_GPCT_EV_STATUS(0x8)
+#define S526_GPCT_CTRL_COUT_STATUS     BIT(4)                  /* R */
+#define S526_GPCT_CTRL_INDEX_STATUS    BIT(5)                  /* R */
+#define S525_GPCT_CTRL_INTEN(x)                ((x) << 6)              /* W */
+#define S525_GPCT_CTRL_INTEN_MASK      S526_GPCT_CTRL_INTEN(0xf)
+#define S525_GPCT_CTRL_INTEN_NONE      S526_GPCT_CTRL_INTEN(0)
+/* these 4 bits can be OR'ed */
+#define S525_GPCT_CTRL_INTEN_ERROR     S526_GPCT_CTRL_INTEN(0x1)
+#define S525_GPCT_CTRL_INTEN_IXFALL    S526_GPCT_CTRL_INTEN(0x2)
+#define S525_GPCT_CTRL_INTEN_IXRISE    S526_GPCT_CTRL_INTEN(0x4)
+#define S525_GPCT_CTRL_INTEN_RO                S526_GPCT_CTRL_INTEN(0x8)
+#define S525_GPCT_CTRL_LATCH_SEL(x)    ((x) << 10)             /* W */
+#define S525_GPCT_CTRL_LATCH_SEL_MASK  S526_GPCT_CTRL_LATCH_SEL(0x7)
+#define S525_GPCT_CTRL_LATCH_SEL_NONE  S526_GPCT_CTRL_LATCH_SEL(0)
+/* these 3 bits can be OR'ed */
+#define S525_GPCT_CTRL_LATCH_SEL_IXFALL        S526_GPCT_CTRL_LATCH_SEL(0x1)
+#define S525_GPCT_CTRL_LATCH_SEL_IXRISE        S526_GPCT_CTRL_LATCH_SEL(0x2)
+#define S525_GPCT_CTRL_LATCH_SEL_ITIMER        S526_GPCT_CTRL_LATCH_SEL(0x4)
+#define S525_GPCT_CTRL_CT_ARM          BIT(13)                 /* W */
+#define S525_GPCT_CTRL_CT_LOAD         BIT(14)                 /* W */
+#define S526_GPCT_CTRL_CT_RESET                BIT(15)                 /* W */
 #define S526_EEPROM_DATA_REG   0x32
 #define S526_EEPROM_CTRL_REG   0x34
 #define S526_EEPROM_CTRL_ADDR(x) (((x) & 0x3f) << 3)
 #define S526_EEPROM_CTRL_READ  S526_EEPROM_CTRL(2)
 #define S526_EEPROM_CTRL_START BIT(0)
 
-struct counter_mode_register_t {
-#if defined(__LITTLE_ENDIAN_BITFIELD)
-       unsigned short coutSource:1;
-       unsigned short coutPolarity:1;
-       unsigned short autoLoadResetRcap:3;
-       unsigned short hwCtEnableSource:2;
-       unsigned short ctEnableCtrl:2;
-       unsigned short clockSource:2;
-       unsigned short countDir:1;
-       unsigned short countDirCtrl:1;
-       unsigned short outputRegLatchCtrl:1;
-       unsigned short preloadRegSel:1;
-       unsigned short reserved:1;
- #elif defined(__BIG_ENDIAN_BITFIELD)
-       unsigned short reserved:1;
-       unsigned short preloadRegSel:1;
-       unsigned short outputRegLatchCtrl:1;
-       unsigned short countDirCtrl:1;
-       unsigned short countDir:1;
-       unsigned short clockSource:2;
-       unsigned short ctEnableCtrl:2;
-       unsigned short hwCtEnableSource:2;
-       unsigned short autoLoadResetRcap:3;
-       unsigned short coutPolarity:1;
-       unsigned short coutSource:1;
-#else
-#error Unknown bit field order
-#endif
-};
-
-union cmReg {
-       struct counter_mode_register_t reg;
-       unsigned short value;
-};
-
 struct s526_private {
        unsigned int gpct_config[4];
        unsigned short ai_ctrl;
@@ -174,7 +223,6 @@ static int s526_gpct_insn_config(struct comedi_device *dev,
        struct s526_private *devpriv = dev->private;
        unsigned int chan = CR_CHAN(insn->chanspec);
        unsigned int val;
-       union cmReg cmReg;
 
        /*
         * Check what type of Counter the user requested
@@ -192,28 +240,31 @@ static int s526_gpct_insn_config(struct comedi_device *dev,
 
 #if 1
                /*  Set Counter Mode Register */
-               cmReg.value = data[1] & 0xffff;
-               outw(cmReg.value, dev->iobase + S526_GPCT_MODE_REG(chan));
+               val = data[1] & 0xffff;
+               outw(val, dev->iobase + S526_GPCT_MODE_REG(chan));
 
                /*  Reset the counter if it is software preload */
-               if (cmReg.reg.autoLoadResetRcap == 0) {
+               if ((val & S526_GPCT_MODE_AUTOLOAD_MASK) ==
+                   S526_GPCT_MODE_AUTOLOAD_NONE) {
                        /*  Reset the counter */
-                       outw(0x8000, dev->iobase + S526_GPCT_CTRL_REG(chan));
-                       /* Load the counter from PR0
-                        * outw(0x4000, dev->iobase + S526_GPCT_CTRL_REG(chan));
+                       outw(S526_GPCT_CTRL_CT_RESET,
+                            dev->iobase + S526_GPCT_CTRL_REG(chan));
+                       /*
+                        * Load the counter from PR0
+                        * outw(S526_GPCT_CTRL_CT_LOAD,
+                        *      dev->iobase + S526_GPCT_CTRL_REG(chan));
                         */
                }
 #else
-               /*  0 quadrature, 1 software control */
-               cmReg.reg.countDirCtrl = 0;
+               val = S526_GPCT_MODE_CTDIR_CTRL_QUAD;
 
                /*  data[1] contains GPCT_X1, GPCT_X2 or GPCT_X4 */
                if (data[1] == GPCT_X2)
-                       cmReg.reg.clockSource = 1;
+                       val |= S526_GPCT_MODE_CLK_SRC_QUADX2;
                else if (data[1] == GPCT_X4)
-                       cmReg.reg.clockSource = 2;
+                       val |= S526_GPCT_MODE_CLK_SRC_QUADX4;
                else
-                       cmReg.reg.clockSource = 0;
+                       val |= S526_GPCT_MODE_CLK_SRC_QUADX1;
 
                /*  When to take into account the indexpulse: */
                /*
@@ -224,13 +275,14 @@ static int s526_gpct_insn_config(struct comedi_device *dev,
                 * }
                 */
                /*  Take into account the index pulse? */
-               if (data[3] == GPCT_RESET_COUNTER_ON_INDEX)
+               if (data[3] == GPCT_RESET_COUNTER_ON_INDEX) {
                        /*  Auto load with INDEX^ */
-                       cmReg.reg.autoLoadResetRcap = 4;
+                       val |= S526_GPCT_MODE_AUTOLOAD_IXRISE;
+               }
 
                /*  Set Counter Mode Register */
-               cmReg.value = data[1] & 0xffff;
-               outw(cmReg.value, dev->iobase + S526_GPCT_MODE_REG(chan));
+               val = data[1] & 0xffff;
+               outw(val, dev->iobase + S526_GPCT_MODE_REG(chan));
 
                /*  Load the pre-load register */
                s526_gpct_write(dev, chan, data[2]);
@@ -241,11 +293,14 @@ static int s526_gpct_insn_config(struct comedi_device *dev,
                             dev->iobase + S526_GPCT_CTRL_REG(chan));
 
                /*  Reset the counter if it is software preload */
-               if (cmReg.reg.autoLoadResetRcap == 0) {
+               if ((val & S526_GPCT_MODE_AUTOLOAD_MASK) ==
+                   S526_GPCT_MODE_AUTOLOAD_NONE) {
                        /*  Reset the counter */
-                       outw(0x8000, dev->iobase + S526_GPCT_CTRL_REG(chan));
+                       outw(S526_GPCT_CTRL_CT_RESET,
+                            dev->iobase + S526_GPCT_CTRL_REG(chan));
                        /*  Load the counter from PR0 */
-                       outw(0x4000, dev->iobase + S526_GPCT_CTRL_REG(chan));
+                       outw(S526_GPCT_CTRL_CT_LOAD,
+                            dev->iobase + S526_GPCT_CTRL_REG(chan));
                }
 #endif
                break;
@@ -261,17 +316,21 @@ static int s526_gpct_insn_config(struct comedi_device *dev,
                devpriv->gpct_config[chan] = data[0];
 
                /*  Set Counter Mode Register */
-               cmReg.value = data[1] & 0xffff;
-               cmReg.reg.preloadRegSel = 0;    /*  PR0 */
-               outw(cmReg.value, dev->iobase + S526_GPCT_MODE_REG(chan));
+               val = data[1] & 0xffff;
+               /* Select PR0 */
+               val &= ~S526_GPCT_MODE_PR_SELECT_MASK;
+               val |= S526_GPCT_MODE_PR_SELECT_PR0;
+               outw(val, dev->iobase + S526_GPCT_MODE_REG(chan));
 
                /* Load the pre-load register 0 */
                s526_gpct_write(dev, chan, data[2]);
 
                /*  Set Counter Mode Register */
-               cmReg.value = data[1] & 0xffff;
-               cmReg.reg.preloadRegSel = 1;    /*  PR1 */
-               outw(cmReg.value, dev->iobase + S526_GPCT_MODE_REG(chan));
+               val = data[1] & 0xffff;
+               /* Select PR1 */
+               val &= ~S526_GPCT_MODE_PR_SELECT_MASK;
+               val |= S526_GPCT_MODE_PR_SELECT_PR1;
+               outw(val, dev->iobase + S526_GPCT_MODE_REG(chan));
 
                /* Load the pre-load register 1 */
                s526_gpct_write(dev, chan, data[3]);
@@ -294,17 +353,21 @@ static int s526_gpct_insn_config(struct comedi_device *dev,
                devpriv->gpct_config[chan] = data[0];
 
                /*  Set Counter Mode Register */
-               cmReg.value = data[1] & 0xffff;
-               cmReg.reg.preloadRegSel = 0;    /*  PR0 */
-               outw(cmReg.value, dev->iobase + S526_GPCT_MODE_REG(chan));
+               val = data[1] & 0xffff;
+               /* Select PR0 */
+               val &= ~S526_GPCT_MODE_PR_SELECT_MASK;
+               val |= S526_GPCT_MODE_PR_SELECT_PR0;
+               outw(val, dev->iobase + S526_GPCT_MODE_REG(chan));
 
                /* Load the pre-load register 0 */
                s526_gpct_write(dev, chan, data[2]);
 
                /*  Set Counter Mode Register */
-               cmReg.value = data[1] & 0xffff;
-               cmReg.reg.preloadRegSel = 1;    /*  PR1 */
-               outw(cmReg.value, dev->iobase + S526_GPCT_MODE_REG(chan));
+               val = data[1] & 0xffff;
+               /* Select PR1 */
+               val &= ~S526_GPCT_MODE_PR_SELECT_MASK;
+               val |= S526_GPCT_MODE_PR_SELECT_PR1;
+               outw(val, dev->iobase + S526_GPCT_MODE_REG(chan));
 
                /* Load the pre-load register 1 */
                s526_gpct_write(dev, chan, data[3]);
index 75040daa40ce8200505817189f39e121059c829a..72f0aaa6911f562383a6c403b430c88d8d28fa0f 100644 (file)
@@ -934,7 +934,7 @@ static void cls_flush_uart_write(struct channel_t *ch)
 
        writeb((UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_XMIT),
               &ch->ch_cls_uart->isr_fcr);
-       udelay(10);
+       usleep_range(10, 20);
 
        ch->ch_flags |= (CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM);
 }
index 8106f5234bf519e6d79efdd903b8d0dff02a8356..39c76e78e56aa6def760fd0e602b0e0afdbf0ac0 100644 (file)
@@ -1108,9 +1108,9 @@ static void neo_copy_data_from_uart_to_queue(struct channel_t *ch)
         * On the other hand, if the UART IS in FIFO mode, then ask
         * the UART to give us an approximation of data it has RX'ed.
         */
-       if (!(ch->ch_flags & CH_FIFO_ENABLED))
+       if (!(ch->ch_flags & CH_FIFO_ENABLED)) {
                total = 0;
-       else {
+       else {
                total = readb(&ch->ch_neo_uart->rfifo);
 
                /*
@@ -1628,7 +1628,7 @@ static void neo_uart_init(struct channel_t *ch)
 
        /* Clear out UART and FIFO */
        readb(&ch->ch_neo_uart->txrx);
-       writeb((UART_FCR_ENABLE_FIFO|UART_FCR_CLEAR_RCVR|UART_FCR_CLEAR_XMIT), &ch->ch_neo_uart->isr_fcr);
+       writeb((UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT), &ch->ch_neo_uart->isr_fcr);
        readb(&ch->ch_neo_uart->lsr);
        readb(&ch->ch_neo_uart->msr);
 
@@ -1779,8 +1779,8 @@ static void neo_vpd(struct dgnc_board *brd)
        /* Store the VPD into our buffer */
        for (i = 0; i < NEO_VPD_IMAGESIZE; i++) {
                a = neo_read_eeprom(brd->re_map_membase, i);
-               brd->vpd[i*2] = a & 0xff;
-               brd->vpd[(i*2)+1] = (a >> 8) & 0xff;
+               brd->vpd[i * 2] = a & 0xff;
+               brd->vpd[(i * 2) + 1] = (a >> 8) & 0xff;
        }
 
        if  (((brd->vpd[0x08] != 0x82)     /* long resource name tag */
index 48e4b90578c17fdb037894d92348d065c4546544..b79eab084c023864389dc283aec9e703b72177e0 100644 (file)
@@ -448,7 +448,7 @@ void dgnc_tty_uninit(struct dgnc_board *brd)
  *     dgnc_wmove - Write data to transmit queue.
  *
  *             ch      - Pointer to channel structure.
- *             buf     - Poiter to characters to be moved.
+ *             buf     - Pointer to characters to be moved.
  *             n       - Number of characters to move.
  *
  *=======================================================================*/
index 4e6c16af40fc5f8fa2065dacb946ad2a78adf0e9..beb9411658ba97ca77037e61fffdf72ed46ac40b 100644 (file)
@@ -823,7 +823,7 @@ static int _nbu2ss_out_dma(
        u32             length
 )
 {
-       u8              *pBuffer;
+       dma_addr_t      pBuffer;
        u32             mpkt;
        u32             lmpkt;
        u32             dmacnt;
@@ -836,7 +836,7 @@ static int _nbu2ss_out_dma(
                return 1;               /* DMA is forwarded */
 
        req->dma_flag = TRUE;
-       pBuffer = (u8 *)req->req.dma;
+       pBuffer = req->req.dma;
        pBuffer += req->req.actual;
 
        /* DMA Address */
@@ -1034,7 +1034,7 @@ static int _nbu2ss_in_dma(
        u32             length
 )
 {
-       u8              *pBuffer;
+       dma_addr_t      pBuffer;
        u32             mpkt;           /* MaxPacketSize */
        u32             lmpkt;          /* Last Packet Data Size */
        u32             dmacnt;         /* IN Data Size */
@@ -1080,7 +1080,7 @@ static int _nbu2ss_in_dma(
        _nbu2ss_writel(&preg->EP_DCR[num].EP_DCR2, data);
 
        /* Address setting */
-       pBuffer = (u8 *)req->req.dma;
+       pBuffer = req->req.dma;
        pBuffer += req->req.actual;
        _nbu2ss_writel(&preg->EP_DCR[num].EP_TADR, (u32)pBuffer);
 
@@ -1285,11 +1285,7 @@ static void _nbu2ss_restert_transfer(struct nbu2ss_ep *ep)
        bool    bflag = FALSE;
        struct nbu2ss_req *req;
 
-       if (list_empty(&ep->queue))
-               req = NULL;
-       else
-               req = list_entry(ep->queue.next, struct nbu2ss_req, queue);
-
+       req = list_first_entry_or_null(&ep->queue, struct nbu2ss_req, queue);
        if (!req)
                return;
 
@@ -1784,11 +1780,7 @@ static inline int _nbu2ss_ep0_in_data_stage(struct nbu2ss_udc *udc)
        struct nbu2ss_req       *req;
        struct nbu2ss_ep        *ep = &udc->ep[0];
 
-       if (list_empty(&ep->queue))
-               req = NULL;
-       else
-               req = list_entry(ep->queue.next, struct nbu2ss_req, queue);
-
+       req = list_first_entry_or_null(&ep->queue, struct nbu2ss_req, queue);
        if (!req)
                req = &udc->ep0_req;
 
@@ -1811,11 +1803,7 @@ static inline int _nbu2ss_ep0_out_data_stage(struct nbu2ss_udc *udc)
        struct nbu2ss_req       *req;
        struct nbu2ss_ep        *ep = &udc->ep[0];
 
-       if (list_empty(&ep->queue))
-               req = NULL;
-       else
-               req = list_entry(ep->queue.next, struct nbu2ss_req, queue);
-
+       req = list_first_entry_or_null(&ep->queue, struct nbu2ss_req, queue);
        if (!req)
                req = &udc->ep0_req;
 
@@ -1838,11 +1826,7 @@ static inline int _nbu2ss_ep0_status_stage(struct nbu2ss_udc *udc)
        struct nbu2ss_req       *req;
        struct nbu2ss_ep        *ep = &udc->ep[0];
 
-       if (list_empty(&ep->queue))
-               req = NULL;
-       else
-               req = list_entry(ep->queue.next, struct nbu2ss_req, queue);
-
+       req = list_first_entry_or_null(&ep->queue, struct nbu2ss_req, queue);
        if (!req) {
                req = &udc->ep0_req;
                if (req->req.complete)
@@ -2145,11 +2129,7 @@ static inline void _nbu2ss_epn_int(struct nbu2ss_udc *udc, u32 epnum)
        /* Interrupt Clear */
        _nbu2ss_writel(&udc->p_regs->EP_REGS[num].EP_STATUS, ~(u32)status);
 
-       if (list_empty(&ep->queue))
-               req = NULL;
-       else
-               req = list_entry(ep->queue.next, struct nbu2ss_req, queue);
-
+       req = list_first_entry_or_null(&ep->queue, struct nbu2ss_req, queue);
        if (!req) {
                /* pr_warn("=== %s(%d) req == NULL\n", __func__, epnum); */
                return;
@@ -2728,7 +2708,7 @@ static int nbu2ss_ep_queue(
        spin_lock_irqsave(&udc->lock, flags);
 
 #ifdef USE_DMA
-       if ((u32)req->req.buf & 0x3)
+       if ((uintptr_t)req->req.buf & 0x3)
                req->unaligned = TRUE;
        else
                req->unaligned = FALSE;
index 5f1375c465e614390ca6ebacca245122d2d4cf34..bb1f15224ac8562ce70f428c52599fb15cb87cb7 100644 (file)
@@ -319,7 +319,7 @@ struct mxs_lradc {
 #define        LRADC_CH_VALUE_OFFSET                   0
 
 #define        LRADC_DELAY(n)                          (0xd0 + (0x10 * (n)))
-#define        LRADC_DELAY_TRIGGER_LRADCS_MASK         (0xff << 24)
+#define        LRADC_DELAY_TRIGGER_LRADCS_MASK         (0xffUL << 24)
 #define        LRADC_DELAY_TRIGGER_LRADCS_OFFSET       24
 #define        LRADC_DELAY_TRIGGER(x) \
                                (((x) << LRADC_DELAY_TRIGGER_LRADCS_OFFSET) & \
index 4d74e8af5088deec183c6d83cc16a5cfd1dc15fa..0d8a91ee5ffc42af6be0b0ece349144c32261dc9 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
 
 #include "curproc.h"
 
-static inline int __is_po2(unsigned long long val)
-{
-       return !(val & (val - 1));
-}
-
-#define IS_PO2(val) __is_po2((unsigned long long)(val))
-
 #define LOWEST_BIT_SET(x)       ((x) & ~((x) - 1))
 
 /*
index 78786784748378b655fc5d0445aa4d79fb07d597..1530b0458a6140a2c28c0338a737186f020c772b 100644 (file)
@@ -22,7 +22,8 @@
  */
 /*
  * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2012, Intel Corporation.
+ *
+ * Copyright (c) 2012, 2015 Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index f14db92346bae74c974018949aa2bf9a08dbe86c..c3f2332fa043b81552fe3e864e3aaea9bd2c6e37 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2012, Intel Corporation.
+ * Copyright (c) 2012, 2015 Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index f5d741f25ffdeb189a6b56f7ce871630f7e303be..485ab267091859214576da349e2bf89a5874667d 100644 (file)
@@ -110,7 +110,6 @@ struct libcfs_ioctl_handler {
 #define IOC_LIBCFS_CLEAR_DEBUG      _IOWR('e', 31, long)
 #define IOC_LIBCFS_MARK_DEBUG        _IOWR('e', 32, long)
 #define IOC_LIBCFS_MEMHOG                _IOWR('e', 36, long)
-#define IOC_LIBCFS_PING_TEST          _IOWR('e', 37, long)
 /* lnet ioctls */
 #define IOC_LIBCFS_GET_NI                _IOWR('e', 50, long)
 #define IOC_LIBCFS_FAIL_NID            _IOWR('e', 51, long)
index 9493d5e236c523a1fa1bc5d2ffa0894dba057b0b..75285fde15e8c06270e99bb0c0bd1409121a5dce 100644 (file)
@@ -161,12 +161,6 @@ int LNetEQAlloc(unsigned int       count_in,
 
 int LNetEQFree(lnet_handle_eq_t eventq_in);
 
-int LNetEQGet(lnet_handle_eq_t  eventq_in,
-             lnet_event_t     *event_out);
-
-int LNetEQWait(lnet_handle_eq_t  eventq_in,
-              lnet_event_t     *event_out);
-
 int LNetEQPoll(lnet_handle_eq_t *eventqs_in,
               int               neq_in,
               int               timeout_ms,
index b61d5045a56667857e48cf3b5759bb79709a4b54..b67a6607bb3b3b5b250a50aeda833f778fd932fb 100644 (file)
@@ -23,7 +23,7 @@
  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2012 - 2015, Intel Corporation.
+ * Copyright (c) 2012, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index d792c4adb0ca4fbf56d45ec2221d17215167285f..3bb9468e0b9d5787adac3e0c4e1f92b0781a7f44 100644 (file)
@@ -23,7 +23,7 @@
  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2012 - 2015, Intel Corporation.
+ * Copyright (c) 2012, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index 46ad9147ad2a4ef173bee3f5c9761adc8e1d93a0..4fc9ddce829d18c83ab0cf98a421ca4a6c2c16f5 100644 (file)
@@ -23,7 +23,7 @@
  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011 - 2015, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 #ifndef _LNET_NIDSTRINGS_H
 #define _LNET_NIDSTRINGS_H
index de0f85f8a2f972ccedb6245b62531651f2eda877..72af486b65df70ee2b011ee745bef74c33beec5c 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index 263db37de7c807821ffe98b2156252b4ecf24ebf..025faa9f86b35641789335650705bd463d0e1ed2 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index 260750354a41707311aaec9afde6667e34959e5a..c7b9ccb13f1c737aaa9690f96a52fb4002871008 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2012, Intel Corporation.
+ * Copyright (c) 2012, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index ebde0369edc814603f9ca0f912c29a4094345919..05aa90ea597a7d558ac9cfa125e33d1f687e3daf 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index 92ca1dd64076f5710f1d4e0f7d5b3ebda8bc2a83..fed57d90028de31738b7edfa715663bd7dfc809b 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index 284150f53f7dbf82618148df23ac6701fd8b4c69..362282fa00bf289928947eafe3884ec18bbd5ec7 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
@@ -354,7 +354,6 @@ lnet_counters_reset(void)
 
        lnet_net_unlock(LNET_LOCK_EX);
 }
-EXPORT_SYMBOL(lnet_counters_reset);
 
 static char *
 lnet_res_type2str(int type)
@@ -1153,7 +1152,6 @@ lnet_init(void)
        lnet_register_lnd(&the_lolnd);
        return 0;
 }
-EXPORT_SYMBOL(lnet_init);
 
 /**
  * Finalize LNet library.
@@ -1177,7 +1175,6 @@ lnet_fini(void)
 
        the_lnet.ln_init = 0;
 }
-EXPORT_SYMBOL(lnet_fini);
 
 /**
  * Set LNet PID and start LNet interfaces, routing, and forwarding.
index 5390ee9963ab4e8b6637e8e381dc35837d2aa3df..284a3c271bc6035372b6ed212d6112b3bcaab849 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2012, Intel Corporation.
+ * Copyright (c) 2012, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index 60889ebd2f2bb38ede887ad6dab88c14a32e62a4..64f94a69008142d98ebb8b8b644112098103be8e 100644 (file)
@@ -282,15 +282,6 @@ lnet_eq_dequeue_event(lnet_eq_t *eq, lnet_event_t *ev)
  * at least one event between this event and the last event obtained from the
  * EQ has been dropped due to limited space in the EQ.
  */
-int
-LNetEQGet(lnet_handle_eq_t eventq, lnet_event_t *event)
-{
-       int which;
-
-       return LNetEQPoll(&eventq, 1, 0,
-                        event, &which);
-}
-EXPORT_SYMBOL(LNetEQGet);
 
 /**
  * Block the calling process until there is an event in the EQ.
@@ -308,15 +299,6 @@ EXPORT_SYMBOL(LNetEQGet);
  * at least one event between this event and the last event obtained from the
  * EQ has been dropped due to limited space in the EQ.
  */
-int
-LNetEQWait(lnet_handle_eq_t eventq, lnet_event_t *event)
-{
-       int which;
-
-       return LNetEQPoll(&eventq, 1, LNET_TIME_FOREVER,
-                        event, &which);
-}
-EXPORT_SYMBOL(LNetEQWait);
 
 static int
 lnet_eq_wait_locked(int *timeout_ms)
index 5631f60a39bc8ffe3487b79275be799e85f19b56..fb8f7be043eccdcff444276e9b7e91b58a3c5a27 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
@@ -1645,7 +1645,6 @@ lnet_msgtyp2str(int type)
                return "<UNKNOWN>";
        }
 }
-EXPORT_SYMBOL(lnet_msgtyp2str);
 
 void
 lnet_print_hdr(lnet_hdr_t *hdr)
index b4f573ab62ccc5aa53d52c09701ab52cab2f1040..bd7b071b287325599b571c8d4e1db47c0401f331 100644 (file)
@@ -21,7 +21,7 @@
  * GPL HEADER END
  */
 /*
- * Copyright (c) 2012, Intel Corporation.
+ * Copyright (c) 2012, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index 6f7ef4c737cdceb7cd7c0a713566aec021c58b4d..589ecc84d1b87eccbb65821c5d3de7e660955ac8 100644 (file)
@@ -23,7 +23,7 @@
  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2012, 2015 Intel Corporation.
+ * Copyright (c) 2012, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index ac2fdf05a5fd9007c290cee732b739950ceb5296..c93c00752a4cc3d216197c0547a57fa0e4ef60d9 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2012, Intel Corporation.
+ * Copyright (c) 2012, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index 4ea651c6db3a4492f14ae49d5e27c1b784c96a5e..f5faa414d25080a89eb291d6333b0628f282e600 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  *
  *   This file is part of Portals
  *   http://sourceforge.net/projects/sandiaportals/
index 0f262267e01ed4d395a5f121123e8a503ad84acc..1f04cc1fc31c36d32a57dc41265a8b6b210bab24 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index 556c837cf62cd8f1f0d3f0cd25299f73ebfa2160..a534665403e57abcb838a96983399f61d8da3355 100644 (file)
@@ -925,5 +925,3 @@ out:
 
        return rc;
 }
-
-EXPORT_SYMBOL(lstcon_ioctl_entry);
index 86de68033f85bb43f21e6bc778af5533d33a8f01..2acf6ec717beb2ffa3385b8cf18019c7c2469bc4 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2012, Intel Corporation.
+ * Copyright (c) 2012, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index fe7c39afd1d9ed1a7af9773196571e12e46b3291..ff8f38dc10ce0ba9f6b88398f320b688ff5c8a89 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2013, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index ce90c1c54a637b4964578d9c807dd144ef956934..39f2aa32e9846d5e4af9ec75f99337e3624ee120 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index baa04074a61f658eead28b62cbe05f902ca58d30..d9459e58e2ce7a00326aa73138f22acc6517f3c4 100644 (file)
@@ -227,7 +227,6 @@ static int fld_cache_shrink(struct fld_cache *cache)
 
        while (cache->fci_cache_count + cache->fci_threshold >
               cache->fci_cache_size && curr != &cache->fci_lru) {
-
                flde = list_entry(curr, struct fld_cache_entry, fce_lru);
                curr = curr->prev;
                fld_cache_entry_delete(cache, flde);
index 959b8e6bba951029cf55dc96d1b073f5f9359cce..12eb1647b4bf315087818bfced23a5303d98f793 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2012, 2013, Intel Corporation.
+ * Copyright (c) 2012, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index 469df685f392de83afb2b86d51bb3c2f980a26ab..d92c01b748658d0f7dcfb8a18f9038641e70b0b3 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2013, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index 603f56e6095ba82beef14a6ab67da7f0c21f2ca1..41ceaa8198a7f9c6da3633f1aeac42bf628b7483 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2012, 2013, Intel Corporation.
+ * Copyright (c) 2012, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index 73564f8e388458ca3f3ed8b689edd9e4e8d454c2..bd7acc2a121939913a370cc5affcfbd0a85ed8b0 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
@@ -3127,7 +3127,6 @@ void cl_page_list_disown (const struct lu_env *env,
                          struct cl_io *io, struct cl_page_list *plist);
 
 void cl_2queue_init     (struct cl_2queue *queue);
-void cl_2queue_add      (struct cl_2queue *queue, struct cl_page *page);
 void cl_2queue_disown   (const struct lu_env *env,
                         struct cl_io *io, struct cl_2queue *queue);
 void cl_2queue_discard  (const struct lu_env *env,
index f18c0c75ef1ec44ca1f9b7e8bced05a441ca6b95..0ac8e0edcc4841dd30dd3724669d1c7fe570ae0a 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index fa78689748a9edc5e73befc001b81ff180f3219b..1d79341a495d13f858d7be8f0bda0638254eadf7 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index 06ce8c9ae9ad45cfd2ee98a990ca9fd5ee61257f..09088f40ba88b4643ec11a19239b82865b4c4169 100644 (file)
@@ -26,6 +26,8 @@
 /*
  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
+ *
+ * Copyright (c) 2014, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index 0b721c65c2a3eb4bca4faef0b2fcd9620c51af52..b064b5821e3fbf337898e9c78251bdc95fd175be 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index 80f8ec5294248a605eaaa4f59a1a986863830c90..2b4dd656d5f580b0809d4c30f0d07d6fd5ec33f9 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2010, 2012, Intel Corporation.
+ * Copyright (c) 2010, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index 138479a9edc1fe781818dac61d52307ed11d9f55..9b319f1df02577b973449aefeafa2e641966ad9e 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2010, 2012, Intel Corporation.
+ * Copyright (c) 2010, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index fee4d2c75506d528d2bafea196d92c5c5269c1db..0b66593a95263463ff093bda3b78cddc854b5a1c 100644 (file)
@@ -76,8 +76,6 @@ extern int
 lustre_posix_acl_xattr_filter(posix_acl_xattr_header *header, size_t size,
                              posix_acl_xattr_header **out);
 extern void
-lustre_posix_acl_xattr_free(posix_acl_xattr_header *header, int size);
-extern void
 lustre_ext_acl_xattr_free(ext_acl_xattr_header *header);
 extern ext_acl_xattr_header *
 lustre_acl_xattr_merge2ext(posix_acl_xattr_header *posix_header, int size,
index 1daf4c572415c246fcf294155ed4a74812952ac4..311e5aa9b0dbf3aac2bf295615d908dc65f644fa 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index 47c3f375024094a585e6adaa99464548409b911c..9b1a9c695113987fb847e72df26c93dd78a59f24 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index d8b3db9cdebaa950e8cbcda2a802e780010900f0..551162624974690e6195387689dcd24675450b6d 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2013, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index 49dfbb14f381a8f591a0166a5faee76cf749f7f7..5488a698dabd08fcbd92390c6f5408469d7fee17 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index 1de0c4d6f7f775cb46ee27b47899e9c0e292ddc1..e4fc8b5e1336349c2dfb4229365d87eed8fea0f5 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2012, Intel Corporation.
+ * Copyright (c) 2012, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
@@ -94,9 +94,6 @@ int llog_open(const struct lu_env *env, struct llog_ctxt *ctxt,
              struct llog_handle **lgh, struct llog_logid *logid,
              char *name, enum llog_open_param open_param);
 int llog_close(const struct lu_env *env, struct llog_handle *cathandle);
-int llog_backup(const struct lu_env *env, struct obd_device *obd,
-               struct llog_ctxt *ctxt, struct llog_ctxt *bak_ctxt,
-               char *name, char *backup);
 
 /* llog_process flags */
 #define LLOG_FLAG_NODEAMON 0x0001
index a16eb8b611789941dcc9862903fc0bad9375019c..95d27ddecfb393e95655727172c1bc57d6e1c42f 100644 (file)
@@ -62,12 +62,6 @@ struct mds_group_info {
 #define MDD_OBD_NAME     "mdd_obd"
 #define MDD_OBD_UUID     "mdd_obd_uuid"
 
-static inline int md_should_create(__u64 flags)
-{
-       return !(flags & MDS_OPEN_DELAY_CREATE ||
-              !(flags & FMODE_WRITE));
-}
-
 /* these are local flags, used only on the client, private */
 #define M_CHECK_STALE     0200000000
 
index 0127f45ca0c3f571d784f8dabdde1bedb6d36516..d834ddd8183bcd15072d45286a85d761b142df85 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2010, 2012, Intel Corporation.
+ * Copyright (c) 2010, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index 8f6c0b26cfaba308677ad9af7554a51d59706029..383fe6febe4ba874f98684c7ea2d7e21f207867d 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index df292f6d4a85e8d1c73d7b0c8c08ac6180ebc90a..46a662f89322f0bddc9ac65742fd84a058b64064 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index 5c90b59cf0db5cec4cc36a5fbcef4be58b20de4e..bcbe61301713c3fd8aef471d0365263bf48ee986 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index 0b7e90ac7818d41c0b4aef79c6bb4f0ff8830689..97d80397503c6e9d007fb5fb0fa2acd73cc70537 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index a22a5308fb48d0de96b67cac62ea2bc41e92ec74..d031437c0528e9b18476335a78f55a3af108184a 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index 12c7f0e669d40e88bf6da1d63bc6d1c93f0a7cdf..34dde7dede74df9551ee2da193e5ed371640a252 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index db3c9b7af7d50d4ace790e606f3f5000e1aa9485..849cc98df7ddc565b52ac3e7ec94e40aad3dc707 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index ccce1e5031202cd4057141d1c91ca9aaec218493..3c8d4413d9768a81c6b39e079c06cdf4badb2814 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2010, 2012, Intel Corporation.
+ * Copyright (c) 2010, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index 7f8c70056ffdeb011db2e175904025714e174a3e..cf9ec0cfe24782788ba4077b75f07dd0e1d84a6e 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2010, 2012, Intel Corporation.
+ * Copyright (c) 2010, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index ca115119501ae1ba3a2272665fc83c4fa3a336db..79aeb2bf6c8e8a0ce68fc7f929993112748a3ba4 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2010, 2012, Intel Corporation.
+ * Copyright (c) 2010, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index e59b2864180fd02f221e884ede314d708afa8e25..3d7c137d223a4a5016ec69a54ea74a7c77928004 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2010, 2012, Intel Corporation.
+ * Copyright (c) 2010, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index fdf81b87aad7b29e90faedee95070a1fd4fdd93f..b9eb37762434ae282d5f94515b0115203acd8580 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2010, 2012, Intel Corporation.
+ * Copyright (c) 2010, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index b55a4f0eb1d5aa564bdcbde7bcb4cec09b0dd10e..0ae610015b7c97a85c45eb14f92ff28d89dd85c0 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2010, 2012, Intel Corporation.
+ * Copyright (c) 2010, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index e56785a482425e8119572c3f2031bc65da1e3d22..0b38dad135465eaff467bc03d166fc7dfa7c961d 100644 (file)
@@ -557,10 +557,3 @@ int libcfs_debug_mark_buffer(const char *text)
 
 #undef DEBUG_SUBSYSTEM
 #define DEBUG_SUBSYSTEM S_LNET
-
-void libcfs_debug_set_level(unsigned int debug_level)
-{
-       pr_warn("Lustre: Setting portals debug level to %08x\n",
-              debug_level);
-       libcfs_debug = debug_level;
-}
index ea059b012a669097a5db7209785ff915944260ae..27831432d69a49e3767e2e75e5c59825d94d66bd 100644 (file)
@@ -26,7 +26,7 @@
  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index d285117af3adaa21cd327b0889a53bf96b0e623a..4d50510434be5b1adbc9583879169e95fa4b5584 100644 (file)
  *   table. Also, user can break the iteration by return 1 in callback.
  */
 #include <linux/seq_file.h>
+#include <linux/log2.h>
 
 #include "../../include/linux/libcfs/libcfs.h"
 
@@ -1777,7 +1778,7 @@ cfs_hash_rehash_cancel_locked(struct cfs_hash *hs)
        for (i = 2; cfs_hash_is_rehashing(hs); i++) {
                cfs_hash_unlock(hs, 1);
                /* raise console warning while waiting too long */
-               CDEBUG(IS_PO2(i >> 3) ? D_WARNING : D_INFO,
+               CDEBUG(is_power_of_2(i >> 3) ? D_WARNING : D_INFO,
                       "hash %s is still rehashing, rescheded %d\n",
                       hs->hs_name, i - 1);
                cond_resched();
index 94bc0078500057d5fe62ba85b5700e643c6691c0..15782d9e6aa961842d3aeead96521c1f1d481fdc 100644 (file)
@@ -21,7 +21,7 @@
  * GPL HEADER END
  */
 /* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2012, Intel Corporation.
+ * Copyright (c) 2012, 2015 Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index d40be5396769482d6cdd305d2029b2914997ca3b..205a3ed435a88d104cbe728925145a5303776481 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2012, Intel Corporation.
+ * Copyright (c) 2012, 2015 Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index 58a4034be1b859f6bf838ced7d348530d8ace985..e52afe35e7eae439f026bf8edccd50e39397d179 100644 (file)
@@ -22,7 +22,8 @@
  */
 /*
  * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2012, Intel Corporation.
+ *
+ * Copyright (c) 2012, 2015 Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index c74c80915dca8bd15ed770cfe31ed82c1d52359f..68515d9130c15b441b016b659dc6e503ae2512ce 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
diff --git a/drivers/staging/lustre/lustre/libcfs/linux/linux-tracefile.h b/drivers/staging/lustre/lustre/libcfs/linux/linux-tracefile.h
deleted file mode 100644 (file)
index ba84e4f..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * GPL HEADER START
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 only,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License version 2 for more details (a copy is included
- * in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; If not, see
- * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- *
- * GPL HEADER END
- */
-/*
- * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
- * Use is subject to license terms.
- */
-/*
- * This file is part of Lustre, http://www.lustre.org/
- * Lustre is a trademark of Sun Microsystems, Inc.
- */
-
-#ifndef __LIBCFS_LINUX_TRACEFILE_H__
-#define __LIBCFS_LINUX_TRACEFILE_H__
-
-/**
- * three types of trace_data in linux
- */
-typedef enum {
-       CFS_TCD_TYPE_PROC = 0,
-       CFS_TCD_TYPE_SOFTIRQ,
-       CFS_TCD_TYPE_IRQ,
-       CFS_TCD_TYPE_MAX
-} cfs_trace_buf_type_t;
-
-#endif
index 96d9d4651a51b3d0a6ce6189ad16f4d592d6242a..329d78ce272d4416309be0fde6f85cf654ab7c5a 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2012, Intel Corporation.
+ * Copyright (c) 2012, 2015 Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
@@ -274,23 +274,6 @@ static int libcfs_ioctl_int(struct cfs_psdev_file *pfile, unsigned long cmd,
                }
                break;
 
-       case IOC_LIBCFS_PING_TEST: {
-               extern void (kping_client)(struct libcfs_ioctl_data *);
-               void (*ping)(struct libcfs_ioctl_data *);
-
-               CDEBUG(D_IOCTL, "doing %d pings to nid %s (%s)\n",
-                      data->ioc_count, libcfs_nid2str(data->ioc_nid),
-                      libcfs_nid2str(data->ioc_nid));
-               ping = symbol_get(kping_client);
-               if (!ping)
-                       CERROR("symbol_get failed\n");
-               else {
-                       ping(data);
-                       symbol_put(kping_client);
-               }
-               return 0;
-       }
-
        default: {
                struct libcfs_ioctl_handler *hand;
 
index 6b37798336f238675a7a3d0183cc135786a451ee..7bf1471a54fb21574d32932164c35e797323a6c0 100644 (file)
 
 #include "../../include/linux/libcfs/libcfs.h"
 
-#include "linux/linux-tracefile.h"
+typedef enum {
+       CFS_TCD_TYPE_PROC = 0,
+       CFS_TCD_TYPE_SOFTIRQ,
+       CFS_TCD_TYPE_IRQ,
+       CFS_TCD_TYPE_MAX
+} cfs_trace_buf_type_t;
 
 /* trace file lock routines */
 
@@ -251,13 +256,6 @@ void cfs_print_to_console(struct ptldebug_header *hdr, int mask,
 int cfs_trace_lock_tcd(struct cfs_trace_cpu_data *tcd, int walking);
 void cfs_trace_unlock_tcd(struct cfs_trace_cpu_data *tcd, int walking);
 
-/**
- * trace_buf_type_t, trace_buf_idx_get() and trace_console_buffers[][]
- * are not public libcfs API; they should be defined in
- * platform-specific tracefile include files
- * (see, for example, linux-tracefile.h).
- */
-
 extern char *cfs_trace_console_buffers[NR_CPUS][CFS_TCD_TYPE_MAX];
 cfs_trace_buf_type_t cfs_trace_buf_idx_get(void);
 
index b57acbfb061b1aab6f40578731c66ef06cedc455..60bb88a00b416a6f398cea44a430f95da8ac194b 100644 (file)
@@ -86,32 +86,20 @@ static struct cfs_workitem_data {
        int                     wi_stopping;
 } cfs_wi_data;
 
-static inline void
-cfs_wi_sched_lock(struct cfs_wi_sched *sched)
-{
-       spin_lock(&sched->ws_lock);
-}
-
-static inline void
-cfs_wi_sched_unlock(struct cfs_wi_sched *sched)
-{
-       spin_unlock(&sched->ws_lock);
-}
-
 static inline int
 cfs_wi_sched_cansleep(struct cfs_wi_sched *sched)
 {
-       cfs_wi_sched_lock(sched);
+       spin_lock(&sched->ws_lock);
        if (sched->ws_stopping) {
-               cfs_wi_sched_unlock(sched);
+               spin_unlock(&sched->ws_lock);
                return 0;
        }
 
        if (!list_empty(&sched->ws_runq)) {
-               cfs_wi_sched_unlock(sched);
+               spin_unlock(&sched->ws_lock);
                return 0;
        }
-       cfs_wi_sched_unlock(sched);
+       spin_unlock(&sched->ws_lock);
        return 1;
 }
 
@@ -125,7 +113,7 @@ cfs_wi_exit(struct cfs_wi_sched *sched, cfs_workitem_t *wi)
        LASSERT(!in_interrupt()); /* because we use plain spinlock */
        LASSERT(!sched->ws_stopping);
 
-       cfs_wi_sched_lock(sched);
+       spin_lock(&sched->ws_lock);
 
        LASSERT(wi->wi_running);
        if (wi->wi_scheduled) { /* cancel pending schedules */
@@ -139,7 +127,7 @@ cfs_wi_exit(struct cfs_wi_sched *sched, cfs_workitem_t *wi)
        LASSERT(list_empty(&wi->wi_list));
 
        wi->wi_scheduled = 1; /* LBUG future schedule attempts */
-       cfs_wi_sched_unlock(sched);
+       spin_unlock(&sched->ws_lock);
 
        return;
 }
@@ -161,7 +149,7 @@ cfs_wi_deschedule(struct cfs_wi_sched *sched, cfs_workitem_t *wi)
         * means the workitem will not be scheduled and will not have
         * any race with wi_action.
         */
-       cfs_wi_sched_lock(sched);
+       spin_lock(&sched->ws_lock);
 
        rc = !(wi->wi_running);
 
@@ -177,7 +165,7 @@ cfs_wi_deschedule(struct cfs_wi_sched *sched, cfs_workitem_t *wi)
 
        LASSERT (list_empty(&wi->wi_list));
 
-       cfs_wi_sched_unlock(sched);
+       spin_unlock(&sched->ws_lock);
        return rc;
 }
 EXPORT_SYMBOL(cfs_wi_deschedule);
@@ -195,7 +183,7 @@ cfs_wi_schedule(struct cfs_wi_sched *sched, cfs_workitem_t *wi)
        LASSERT(!in_interrupt()); /* because we use plain spinlock */
        LASSERT(!sched->ws_stopping);
 
-       cfs_wi_sched_lock(sched);
+       spin_lock(&sched->ws_lock);
 
        if (!wi->wi_scheduled) {
                LASSERT (list_empty(&wi->wi_list));
@@ -211,7 +199,7 @@ cfs_wi_schedule(struct cfs_wi_sched *sched, cfs_workitem_t *wi)
        }
 
        LASSERT (!list_empty(&wi->wi_list));
-       cfs_wi_sched_unlock(sched);
+       spin_unlock(&sched->ws_lock);
        return;
 }
 EXPORT_SYMBOL(cfs_wi_schedule);
@@ -237,7 +225,7 @@ cfs_wi_scheduler (void *arg)
 
        spin_unlock(&cfs_wi_data.wi_glock);
 
-       cfs_wi_sched_lock(sched);
+       spin_lock(&sched->ws_lock);
 
        while (!sched->ws_stopping) {
                int          nloops = 0;
@@ -258,12 +246,12 @@ cfs_wi_scheduler (void *arg)
                        wi->wi_running   = 1;
                        wi->wi_scheduled = 0;
 
-                       cfs_wi_sched_unlock(sched);
+                       spin_unlock(&sched->ws_lock);
                        nloops++;
 
                        rc = (*wi->wi_action) (wi);
 
-                       cfs_wi_sched_lock(sched);
+                       spin_lock(&sched->ws_lock);
                        if (rc != 0) /* WI should be dead, even be freed! */
                                continue;
 
@@ -278,21 +266,21 @@ cfs_wi_scheduler (void *arg)
                }
 
                if (!list_empty(&sched->ws_runq)) {
-                       cfs_wi_sched_unlock(sched);
+                       spin_unlock(&sched->ws_lock);
                        /* don't sleep because some workitems still
                         * expect me to come back soon */
                        cond_resched();
-                       cfs_wi_sched_lock(sched);
+                       spin_lock(&sched->ws_lock);
                        continue;
                }
 
-               cfs_wi_sched_unlock(sched);
+               spin_unlock(&sched->ws_lock);
                rc = wait_event_interruptible_exclusive(sched->ws_waitq,
                                                !cfs_wi_sched_cansleep(sched));
-               cfs_wi_sched_lock(sched);
+               spin_lock(&sched->ws_lock);
        }
 
-       cfs_wi_sched_unlock(sched);
+       spin_unlock(&sched->ws_lock);
 
        spin_lock(&cfs_wi_data.wi_glock);
        sched->ws_nthreads--;
index 80cba0448499481eab069fccedf69d88b7954430..3d6745e63fe370cd09ccdf74d5071a5a6a5b5576 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index 5c2ef92809e64ec0ece77f04b06af32a58da2750..7b355319079c3f2b4ca41f944929411747b30b5c 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index 02f27593013e3650e16bd22b511084755b2dc519..c92d58b770ec2bbd3b56c0600a0c2a6aeb8b015e 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
@@ -3139,7 +3139,7 @@ struct file_operations ll_file_operations_noflock = {
        .lock      = ll_file_noflock
 };
 
-struct inode_operations ll_file_inode_operations = {
+const struct inode_operations ll_file_inode_operations = {
        .setattr        = ll_setattr,
        .getattr        = ll_getattr,
        .permission     = ll_inode_permission,
index 157c32840e0635408b268b70fcd1a84ce1cfae32..ee8a1d67d19119ee034ed5ffa7d64829042aa20d 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
@@ -705,7 +705,7 @@ extern const struct address_space_operations ll_aops;
 extern struct file_operations ll_file_operations;
 extern struct file_operations ll_file_operations_flock;
 extern struct file_operations ll_file_operations_noflock;
-extern struct inode_operations ll_file_inode_operations;
+extern const struct inode_operations ll_file_inode_operations;
 int ll_have_md_lock(struct inode *inode, __u64 *bits,
                    ldlm_mode_t l_req_mode);
 ldlm_mode_t ll_take_md_lock(struct inode *inode, __u64 bits,
@@ -805,7 +805,7 @@ struct inode *search_inode_for_lustre(struct super_block *sb,
                                      const struct lu_fid *fid);
 
 /* llite/symlink.c */
-extern struct inode_operations ll_fast_symlink_inode_operations;
+extern const struct inode_operations ll_fast_symlink_inode_operations;
 
 /* llite/llite_close.c */
 struct ll_close_queue {
index 4a8c759fef42c4db97089658723df050113330ef..1db93af62badd52ecf551ce6b5b3f2d050efd678 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index 7df978371c9a34a69d6a4d80c09fb668062e5ac5..bbae95c9feed530c4d64e77bfd0900dfdb22e2b7 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index 190fc44114e1cd4fe0e2a51e9e32c855fcdf1225..f134ad9d23f0ca07225ff54ad44a9c6adc3811bf 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index 2ca22001a534d87759e644151da517368338ad4a..8d8220f3db83f95beca05ff5f9ffe17d799faf36 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
@@ -556,7 +556,6 @@ static struct dentry *ll_lookup_it(struct inode *parent, struct dentry *dentry,
                retval = NULL;
        else
                retval = dentry;
-       goto out;
  out:
        if (req)
                ptlrpc_req_finished(req);
index f79193fa2fb7727d9450f016f746d2d9b6ca742c..95cdb0c58b04dffaa784cd04ef07f6f36fad004e 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
@@ -880,14 +880,6 @@ static void ras_update_stride_detector(struct ll_readahead_state *ras,
        return;
 }
 
-static unsigned long
-stride_page_count(struct ll_readahead_state *ras, unsigned long len)
-{
-       return stride_pg_count(ras->ras_stride_offset, ras->ras_stride_length,
-                              ras->ras_stride_pages, ras->ras_stride_offset,
-                              len);
-}
-
 /* Stride Read-ahead window will be increased inc_len according to
  * stride I/O pattern */
 static void ras_stride_increase_window(struct ll_readahead_state *ras,
@@ -921,7 +913,9 @@ static void ras_stride_increase_window(struct ll_readahead_state *ras,
 
        window_len += step * ras->ras_stride_length + left;
 
-       if (stride_page_count(ras, window_len) <= ra->ra_max_pages_per_file)
+       if (stride_pg_count(ras->ras_stride_offset, ras->ras_stride_length,
+                           ras->ras_stride_pages, ras->ras_stride_offset,
+                           window_len) <= ra->ra_max_pages_per_file)
                ras->ras_window_len = window_len;
 
        RAS_CDEBUG(ras);
index 3da4c01e2159684faf4e8b63c3d706be08622bf2..39fa13b74cbdac3f82f128aee9837063d253183a 100644 (file)
@@ -298,7 +298,10 @@ ssize_t ll_direct_rw_pages(const struct lu_env *env, struct cl_io *io,
                }
 
                if (likely(do_io)) {
-                       cl_2queue_add(queue, clp);
+                       /*
+                        * Add a page to the incoming page list of 2-queue.
+                        */
+                       cl_page_list_add(&queue->c2_qin, clp);
 
                        /*
                         * Set page clip to tell transfer formation engine
index 18f5f2b7e90209e38a9e1a67fc8d54ce758654e3..88ffd8e3abdb676c2976cfbd7cae097faa96a39e 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
@@ -87,11 +87,6 @@ struct ll_sa_entry {
 static unsigned int sai_generation;
 static DEFINE_SPINLOCK(sai_generation_lock);
 
-static inline int ll_sa_entry_unhashed(struct ll_sa_entry *entry)
-{
-       return list_empty(&entry->se_hash);
-}
-
 /*
  * The entry only can be released by the caller, it is necessary to hold lock.
  */
@@ -138,20 +133,6 @@ static inline int agl_should_run(struct ll_statahead_info *sai,
        return (inode != NULL && S_ISREG(inode->i_mode) && sai->sai_agl_valid);
 }
 
-static inline struct ll_sa_entry *
-sa_first_received_entry(struct ll_statahead_info *sai)
-{
-       return list_entry(sai->sai_entries_received.next,
-                             struct ll_sa_entry, se_list);
-}
-
-static inline struct ll_inode_info *
-agl_first_entry(struct ll_statahead_info *sai)
-{
-       return list_entry(sai->sai_entries_agl.next,
-                             struct ll_inode_info, lli_agl_list);
-}
-
 static inline int sa_sent_full(struct ll_statahead_info *sai)
 {
        return atomic_read(&sai->sai_cache_count) >= sai->sai_max;
@@ -331,7 +312,7 @@ static void ll_sa_entry_put(struct ll_statahead_info *sai,
 
                LASSERT(list_empty(&entry->se_link));
                LASSERT(list_empty(&entry->se_list));
-               LASSERT(ll_sa_entry_unhashed(entry));
+               LASSERT(list_empty(&entry->se_hash));
 
                ll_sa_entry_cleanup(sai, entry);
                iput(entry->se_inode);
@@ -346,7 +327,7 @@ do_sa_entry_fini(struct ll_statahead_info *sai, struct ll_sa_entry *entry)
 {
        struct ll_inode_info *lli = ll_i2info(sai->sai_inode);
 
-       LASSERT(!ll_sa_entry_unhashed(entry));
+       LASSERT(!list_empty(&entry->se_hash));
        LASSERT(!list_empty(&entry->se_link));
 
        ll_sa_entry_unhash(sai, entry);
@@ -447,7 +428,7 @@ static void ll_agl_add(struct ll_statahead_info *sai,
 
                igrab(inode);
                spin_lock(&parent->lli_agl_lock);
-               if (agl_list_empty(sai))
+               if (list_empty(&sai->sai_entries_agl))
                        added = 1;
                list_add_tail(&child->lli_agl_list, &sai->sai_entries_agl);
                spin_unlock(&parent->lli_agl_lock);
@@ -537,11 +518,11 @@ static void ll_sai_put(struct ll_statahead_info *sai)
                        do_sa_entry_fini(sai, entry);
 
                LASSERT(list_empty(&sai->sai_entries));
-               LASSERT(sa_received_empty(sai));
+               LASSERT(list_empty(&sai->sai_entries_received));
                LASSERT(list_empty(&sai->sai_entries_stated));
 
                LASSERT(atomic_read(&sai->sai_cache_count) == 0);
-               LASSERT(agl_list_empty(sai));
+               LASSERT(list_empty(&sai->sai_entries_agl));
 
                iput(inode);
                kfree(sai);
@@ -621,11 +602,12 @@ static void ll_post_statahead(struct ll_statahead_info *sai)
        int                  rc    = 0;
 
        spin_lock(&lli->lli_sa_lock);
-       if (unlikely(sa_received_empty(sai))) {
+       if (unlikely(list_empty(&sai->sai_entries_received))) {
                spin_unlock(&lli->lli_sa_lock);
                return;
        }
-       entry = sa_first_received_entry(sai);
+       entry = list_entry(sai->sai_entries_received.next,
+                          struct ll_sa_entry, se_list);
        atomic_inc(&entry->se_refcount);
        list_del_init(&entry->se_list);
        spin_unlock(&lli->lli_sa_lock);
@@ -756,7 +738,7 @@ static int ll_statahead_interpret(struct ptlrpc_request *req,
                         * for readpage and other tries to enqueue lock on child
                         * with parent's lock held, for example: unlink. */
                        entry->se_handle = handle;
-                       wakeup = sa_received_empty(sai);
+                       wakeup = list_empty(&sai->sai_entries_received);
                        list_add_tail(&entry->se_list,
                                          &sai->sai_entries_received);
                }
@@ -973,7 +955,7 @@ static int ll_agl_thread(void *arg)
 
        while (1) {
                l_wait_event(thread->t_ctl_waitq,
-                            !agl_list_empty(sai) ||
+                            !list_empty(&sai->sai_entries_agl) ||
                             !thread_is_running(thread),
                             &lwi);
 
@@ -983,8 +965,9 @@ static int ll_agl_thread(void *arg)
                spin_lock(&plli->lli_agl_lock);
                /* The statahead thread maybe help to process AGL entries,
                 * so check whether list empty again. */
-               if (!agl_list_empty(sai)) {
-                       clli = agl_first_entry(sai);
+               if (!list_empty(&sai->sai_entries_agl)) {
+                       clli = list_entry(sai->sai_entries_agl.next,
+                                         struct ll_inode_info, lli_agl_list);
                        list_del_init(&clli->lli_agl_list);
                        spin_unlock(&plli->lli_agl_lock);
                        ll_agl_trigger(&clli->lli_vfs_inode, sai);
@@ -995,8 +978,9 @@ static int ll_agl_thread(void *arg)
 
        spin_lock(&plli->lli_agl_lock);
        sai->sai_agl_valid = 0;
-       while (!agl_list_empty(sai)) {
-               clli = agl_first_entry(sai);
+       while (!list_empty(&sai->sai_entries_agl)) {
+               clli = list_entry(sai->sai_entries_agl.next,
+                                 struct ll_inode_info, lli_agl_list);
                list_del_init(&clli->lli_agl_list);
                spin_unlock(&plli->lli_agl_lock);
                clli->lli_agl_index = 0;
@@ -1136,13 +1120,13 @@ static int ll_statahead_thread(void *arg)
 keep_it:
                        l_wait_event(thread->t_ctl_waitq,
                                     !sa_sent_full(sai) ||
-                                    !sa_received_empty(sai) ||
-                                    !agl_list_empty(sai) ||
+                                    !list_empty(&sai->sai_entries_received) ||
+                                    !list_empty(&sai->sai_entries_agl) ||
                                     !thread_is_running(thread),
                                     &lwi);
 
 interpret_it:
-                       while (!sa_received_empty(sai))
+                       while (!list_empty(&sai->sai_entries_received))
                                ll_post_statahead(sai);
 
                        if (unlikely(!thread_is_running(thread))) {
@@ -1156,14 +1140,15 @@ interpret_it:
                         * to process the AGL entries. */
                        if (sa_sent_full(sai)) {
                                spin_lock(&plli->lli_agl_lock);
-                               while (!agl_list_empty(sai)) {
-                                       clli = agl_first_entry(sai);
+                               while (!list_empty(&sai->sai_entries_agl)) {
+                                       clli = list_entry(sai->sai_entries_agl.next,
+                                                         struct ll_inode_info, lli_agl_list);
                                        list_del_init(&clli->lli_agl_list);
                                        spin_unlock(&plli->lli_agl_lock);
                                        ll_agl_trigger(&clli->lli_vfs_inode,
                                                       sai);
 
-                                       if (!sa_received_empty(sai))
+                                       if (!list_empty(&sai->sai_entries_received))
                                                goto interpret_it;
 
                                        if (unlikely(
@@ -1194,12 +1179,12 @@ do_it:
                        ll_release_page(page, 0);
                        while (1) {
                                l_wait_event(thread->t_ctl_waitq,
-                                            !sa_received_empty(sai) ||
+                                            !list_empty(&sai->sai_entries_received) ||
                                             sai->sai_sent == sai->sai_replied ||
                                             !thread_is_running(thread),
                                             &lwi);
 
-                               while (!sa_received_empty(sai))
+                               while (!list_empty(&sai->sai_entries_received))
                                        ll_post_statahead(sai);
 
                                if (unlikely(!thread_is_running(thread))) {
@@ -1208,14 +1193,15 @@ do_it:
                                }
 
                                if (sai->sai_sent == sai->sai_replied &&
-                                   sa_received_empty(sai))
+                                   list_empty(&sai->sai_entries_received))
                                        break;
                        }
 
                        spin_lock(&plli->lli_agl_lock);
-                       while (!agl_list_empty(sai) &&
+                       while (!list_empty(&sai->sai_entries_agl) &&
                               thread_is_running(thread)) {
-                               clli = agl_first_entry(sai);
+                               clli = list_entry(sai->sai_entries_agl.next,
+                                                 struct ll_inode_info, lli_agl_list);
                                list_del_init(&clli->lli_agl_list);
                                spin_unlock(&plli->lli_agl_lock);
                                ll_agl_trigger(&clli->lli_vfs_inode, sai);
@@ -1260,12 +1246,12 @@ out:
        }
        ll_dir_chain_fini(&chain);
        spin_lock(&plli->lli_sa_lock);
-       if (!sa_received_empty(sai)) {
+       if (!list_empty(&sai->sai_entries_received)) {
                thread_set_flags(thread, SVC_STOPPING);
                spin_unlock(&plli->lli_sa_lock);
 
                /* To release the resources held by received entries. */
-               while (!sa_received_empty(sai))
+               while (!list_empty(&sai->sai_entries_received))
                        ll_post_statahead(sai);
 
                spin_lock(&plli->lli_sa_lock);
index 69b203651905e93f77149754a5b9d6a021b6bf32..32c4cf48b318398cbd58fa32c48e309877a8661f 100644 (file)
@@ -146,7 +146,7 @@ static void ll_put_link(struct inode *unused, void *cookie)
        ptlrpc_req_finished(cookie);
 }
 
-struct inode_operations ll_fast_symlink_inode_operations = {
+const struct inode_operations ll_fast_symlink_inode_operations = {
        .readlink       = generic_readlink,
        .setattr        = ll_setattr,
        .follow_link    = ll_follow_link,
index d16d6cfce81a6b99dffa4afb20d87deaa8a4d13a..fdca4ec0555de9556ff10200844a58e5a5bfbe4b 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2012, Intel Corporation.
+ * Copyright (c) 2012, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index b5a6661d47d5e5ab0485c2417842c0e8cb315aeb..2e39533a45f8d5ae89cbbbdb9856d529d7134fd7 100644 (file)
@@ -26,6 +26,8 @@
 /*
  * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
+ *
+ * Copyright (c) 2013, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index 37773c181729e4e07bdec5f6e9c1e7de0f03902c..f68e972886caeb510b53f7704dc7ca85a8f1df90 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
@@ -849,7 +849,7 @@ static int vvp_io_read_page(const struct lu_env *env,
         * Add page into the queue even when it is marked uptodate above.
         * this will unlock it automatically as part of cl_page_list_disown().
         */
-       cl_2queue_add(queue, page);
+       cl_page_list_add(&queue->c2_qin, page);
        if (sbi->ll_ra_info.ra_max_pages_per_file &&
            sbi->ll_ra_info.ra_max_pages)
                ll_readahead(env, io, ras,
index f7b1144aadeeabc532b0dab47e2148abb344439e..ff0948043c7aa05f2a1c95df7e86fa35061d4b3d 100644 (file)
@@ -26,6 +26,8 @@
 /*
  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
+ *
+ * Copyright (c) 2014, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index e13afb7e8dca97a29d3775e270ac300b6025db60..c82714ea898e5c3900381013b949e33da8b3a1ed 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2012, Intel Corporation.
+ * Copyright (c) 2012, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index 92f60c350f35be9701d915a5fb66bbeb1fe4232f..99c0d7aee921d884d7ebc81e2d2658b978c88930 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index 4b7eb33f7d0172d8f8c716c309e98b7fdce19b1a..4d91538668acfbd874d9ad88e55c3020e9050ace 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
@@ -193,7 +193,10 @@ int ll_setxattr_common(struct inode *inode, const char *name,
                         ll_i2suppgid(inode), &req);
 #ifdef CONFIG_FS_POSIX_ACL
        if (new_value != NULL)
-               lustre_posix_acl_xattr_free(new_value, size);
+               /*
+                * Release the posix ACL space.
+                */
+               kfree(new_value);
        if (acl != NULL)
                lustre_ext_acl_xattr_free(acl);
 #endif
index e1e599ceb173c4e28d7ef3bb9fe7a0c28a56d1cf..d1402762a0b284f3371ff46a3ef8b4896e8673f2 100644 (file)
@@ -1,6 +1,8 @@
 /*
  * Copyright 2012 Xyratex Technology Limited
  *
+ * Copyright (c) 2013, 2015, Intel Corporation.
+ *
  * Author: Andrew Perepechko <Andrew_Perepechko@xyratex.com>
  *
  */
index 3c585aea5bb83cf0bc9c99afbb8b89eba61d1f1e..66de27f1d289b877a0fb1c84bd962c84a38bd8b3 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index 467cfb3e7fca44162ec7c227c04bbb322cb8395d..eb8e673cbc3f37c901b1fc916b0212ccaee38a26 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index a4de9a3fd847c19960f7c7751afd193b5ae40df5..bbafe0a710d8a4fb2e2b530885d5c81cee32f3ef 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index 1c0fe65243e15879badcc38123eefe1612e20809..66a2492c1cc386362ab0a35ce9920308b7c2bfd2 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2012, Intel Corporation.
+ * Copyright (c) 2012, 2015 Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index 2e8b566458f6d6c08d6386a9ca134fcc2a95c415..3733fdc88c8c8882cac664d020273254ff011b12 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2012, Intel Corporation.
+ * Copyright (c) 2012, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index 34c1346f0dc76e9c1f05d3651676cd2098ddea23..b3c9c85aab9d13cee84dd647ba49e70ac04b74c2 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index b8028735e5683d8f3f51cc5fb632cb1b520a26d7..2d00bad58e351c655387e30da7714feadb7bafaa 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index 5e6228b9ca0111255884b94575ae7b390eecde5d..93fe69eb2560fb368e3c87e89fcaf06ef740f5d5 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index dd1cf3d2d039d4e36539fe98c61877d6a0400cf2..97115bec7ccab89174115e1ef23d4621c68f0db8 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2012, Intel Corporation.
+ * Copyright (c) 2012, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index b52609aead4cfbe5b934615a3f1d4261c78a12d1..6c2bdfe9cdcf7a861fda0f305cc777b33fec94c4 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index c7ff817bb6fb098dfd34771d17d395505a0cd3de..3b79ebc8eccf6534fce2d3c9ac6367246c515551 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index 9c8c77c05a8a7f2fe9b513abf742148374d4490c..aa520aa76e091c57ff600494fb3e6233d81c3eb9 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index 2fb1e974cc70b188e788faf579c1466b38c793f5..6b2d1007192b8dee89fd2f6837926edfe4c1baf2 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
@@ -258,22 +258,9 @@ static int lov_verify_lmm(void *lmm, int lmm_bytes, __u16 *stripe_count)
        int rc;
 
        if (lsm_op_find(le32_to_cpu(*(__u32 *)lmm)) == NULL) {
-               char *buffer;
-               int sz;
-
                CERROR("bad disk LOV MAGIC: 0x%08X; dumping LMM (size=%d):\n",
                       le32_to_cpu(*(__u32 *)lmm), lmm_bytes);
-               sz = lmm_bytes * 2 + 1;
-               buffer = libcfs_kvzalloc(sz, GFP_NOFS);
-               if (buffer != NULL) {
-                       int i;
-
-                       for (i = 0; i < lmm_bytes; i++)
-                               sprintf(buffer+2*i, "%.2X", ((char *)lmm)[i]);
-                       buffer[sz - 1] = '\0';
-                       CERROR("%s\n", buffer);
-                       kvfree(buffer);
-               }
+               CERROR("%*phN\n", lmm_bytes, lmm);
                return -EINVAL;
        }
        rc = lsm_op_find(le32_to_cpu(*(__u32 *)lmm))->lsm_lmm_verify(lmm,
index 463cadbd9d40d8f1870ccf6129c1695f2d655b1e..037ae91b74e7d8922d651b4806696854df67a1f7 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index bb1a03fef60d95c2096392cc6357855004a8a6cf..42deda71f577c9f0f07b75d72a32f9f830611e3d 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index 8bc04c8d3d600bb797d68cc81bec024a02afdc39..f1795c3e2db524217f917ce69f433ed14c1bff74 100644 (file)
@@ -26,6 +26,8 @@
 /*
  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
+ *
+ * Copyright (c) 2013, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index d775e28d40973d02a52bfdc51869567c12a95086..5ba5ee1b86818b3e119d464a05cd135cbec38b6c 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2012, Intel Corporation.
+ * Copyright (c) 2012, 2015 Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index a0be15c6b55acf66f8e8a8c6d7adf275602a1761..337241d84980a4629d1e77107694f0bcc51c0a0b 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2012, Intel Corporation.
+ * Copyright (c) 2012, 2015 Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index 1c95f87a0e2ae62aaeb03683ef41b03fa13a15b6..38f267a60f59a23eeeba1c205d8d0ffe039e9610 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
@@ -82,82 +82,6 @@ static ssize_t max_rpcs_in_flight_store(struct kobject *kobj,
 }
 LUSTRE_RW_ATTR(max_rpcs_in_flight);
 
-static int mdc_kuc_open(struct inode *inode, struct file *file)
-{
-       return single_open(file, NULL, inode->i_private);
-}
-
-/* temporary for testing */
-static ssize_t mdc_kuc_write(struct file *file,
-                               const char __user *buffer,
-                               size_t count, loff_t *off)
-{
-       struct obd_device *obd =
-                       ((struct seq_file *)file->private_data)->private;
-       struct kuc_hdr          *lh;
-       struct hsm_action_list  *hal;
-       struct hsm_action_item  *hai;
-       int                      len;
-       int                      fd, rc;
-
-       rc = lprocfs_write_helper(buffer, count, &fd);
-       if (rc)
-               return rc;
-
-       if (fd < 0)
-               return -ERANGE;
-       CWARN("message to fd %d\n", fd);
-
-       len = sizeof(*lh) + sizeof(*hal) + MTI_NAME_MAXLEN +
-               /* for mockup below */ 2 * cfs_size_round(sizeof(*hai));
-
-       lh = kzalloc(len, GFP_NOFS);
-       if (!lh)
-               return -ENOMEM;
-
-       lh->kuc_magic = KUC_MAGIC;
-       lh->kuc_transport = KUC_TRANSPORT_HSM;
-       lh->kuc_msgtype = HMT_ACTION_LIST;
-       lh->kuc_msglen = len;
-
-       hal = (struct hsm_action_list *)(lh + 1);
-       hal->hal_version = HAL_VERSION;
-       hal->hal_archive_id = 1;
-       hal->hal_flags = 0;
-       obd_uuid2fsname(hal->hal_fsname, obd->obd_name, MTI_NAME_MAXLEN);
-
-       /* mock up an action list */
-       hal->hal_count = 2;
-       hai = hai_zero(hal);
-       hai->hai_action = HSMA_ARCHIVE;
-       hai->hai_fid.f_oid = 5;
-       hai->hai_len = sizeof(*hai);
-       hai = hai_next(hai);
-       hai->hai_action = HSMA_RESTORE;
-       hai->hai_fid.f_oid = 10;
-       hai->hai_len = sizeof(*hai);
-
-       /* This works for either broadcast or unicast to a single fd */
-       if (fd == 0) {
-               rc = libcfs_kkuc_group_put(KUC_GRP_HSM, lh);
-       } else {
-               struct file *fp = fget(fd);
-
-               rc = libcfs_kkuc_msg_put(fp, lh);
-               fput(fp);
-       }
-       kfree(lh);
-       if (rc < 0)
-               return rc;
-       return count;
-}
-
-static struct file_operations mdc_kuc_fops = {
-       .open           = mdc_kuc_open,
-       .write          = mdc_kuc_write,
-       .release        = single_release,
-};
-
 LPROC_SEQ_FOPS_WR_ONLY(mdc, ping);
 
 LPROC_SEQ_FOPS_RO_TYPE(mdc, connect_flags);
@@ -196,7 +120,6 @@ static struct lprocfs_vars lprocfs_mdc_obd_vars[] = {
        { "timeouts",           &mdc_timeouts_fops,             NULL, 0 },
        { "import",             &mdc_import_fops,               NULL, 0 },
        { "state",              &mdc_state_fops,                NULL, 0 },
-       { "hsm_nl",             &mdc_kuc_fops,                  NULL, 0200 },
        { "pinger_recov",       &mdc_pinger_recov_fops,         NULL, 0 },
        { NULL }
 };
index df50bdbcde19f0e4f4988bc3b273321409c50820..3d2997a161b61ce5e989204bcf264f24217ba75c 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, Intel Corporation.
+ * Copyright (c) 2011, 2015 Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index 227fc9ee0dcfb2a382b796564705cedda7f0102a..7218532ffea312cf14928ebdd48b3323108e2d55 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index d4bf34b61f3a6ec80b4557d5e80da1ed2a399b03..ef9a1e124ea486d518b5c098614c806c5a752caa 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index c87c7d8efa074b70a62f30570cee412c73f9f45e..ac7695a107530ec80e7b44b039d56c063c700c5f 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index 294c05084b976bc666d9cac96abf6c22db4fbe98..57e0fc1e8549d9e7ff4d7fe0a52481a05f2b31c2 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
@@ -1181,7 +1181,6 @@ static int mdc_ioc_hsm_progress(struct obd_export *exp,
        ptlrpc_request_set_replen(req);
 
        rc = mdc_queue_wait(req);
-       goto out;
 out:
        ptlrpc_req_finished(req);
        return rc;
@@ -1216,7 +1215,6 @@ static int mdc_ioc_hsm_ct_register(struct obd_import *imp, __u32 archives)
        ptlrpc_request_set_replen(req);
 
        rc = mdc_queue_wait(req);
-       goto out;
 out:
        ptlrpc_req_finished(req);
        return rc;
@@ -1282,7 +1280,6 @@ static int mdc_ioc_hsm_ct_unregister(struct obd_import *imp)
        ptlrpc_request_set_replen(req);
 
        rc = mdc_queue_wait(req);
-       goto out;
 out:
        ptlrpc_req_finished(req);
        return rc;
@@ -1362,8 +1359,6 @@ static int mdc_ioc_hsm_state_set(struct obd_export *exp,
        ptlrpc_request_set_replen(req);
 
        rc = mdc_queue_wait(req);
-       goto out;
-
 out:
        ptlrpc_req_finished(req);
        return rc;
@@ -1427,8 +1422,6 @@ static int mdc_ioc_hsm_request(struct obd_export *exp,
        ptlrpc_request_set_replen(req);
 
        rc = mdc_queue_wait(req);
-       goto out;
-
 out:
        ptlrpc_req_finished(req);
        return rc;
@@ -2037,17 +2030,6 @@ static int mdc_hsm_ct_reregister(__u32 data, void *cb_arg)
        return ((rc != 0) && (rc != -EEXIST)) ? rc : 0;
 }
 
-/**
- * Re-establish all kuc contexts with MDT
- * after MDT shutdown/recovery.
- */
-static int mdc_kuc_reregister(struct obd_import *imp)
-{
-       /* re-register HSM agents */
-       return libcfs_kkuc_group_foreach(KUC_GRP_HSM, mdc_hsm_ct_reregister,
-                                        (void *)imp);
-}
-
 static int mdc_set_info_async(const struct lu_env *env,
                              struct obd_export *exp,
                              u32 keylen, void *key,
@@ -2210,7 +2192,10 @@ static int mdc_import_event(struct obd_device *obd, struct obd_import *imp,
                rc = obd_notify_observer(obd, obd, OBD_NOTIFY_ACTIVE, NULL);
                /* redo the kuc registration after reconnecting */
                if (rc == 0)
-                       rc = mdc_kuc_reregister(imp);
+                       /* re-register HSM agents */
+                       rc = libcfs_kkuc_group_foreach(KUC_GRP_HSM,
+                                                      mdc_hsm_ct_reregister,
+                                                      (void *)imp);
                break;
        case IMP_EVENT_OCD:
                rc = obd_notify_observer(obd, obd, OBD_NOTIFY_OCD, NULL);
index 2c48847276260a5aba748012fc677a813f16f8aa..ab4800c20a95a967f05e3270cfcec0f554705360 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
@@ -1293,7 +1293,7 @@ static int mgc_process_recover_log(struct obd_device *obd,
        struct page **pages;
        int nrpages;
        bool eof = true;
-       bool mne_swab = false;
+       bool mne_swab;
        int i;
        int ealen;
        int rc;
index 2e20cf635b2779ebd7062f18ac348368da788d65..49ba8851c8ac709eaa14e3e5e67c264081f792e5 100644 (file)
@@ -235,15 +235,6 @@ _out:
 }
 EXPORT_SYMBOL(lustre_posix_acl_xattr_filter);
 
-/*
- * Release the posix ACL space.
- */
-void lustre_posix_acl_xattr_free(posix_acl_xattr_header *header, int size)
-{
-       kfree(header);
-}
-EXPORT_SYMBOL(lustre_posix_acl_xattr_free);
-
 /*
  * Release the extended ACL space.
  */
index e67cea7584052a7784e8920c60017da196f51920..63246ba36798d55aa7091b341b1353160e9328c8 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
@@ -236,16 +236,11 @@ int cl_io_rw_init(const struct lu_env *env, struct cl_io *io,
 }
 EXPORT_SYMBOL(cl_io_rw_init);
 
-static inline const struct lu_fid *
-cl_lock_descr_fid(const struct cl_lock_descr *descr)
-{
-       return lu_object_fid(&descr->cld_obj->co_lu);
-}
-
 static int cl_lock_descr_sort(const struct cl_lock_descr *d0,
                              const struct cl_lock_descr *d1)
 {
-       return lu_fid_cmp(cl_lock_descr_fid(d0), cl_lock_descr_fid(d1)) ?:
+       return lu_fid_cmp(lu_object_fid(&d0->cld_obj->co_lu),
+                         lu_object_fid(&d1->cld_obj->co_lu)) ?:
                __diff_normalize(d0->cld_start, d1->cld_start);
 }
 
@@ -254,7 +249,8 @@ static int cl_lock_descr_cmp(const struct cl_lock_descr *d0,
 {
        int ret;
 
-       ret = lu_fid_cmp(cl_lock_descr_fid(d0), cl_lock_descr_fid(d1));
+       ret = lu_fid_cmp(lu_object_fid(&d0->cld_obj->co_lu),
+                        lu_object_fid(&d1->cld_obj->co_lu));
        if (ret)
                return ret;
        if (d0->cld_end < d1->cld_start)
@@ -1215,15 +1211,6 @@ void cl_2queue_init(struct cl_2queue *queue)
 }
 EXPORT_SYMBOL(cl_2queue_init);
 
-/**
- * Add a page to the incoming page list of 2-queue.
- */
-void cl_2queue_add(struct cl_2queue *queue, struct cl_page *page)
-{
-       cl_page_list_add(&queue->c2_qin, page);
-}
-EXPORT_SYMBOL(cl_2queue_add);
-
 /**
  * Disown pages in both lists of a 2-queue.
  */
@@ -1262,7 +1249,10 @@ EXPORT_SYMBOL(cl_2queue_fini);
 void cl_2queue_init_page(struct cl_2queue *queue, struct cl_page *page)
 {
        cl_2queue_init(queue);
-       cl_2queue_add(queue, page);
+       /*
+        * Add a page to the incoming page list of 2-queue.
+        */
+       cl_page_list_add(&queue->c2_qin, page);
 }
 EXPORT_SYMBOL(cl_2queue_init_page);
 
index a1a6024220ffd26c564a68cd2f875907cc8f120b..57c8d5412bbd1d4ebfa37e151181b2ff3a04ada2 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
@@ -704,7 +704,7 @@ static inline struct cl_env *cl_env_container(struct lu_env *env)
        return container_of(env, struct cl_env, ce_lu);
 }
 
-struct lu_env *cl_env_peek(int *refcheck)
+static struct lu_env *cl_env_peek(int *refcheck)
 {
        struct lu_env *env;
        struct cl_env *cle;
@@ -724,7 +724,6 @@ struct lu_env *cl_env_peek(int *refcheck)
        CDEBUG(D_OTHER, "%d@%p\n", cle ? cle->ce_ref : 0, cle);
        return env;
 }
-EXPORT_SYMBOL(cl_env_peek);
 
 /**
  * Returns lu_env: if there already is an environment associated with the
index 2f569edd081143fff4473ee97d1e7bee03cc8721..61f28ebfc0589919849dd3296ff65ed69d701dc9 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index beb59f009cbe85e76f3db8c00a7a81e4f313d33f..0975e443057c001086573030a3f827078d3a22ce 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index 26f54f9503508ca6ef7e2eaf659b44e6eb85a0b7..228c44c37c4a0f6d7fcd49862a3ca1c3621947fd 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index 518288df4d53df69820259f8085bf726d8e78cd5..42fc26f4ae2574157fa471276678411666dd9063 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index 7cb55ef79737b46c9607cc9068834cfbbcaf4e36..f956d7ed67854d4c6989cff4b68e1e741e13de9e 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2012, Intel Corporation.
+ * Copyright (c) 2012, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index c442cae5fd375d95ec0e28c0e2b4e12f670f5759..0f05e9c4a5b26a5895a9ffd6ef51c0286bb513f2 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2012, Intel Corporation.
+ * Copyright (c) 2012, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index b9fe4b01c690a7a2504128781acc7739ad8f7431..7fb48dda355e996cb1ff017a6eb7ec5e4a3e664f 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2012, Intel Corporation.
+ * Copyright (c) 2012, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index 3900b9d4007e792e676adb6040bb5187ec79b36c..9bc51998c05c8608ff9a2f0489ee153fa7c49ed3 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2012, Intel Corporation.
+ * Copyright (c) 2012, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index 9354f75b5cab7b6e438d03be0aa05ad0057fdbdf..3aa7393b20c36a71a16383a6a4e3897d56ee124f 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2012, Intel Corporation.
+ * Copyright (c) 2012, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index dda5ad105f2e32489d13e113926d62c57c4349f9..51fe15f5d6870fe26987120f88f35d8477a83deb 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index 0193608a930adc6c95ad03b505e84f445dc42760..ce248f4072c2697a4121c0ba777443c90139adf3 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
@@ -916,7 +916,7 @@ static void lu_obj_hop_put_locked(struct cfs_hash *hs, struct hlist_node *hnode)
        LBUG(); /* we should never called it */
 }
 
-struct cfs_hash_ops lu_site_hash_ops = {
+static struct cfs_hash_ops lu_site_hash_ops = {
        .hs_hash        = lu_obj_hop_hash,
        .hs_key         = lu_obj_hop_key,
        .hs_keycmp      = lu_obj_hop_keycmp,
index c231e0da0e2aeaf165f76de030db2e76aa3a298f..49cdc647910c7b8ea9dd372645896b97e215a02d 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index 7617c57d16e0c459060ca3598e7ecdbc6342504b..b5aa8168dbffaf74eebaf418faaa9c640877ba84 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index 14ac56bb0d77cc404fcfe15dcf73bb26664fa1ad..7b53f7dd1797c4c6013f0270cb8e407c28d51cfe 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
@@ -1228,8 +1228,10 @@ static int cl_echo_object_brw(struct echo_object *eco, int rw, u64 offset,
                        cl_page_put(env, clp);
                        break;
                }
-
-               cl_2queue_add(queue, clp);
+               /*
+                * Add a page to the incoming page list of 2-queue.
+                */
+               cl_page_list_add(&queue->c2_qin, clp);
 
                /* drop the reference count for cl_page_find, so that the page
                 * will be freed in cl_2queue_fini. */
@@ -1270,6 +1272,7 @@ static int
 echo_copyout_lsm(struct lov_stripe_md *lsm, void *_ulsm, int ulsm_nob)
 {
        struct lov_stripe_md *ulsm = _ulsm;
+       struct lov_oinfo **p;
        int nob, i;
 
        nob = offsetof(struct lov_stripe_md, lsm_oinfo[lsm->lsm_stripe_count]);
@@ -1279,9 +1282,10 @@ echo_copyout_lsm(struct lov_stripe_md *lsm, void *_ulsm, int ulsm_nob)
        if (copy_to_user(ulsm, lsm, sizeof(*ulsm)))
                return -EFAULT;
 
-       for (i = 0; i < lsm->lsm_stripe_count; i++) {
-               if (copy_to_user(ulsm->lsm_oinfo[i], lsm->lsm_oinfo[i],
-                                     sizeof(lsm->lsm_oinfo[0])))
+       for (i = 0, p = lsm->lsm_oinfo; i < lsm->lsm_stripe_count; i++, p++) {
+               struct lov_oinfo __user *up;
+               if (get_user(up, ulsm->lsm_oinfo + i) ||
+                   copy_to_user(up, *p, sizeof(struct lov_oinfo)))
                        return -EFAULT;
        }
        return 0;
@@ -1289,9 +1293,10 @@ echo_copyout_lsm(struct lov_stripe_md *lsm, void *_ulsm, int ulsm_nob)
 
 static int
 echo_copyin_lsm(struct echo_device *ed, struct lov_stripe_md *lsm,
-                void *ulsm, int ulsm_nob)
+               struct lov_stripe_md __user *ulsm, int ulsm_nob)
 {
        struct echo_client_obd *ec = ed->ed_ec;
+       struct lov_oinfo **p;
        int                  i;
 
        if (ulsm_nob < sizeof(*lsm))
@@ -1306,11 +1311,10 @@ echo_copyin_lsm(struct echo_device *ed, struct lov_stripe_md *lsm,
            ((__u64)lsm->lsm_stripe_size * lsm->lsm_stripe_count > ~0UL))
                return -EINVAL;
 
-       for (i = 0; i < lsm->lsm_stripe_count; i++) {
-               if (copy_from_user(lsm->lsm_oinfo[i],
-                                      ((struct lov_stripe_md *)ulsm)-> \
-                                      lsm_oinfo[i],
-                                      sizeof(lsm->lsm_oinfo[0])))
+       for (i = 0, p = lsm->lsm_oinfo; i < lsm->lsm_stripe_count; i++, p++) {
+               struct lov_oinfo __user *up;
+               if (get_user(up, ulsm->lsm_oinfo + i) ||
+                   copy_from_user(*p, up, sizeof(struct lov_oinfo)))
                        return -EFAULT;
        }
        return 0;
index c4d44e70f1d719ba9781fef157575bef92a73a61..1091536fc90d3ac185bb7bb71cf192aa5b7f25cc 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index b1d1a87f05e337b4aec56d8f170845080f90f563..2229419b718453417dea3934e2bc1792ba97713f 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2012, Intel Corporation.
+ * Copyright (c) 2012, 2015, Intel Corporation.
  *
  */
 /*
@@ -619,9 +619,9 @@ static inline int overlapped(struct osc_extent *ex1, struct osc_extent *ex2)
  * Find or create an extent which includes @index, core function to manage
  * extent tree.
  */
-struct osc_extent *osc_extent_find(const struct lu_env *env,
-                                  struct osc_object *obj, pgoff_t index,
-                                  int *grants)
+static struct osc_extent *osc_extent_find(const struct lu_env *env,
+                                         struct osc_object *obj, pgoff_t index,
+                                         int *grants)
 
 {
        struct client_obd *cli = osc_cli(obj);
@@ -1420,8 +1420,8 @@ static void __osc_unreserve_grant(struct client_obd *cli,
        }
 }
 
-void osc_unreserve_grant(struct client_obd *cli,
-                        unsigned int reserved, unsigned int unused)
+static void osc_unreserve_grant(struct client_obd *cli,
+                               unsigned int reserved, unsigned int unused)
 {
        client_obd_list_lock(&cli->cl_loi_list_lock);
        __osc_unreserve_grant(cli, reserved, unused);
index d2d68452d38271b9ab842de92530ae86fa01cf17..415c27e4ab660a881fc583362cad3dd31a261b4b 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2012, Intel Corporation.
+ * Copyright (c) 2012, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index 69b523c0f570263cb0a32eedd699f2b115a44829..7078cc57d8b9aeb1d8716e9589a101d046ca4d13 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2012, Intel Corporation.
+ * Copyright (c) 2012, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index db2ee9c23b42df409942a04c498be78bb9db3de7..a4c61463b1c7270d143c7f43d948d9a544e808d3 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index d413496c0f63276b08caf6e9740567556cb7fb20..abd0beb483fef25ce6773f3822b00b86def75157 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index 194490dcaca9e0f6d4a7c5ad6b25ced9645edbb0..71f2810d18b97c12ccfd8a968633a084240cdb80 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index ba57f8df5c7f7a63a77465376c46d482c14a4b30..fdd6219aacf699f59b01b6e7ff1a875f17daa0f3 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
@@ -158,8 +158,8 @@ static int osc_attr_get(const struct lu_env *env, struct cl_object *obj,
        return 0;
 }
 
-int osc_attr_set(const struct lu_env *env, struct cl_object *obj,
-                const struct cl_attr *attr, unsigned valid)
+static int osc_attr_set(const struct lu_env *env, struct cl_object *obj,
+                       const struct cl_attr *attr, unsigned valid)
 {
        struct lov_oinfo *oinfo = cl2osc(obj)->oo_oinfo;
        struct ost_lvb *lvb = &oinfo->loi_lvb;
index 61eaf7172fdf892b2f13bf4faf5e99ce77204d8b..2439d804fe75c132cc7eb362827d57c720755286 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index 199783103f711367c9d78206eb9deb794242f1c2..e70e7961d7630e510e0bd41eb4ba769308d722b3 100644 (file)
@@ -23,7 +23,7 @@
 /*
  * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  *
  * Code originally extracted from quota directory
  */
index d6c1447f6bd95e12957aa4616242d03921806ed1..7034f0a942c52046549067180ccf09ffce873187 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
@@ -2727,7 +2727,7 @@ static int osc_get_info(const struct lu_env *env, struct obd_export *exp,
                }
 
                *((u64 *)val) = *reply;
-       out:
+out:
                ptlrpc_req_finished(req);
                return rc;
        } else if (KEY_IS(KEY_FIEMAP)) {
index a9f1bf536da9b014b010c7aef2164b3e6e58ae08..efdda09507bf122f01aa2c4a51cbd7b6b15331c0 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index 9c2fd34e2eb9b095b4b0f1c1d1b84d6d33ad528f..990156986986c4a678940f908f4936dfadec4c71 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2012, Intel Corporation.
+ * Copyright (c) 2012, 2015 Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index bfa410f7e773fbe0f2ae2271f6c8b6c095c9a486..f752c789bda010902cbe8c20a1b6b4124453d6e6 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index d7c4f47808bd1682437c515d5bc66e46bd3e0c5a..c0e613c23854c01a7e6ce049fbcf6a999ab30889 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index 5122205cbb99c41599554ce34502f72ec1687d2a..e87702073f1fee140ae456fbe3738cb358a38e1b 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2012, Intel Corporation.
+ * Copyright (c) 2012, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index 2aecab21e3e1aaa1a63c3fb7e053934ded337ee4..cc55b7973721ec83c5150ba5b3220eeb88fe67c0 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index 09ddeef6ba484d543b327de89628bd3344746b45..c5d7ff5cbd732d763364476e101c49fa43fd4eb3 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index 2a2a9fb6549ce5991c744ed0a748f8b4a4676391..ec3af109a1d7c4e55cbee7d166c23938b120e4cd 100644 (file)
@@ -26,6 +26,8 @@
 /*
  * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
+ *
+ * Copyright (c) 2014, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index 5c719f175657c56180f067ff2b134b06ceb44c4f..fb2d5236a971df21b2f0ee52b2a6a8fe343167a3 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index 833ed944125e142a608f45b776b14bcd964bd1c9..8f67e0562b7329b2d458abd9ddc516e9899a0bf6 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index ac87aa12bd7e727bff03b8e3d8fabd1ea4544f69..60fb0ced7137cc02cacc6035f556917a5fc96ba1 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index 7b1d72947330a39c4fdb6448f4e307bc113ccbea..db6626cab6f2f38d7ff42b67284b80c944c55d90 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index cd8a9987f7ac9706901664bc207b4270663bc0d9..6152c1b766c3d712f0d6a8656005dacda1d2e9dc 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index 7a206705865b76dc190ea54cf489713b3fd95041..4b0b81c115ee9cb5a8defc69a1d786461089a1d5 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index f448b4567af0e9af16f61d1523fc893e39fd2608..905a41451ca3491c223e1dbf88a96ccea9e402c3 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index f45898f17793bebfabb28d6d208abf7710c90079..8598300a61d1a1c172c978c75bb2fd1b26cefd7f 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2010, 2012, Intel Corporation.
+ * Copyright (c) 2010, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index 40f720ca3b140249e69136bbd15e2529e6dd7c64..61d9ca93c53ad99d4a7f96cb65d52c4754f6c20c 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
index fd7b6d044ec1086aebd507d02f406fa646f75c00..94e088c2d989ac5ad3eb8177551bf3409d4edb14 100644 (file)
@@ -275,6 +275,5 @@ int ehca_init_av_cache(void)
 
 void ehca_cleanup_av_cache(void)
 {
-       if (av_cache)
-               kmem_cache_destroy(av_cache);
+       kmem_cache_destroy(av_cache);
 }
index ea1b5c1203b4e8292ea6aab4e9760b56c7cbe0b0..1aa7931fe860fe728787199ded51a9f5edae41ab 100644 (file)
@@ -393,6 +393,5 @@ int ehca_init_cq_cache(void)
 
 void ehca_cleanup_cq_cache(void)
 {
-       if (cq_cache)
-               kmem_cache_destroy(cq_cache);
+       kmem_cache_destroy(cq_cache);
 }
index 8246418cd4e085352f31954dc876c303a0b10daa..860b974e9faab6107aaecf748433fb415684024f 100644 (file)
@@ -245,8 +245,7 @@ static void ehca_destroy_slab_caches(void)
        ehca_cleanup_cq_cache();
        ehca_cleanup_pd_cache();
 #ifdef CONFIG_PPC_64K_PAGES
-       if (ctblk_cache)
-               kmem_cache_destroy(ctblk_cache);
+       kmem_cache_destroy(ctblk_cache);
 #endif
 }
 
index f914b30999f8d1519ee28edeb134762cf4796b52..553e883a5718ee0102f4923c5283e7d5ddded6a6 100644 (file)
@@ -2251,10 +2251,8 @@ int ehca_init_mrmw_cache(void)
 
 void ehca_cleanup_mrmw_cache(void)
 {
-       if (mr_cache)
-               kmem_cache_destroy(mr_cache);
-       if (mw_cache)
-               kmem_cache_destroy(mw_cache);
+       kmem_cache_destroy(mr_cache);
+       kmem_cache_destroy(mw_cache);
 }
 
 static inline int ehca_init_top_bmap(struct ehca_top_bmap *ehca_top_bmap,
index 351577a6670a5be1c24cf61416793f763aac3510..2a8aae411941f4bd73a23c5362f4bebd650008b1 100644 (file)
@@ -119,6 +119,5 @@ int ehca_init_pd_cache(void)
 
 void ehca_cleanup_pd_cache(void)
 {
-       if (pd_cache)
-               kmem_cache_destroy(pd_cache);
+       kmem_cache_destroy(pd_cache);
 }
index 2e89356c46faf7d53e5e37768d43ea4e812615ab..896c01f810f6fcc5e88ed38946a65982acd1d12f 100644 (file)
@@ -2252,6 +2252,5 @@ int ehca_init_qp_cache(void)
 
 void ehca_cleanup_qp_cache(void)
 {
-       if (qp_cache)
-               kmem_cache_destroy(qp_cache);
+       kmem_cache_destroy(qp_cache);
 }
index 2e5daa6cdcc261cb64cdbc539ea4fdb63f232f20..68c5a315e557fa27fedcd3ec5f8e1c14e018c224 100644 (file)
@@ -7,7 +7,7 @@
 #
 obj-$(CONFIG_INFINIBAND_HFI1) += hfi1.o
 
-hfi1-y := chip.o cq.o device.o diag.o dma.o driver.o eprom.o file_ops.o firmware.o \
+hfi1-y := chip.o cq.o device.o diag.o dma.o driver.o efivar.o eprom.o file_ops.o firmware.o \
        init.o intr.o keys.o mad.o mmap.o mr.o pcie.o pio.o pio_copy.o \
        qp.o qsfp.o rc.o ruc.o sdma.o srq.o sysfs.o trace.o twsi.o \
        uc.o ud.o user_pages.o user_sdma.o verbs_mcast.o verbs.o
index dc6915947c78d6cae88a3b83ea546d7ff5cd1baa..bbe5ad85cec07d47c460e35b53a0dae1e9672ed4 100644 (file)
@@ -63,6 +63,7 @@
 #include "pio.h"
 #include "sdma.h"
 #include "eprom.h"
+#include "efivar.h"
 
 #define NUM_IB_PORTS 1
 
@@ -663,7 +664,7 @@ static struct flag_table egress_err_info_flags[] = {
  */
 #define SES(name) SEND_ERR_STATUS_SEND_##name##_ERR_SMASK
 static struct flag_table send_err_status_flags[] = {
-/* 0*/ FLAG_ENTRY0("SDmaRpyTagErr", SES(CSR_PARITY)),
+/* 0*/ FLAG_ENTRY0("SendCsrParityErr", SES(CSR_PARITY)),
 /* 1*/ FLAG_ENTRY0("SendCsrReadBadAddrErr", SES(CSR_READ_BAD_ADDR)),
 /* 2*/ FLAG_ENTRY0("SendCsrWriteBadAddrErr", SES(CSR_WRITE_BAD_ADDR))
 };
@@ -1417,125 +1418,2466 @@ static u64 access_sw_link_up_cnt(const struct cntr_entry *entry, void *context,
        return read_write_sw(ppd->dd, &ppd->link_up, mode, data);
 }
 
+static u64 access_sw_unknown_frame_cnt(const struct cntr_entry *entry,
+                                      void *context, int vl, int mode,
+                                      u64 data)
+{
+       struct hfi1_pportdata *ppd = (struct hfi1_pportdata *)context;
+
+       if (vl != CNTR_INVALID_VL)
+               return 0;
+       return read_write_sw(ppd->dd, &ppd->unknown_frame_count, mode, data);
+}
+
 static u64 access_sw_xmit_discards(const struct cntr_entry *entry,
                                    void *context, int vl, int mode, u64 data)
 {
-       struct hfi1_pportdata *ppd = context;
+       struct hfi1_pportdata *ppd = context;
+
+       if (vl != CNTR_INVALID_VL)
+               return 0;
+
+       return read_write_sw(ppd->dd, &ppd->port_xmit_discards, mode, data);
+}
+
+static u64 access_xmit_constraint_errs(const struct cntr_entry *entry,
+                                    void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_pportdata *ppd = context;
+
+       if (vl != CNTR_INVALID_VL)
+               return 0;
+
+       return read_write_sw(ppd->dd, &ppd->port_xmit_constraint_errors,
+                            mode, data);
+}
+
+static u64 access_rcv_constraint_errs(const struct cntr_entry *entry,
+                                    void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_pportdata *ppd = context;
+
+       if (vl != CNTR_INVALID_VL)
+               return 0;
+
+       return read_write_sw(ppd->dd, &ppd->port_rcv_constraint_errors,
+                            mode, data);
+}
+
+u64 get_all_cpu_total(u64 __percpu *cntr)
+{
+       int cpu;
+       u64 counter = 0;
+
+       for_each_possible_cpu(cpu)
+               counter += *per_cpu_ptr(cntr, cpu);
+       return counter;
+}
+
+static u64 read_write_cpu(struct hfi1_devdata *dd, u64 *z_val,
+                         u64 __percpu *cntr,
+                         int vl, int mode, u64 data)
+{
+
+       u64 ret = 0;
+
+       if (vl != CNTR_INVALID_VL)
+               return 0;
+
+       if (mode == CNTR_MODE_R) {
+               ret = get_all_cpu_total(cntr) - *z_val;
+       } else if (mode == CNTR_MODE_W) {
+               /* A write can only zero the counter */
+               if (data == 0)
+                       *z_val = get_all_cpu_total(cntr);
+               else
+                       dd_dev_err(dd, "Per CPU cntrs can only be zeroed");
+       } else {
+               dd_dev_err(dd, "Invalid cntr sw cpu access mode");
+               return 0;
+       }
+
+       return ret;
+}
+
+static u64 access_sw_cpu_intr(const struct cntr_entry *entry,
+                             void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = context;
+
+       return read_write_cpu(dd, &dd->z_int_counter, dd->int_counter, vl,
+                             mode, data);
+}
+
+static u64 access_sw_cpu_rcv_limit(const struct cntr_entry *entry,
+                             void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = context;
+
+       return read_write_cpu(dd, &dd->z_rcv_limit, dd->rcv_limit, vl,
+                             mode, data);
+}
+
+static u64 access_sw_pio_wait(const struct cntr_entry *entry,
+                             void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = context;
+
+       return dd->verbs_dev.n_piowait;
+}
+
+static u64 access_sw_vtx_wait(const struct cntr_entry *entry,
+                             void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = context;
+
+       return dd->verbs_dev.n_txwait;
+}
+
+static u64 access_sw_kmem_wait(const struct cntr_entry *entry,
+                              void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = context;
+
+       return dd->verbs_dev.n_kmem_wait;
+}
+
+static u64 access_sw_send_schedule(const struct cntr_entry *entry,
+                              void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->verbs_dev.n_send_schedule;
+}
+
+/* Software counters for the error status bits within MISC_ERR_STATUS */
+static u64 access_misc_pll_lock_fail_err_cnt(const struct cntr_entry *entry,
+                                            void *context, int vl, int mode,
+                                            u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->misc_err_status_cnt[12];
+}
+
+static u64 access_misc_mbist_fail_err_cnt(const struct cntr_entry *entry,
+                                         void *context, int vl, int mode,
+                                         u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->misc_err_status_cnt[11];
+}
+
+static u64 access_misc_invalid_eep_cmd_err_cnt(const struct cntr_entry *entry,
+                                              void *context, int vl, int mode,
+                                              u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->misc_err_status_cnt[10];
+}
+
+static u64 access_misc_efuse_done_parity_err_cnt(const struct cntr_entry *entry,
+                                                void *context, int vl,
+                                                int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->misc_err_status_cnt[9];
+}
+
+static u64 access_misc_efuse_write_err_cnt(const struct cntr_entry *entry,
+                                          void *context, int vl, int mode,
+                                          u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->misc_err_status_cnt[8];
+}
+
+static u64 access_misc_efuse_read_bad_addr_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->misc_err_status_cnt[7];
+}
+
+static u64 access_misc_efuse_csr_parity_err_cnt(const struct cntr_entry *entry,
+                                               void *context, int vl,
+                                               int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->misc_err_status_cnt[6];
+}
+
+static u64 access_misc_fw_auth_failed_err_cnt(const struct cntr_entry *entry,
+                                             void *context, int vl, int mode,
+                                             u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->misc_err_status_cnt[5];
+}
+
+static u64 access_misc_key_mismatch_err_cnt(const struct cntr_entry *entry,
+                                           void *context, int vl, int mode,
+                                           u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->misc_err_status_cnt[4];
+}
+
+static u64 access_misc_sbus_write_failed_err_cnt(const struct cntr_entry *entry,
+                                                void *context, int vl,
+                                                int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->misc_err_status_cnt[3];
+}
+
+static u64 access_misc_csr_write_bad_addr_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->misc_err_status_cnt[2];
+}
+
+static u64 access_misc_csr_read_bad_addr_err_cnt(const struct cntr_entry *entry,
+                                                void *context, int vl,
+                                                int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->misc_err_status_cnt[1];
+}
+
+static u64 access_misc_csr_parity_err_cnt(const struct cntr_entry *entry,
+                                         void *context, int vl, int mode,
+                                         u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->misc_err_status_cnt[0];
+}
+
+/*
+ * Software counter for the aggregate of
+ * individual CceErrStatus counters
+ */
+static u64 access_sw_cce_err_status_aggregated_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->sw_cce_err_status_aggregate;
+}
+
+/*
+ * Software counters corresponding to each of the
+ * error status bits within CceErrStatus
+ */
+static u64 access_cce_msix_csr_parity_err_cnt(const struct cntr_entry *entry,
+                                             void *context, int vl, int mode,
+                                             u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->cce_err_status_cnt[40];
+}
+
+static u64 access_cce_int_map_unc_err_cnt(const struct cntr_entry *entry,
+                                         void *context, int vl, int mode,
+                                         u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->cce_err_status_cnt[39];
+}
+
+static u64 access_cce_int_map_cor_err_cnt(const struct cntr_entry *entry,
+                                         void *context, int vl, int mode,
+                                         u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->cce_err_status_cnt[38];
+}
+
+static u64 access_cce_msix_table_unc_err_cnt(const struct cntr_entry *entry,
+                                            void *context, int vl, int mode,
+                                            u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->cce_err_status_cnt[37];
+}
+
+static u64 access_cce_msix_table_cor_err_cnt(const struct cntr_entry *entry,
+                                            void *context, int vl, int mode,
+                                            u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->cce_err_status_cnt[36];
+}
+
+static u64 access_cce_rxdma_conv_fifo_parity_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->cce_err_status_cnt[35];
+}
+
+static u64 access_cce_rcpl_async_fifo_parity_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->cce_err_status_cnt[34];
+}
+
+static u64 access_cce_seg_write_bad_addr_err_cnt(const struct cntr_entry *entry,
+                                                void *context, int vl,
+                                                int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->cce_err_status_cnt[33];
+}
+
+static u64 access_cce_seg_read_bad_addr_err_cnt(const struct cntr_entry *entry,
+                                               void *context, int vl, int mode,
+                                               u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->cce_err_status_cnt[32];
+}
+
+static u64 access_la_triggered_cnt(const struct cntr_entry *entry,
+                                  void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->cce_err_status_cnt[31];
+}
+
+static u64 access_cce_trgt_cpl_timeout_err_cnt(const struct cntr_entry *entry,
+                                              void *context, int vl, int mode,
+                                              u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->cce_err_status_cnt[30];
+}
+
+static u64 access_pcic_receive_parity_err_cnt(const struct cntr_entry *entry,
+                                             void *context, int vl, int mode,
+                                             u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->cce_err_status_cnt[29];
+}
+
+static u64 access_pcic_transmit_back_parity_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->cce_err_status_cnt[28];
+}
+
+static u64 access_pcic_transmit_front_parity_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->cce_err_status_cnt[27];
+}
+
+static u64 access_pcic_cpl_dat_q_unc_err_cnt(const struct cntr_entry *entry,
+                                            void *context, int vl, int mode,
+                                            u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->cce_err_status_cnt[26];
+}
+
+static u64 access_pcic_cpl_hd_q_unc_err_cnt(const struct cntr_entry *entry,
+                                           void *context, int vl, int mode,
+                                           u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->cce_err_status_cnt[25];
+}
+
+static u64 access_pcic_post_dat_q_unc_err_cnt(const struct cntr_entry *entry,
+                                             void *context, int vl, int mode,
+                                             u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->cce_err_status_cnt[24];
+}
+
+static u64 access_pcic_post_hd_q_unc_err_cnt(const struct cntr_entry *entry,
+                                            void *context, int vl, int mode,
+                                            u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->cce_err_status_cnt[23];
+}
+
+static u64 access_pcic_retry_sot_mem_unc_err_cnt(const struct cntr_entry *entry,
+                                                void *context, int vl,
+                                                int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->cce_err_status_cnt[22];
+}
+
+static u64 access_pcic_retry_mem_unc_err(const struct cntr_entry *entry,
+                                        void *context, int vl, int mode,
+                                        u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->cce_err_status_cnt[21];
+}
+
+static u64 access_pcic_n_post_dat_q_parity_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->cce_err_status_cnt[20];
+}
+
+static u64 access_pcic_n_post_h_q_parity_err_cnt(const struct cntr_entry *entry,
+                                                void *context, int vl,
+                                                int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->cce_err_status_cnt[19];
+}
+
+static u64 access_pcic_cpl_dat_q_cor_err_cnt(const struct cntr_entry *entry,
+                                            void *context, int vl, int mode,
+                                            u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->cce_err_status_cnt[18];
+}
+
+static u64 access_pcic_cpl_hd_q_cor_err_cnt(const struct cntr_entry *entry,
+                                           void *context, int vl, int mode,
+                                           u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->cce_err_status_cnt[17];
+}
+
+static u64 access_pcic_post_dat_q_cor_err_cnt(const struct cntr_entry *entry,
+                                             void *context, int vl, int mode,
+                                             u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->cce_err_status_cnt[16];
+}
+
+static u64 access_pcic_post_hd_q_cor_err_cnt(const struct cntr_entry *entry,
+                                            void *context, int vl, int mode,
+                                            u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->cce_err_status_cnt[15];
+}
+
+static u64 access_pcic_retry_sot_mem_cor_err_cnt(const struct cntr_entry *entry,
+                                                void *context, int vl,
+                                                int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->cce_err_status_cnt[14];
+}
+
+static u64 access_pcic_retry_mem_cor_err_cnt(const struct cntr_entry *entry,
+                                            void *context, int vl, int mode,
+                                            u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->cce_err_status_cnt[13];
+}
+
+static u64 access_cce_cli1_async_fifo_dbg_parity_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->cce_err_status_cnt[12];
+}
+
+static u64 access_cce_cli1_async_fifo_rxdma_parity_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->cce_err_status_cnt[11];
+}
+
+static u64 access_cce_cli1_async_fifo_sdma_hd_parity_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->cce_err_status_cnt[10];
+}
+
+static u64 access_cce_cl1_async_fifo_pio_crdt_parity_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->cce_err_status_cnt[9];
+}
+
+static u64 access_cce_cli2_async_fifo_parity_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->cce_err_status_cnt[8];
+}
+
+static u64 access_cce_csr_cfg_bus_parity_err_cnt(const struct cntr_entry *entry,
+                                                void *context, int vl,
+                                                int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->cce_err_status_cnt[7];
+}
+
+static u64 access_cce_cli0_async_fifo_parity_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->cce_err_status_cnt[6];
+}
+
+static u64 access_cce_rspd_data_parity_err_cnt(const struct cntr_entry *entry,
+                                              void *context, int vl, int mode,
+                                              u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->cce_err_status_cnt[5];
+}
+
+static u64 access_cce_trgt_access_err_cnt(const struct cntr_entry *entry,
+                                         void *context, int vl, int mode,
+                                         u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->cce_err_status_cnt[4];
+}
+
+static u64 access_cce_trgt_async_fifo_parity_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->cce_err_status_cnt[3];
+}
+
+static u64 access_cce_csr_write_bad_addr_err_cnt(const struct cntr_entry *entry,
+                                                void *context, int vl,
+                                                int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->cce_err_status_cnt[2];
+}
+
+static u64 access_cce_csr_read_bad_addr_err_cnt(const struct cntr_entry *entry,
+                                               void *context, int vl,
+                                               int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->cce_err_status_cnt[1];
+}
+
+static u64 access_ccs_csr_parity_err_cnt(const struct cntr_entry *entry,
+                                        void *context, int vl, int mode,
+                                        u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->cce_err_status_cnt[0];
+}
+
+/*
+ * Software counters corresponding to each of the
+ * error status bits within RcvErrStatus
+ */
+static u64 access_rx_csr_parity_err_cnt(const struct cntr_entry *entry,
+                                       void *context, int vl, int mode,
+                                       u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->rcv_err_status_cnt[63];
+}
+
+static u64 access_rx_csr_write_bad_addr_err_cnt(const struct cntr_entry *entry,
+                                               void *context, int vl,
+                                               int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->rcv_err_status_cnt[62];
+}
+
+static u64 access_rx_csr_read_bad_addr_err_cnt(const struct cntr_entry *entry,
+                                              void *context, int vl, int mode,
+                                              u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->rcv_err_status_cnt[61];
+}
+
+static u64 access_rx_dma_csr_unc_err_cnt(const struct cntr_entry *entry,
+                                        void *context, int vl, int mode,
+                                        u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->rcv_err_status_cnt[60];
+}
+
+static u64 access_rx_dma_dq_fsm_encoding_err_cnt(const struct cntr_entry *entry,
+                                                void *context, int vl,
+                                                int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->rcv_err_status_cnt[59];
+}
+
+static u64 access_rx_dma_eq_fsm_encoding_err_cnt(const struct cntr_entry *entry,
+                                                void *context, int vl,
+                                                int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->rcv_err_status_cnt[58];
+}
+
+static u64 access_rx_dma_csr_parity_err_cnt(const struct cntr_entry *entry,
+                                           void *context, int vl, int mode,
+                                           u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->rcv_err_status_cnt[57];
+}
+
+static u64 access_rx_rbuf_data_cor_err_cnt(const struct cntr_entry *entry,
+                                          void *context, int vl, int mode,
+                                          u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->rcv_err_status_cnt[56];
+}
+
+static u64 access_rx_rbuf_data_unc_err_cnt(const struct cntr_entry *entry,
+                                          void *context, int vl, int mode,
+                                          u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->rcv_err_status_cnt[55];
+}
+
+static u64 access_rx_dma_data_fifo_rd_cor_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->rcv_err_status_cnt[54];
+}
+
+static u64 access_rx_dma_data_fifo_rd_unc_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->rcv_err_status_cnt[53];
+}
+
+static u64 access_rx_dma_hdr_fifo_rd_cor_err_cnt(const struct cntr_entry *entry,
+                                                void *context, int vl,
+                                                int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->rcv_err_status_cnt[52];
+}
+
+static u64 access_rx_dma_hdr_fifo_rd_unc_err_cnt(const struct cntr_entry *entry,
+                                                void *context, int vl,
+                                                int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->rcv_err_status_cnt[51];
+}
+
+static u64 access_rx_rbuf_desc_part2_cor_err_cnt(const struct cntr_entry *entry,
+                                                void *context, int vl,
+                                                int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->rcv_err_status_cnt[50];
+}
+
+static u64 access_rx_rbuf_desc_part2_unc_err_cnt(const struct cntr_entry *entry,
+                                                void *context, int vl,
+                                                int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->rcv_err_status_cnt[49];
+}
+
+static u64 access_rx_rbuf_desc_part1_cor_err_cnt(const struct cntr_entry *entry,
+                                                void *context, int vl,
+                                                int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->rcv_err_status_cnt[48];
+}
+
+static u64 access_rx_rbuf_desc_part1_unc_err_cnt(const struct cntr_entry *entry,
+                                                void *context, int vl,
+                                                int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->rcv_err_status_cnt[47];
+}
+
+static u64 access_rx_hq_intr_fsm_err_cnt(const struct cntr_entry *entry,
+                                        void *context, int vl, int mode,
+                                        u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->rcv_err_status_cnt[46];
+}
+
+static u64 access_rx_hq_intr_csr_parity_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->rcv_err_status_cnt[45];
+}
+
+static u64 access_rx_lookup_csr_parity_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->rcv_err_status_cnt[44];
+}
+
+static u64 access_rx_lookup_rcv_array_cor_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->rcv_err_status_cnt[43];
+}
+
+static u64 access_rx_lookup_rcv_array_unc_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->rcv_err_status_cnt[42];
+}
+
+static u64 access_rx_lookup_des_part2_parity_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->rcv_err_status_cnt[41];
+}
+
+static u64 access_rx_lookup_des_part1_unc_cor_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->rcv_err_status_cnt[40];
+}
+
+static u64 access_rx_lookup_des_part1_unc_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->rcv_err_status_cnt[39];
+}
+
+static u64 access_rx_rbuf_next_free_buf_cor_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->rcv_err_status_cnt[38];
+}
+
+static u64 access_rx_rbuf_next_free_buf_unc_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->rcv_err_status_cnt[37];
+}
+
+static u64 access_rbuf_fl_init_wr_addr_parity_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->rcv_err_status_cnt[36];
+}
+
+static u64 access_rx_rbuf_fl_initdone_parity_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->rcv_err_status_cnt[35];
+}
+
+static u64 access_rx_rbuf_fl_write_addr_parity_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->rcv_err_status_cnt[34];
+}
+
+static u64 access_rx_rbuf_fl_rd_addr_parity_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->rcv_err_status_cnt[33];
+}
+
+static u64 access_rx_rbuf_empty_err_cnt(const struct cntr_entry *entry,
+                                       void *context, int vl, int mode,
+                                       u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->rcv_err_status_cnt[32];
+}
+
+static u64 access_rx_rbuf_full_err_cnt(const struct cntr_entry *entry,
+                                      void *context, int vl, int mode,
+                                      u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->rcv_err_status_cnt[31];
+}
+
+static u64 access_rbuf_bad_lookup_err_cnt(const struct cntr_entry *entry,
+                                         void *context, int vl, int mode,
+                                         u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->rcv_err_status_cnt[30];
+}
+
+static u64 access_rbuf_ctx_id_parity_err_cnt(const struct cntr_entry *entry,
+                                            void *context, int vl, int mode,
+                                            u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->rcv_err_status_cnt[29];
+}
+
+static u64 access_rbuf_csr_qeopdw_parity_err_cnt(const struct cntr_entry *entry,
+                                                void *context, int vl,
+                                                int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->rcv_err_status_cnt[28];
+}
+
+static u64 access_rx_rbuf_csr_q_num_of_pkt_parity_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->rcv_err_status_cnt[27];
+}
+
+static u64 access_rx_rbuf_csr_q_t1_ptr_parity_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->rcv_err_status_cnt[26];
+}
+
+static u64 access_rx_rbuf_csr_q_hd_ptr_parity_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->rcv_err_status_cnt[25];
+}
+
+static u64 access_rx_rbuf_csr_q_vld_bit_parity_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->rcv_err_status_cnt[24];
+}
+
+static u64 access_rx_rbuf_csr_q_next_buf_parity_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->rcv_err_status_cnt[23];
+}
+
+static u64 access_rx_rbuf_csr_q_ent_cnt_parity_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->rcv_err_status_cnt[22];
+}
+
+static u64 access_rx_rbuf_csr_q_head_buf_num_parity_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->rcv_err_status_cnt[21];
+}
+
+static u64 access_rx_rbuf_block_list_read_cor_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->rcv_err_status_cnt[20];
+}
+
+static u64 access_rx_rbuf_block_list_read_unc_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->rcv_err_status_cnt[19];
+}
+
+static u64 access_rx_rbuf_lookup_des_cor_err_cnt(const struct cntr_entry *entry,
+                                                void *context, int vl,
+                                                int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->rcv_err_status_cnt[18];
+}
+
+static u64 access_rx_rbuf_lookup_des_unc_err_cnt(const struct cntr_entry *entry,
+                                                void *context, int vl,
+                                                int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->rcv_err_status_cnt[17];
+}
+
+static u64 access_rx_rbuf_lookup_des_reg_unc_cor_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->rcv_err_status_cnt[16];
+}
+
+static u64 access_rx_rbuf_lookup_des_reg_unc_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->rcv_err_status_cnt[15];
+}
+
+static u64 access_rx_rbuf_free_list_cor_err_cnt(const struct cntr_entry *entry,
+                                               void *context, int vl,
+                                               int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->rcv_err_status_cnt[14];
+}
+
+static u64 access_rx_rbuf_free_list_unc_err_cnt(const struct cntr_entry *entry,
+                                               void *context, int vl,
+                                               int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->rcv_err_status_cnt[13];
+}
+
+static u64 access_rx_rcv_fsm_encoding_err_cnt(const struct cntr_entry *entry,
+                                             void *context, int vl, int mode,
+                                             u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->rcv_err_status_cnt[12];
+}
+
+static u64 access_rx_dma_flag_cor_err_cnt(const struct cntr_entry *entry,
+                                         void *context, int vl, int mode,
+                                         u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->rcv_err_status_cnt[11];
+}
+
+static u64 access_rx_dma_flag_unc_err_cnt(const struct cntr_entry *entry,
+                                         void *context, int vl, int mode,
+                                         u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->rcv_err_status_cnt[10];
+}
+
+static u64 access_rx_dc_sop_eop_parity_err_cnt(const struct cntr_entry *entry,
+                                              void *context, int vl, int mode,
+                                              u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->rcv_err_status_cnt[9];
+}
+
+static u64 access_rx_rcv_csr_parity_err_cnt(const struct cntr_entry *entry,
+                                           void *context, int vl, int mode,
+                                           u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->rcv_err_status_cnt[8];
+}
+
+static u64 access_rx_rcv_qp_map_table_cor_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->rcv_err_status_cnt[7];
+}
+
+static u64 access_rx_rcv_qp_map_table_unc_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->rcv_err_status_cnt[6];
+}
+
+static u64 access_rx_rcv_data_cor_err_cnt(const struct cntr_entry *entry,
+                                         void *context, int vl, int mode,
+                                         u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->rcv_err_status_cnt[5];
+}
+
+static u64 access_rx_rcv_data_unc_err_cnt(const struct cntr_entry *entry,
+                                         void *context, int vl, int mode,
+                                         u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->rcv_err_status_cnt[4];
+}
+
+static u64 access_rx_rcv_hdr_cor_err_cnt(const struct cntr_entry *entry,
+                                        void *context, int vl, int mode,
+                                        u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->rcv_err_status_cnt[3];
+}
+
+static u64 access_rx_rcv_hdr_unc_err_cnt(const struct cntr_entry *entry,
+                                        void *context, int vl, int mode,
+                                        u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->rcv_err_status_cnt[2];
+}
+
+static u64 access_rx_dc_intf_parity_err_cnt(const struct cntr_entry *entry,
+                                           void *context, int vl, int mode,
+                                           u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->rcv_err_status_cnt[1];
+}
+
+static u64 access_rx_dma_csr_cor_err_cnt(const struct cntr_entry *entry,
+                                        void *context, int vl, int mode,
+                                        u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->rcv_err_status_cnt[0];
+}
+
+/*
+ * Software counters corresponding to each of the
+ * error status bits within SendPioErrStatus
+ */
+static u64 access_pio_pec_sop_head_parity_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_pio_err_status_cnt[35];
+}
+
+static u64 access_pio_pcc_sop_head_parity_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_pio_err_status_cnt[34];
+}
+
+static u64 access_pio_last_returned_cnt_parity_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_pio_err_status_cnt[33];
+}
+
+static u64 access_pio_current_free_cnt_parity_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_pio_err_status_cnt[32];
+}
+
+static u64 access_pio_reserved_31_err_cnt(const struct cntr_entry *entry,
+                                         void *context, int vl, int mode,
+                                         u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_pio_err_status_cnt[31];
+}
+
+static u64 access_pio_reserved_30_err_cnt(const struct cntr_entry *entry,
+                                         void *context, int vl, int mode,
+                                         u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_pio_err_status_cnt[30];
+}
+
+static u64 access_pio_ppmc_sop_len_err_cnt(const struct cntr_entry *entry,
+                                          void *context, int vl, int mode,
+                                          u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_pio_err_status_cnt[29];
+}
+
+static u64 access_pio_ppmc_bqc_mem_parity_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_pio_err_status_cnt[28];
+}
+
+static u64 access_pio_vl_fifo_parity_err_cnt(const struct cntr_entry *entry,
+                                            void *context, int vl, int mode,
+                                            u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_pio_err_status_cnt[27];
+}
+
+static u64 access_pio_vlf_sop_parity_err_cnt(const struct cntr_entry *entry,
+                                            void *context, int vl, int mode,
+                                            u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_pio_err_status_cnt[26];
+}
+
+static u64 access_pio_vlf_v1_len_parity_err_cnt(const struct cntr_entry *entry,
+                                               void *context, int vl,
+                                               int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_pio_err_status_cnt[25];
+}
+
+static u64 access_pio_block_qw_count_parity_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_pio_err_status_cnt[24];
+}
+
+static u64 access_pio_write_qw_valid_parity_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_pio_err_status_cnt[23];
+}
+
+static u64 access_pio_state_machine_err_cnt(const struct cntr_entry *entry,
+                                           void *context, int vl, int mode,
+                                           u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_pio_err_status_cnt[22];
+}
+
+static u64 access_pio_write_data_parity_err_cnt(const struct cntr_entry *entry,
+                                               void *context, int vl,
+                                               int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_pio_err_status_cnt[21];
+}
+
+static u64 access_pio_host_addr_mem_cor_err_cnt(const struct cntr_entry *entry,
+                                               void *context, int vl,
+                                               int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_pio_err_status_cnt[20];
+}
+
+static u64 access_pio_host_addr_mem_unc_err_cnt(const struct cntr_entry *entry,
+                                               void *context, int vl,
+                                               int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_pio_err_status_cnt[19];
+}
+
+static u64 access_pio_pkt_evict_sm_or_arb_sm_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_pio_err_status_cnt[18];
+}
+
+static u64 access_pio_init_sm_in_err_cnt(const struct cntr_entry *entry,
+                                        void *context, int vl, int mode,
+                                        u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_pio_err_status_cnt[17];
+}
+
+static u64 access_pio_ppmc_pbl_fifo_err_cnt(const struct cntr_entry *entry,
+                                           void *context, int vl, int mode,
+                                           u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_pio_err_status_cnt[16];
+}
+
+static u64 access_pio_credit_ret_fifo_parity_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_pio_err_status_cnt[15];
+}
+
+static u64 access_pio_v1_len_mem_bank1_cor_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_pio_err_status_cnt[14];
+}
+
+static u64 access_pio_v1_len_mem_bank0_cor_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_pio_err_status_cnt[13];
+}
+
+static u64 access_pio_v1_len_mem_bank1_unc_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_pio_err_status_cnt[12];
+}
+
+static u64 access_pio_v1_len_mem_bank0_unc_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_pio_err_status_cnt[11];
+}
+
+static u64 access_pio_sm_pkt_reset_parity_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_pio_err_status_cnt[10];
+}
+
+static u64 access_pio_pkt_evict_fifo_parity_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_pio_err_status_cnt[9];
+}
+
+static u64 access_pio_sbrdctrl_crrel_fifo_parity_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_pio_err_status_cnt[8];
+}
+
+static u64 access_pio_sbrdctl_crrel_parity_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_pio_err_status_cnt[7];
+}
+
+static u64 access_pio_pec_fifo_parity_err_cnt(const struct cntr_entry *entry,
+                                             void *context, int vl, int mode,
+                                             u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_pio_err_status_cnt[6];
+}
+
+static u64 access_pio_pcc_fifo_parity_err_cnt(const struct cntr_entry *entry,
+                                             void *context, int vl, int mode,
+                                             u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_pio_err_status_cnt[5];
+}
+
+static u64 access_pio_sb_mem_fifo1_err_cnt(const struct cntr_entry *entry,
+                                          void *context, int vl, int mode,
+                                          u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_pio_err_status_cnt[4];
+}
+
+static u64 access_pio_sb_mem_fifo0_err_cnt(const struct cntr_entry *entry,
+                                          void *context, int vl, int mode,
+                                          u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_pio_err_status_cnt[3];
+}
+
+static u64 access_pio_csr_parity_err_cnt(const struct cntr_entry *entry,
+                                        void *context, int vl, int mode,
+                                        u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_pio_err_status_cnt[2];
+}
+
+static u64 access_pio_write_addr_parity_err_cnt(const struct cntr_entry *entry,
+                                               void *context, int vl,
+                                               int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_pio_err_status_cnt[1];
+}
+
+static u64 access_pio_write_bad_ctxt_err_cnt(const struct cntr_entry *entry,
+                                            void *context, int vl, int mode,
+                                            u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_pio_err_status_cnt[0];
+}
+
+/*
+ * Software counters corresponding to each of the
+ * error status bits within SendDmaErrStatus
+ */
+static u64 access_sdma_pcie_req_tracking_cor_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_dma_err_status_cnt[3];
+}
+
+static u64 access_sdma_pcie_req_tracking_unc_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_dma_err_status_cnt[2];
+}
+
+static u64 access_sdma_csr_parity_err_cnt(const struct cntr_entry *entry,
+                                         void *context, int vl, int mode,
+                                         u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_dma_err_status_cnt[1];
+}
+
+static u64 access_sdma_rpy_tag_err_cnt(const struct cntr_entry *entry,
+                                      void *context, int vl, int mode,
+                                      u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_dma_err_status_cnt[0];
+}
+
+/*
+ * Software counters corresponding to each of the
+ * error status bits within SendEgressErrStatus
+ */
+static u64 access_tx_read_pio_memory_csr_unc_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_egress_err_status_cnt[63];
+}
+
+static u64 access_tx_read_sdma_memory_csr_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_egress_err_status_cnt[62];
+}
+
+static u64 access_tx_egress_fifo_cor_err_cnt(const struct cntr_entry *entry,
+                                            void *context, int vl, int mode,
+                                            u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_egress_err_status_cnt[61];
+}
+
+static u64 access_tx_read_pio_memory_cor_err_cnt(const struct cntr_entry *entry,
+                                                void *context, int vl,
+                                                int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_egress_err_status_cnt[60];
+}
+
+static u64 access_tx_read_sdma_memory_cor_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_egress_err_status_cnt[59];
+}
+
+static u64 access_tx_sb_hdr_cor_err_cnt(const struct cntr_entry *entry,
+                                       void *context, int vl, int mode,
+                                       u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_egress_err_status_cnt[58];
+}
+
+static u64 access_tx_credit_overrun_err_cnt(const struct cntr_entry *entry,
+                                           void *context, int vl, int mode,
+                                           u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_egress_err_status_cnt[57];
+}
+
+static u64 access_tx_launch_fifo8_cor_err_cnt(const struct cntr_entry *entry,
+                                             void *context, int vl, int mode,
+                                             u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_egress_err_status_cnt[56];
+}
+
+static u64 access_tx_launch_fifo7_cor_err_cnt(const struct cntr_entry *entry,
+                                             void *context, int vl, int mode,
+                                             u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_egress_err_status_cnt[55];
+}
+
+static u64 access_tx_launch_fifo6_cor_err_cnt(const struct cntr_entry *entry,
+                                             void *context, int vl, int mode,
+                                             u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_egress_err_status_cnt[54];
+}
+
+static u64 access_tx_launch_fifo5_cor_err_cnt(const struct cntr_entry *entry,
+                                             void *context, int vl, int mode,
+                                             u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_egress_err_status_cnt[53];
+}
+
+static u64 access_tx_launch_fifo4_cor_err_cnt(const struct cntr_entry *entry,
+                                             void *context, int vl, int mode,
+                                             u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_egress_err_status_cnt[52];
+}
+
+static u64 access_tx_launch_fifo3_cor_err_cnt(const struct cntr_entry *entry,
+                                             void *context, int vl, int mode,
+                                             u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_egress_err_status_cnt[51];
+}
+
+static u64 access_tx_launch_fifo2_cor_err_cnt(const struct cntr_entry *entry,
+                                             void *context, int vl, int mode,
+                                             u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_egress_err_status_cnt[50];
+}
+
+static u64 access_tx_launch_fifo1_cor_err_cnt(const struct cntr_entry *entry,
+                                             void *context, int vl, int mode,
+                                             u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_egress_err_status_cnt[49];
+}
+
+static u64 access_tx_launch_fifo0_cor_err_cnt(const struct cntr_entry *entry,
+                                             void *context, int vl, int mode,
+                                             u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_egress_err_status_cnt[48];
+}
+
+static u64 access_tx_credit_return_vl_err_cnt(const struct cntr_entry *entry,
+                                             void *context, int vl, int mode,
+                                             u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_egress_err_status_cnt[47];
+}
+
+static u64 access_tx_hcrc_insertion_err_cnt(const struct cntr_entry *entry,
+                                           void *context, int vl, int mode,
+                                           u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_egress_err_status_cnt[46];
+}
+
+static u64 access_tx_egress_fifo_unc_err_cnt(const struct cntr_entry *entry,
+                                            void *context, int vl, int mode,
+                                            u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_egress_err_status_cnt[45];
+}
+
+static u64 access_tx_read_pio_memory_unc_err_cnt(const struct cntr_entry *entry,
+                                                void *context, int vl,
+                                                int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_egress_err_status_cnt[44];
+}
+
+static u64 access_tx_read_sdma_memory_unc_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_egress_err_status_cnt[43];
+}
+
+static u64 access_tx_sb_hdr_unc_err_cnt(const struct cntr_entry *entry,
+                                       void *context, int vl, int mode,
+                                       u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_egress_err_status_cnt[42];
+}
+
+static u64 access_tx_credit_return_partiy_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_egress_err_status_cnt[41];
+}
+
+static u64 access_tx_launch_fifo8_unc_or_parity_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_egress_err_status_cnt[40];
+}
+
+static u64 access_tx_launch_fifo7_unc_or_parity_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_egress_err_status_cnt[39];
+}
+
+static u64 access_tx_launch_fifo6_unc_or_parity_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_egress_err_status_cnt[38];
+}
+
+static u64 access_tx_launch_fifo5_unc_or_parity_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_egress_err_status_cnt[37];
+}
+
+static u64 access_tx_launch_fifo4_unc_or_parity_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_egress_err_status_cnt[36];
+}
+
+static u64 access_tx_launch_fifo3_unc_or_parity_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_egress_err_status_cnt[35];
+}
+
+static u64 access_tx_launch_fifo2_unc_or_parity_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_egress_err_status_cnt[34];
+}
+
+static u64 access_tx_launch_fifo1_unc_or_parity_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_egress_err_status_cnt[33];
+}
+
+static u64 access_tx_launch_fifo0_unc_or_parity_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_egress_err_status_cnt[32];
+}
+
+static u64 access_tx_sdma15_disallowed_packet_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_egress_err_status_cnt[31];
+}
+
+static u64 access_tx_sdma14_disallowed_packet_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_egress_err_status_cnt[30];
+}
+
+static u64 access_tx_sdma13_disallowed_packet_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_egress_err_status_cnt[29];
+}
+
+static u64 access_tx_sdma12_disallowed_packet_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_egress_err_status_cnt[28];
+}
+
+static u64 access_tx_sdma11_disallowed_packet_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_egress_err_status_cnt[27];
+}
+
+static u64 access_tx_sdma10_disallowed_packet_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_egress_err_status_cnt[26];
+}
+
+static u64 access_tx_sdma9_disallowed_packet_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_egress_err_status_cnt[25];
+}
+
+static u64 access_tx_sdma8_disallowed_packet_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_egress_err_status_cnt[24];
+}
+
+static u64 access_tx_sdma7_disallowed_packet_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_egress_err_status_cnt[23];
+}
+
+static u64 access_tx_sdma6_disallowed_packet_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_egress_err_status_cnt[22];
+}
+
+static u64 access_tx_sdma5_disallowed_packet_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_egress_err_status_cnt[21];
+}
+
+static u64 access_tx_sdma4_disallowed_packet_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_egress_err_status_cnt[20];
+}
+
+static u64 access_tx_sdma3_disallowed_packet_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_egress_err_status_cnt[19];
+}
+
+static u64 access_tx_sdma2_disallowed_packet_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_egress_err_status_cnt[18];
+}
+
+static u64 access_tx_sdma1_disallowed_packet_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_egress_err_status_cnt[17];
+}
+
+static u64 access_tx_sdma0_disallowed_packet_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_egress_err_status_cnt[16];
+}
+
+static u64 access_tx_config_parity_err_cnt(const struct cntr_entry *entry,
+                                          void *context, int vl, int mode,
+                                          u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_egress_err_status_cnt[15];
+}
+
+static u64 access_tx_sbrd_ctl_csr_parity_err_cnt(const struct cntr_entry *entry,
+                                                void *context, int vl,
+                                                int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_egress_err_status_cnt[14];
+}
+
+static u64 access_tx_launch_csr_parity_err_cnt(const struct cntr_entry *entry,
+                                              void *context, int vl, int mode,
+                                              u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_egress_err_status_cnt[13];
+}
+
+static u64 access_tx_illegal_vl_err_cnt(const struct cntr_entry *entry,
+                                       void *context, int vl, int mode,
+                                       u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_egress_err_status_cnt[12];
+}
+
+static u64 access_tx_sbrd_ctl_state_machine_parity_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_egress_err_status_cnt[11];
+}
+
+static u64 access_egress_reserved_10_err_cnt(const struct cntr_entry *entry,
+                                            void *context, int vl, int mode,
+                                            u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_egress_err_status_cnt[10];
+}
+
+static u64 access_egress_reserved_9_err_cnt(const struct cntr_entry *entry,
+                                           void *context, int vl, int mode,
+                                           u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_egress_err_status_cnt[9];
+}
+
+static u64 access_tx_sdma_launch_intf_parity_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_egress_err_status_cnt[8];
+}
+
+static u64 access_tx_pio_launch_intf_parity_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_egress_err_status_cnt[7];
+}
+
+static u64 access_egress_reserved_6_err_cnt(const struct cntr_entry *entry,
+                                           void *context, int vl, int mode,
+                                           u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_egress_err_status_cnt[6];
+}
+
+static u64 access_tx_incorrect_link_state_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_egress_err_status_cnt[5];
+}
+
+static u64 access_tx_linkdown_err_cnt(const struct cntr_entry *entry,
+                                     void *context, int vl, int mode,
+                                     u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_egress_err_status_cnt[4];
+}
+
+static u64 access_tx_egress_fifi_underrun_or_parity_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_egress_err_status_cnt[3];
+}
+
+static u64 access_egress_reserved_2_err_cnt(const struct cntr_entry *entry,
+                                           void *context, int vl, int mode,
+                                           u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_egress_err_status_cnt[2];
+}
+
+static u64 access_tx_pkt_integrity_mem_unc_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
 
-       if (vl != CNTR_INVALID_VL)
-               return 0;
+       return dd->send_egress_err_status_cnt[1];
+}
 
-       return read_write_sw(ppd->dd, &ppd->port_xmit_discards, mode, data);
+static u64 access_tx_pkt_integrity_mem_cor_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_egress_err_status_cnt[0];
 }
 
-static u64 access_xmit_constraint_errs(const struct cntr_entry *entry,
-                                    void *context, int vl, int mode, u64 data)
+/*
+ * Software counters corresponding to each of the
+ * error status bits within SendErrStatus
+ */
+static u64 access_send_csr_write_bad_addr_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
 {
-       struct hfi1_pportdata *ppd = context;
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
 
-       if (vl != CNTR_INVALID_VL)
-               return 0;
+       return dd->send_err_status_cnt[2];
+}
 
-       return read_write_sw(ppd->dd, &ppd->port_xmit_constraint_errors,
-                            mode, data);
+static u64 access_send_csr_read_bad_addr_err_cnt(const struct cntr_entry *entry,
+                                                void *context, int vl,
+                                                int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->send_err_status_cnt[1];
 }
 
-static u64 access_rcv_constraint_errs(const struct cntr_entry *entry,
-                                    void *context, int vl, int mode, u64 data)
+static u64 access_send_csr_parity_cnt(const struct cntr_entry *entry,
+                                     void *context, int vl, int mode,
+                                     u64 data)
 {
-       struct hfi1_pportdata *ppd = context;
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
 
-       if (vl != CNTR_INVALID_VL)
-               return 0;
+       return dd->send_err_status_cnt[0];
+}
 
-       return read_write_sw(ppd->dd, &ppd->port_rcv_constraint_errors,
-                            mode, data);
+/*
+ * Software counters corresponding to each of the
+ * error status bits within SendCtxtErrStatus
+ */
+static u64 access_pio_write_out_of_bounds_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->sw_ctxt_err_status_cnt[4];
 }
 
-u64 get_all_cpu_total(u64 __percpu *cntr)
+static u64 access_pio_write_overflow_err_cnt(const struct cntr_entry *entry,
+                                            void *context, int vl, int mode,
+                                            u64 data)
 {
-       int cpu;
-       u64 counter = 0;
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
 
-       for_each_possible_cpu(cpu)
-               counter += *per_cpu_ptr(cntr, cpu);
-       return counter;
+       return dd->sw_ctxt_err_status_cnt[3];
 }
 
-static u64 read_write_cpu(struct hfi1_devdata *dd, u64 *z_val,
-                         u64 __percpu *cntr,
-                         int vl, int mode, u64 data)
+static u64 access_pio_write_crosses_boundary_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
 {
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
 
-       u64 ret = 0;
+       return dd->sw_ctxt_err_status_cnt[2];
+}
 
-       if (vl != CNTR_INVALID_VL)
-               return 0;
+static u64 access_pio_disallowed_packet_err_cnt(const struct cntr_entry *entry,
+                                               void *context, int vl,
+                                               int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
 
-       if (mode == CNTR_MODE_R) {
-               ret = get_all_cpu_total(cntr) - *z_val;
-       } else if (mode == CNTR_MODE_W) {
-               /* A write can only zero the counter */
-               if (data == 0)
-                       *z_val = get_all_cpu_total(cntr);
-               else
-                       dd_dev_err(dd, "Per CPU cntrs can only be zeroed");
-       } else {
-               dd_dev_err(dd, "Invalid cntr sw cpu access mode");
-               return 0;
-       }
+       return dd->sw_ctxt_err_status_cnt[1];
+}
 
-       return ret;
+static u64 access_pio_inconsistent_sop_err_cnt(const struct cntr_entry *entry,
+                                              void *context, int vl, int mode,
+                                              u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->sw_ctxt_err_status_cnt[0];
 }
 
-static u64 access_sw_cpu_intr(const struct cntr_entry *entry,
-                             void *context, int vl, int mode, u64 data)
+/*
+ * Software counters corresponding to each of the
+ * error status bits within SendDmaEngErrStatus
+ */
+static u64 access_sdma_header_request_fifo_cor_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
 {
-       struct hfi1_devdata *dd = context;
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
 
-       return read_write_cpu(dd, &dd->z_int_counter, dd->int_counter, vl,
-                             mode, data);
+       return dd->sw_send_dma_eng_err_status_cnt[23];
 }
 
-static u64 access_sw_cpu_rcv_limit(const struct cntr_entry *entry,
-                             void *context, int vl, int mode, u64 data)
+static u64 access_sdma_header_storage_cor_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
 {
-       struct hfi1_devdata *dd = context;
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
 
-       return read_write_cpu(dd, &dd->z_rcv_limit, dd->rcv_limit, vl,
-                             mode, data);
+       return dd->sw_send_dma_eng_err_status_cnt[22];
 }
 
-static u64 access_sw_pio_wait(const struct cntr_entry *entry,
-                             void *context, int vl, int mode, u64 data)
+static u64 access_sdma_packet_tracking_cor_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
 {
-       struct hfi1_devdata *dd = context;
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
 
-       return dd->verbs_dev.n_piowait;
+       return dd->sw_send_dma_eng_err_status_cnt[21];
 }
 
-static u64 access_sw_vtx_wait(const struct cntr_entry *entry,
-                             void *context, int vl, int mode, u64 data)
+static u64 access_sdma_assembly_cor_err_cnt(const struct cntr_entry *entry,
+                                           void *context, int vl, int mode,
+                                           u64 data)
 {
-       struct hfi1_devdata *dd = context;
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
 
-       return dd->verbs_dev.n_txwait;
+       return dd->sw_send_dma_eng_err_status_cnt[20];
 }
 
-static u64 access_sw_kmem_wait(const struct cntr_entry *entry,
-                              void *context, int vl, int mode, u64 data)
+static u64 access_sdma_desc_table_cor_err_cnt(const struct cntr_entry *entry,
+                                             void *context, int vl, int mode,
+                                             u64 data)
 {
-       struct hfi1_devdata *dd = context;
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
 
-       return dd->verbs_dev.n_kmem_wait;
+       return dd->sw_send_dma_eng_err_status_cnt[19];
 }
 
-static u64 access_sw_send_schedule(const struct cntr_entry *entry,
-                              void *context, int vl, int mode, u64 data)
+static u64 access_sdma_header_request_fifo_unc_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
 {
        struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
 
-       return dd->verbs_dev.n_send_schedule;
+       return dd->sw_send_dma_eng_err_status_cnt[18];
+}
+
+static u64 access_sdma_header_storage_unc_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->sw_send_dma_eng_err_status_cnt[17];
+}
+
+static u64 access_sdma_packet_tracking_unc_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->sw_send_dma_eng_err_status_cnt[16];
+}
+
+static u64 access_sdma_assembly_unc_err_cnt(const struct cntr_entry *entry,
+                                           void *context, int vl, int mode,
+                                           u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->sw_send_dma_eng_err_status_cnt[15];
+}
+
+static u64 access_sdma_desc_table_unc_err_cnt(const struct cntr_entry *entry,
+                                             void *context, int vl, int mode,
+                                             u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->sw_send_dma_eng_err_status_cnt[14];
+}
+
+static u64 access_sdma_timeout_err_cnt(const struct cntr_entry *entry,
+                                      void *context, int vl, int mode,
+                                      u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->sw_send_dma_eng_err_status_cnt[13];
+}
+
+static u64 access_sdma_header_length_err_cnt(const struct cntr_entry *entry,
+                                            void *context, int vl, int mode,
+                                            u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->sw_send_dma_eng_err_status_cnt[12];
+}
+
+static u64 access_sdma_header_address_err_cnt(const struct cntr_entry *entry,
+                                             void *context, int vl, int mode,
+                                             u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->sw_send_dma_eng_err_status_cnt[11];
+}
+
+static u64 access_sdma_header_select_err_cnt(const struct cntr_entry *entry,
+                                            void *context, int vl, int mode,
+                                            u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->sw_send_dma_eng_err_status_cnt[10];
+}
+
+static u64 access_sdma_reserved_9_err_cnt(const struct cntr_entry *entry,
+                                         void *context, int vl, int mode,
+                                         u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->sw_send_dma_eng_err_status_cnt[9];
+}
+
+static u64 access_sdma_packet_desc_overflow_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->sw_send_dma_eng_err_status_cnt[8];
+}
+
+static u64 access_sdma_length_mismatch_err_cnt(const struct cntr_entry *entry,
+                                              void *context, int vl,
+                                              int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->sw_send_dma_eng_err_status_cnt[7];
+}
+
+static u64 access_sdma_halt_err_cnt(const struct cntr_entry *entry,
+                                   void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->sw_send_dma_eng_err_status_cnt[6];
+}
+
+static u64 access_sdma_mem_read_err_cnt(const struct cntr_entry *entry,
+                                       void *context, int vl, int mode,
+                                       u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->sw_send_dma_eng_err_status_cnt[5];
+}
+
+static u64 access_sdma_first_desc_err_cnt(const struct cntr_entry *entry,
+                                         void *context, int vl, int mode,
+                                         u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->sw_send_dma_eng_err_status_cnt[4];
+}
+
+static u64 access_sdma_tail_out_of_bounds_err_cnt(
+                               const struct cntr_entry *entry,
+                               void *context, int vl, int mode, u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->sw_send_dma_eng_err_status_cnt[3];
+}
+
+static u64 access_sdma_too_long_err_cnt(const struct cntr_entry *entry,
+                                       void *context, int vl, int mode,
+                                       u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->sw_send_dma_eng_err_status_cnt[2];
+}
+
+static u64 access_sdma_gen_mismatch_err_cnt(const struct cntr_entry *entry,
+                                           void *context, int vl, int mode,
+                                           u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->sw_send_dma_eng_err_status_cnt[1];
+}
+
+static u64 access_sdma_wrong_dw_err_cnt(const struct cntr_entry *entry,
+                                       void *context, int vl, int mode,
+                                       u64 data)
+{
+       struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
+
+       return dd->sw_send_dma_eng_err_status_cnt[0];
 }
 
 #define def_access_sw_cpu(cntr) \
@@ -1587,8 +3929,6 @@ static struct cntr_entry dev_cntrs[DEV_CNTR_LAST] = {
 [C_RX_TID_FLGMS] = RXE32_DEV_CNTR_ELEM(RxTidFLGMs,
                        RCV_TID_FLOW_GEN_MISMATCH_CNT,
                        CNTR_NORMAL),
-[C_RX_CTX_RHQS] = RXE32_DEV_CNTR_ELEM(RxCtxRHQS, RCV_CONTEXT_RHQ_STALL,
-                       CNTR_NORMAL),
 [C_RX_CTX_EGRS] = RXE32_DEV_CNTR_ELEM(RxCtxEgrS, RCV_CONTEXT_EGR_STALL,
                        CNTR_NORMAL),
 [C_RCV_TID_FLSMS] = RXE32_DEV_CNTR_ELEM(RxTidFLSMs,
@@ -1730,6 +4070,794 @@ static struct cntr_entry dev_cntrs[DEV_CNTR_LAST] = {
                            access_sw_kmem_wait),
 [C_SW_SEND_SCHED] = CNTR_ELEM("SendSched", 0, 0, CNTR_NORMAL,
                            access_sw_send_schedule),
+/* MISC_ERR_STATUS */
+[C_MISC_PLL_LOCK_FAIL_ERR] = CNTR_ELEM("MISC_PLL_LOCK_FAIL_ERR", 0, 0,
+                               CNTR_NORMAL,
+                               access_misc_pll_lock_fail_err_cnt),
+[C_MISC_MBIST_FAIL_ERR] = CNTR_ELEM("MISC_MBIST_FAIL_ERR", 0, 0,
+                               CNTR_NORMAL,
+                               access_misc_mbist_fail_err_cnt),
+[C_MISC_INVALID_EEP_CMD_ERR] = CNTR_ELEM("MISC_INVALID_EEP_CMD_ERR", 0, 0,
+                               CNTR_NORMAL,
+                               access_misc_invalid_eep_cmd_err_cnt),
+[C_MISC_EFUSE_DONE_PARITY_ERR] = CNTR_ELEM("MISC_EFUSE_DONE_PARITY_ERR", 0, 0,
+                               CNTR_NORMAL,
+                               access_misc_efuse_done_parity_err_cnt),
+[C_MISC_EFUSE_WRITE_ERR] = CNTR_ELEM("MISC_EFUSE_WRITE_ERR", 0, 0,
+                               CNTR_NORMAL,
+                               access_misc_efuse_write_err_cnt),
+[C_MISC_EFUSE_READ_BAD_ADDR_ERR] = CNTR_ELEM("MISC_EFUSE_READ_BAD_ADDR_ERR", 0,
+                               0, CNTR_NORMAL,
+                               access_misc_efuse_read_bad_addr_err_cnt),
+[C_MISC_EFUSE_CSR_PARITY_ERR] = CNTR_ELEM("MISC_EFUSE_CSR_PARITY_ERR", 0, 0,
+                               CNTR_NORMAL,
+                               access_misc_efuse_csr_parity_err_cnt),
+[C_MISC_FW_AUTH_FAILED_ERR] = CNTR_ELEM("MISC_FW_AUTH_FAILED_ERR", 0, 0,
+                               CNTR_NORMAL,
+                               access_misc_fw_auth_failed_err_cnt),
+[C_MISC_KEY_MISMATCH_ERR] = CNTR_ELEM("MISC_KEY_MISMATCH_ERR", 0, 0,
+                               CNTR_NORMAL,
+                               access_misc_key_mismatch_err_cnt),
+[C_MISC_SBUS_WRITE_FAILED_ERR] = CNTR_ELEM("MISC_SBUS_WRITE_FAILED_ERR", 0, 0,
+                               CNTR_NORMAL,
+                               access_misc_sbus_write_failed_err_cnt),
+[C_MISC_CSR_WRITE_BAD_ADDR_ERR] = CNTR_ELEM("MISC_CSR_WRITE_BAD_ADDR_ERR", 0, 0,
+                               CNTR_NORMAL,
+                               access_misc_csr_write_bad_addr_err_cnt),
+[C_MISC_CSR_READ_BAD_ADDR_ERR] = CNTR_ELEM("MISC_CSR_READ_BAD_ADDR_ERR", 0, 0,
+                               CNTR_NORMAL,
+                               access_misc_csr_read_bad_addr_err_cnt),
+[C_MISC_CSR_PARITY_ERR] = CNTR_ELEM("MISC_CSR_PARITY_ERR", 0, 0,
+                               CNTR_NORMAL,
+                               access_misc_csr_parity_err_cnt),
+/* CceErrStatus */
+[C_CCE_ERR_STATUS_AGGREGATED_CNT] = CNTR_ELEM("CceErrStatusAggregatedCnt", 0, 0,
+                               CNTR_NORMAL,
+                               access_sw_cce_err_status_aggregated_cnt),
+[C_CCE_MSIX_CSR_PARITY_ERR] = CNTR_ELEM("CceMsixCsrParityErr", 0, 0,
+                               CNTR_NORMAL,
+                               access_cce_msix_csr_parity_err_cnt),
+[C_CCE_INT_MAP_UNC_ERR] = CNTR_ELEM("CceIntMapUncErr", 0, 0,
+                               CNTR_NORMAL,
+                               access_cce_int_map_unc_err_cnt),
+[C_CCE_INT_MAP_COR_ERR] = CNTR_ELEM("CceIntMapCorErr", 0, 0,
+                               CNTR_NORMAL,
+                               access_cce_int_map_cor_err_cnt),
+[C_CCE_MSIX_TABLE_UNC_ERR] = CNTR_ELEM("CceMsixTableUncErr", 0, 0,
+                               CNTR_NORMAL,
+                               access_cce_msix_table_unc_err_cnt),
+[C_CCE_MSIX_TABLE_COR_ERR] = CNTR_ELEM("CceMsixTableCorErr", 0, 0,
+                               CNTR_NORMAL,
+                               access_cce_msix_table_cor_err_cnt),
+[C_CCE_RXDMA_CONV_FIFO_PARITY_ERR] = CNTR_ELEM("CceRxdmaConvFifoParityErr", 0,
+                               0, CNTR_NORMAL,
+                               access_cce_rxdma_conv_fifo_parity_err_cnt),
+[C_CCE_RCPL_ASYNC_FIFO_PARITY_ERR] = CNTR_ELEM("CceRcplAsyncFifoParityErr", 0,
+                               0, CNTR_NORMAL,
+                               access_cce_rcpl_async_fifo_parity_err_cnt),
+[C_CCE_SEG_WRITE_BAD_ADDR_ERR] = CNTR_ELEM("CceSegWriteBadAddrErr", 0, 0,
+                               CNTR_NORMAL,
+                               access_cce_seg_write_bad_addr_err_cnt),
+[C_CCE_SEG_READ_BAD_ADDR_ERR] = CNTR_ELEM("CceSegReadBadAddrErr", 0, 0,
+                               CNTR_NORMAL,
+                               access_cce_seg_read_bad_addr_err_cnt),
+[C_LA_TRIGGERED] = CNTR_ELEM("Cce LATriggered", 0, 0,
+                               CNTR_NORMAL,
+                               access_la_triggered_cnt),
+[C_CCE_TRGT_CPL_TIMEOUT_ERR] = CNTR_ELEM("CceTrgtCplTimeoutErr", 0, 0,
+                               CNTR_NORMAL,
+                               access_cce_trgt_cpl_timeout_err_cnt),
+[C_PCIC_RECEIVE_PARITY_ERR] = CNTR_ELEM("PcicReceiveParityErr", 0, 0,
+                               CNTR_NORMAL,
+                               access_pcic_receive_parity_err_cnt),
+[C_PCIC_TRANSMIT_BACK_PARITY_ERR] = CNTR_ELEM("PcicTransmitBackParityErr", 0, 0,
+                               CNTR_NORMAL,
+                               access_pcic_transmit_back_parity_err_cnt),
+[C_PCIC_TRANSMIT_FRONT_PARITY_ERR] = CNTR_ELEM("PcicTransmitFrontParityErr", 0,
+                               0, CNTR_NORMAL,
+                               access_pcic_transmit_front_parity_err_cnt),
+[C_PCIC_CPL_DAT_Q_UNC_ERR] = CNTR_ELEM("PcicCplDatQUncErr", 0, 0,
+                               CNTR_NORMAL,
+                               access_pcic_cpl_dat_q_unc_err_cnt),
+[C_PCIC_CPL_HD_Q_UNC_ERR] = CNTR_ELEM("PcicCplHdQUncErr", 0, 0,
+                               CNTR_NORMAL,
+                               access_pcic_cpl_hd_q_unc_err_cnt),
+[C_PCIC_POST_DAT_Q_UNC_ERR] = CNTR_ELEM("PcicPostDatQUncErr", 0, 0,
+                               CNTR_NORMAL,
+                               access_pcic_post_dat_q_unc_err_cnt),
+[C_PCIC_POST_HD_Q_UNC_ERR] = CNTR_ELEM("PcicPostHdQUncErr", 0, 0,
+                               CNTR_NORMAL,
+                               access_pcic_post_hd_q_unc_err_cnt),
+[C_PCIC_RETRY_SOT_MEM_UNC_ERR] = CNTR_ELEM("PcicRetrySotMemUncErr", 0, 0,
+                               CNTR_NORMAL,
+                               access_pcic_retry_sot_mem_unc_err_cnt),
+[C_PCIC_RETRY_MEM_UNC_ERR] = CNTR_ELEM("PcicRetryMemUncErr", 0, 0,
+                               CNTR_NORMAL,
+                               access_pcic_retry_mem_unc_err),
+[C_PCIC_N_POST_DAT_Q_PARITY_ERR] = CNTR_ELEM("PcicNPostDatQParityErr", 0, 0,
+                               CNTR_NORMAL,
+                               access_pcic_n_post_dat_q_parity_err_cnt),
+[C_PCIC_N_POST_H_Q_PARITY_ERR] = CNTR_ELEM("PcicNPostHQParityErr", 0, 0,
+                               CNTR_NORMAL,
+                               access_pcic_n_post_h_q_parity_err_cnt),
+[C_PCIC_CPL_DAT_Q_COR_ERR] = CNTR_ELEM("PcicCplDatQCorErr", 0, 0,
+                               CNTR_NORMAL,
+                               access_pcic_cpl_dat_q_cor_err_cnt),
+[C_PCIC_CPL_HD_Q_COR_ERR] = CNTR_ELEM("PcicCplHdQCorErr", 0, 0,
+                               CNTR_NORMAL,
+                               access_pcic_cpl_hd_q_cor_err_cnt),
+[C_PCIC_POST_DAT_Q_COR_ERR] = CNTR_ELEM("PcicPostDatQCorErr", 0, 0,
+                               CNTR_NORMAL,
+                               access_pcic_post_dat_q_cor_err_cnt),
+[C_PCIC_POST_HD_Q_COR_ERR] = CNTR_ELEM("PcicPostHdQCorErr", 0, 0,
+                               CNTR_NORMAL,
+                               access_pcic_post_hd_q_cor_err_cnt),
+[C_PCIC_RETRY_SOT_MEM_COR_ERR] = CNTR_ELEM("PcicRetrySotMemCorErr", 0, 0,
+                               CNTR_NORMAL,
+                               access_pcic_retry_sot_mem_cor_err_cnt),
+[C_PCIC_RETRY_MEM_COR_ERR] = CNTR_ELEM("PcicRetryMemCorErr", 0, 0,
+                               CNTR_NORMAL,
+                               access_pcic_retry_mem_cor_err_cnt),
+[C_CCE_CLI1_ASYNC_FIFO_DBG_PARITY_ERR] = CNTR_ELEM(
+                               "CceCli1AsyncFifoDbgParityError", 0, 0,
+                               CNTR_NORMAL,
+                               access_cce_cli1_async_fifo_dbg_parity_err_cnt),
+[C_CCE_CLI1_ASYNC_FIFO_RXDMA_PARITY_ERR] = CNTR_ELEM(
+                               "CceCli1AsyncFifoRxdmaParityError", 0, 0,
+                               CNTR_NORMAL,
+                               access_cce_cli1_async_fifo_rxdma_parity_err_cnt
+                               ),
+[C_CCE_CLI1_ASYNC_FIFO_SDMA_HD_PARITY_ERR] = CNTR_ELEM(
+                       "CceCli1AsyncFifoSdmaHdParityErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_cce_cli1_async_fifo_sdma_hd_parity_err_cnt),
+[C_CCE_CLI1_ASYNC_FIFO_PIO_CRDT_PARITY_ERR] = CNTR_ELEM(
+                       "CceCli1AsyncFifoPioCrdtParityErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_cce_cl1_async_fifo_pio_crdt_parity_err_cnt),
+[C_CCE_CLI2_ASYNC_FIFO_PARITY_ERR] = CNTR_ELEM("CceCli2AsyncFifoParityErr", 0,
+                       0, CNTR_NORMAL,
+                       access_cce_cli2_async_fifo_parity_err_cnt),
+[C_CCE_CSR_CFG_BUS_PARITY_ERR] = CNTR_ELEM("CceCsrCfgBusParityErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_cce_csr_cfg_bus_parity_err_cnt),
+[C_CCE_CLI0_ASYNC_FIFO_PARTIY_ERR] = CNTR_ELEM("CceCli0AsyncFifoParityErr", 0,
+                       0, CNTR_NORMAL,
+                       access_cce_cli0_async_fifo_parity_err_cnt),
+[C_CCE_RSPD_DATA_PARITY_ERR] = CNTR_ELEM("CceRspdDataParityErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_cce_rspd_data_parity_err_cnt),
+[C_CCE_TRGT_ACCESS_ERR] = CNTR_ELEM("CceTrgtAccessErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_cce_trgt_access_err_cnt),
+[C_CCE_TRGT_ASYNC_FIFO_PARITY_ERR] = CNTR_ELEM("CceTrgtAsyncFifoParityErr", 0,
+                       0, CNTR_NORMAL,
+                       access_cce_trgt_async_fifo_parity_err_cnt),
+[C_CCE_CSR_WRITE_BAD_ADDR_ERR] = CNTR_ELEM("CceCsrWriteBadAddrErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_cce_csr_write_bad_addr_err_cnt),
+[C_CCE_CSR_READ_BAD_ADDR_ERR] = CNTR_ELEM("CceCsrReadBadAddrErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_cce_csr_read_bad_addr_err_cnt),
+[C_CCE_CSR_PARITY_ERR] = CNTR_ELEM("CceCsrParityErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_ccs_csr_parity_err_cnt),
+
+/* RcvErrStatus */
+[C_RX_CSR_PARITY_ERR] = CNTR_ELEM("RxCsrParityErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_rx_csr_parity_err_cnt),
+[C_RX_CSR_WRITE_BAD_ADDR_ERR] = CNTR_ELEM("RxCsrWriteBadAddrErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_rx_csr_write_bad_addr_err_cnt),
+[C_RX_CSR_READ_BAD_ADDR_ERR] = CNTR_ELEM("RxCsrReadBadAddrErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_rx_csr_read_bad_addr_err_cnt),
+[C_RX_DMA_CSR_UNC_ERR] = CNTR_ELEM("RxDmaCsrUncErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_rx_dma_csr_unc_err_cnt),
+[C_RX_DMA_DQ_FSM_ENCODING_ERR] = CNTR_ELEM("RxDmaDqFsmEncodingErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_rx_dma_dq_fsm_encoding_err_cnt),
+[C_RX_DMA_EQ_FSM_ENCODING_ERR] = CNTR_ELEM("RxDmaEqFsmEncodingErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_rx_dma_eq_fsm_encoding_err_cnt),
+[C_RX_DMA_CSR_PARITY_ERR] = CNTR_ELEM("RxDmaCsrParityErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_rx_dma_csr_parity_err_cnt),
+[C_RX_RBUF_DATA_COR_ERR] = CNTR_ELEM("RxRbufDataCorErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_rx_rbuf_data_cor_err_cnt),
+[C_RX_RBUF_DATA_UNC_ERR] = CNTR_ELEM("RxRbufDataUncErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_rx_rbuf_data_unc_err_cnt),
+[C_RX_DMA_DATA_FIFO_RD_COR_ERR] = CNTR_ELEM("RxDmaDataFifoRdCorErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_rx_dma_data_fifo_rd_cor_err_cnt),
+[C_RX_DMA_DATA_FIFO_RD_UNC_ERR] = CNTR_ELEM("RxDmaDataFifoRdUncErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_rx_dma_data_fifo_rd_unc_err_cnt),
+[C_RX_DMA_HDR_FIFO_RD_COR_ERR] = CNTR_ELEM("RxDmaHdrFifoRdCorErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_rx_dma_hdr_fifo_rd_cor_err_cnt),
+[C_RX_DMA_HDR_FIFO_RD_UNC_ERR] = CNTR_ELEM("RxDmaHdrFifoRdUncErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_rx_dma_hdr_fifo_rd_unc_err_cnt),
+[C_RX_RBUF_DESC_PART2_COR_ERR] = CNTR_ELEM("RxRbufDescPart2CorErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_rx_rbuf_desc_part2_cor_err_cnt),
+[C_RX_RBUF_DESC_PART2_UNC_ERR] = CNTR_ELEM("RxRbufDescPart2UncErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_rx_rbuf_desc_part2_unc_err_cnt),
+[C_RX_RBUF_DESC_PART1_COR_ERR] = CNTR_ELEM("RxRbufDescPart1CorErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_rx_rbuf_desc_part1_cor_err_cnt),
+[C_RX_RBUF_DESC_PART1_UNC_ERR] = CNTR_ELEM("RxRbufDescPart1UncErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_rx_rbuf_desc_part1_unc_err_cnt),
+[C_RX_HQ_INTR_FSM_ERR] = CNTR_ELEM("RxHqIntrFsmErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_rx_hq_intr_fsm_err_cnt),
+[C_RX_HQ_INTR_CSR_PARITY_ERR] = CNTR_ELEM("RxHqIntrCsrParityErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_rx_hq_intr_csr_parity_err_cnt),
+[C_RX_LOOKUP_CSR_PARITY_ERR] = CNTR_ELEM("RxLookupCsrParityErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_rx_lookup_csr_parity_err_cnt),
+[C_RX_LOOKUP_RCV_ARRAY_COR_ERR] = CNTR_ELEM("RxLookupRcvArrayCorErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_rx_lookup_rcv_array_cor_err_cnt),
+[C_RX_LOOKUP_RCV_ARRAY_UNC_ERR] = CNTR_ELEM("RxLookupRcvArrayUncErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_rx_lookup_rcv_array_unc_err_cnt),
+[C_RX_LOOKUP_DES_PART2_PARITY_ERR] = CNTR_ELEM("RxLookupDesPart2ParityErr", 0,
+                       0, CNTR_NORMAL,
+                       access_rx_lookup_des_part2_parity_err_cnt),
+[C_RX_LOOKUP_DES_PART1_UNC_COR_ERR] = CNTR_ELEM("RxLookupDesPart1UncCorErr", 0,
+                       0, CNTR_NORMAL,
+                       access_rx_lookup_des_part1_unc_cor_err_cnt),
+[C_RX_LOOKUP_DES_PART1_UNC_ERR] = CNTR_ELEM("RxLookupDesPart1UncErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_rx_lookup_des_part1_unc_err_cnt),
+[C_RX_RBUF_NEXT_FREE_BUF_COR_ERR] = CNTR_ELEM("RxRbufNextFreeBufCorErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_rx_rbuf_next_free_buf_cor_err_cnt),
+[C_RX_RBUF_NEXT_FREE_BUF_UNC_ERR] = CNTR_ELEM("RxRbufNextFreeBufUncErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_rx_rbuf_next_free_buf_unc_err_cnt),
+[C_RX_RBUF_FL_INIT_WR_ADDR_PARITY_ERR] = CNTR_ELEM(
+                       "RxRbufFlInitWrAddrParityErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_rbuf_fl_init_wr_addr_parity_err_cnt),
+[C_RX_RBUF_FL_INITDONE_PARITY_ERR] = CNTR_ELEM("RxRbufFlInitdoneParityErr", 0,
+                       0, CNTR_NORMAL,
+                       access_rx_rbuf_fl_initdone_parity_err_cnt),
+[C_RX_RBUF_FL_WRITE_ADDR_PARITY_ERR] = CNTR_ELEM("RxRbufFlWrAddrParityErr", 0,
+                       0, CNTR_NORMAL,
+                       access_rx_rbuf_fl_write_addr_parity_err_cnt),
+[C_RX_RBUF_FL_RD_ADDR_PARITY_ERR] = CNTR_ELEM("RxRbufFlRdAddrParityErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_rx_rbuf_fl_rd_addr_parity_err_cnt),
+[C_RX_RBUF_EMPTY_ERR] = CNTR_ELEM("RxRbufEmptyErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_rx_rbuf_empty_err_cnt),
+[C_RX_RBUF_FULL_ERR] = CNTR_ELEM("RxRbufFullErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_rx_rbuf_full_err_cnt),
+[C_RX_RBUF_BAD_LOOKUP_ERR] = CNTR_ELEM("RxRBufBadLookupErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_rbuf_bad_lookup_err_cnt),
+[C_RX_RBUF_CTX_ID_PARITY_ERR] = CNTR_ELEM("RxRbufCtxIdParityErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_rbuf_ctx_id_parity_err_cnt),
+[C_RX_RBUF_CSR_QEOPDW_PARITY_ERR] = CNTR_ELEM("RxRbufCsrQEOPDWParityErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_rbuf_csr_qeopdw_parity_err_cnt),
+[C_RX_RBUF_CSR_Q_NUM_OF_PKT_PARITY_ERR] = CNTR_ELEM(
+                       "RxRbufCsrQNumOfPktParityErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_rx_rbuf_csr_q_num_of_pkt_parity_err_cnt),
+[C_RX_RBUF_CSR_Q_T1_PTR_PARITY_ERR] = CNTR_ELEM(
+                       "RxRbufCsrQTlPtrParityErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_rx_rbuf_csr_q_t1_ptr_parity_err_cnt),
+[C_RX_RBUF_CSR_Q_HD_PTR_PARITY_ERR] = CNTR_ELEM("RxRbufCsrQHdPtrParityErr", 0,
+                       0, CNTR_NORMAL,
+                       access_rx_rbuf_csr_q_hd_ptr_parity_err_cnt),
+[C_RX_RBUF_CSR_Q_VLD_BIT_PARITY_ERR] = CNTR_ELEM("RxRbufCsrQVldBitParityErr", 0,
+                       0, CNTR_NORMAL,
+                       access_rx_rbuf_csr_q_vld_bit_parity_err_cnt),
+[C_RX_RBUF_CSR_Q_NEXT_BUF_PARITY_ERR] = CNTR_ELEM("RxRbufCsrQNextBufParityErr",
+                       0, 0, CNTR_NORMAL,
+                       access_rx_rbuf_csr_q_next_buf_parity_err_cnt),
+[C_RX_RBUF_CSR_Q_ENT_CNT_PARITY_ERR] = CNTR_ELEM("RxRbufCsrQEntCntParityErr", 0,
+                       0, CNTR_NORMAL,
+                       access_rx_rbuf_csr_q_ent_cnt_parity_err_cnt),
+[C_RX_RBUF_CSR_Q_HEAD_BUF_NUM_PARITY_ERR] = CNTR_ELEM(
+                       "RxRbufCsrQHeadBufNumParityErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_rx_rbuf_csr_q_head_buf_num_parity_err_cnt),
+[C_RX_RBUF_BLOCK_LIST_READ_COR_ERR] = CNTR_ELEM("RxRbufBlockListReadCorErr", 0,
+                       0, CNTR_NORMAL,
+                       access_rx_rbuf_block_list_read_cor_err_cnt),
+[C_RX_RBUF_BLOCK_LIST_READ_UNC_ERR] = CNTR_ELEM("RxRbufBlockListReadUncErr", 0,
+                       0, CNTR_NORMAL,
+                       access_rx_rbuf_block_list_read_unc_err_cnt),
+[C_RX_RBUF_LOOKUP_DES_COR_ERR] = CNTR_ELEM("RxRbufLookupDesCorErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_rx_rbuf_lookup_des_cor_err_cnt),
+[C_RX_RBUF_LOOKUP_DES_UNC_ERR] = CNTR_ELEM("RxRbufLookupDesUncErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_rx_rbuf_lookup_des_unc_err_cnt),
+[C_RX_RBUF_LOOKUP_DES_REG_UNC_COR_ERR] = CNTR_ELEM(
+                       "RxRbufLookupDesRegUncCorErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_rx_rbuf_lookup_des_reg_unc_cor_err_cnt),
+[C_RX_RBUF_LOOKUP_DES_REG_UNC_ERR] = CNTR_ELEM("RxRbufLookupDesRegUncErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_rx_rbuf_lookup_des_reg_unc_err_cnt),
+[C_RX_RBUF_FREE_LIST_COR_ERR] = CNTR_ELEM("RxRbufFreeListCorErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_rx_rbuf_free_list_cor_err_cnt),
+[C_RX_RBUF_FREE_LIST_UNC_ERR] = CNTR_ELEM("RxRbufFreeListUncErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_rx_rbuf_free_list_unc_err_cnt),
+[C_RX_RCV_FSM_ENCODING_ERR] = CNTR_ELEM("RxRcvFsmEncodingErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_rx_rcv_fsm_encoding_err_cnt),
+[C_RX_DMA_FLAG_COR_ERR] = CNTR_ELEM("RxDmaFlagCorErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_rx_dma_flag_cor_err_cnt),
+[C_RX_DMA_FLAG_UNC_ERR] = CNTR_ELEM("RxDmaFlagUncErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_rx_dma_flag_unc_err_cnt),
+[C_RX_DC_SOP_EOP_PARITY_ERR] = CNTR_ELEM("RxDcSopEopParityErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_rx_dc_sop_eop_parity_err_cnt),
+[C_RX_RCV_CSR_PARITY_ERR] = CNTR_ELEM("RxRcvCsrParityErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_rx_rcv_csr_parity_err_cnt),
+[C_RX_RCV_QP_MAP_TABLE_COR_ERR] = CNTR_ELEM("RxRcvQpMapTableCorErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_rx_rcv_qp_map_table_cor_err_cnt),
+[C_RX_RCV_QP_MAP_TABLE_UNC_ERR] = CNTR_ELEM("RxRcvQpMapTableUncErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_rx_rcv_qp_map_table_unc_err_cnt),
+[C_RX_RCV_DATA_COR_ERR] = CNTR_ELEM("RxRcvDataCorErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_rx_rcv_data_cor_err_cnt),
+[C_RX_RCV_DATA_UNC_ERR] = CNTR_ELEM("RxRcvDataUncErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_rx_rcv_data_unc_err_cnt),
+[C_RX_RCV_HDR_COR_ERR] = CNTR_ELEM("RxRcvHdrCorErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_rx_rcv_hdr_cor_err_cnt),
+[C_RX_RCV_HDR_UNC_ERR] = CNTR_ELEM("RxRcvHdrUncErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_rx_rcv_hdr_unc_err_cnt),
+[C_RX_DC_INTF_PARITY_ERR] = CNTR_ELEM("RxDcIntfParityErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_rx_dc_intf_parity_err_cnt),
+[C_RX_DMA_CSR_COR_ERR] = CNTR_ELEM("RxDmaCsrCorErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_rx_dma_csr_cor_err_cnt),
+/* SendPioErrStatus */
+[C_PIO_PEC_SOP_HEAD_PARITY_ERR] = CNTR_ELEM("PioPecSopHeadParityErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_pio_pec_sop_head_parity_err_cnt),
+[C_PIO_PCC_SOP_HEAD_PARITY_ERR] = CNTR_ELEM("PioPccSopHeadParityErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_pio_pcc_sop_head_parity_err_cnt),
+[C_PIO_LAST_RETURNED_CNT_PARITY_ERR] = CNTR_ELEM("PioLastReturnedCntParityErr",
+                       0, 0, CNTR_NORMAL,
+                       access_pio_last_returned_cnt_parity_err_cnt),
+[C_PIO_CURRENT_FREE_CNT_PARITY_ERR] = CNTR_ELEM("PioCurrentFreeCntParityErr", 0,
+                       0, CNTR_NORMAL,
+                       access_pio_current_free_cnt_parity_err_cnt),
+[C_PIO_RSVD_31_ERR] = CNTR_ELEM("Pio Reserved 31", 0, 0,
+                       CNTR_NORMAL,
+                       access_pio_reserved_31_err_cnt),
+[C_PIO_RSVD_30_ERR] = CNTR_ELEM("Pio Reserved 30", 0, 0,
+                       CNTR_NORMAL,
+                       access_pio_reserved_30_err_cnt),
+[C_PIO_PPMC_SOP_LEN_ERR] = CNTR_ELEM("PioPpmcSopLenErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_pio_ppmc_sop_len_err_cnt),
+[C_PIO_PPMC_BQC_MEM_PARITY_ERR] = CNTR_ELEM("PioPpmcBqcMemParityErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_pio_ppmc_bqc_mem_parity_err_cnt),
+[C_PIO_VL_FIFO_PARITY_ERR] = CNTR_ELEM("PioVlFifoParityErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_pio_vl_fifo_parity_err_cnt),
+[C_PIO_VLF_SOP_PARITY_ERR] = CNTR_ELEM("PioVlfSopParityErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_pio_vlf_sop_parity_err_cnt),
+[C_PIO_VLF_V1_LEN_PARITY_ERR] = CNTR_ELEM("PioVlfVlLenParityErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_pio_vlf_v1_len_parity_err_cnt),
+[C_PIO_BLOCK_QW_COUNT_PARITY_ERR] = CNTR_ELEM("PioBlockQwCountParityErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_pio_block_qw_count_parity_err_cnt),
+[C_PIO_WRITE_QW_VALID_PARITY_ERR] = CNTR_ELEM("PioWriteQwValidParityErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_pio_write_qw_valid_parity_err_cnt),
+[C_PIO_STATE_MACHINE_ERR] = CNTR_ELEM("PioStateMachineErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_pio_state_machine_err_cnt),
+[C_PIO_WRITE_DATA_PARITY_ERR] = CNTR_ELEM("PioWriteDataParityErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_pio_write_data_parity_err_cnt),
+[C_PIO_HOST_ADDR_MEM_COR_ERR] = CNTR_ELEM("PioHostAddrMemCorErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_pio_host_addr_mem_cor_err_cnt),
+[C_PIO_HOST_ADDR_MEM_UNC_ERR] = CNTR_ELEM("PioHostAddrMemUncErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_pio_host_addr_mem_unc_err_cnt),
+[C_PIO_PKT_EVICT_SM_OR_ARM_SM_ERR] = CNTR_ELEM("PioPktEvictSmOrArbSmErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_pio_pkt_evict_sm_or_arb_sm_err_cnt),
+[C_PIO_INIT_SM_IN_ERR] = CNTR_ELEM("PioInitSmInErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_pio_init_sm_in_err_cnt),
+[C_PIO_PPMC_PBL_FIFO_ERR] = CNTR_ELEM("PioPpmcPblFifoErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_pio_ppmc_pbl_fifo_err_cnt),
+[C_PIO_CREDIT_RET_FIFO_PARITY_ERR] = CNTR_ELEM("PioCreditRetFifoParityErr", 0,
+                       0, CNTR_NORMAL,
+                       access_pio_credit_ret_fifo_parity_err_cnt),
+[C_PIO_V1_LEN_MEM_BANK1_COR_ERR] = CNTR_ELEM("PioVlLenMemBank1CorErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_pio_v1_len_mem_bank1_cor_err_cnt),
+[C_PIO_V1_LEN_MEM_BANK0_COR_ERR] = CNTR_ELEM("PioVlLenMemBank0CorErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_pio_v1_len_mem_bank0_cor_err_cnt),
+[C_PIO_V1_LEN_MEM_BANK1_UNC_ERR] = CNTR_ELEM("PioVlLenMemBank1UncErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_pio_v1_len_mem_bank1_unc_err_cnt),
+[C_PIO_V1_LEN_MEM_BANK0_UNC_ERR] = CNTR_ELEM("PioVlLenMemBank0UncErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_pio_v1_len_mem_bank0_unc_err_cnt),
+[C_PIO_SM_PKT_RESET_PARITY_ERR] = CNTR_ELEM("PioSmPktResetParityErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_pio_sm_pkt_reset_parity_err_cnt),
+[C_PIO_PKT_EVICT_FIFO_PARITY_ERR] = CNTR_ELEM("PioPktEvictFifoParityErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_pio_pkt_evict_fifo_parity_err_cnt),
+[C_PIO_SBRDCTRL_CRREL_FIFO_PARITY_ERR] = CNTR_ELEM(
+                       "PioSbrdctrlCrrelFifoParityErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_pio_sbrdctrl_crrel_fifo_parity_err_cnt),
+[C_PIO_SBRDCTL_CRREL_PARITY_ERR] = CNTR_ELEM("PioSbrdctlCrrelParityErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_pio_sbrdctl_crrel_parity_err_cnt),
+[C_PIO_PEC_FIFO_PARITY_ERR] = CNTR_ELEM("PioPecFifoParityErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_pio_pec_fifo_parity_err_cnt),
+[C_PIO_PCC_FIFO_PARITY_ERR] = CNTR_ELEM("PioPccFifoParityErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_pio_pcc_fifo_parity_err_cnt),
+[C_PIO_SB_MEM_FIFO1_ERR] = CNTR_ELEM("PioSbMemFifo1Err", 0, 0,
+                       CNTR_NORMAL,
+                       access_pio_sb_mem_fifo1_err_cnt),
+[C_PIO_SB_MEM_FIFO0_ERR] = CNTR_ELEM("PioSbMemFifo0Err", 0, 0,
+                       CNTR_NORMAL,
+                       access_pio_sb_mem_fifo0_err_cnt),
+[C_PIO_CSR_PARITY_ERR] = CNTR_ELEM("PioCsrParityErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_pio_csr_parity_err_cnt),
+[C_PIO_WRITE_ADDR_PARITY_ERR] = CNTR_ELEM("PioWriteAddrParityErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_pio_write_addr_parity_err_cnt),
+[C_PIO_WRITE_BAD_CTXT_ERR] = CNTR_ELEM("PioWriteBadCtxtErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_pio_write_bad_ctxt_err_cnt),
+/* SendDmaErrStatus */
+[C_SDMA_PCIE_REQ_TRACKING_COR_ERR] = CNTR_ELEM("SDmaPcieReqTrackingCorErr", 0,
+                       0, CNTR_NORMAL,
+                       access_sdma_pcie_req_tracking_cor_err_cnt),
+[C_SDMA_PCIE_REQ_TRACKING_UNC_ERR] = CNTR_ELEM("SDmaPcieReqTrackingUncErr", 0,
+                       0, CNTR_NORMAL,
+                       access_sdma_pcie_req_tracking_unc_err_cnt),
+[C_SDMA_CSR_PARITY_ERR] = CNTR_ELEM("SDmaCsrParityErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_sdma_csr_parity_err_cnt),
+[C_SDMA_RPY_TAG_ERR] = CNTR_ELEM("SDmaRpyTagErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_sdma_rpy_tag_err_cnt),
+/* SendEgressErrStatus */
+[C_TX_READ_PIO_MEMORY_CSR_UNC_ERR] = CNTR_ELEM("TxReadPioMemoryCsrUncErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_tx_read_pio_memory_csr_unc_err_cnt),
+[C_TX_READ_SDMA_MEMORY_CSR_UNC_ERR] = CNTR_ELEM("TxReadSdmaMemoryCsrUncErr", 0,
+                       0, CNTR_NORMAL,
+                       access_tx_read_sdma_memory_csr_err_cnt),
+[C_TX_EGRESS_FIFO_COR_ERR] = CNTR_ELEM("TxEgressFifoCorErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_tx_egress_fifo_cor_err_cnt),
+[C_TX_READ_PIO_MEMORY_COR_ERR] = CNTR_ELEM("TxReadPioMemoryCorErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_tx_read_pio_memory_cor_err_cnt),
+[C_TX_READ_SDMA_MEMORY_COR_ERR] = CNTR_ELEM("TxReadSdmaMemoryCorErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_tx_read_sdma_memory_cor_err_cnt),
+[C_TX_SB_HDR_COR_ERR] = CNTR_ELEM("TxSbHdrCorErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_tx_sb_hdr_cor_err_cnt),
+[C_TX_CREDIT_OVERRUN_ERR] = CNTR_ELEM("TxCreditOverrunErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_tx_credit_overrun_err_cnt),
+[C_TX_LAUNCH_FIFO8_COR_ERR] = CNTR_ELEM("TxLaunchFifo8CorErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_tx_launch_fifo8_cor_err_cnt),
+[C_TX_LAUNCH_FIFO7_COR_ERR] = CNTR_ELEM("TxLaunchFifo7CorErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_tx_launch_fifo7_cor_err_cnt),
+[C_TX_LAUNCH_FIFO6_COR_ERR] = CNTR_ELEM("TxLaunchFifo6CorErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_tx_launch_fifo6_cor_err_cnt),
+[C_TX_LAUNCH_FIFO5_COR_ERR] = CNTR_ELEM("TxLaunchFifo5CorErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_tx_launch_fifo5_cor_err_cnt),
+[C_TX_LAUNCH_FIFO4_COR_ERR] = CNTR_ELEM("TxLaunchFifo4CorErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_tx_launch_fifo4_cor_err_cnt),
+[C_TX_LAUNCH_FIFO3_COR_ERR] = CNTR_ELEM("TxLaunchFifo3CorErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_tx_launch_fifo3_cor_err_cnt),
+[C_TX_LAUNCH_FIFO2_COR_ERR] = CNTR_ELEM("TxLaunchFifo2CorErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_tx_launch_fifo2_cor_err_cnt),
+[C_TX_LAUNCH_FIFO1_COR_ERR] = CNTR_ELEM("TxLaunchFifo1CorErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_tx_launch_fifo1_cor_err_cnt),
+[C_TX_LAUNCH_FIFO0_COR_ERR] = CNTR_ELEM("TxLaunchFifo0CorErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_tx_launch_fifo0_cor_err_cnt),
+[C_TX_CREDIT_RETURN_VL_ERR] = CNTR_ELEM("TxCreditReturnVLErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_tx_credit_return_vl_err_cnt),
+[C_TX_HCRC_INSERTION_ERR] = CNTR_ELEM("TxHcrcInsertionErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_tx_hcrc_insertion_err_cnt),
+[C_TX_EGRESS_FIFI_UNC_ERR] = CNTR_ELEM("TxEgressFifoUncErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_tx_egress_fifo_unc_err_cnt),
+[C_TX_READ_PIO_MEMORY_UNC_ERR] = CNTR_ELEM("TxReadPioMemoryUncErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_tx_read_pio_memory_unc_err_cnt),
+[C_TX_READ_SDMA_MEMORY_UNC_ERR] = CNTR_ELEM("TxReadSdmaMemoryUncErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_tx_read_sdma_memory_unc_err_cnt),
+[C_TX_SB_HDR_UNC_ERR] = CNTR_ELEM("TxSbHdrUncErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_tx_sb_hdr_unc_err_cnt),
+[C_TX_CREDIT_RETURN_PARITY_ERR] = CNTR_ELEM("TxCreditReturnParityErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_tx_credit_return_partiy_err_cnt),
+[C_TX_LAUNCH_FIFO8_UNC_OR_PARITY_ERR] = CNTR_ELEM("TxLaunchFifo8UncOrParityErr",
+                       0, 0, CNTR_NORMAL,
+                       access_tx_launch_fifo8_unc_or_parity_err_cnt),
+[C_TX_LAUNCH_FIFO7_UNC_OR_PARITY_ERR] = CNTR_ELEM("TxLaunchFifo7UncOrParityErr",
+                       0, 0, CNTR_NORMAL,
+                       access_tx_launch_fifo7_unc_or_parity_err_cnt),
+[C_TX_LAUNCH_FIFO6_UNC_OR_PARITY_ERR] = CNTR_ELEM("TxLaunchFifo6UncOrParityErr",
+                       0, 0, CNTR_NORMAL,
+                       access_tx_launch_fifo6_unc_or_parity_err_cnt),
+[C_TX_LAUNCH_FIFO5_UNC_OR_PARITY_ERR] = CNTR_ELEM("TxLaunchFifo5UncOrParityErr",
+                       0, 0, CNTR_NORMAL,
+                       access_tx_launch_fifo5_unc_or_parity_err_cnt),
+[C_TX_LAUNCH_FIFO4_UNC_OR_PARITY_ERR] = CNTR_ELEM("TxLaunchFifo4UncOrParityErr",
+                       0, 0, CNTR_NORMAL,
+                       access_tx_launch_fifo4_unc_or_parity_err_cnt),
+[C_TX_LAUNCH_FIFO3_UNC_OR_PARITY_ERR] = CNTR_ELEM("TxLaunchFifo3UncOrParityErr",
+                       0, 0, CNTR_NORMAL,
+                       access_tx_launch_fifo3_unc_or_parity_err_cnt),
+[C_TX_LAUNCH_FIFO2_UNC_OR_PARITY_ERR] = CNTR_ELEM("TxLaunchFifo2UncOrParityErr",
+                       0, 0, CNTR_NORMAL,
+                       access_tx_launch_fifo2_unc_or_parity_err_cnt),
+[C_TX_LAUNCH_FIFO1_UNC_OR_PARITY_ERR] = CNTR_ELEM("TxLaunchFifo1UncOrParityErr",
+                       0, 0, CNTR_NORMAL,
+                       access_tx_launch_fifo1_unc_or_parity_err_cnt),
+[C_TX_LAUNCH_FIFO0_UNC_OR_PARITY_ERR] = CNTR_ELEM("TxLaunchFifo0UncOrParityErr",
+                       0, 0, CNTR_NORMAL,
+                       access_tx_launch_fifo0_unc_or_parity_err_cnt),
+[C_TX_SDMA15_DISALLOWED_PACKET_ERR] = CNTR_ELEM("TxSdma15DisallowedPacketErr",
+                       0, 0, CNTR_NORMAL,
+                       access_tx_sdma15_disallowed_packet_err_cnt),
+[C_TX_SDMA14_DISALLOWED_PACKET_ERR] = CNTR_ELEM("TxSdma14DisallowedPacketErr",
+                       0, 0, CNTR_NORMAL,
+                       access_tx_sdma14_disallowed_packet_err_cnt),
+[C_TX_SDMA13_DISALLOWED_PACKET_ERR] = CNTR_ELEM("TxSdma13DisallowedPacketErr",
+                       0, 0, CNTR_NORMAL,
+                       access_tx_sdma13_disallowed_packet_err_cnt),
+[C_TX_SDMA12_DISALLOWED_PACKET_ERR] = CNTR_ELEM("TxSdma12DisallowedPacketErr",
+                       0, 0, CNTR_NORMAL,
+                       access_tx_sdma12_disallowed_packet_err_cnt),
+[C_TX_SDMA11_DISALLOWED_PACKET_ERR] = CNTR_ELEM("TxSdma11DisallowedPacketErr",
+                       0, 0, CNTR_NORMAL,
+                       access_tx_sdma11_disallowed_packet_err_cnt),
+[C_TX_SDMA10_DISALLOWED_PACKET_ERR] = CNTR_ELEM("TxSdma10DisallowedPacketErr",
+                       0, 0, CNTR_NORMAL,
+                       access_tx_sdma10_disallowed_packet_err_cnt),
+[C_TX_SDMA9_DISALLOWED_PACKET_ERR] = CNTR_ELEM("TxSdma9DisallowedPacketErr",
+                       0, 0, CNTR_NORMAL,
+                       access_tx_sdma9_disallowed_packet_err_cnt),
+[C_TX_SDMA8_DISALLOWED_PACKET_ERR] = CNTR_ELEM("TxSdma8DisallowedPacketErr",
+                       0, 0, CNTR_NORMAL,
+                       access_tx_sdma8_disallowed_packet_err_cnt),
+[C_TX_SDMA7_DISALLOWED_PACKET_ERR] = CNTR_ELEM("TxSdma7DisallowedPacketErr",
+                       0, 0, CNTR_NORMAL,
+                       access_tx_sdma7_disallowed_packet_err_cnt),
+[C_TX_SDMA6_DISALLOWED_PACKET_ERR] = CNTR_ELEM("TxSdma6DisallowedPacketErr",
+                       0, 0, CNTR_NORMAL,
+                       access_tx_sdma6_disallowed_packet_err_cnt),
+[C_TX_SDMA5_DISALLOWED_PACKET_ERR] = CNTR_ELEM("TxSdma5DisallowedPacketErr",
+                       0, 0, CNTR_NORMAL,
+                       access_tx_sdma5_disallowed_packet_err_cnt),
+[C_TX_SDMA4_DISALLOWED_PACKET_ERR] = CNTR_ELEM("TxSdma4DisallowedPacketErr",
+                       0, 0, CNTR_NORMAL,
+                       access_tx_sdma4_disallowed_packet_err_cnt),
+[C_TX_SDMA3_DISALLOWED_PACKET_ERR] = CNTR_ELEM("TxSdma3DisallowedPacketErr",
+                       0, 0, CNTR_NORMAL,
+                       access_tx_sdma3_disallowed_packet_err_cnt),
+[C_TX_SDMA2_DISALLOWED_PACKET_ERR] = CNTR_ELEM("TxSdma2DisallowedPacketErr",
+                       0, 0, CNTR_NORMAL,
+                       access_tx_sdma2_disallowed_packet_err_cnt),
+[C_TX_SDMA1_DISALLOWED_PACKET_ERR] = CNTR_ELEM("TxSdma1DisallowedPacketErr",
+                       0, 0, CNTR_NORMAL,
+                       access_tx_sdma1_disallowed_packet_err_cnt),
+[C_TX_SDMA0_DISALLOWED_PACKET_ERR] = CNTR_ELEM("TxSdma0DisallowedPacketErr",
+                       0, 0, CNTR_NORMAL,
+                       access_tx_sdma0_disallowed_packet_err_cnt),
+[C_TX_CONFIG_PARITY_ERR] = CNTR_ELEM("TxConfigParityErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_tx_config_parity_err_cnt),
+[C_TX_SBRD_CTL_CSR_PARITY_ERR] = CNTR_ELEM("TxSbrdCtlCsrParityErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_tx_sbrd_ctl_csr_parity_err_cnt),
+[C_TX_LAUNCH_CSR_PARITY_ERR] = CNTR_ELEM("TxLaunchCsrParityErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_tx_launch_csr_parity_err_cnt),
+[C_TX_ILLEGAL_CL_ERR] = CNTR_ELEM("TxIllegalVLErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_tx_illegal_vl_err_cnt),
+[C_TX_SBRD_CTL_STATE_MACHINE_PARITY_ERR] = CNTR_ELEM(
+                       "TxSbrdCtlStateMachineParityErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_tx_sbrd_ctl_state_machine_parity_err_cnt),
+[C_TX_RESERVED_10] = CNTR_ELEM("Tx Egress Reserved 10", 0, 0,
+                       CNTR_NORMAL,
+                       access_egress_reserved_10_err_cnt),
+[C_TX_RESERVED_9] = CNTR_ELEM("Tx Egress Reserved 9", 0, 0,
+                       CNTR_NORMAL,
+                       access_egress_reserved_9_err_cnt),
+[C_TX_SDMA_LAUNCH_INTF_PARITY_ERR] = CNTR_ELEM("TxSdmaLaunchIntfParityErr",
+                       0, 0, CNTR_NORMAL,
+                       access_tx_sdma_launch_intf_parity_err_cnt),
+[C_TX_PIO_LAUNCH_INTF_PARITY_ERR] = CNTR_ELEM("TxPioLaunchIntfParityErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_tx_pio_launch_intf_parity_err_cnt),
+[C_TX_RESERVED_6] = CNTR_ELEM("Tx Egress Reserved 6", 0, 0,
+                       CNTR_NORMAL,
+                       access_egress_reserved_6_err_cnt),
+[C_TX_INCORRECT_LINK_STATE_ERR] = CNTR_ELEM("TxIncorrectLinkStateErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_tx_incorrect_link_state_err_cnt),
+[C_TX_LINK_DOWN_ERR] = CNTR_ELEM("TxLinkdownErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_tx_linkdown_err_cnt),
+[C_TX_EGRESS_FIFO_UNDERRUN_OR_PARITY_ERR] = CNTR_ELEM(
+                       "EgressFifoUnderrunOrParityErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_tx_egress_fifi_underrun_or_parity_err_cnt),
+[C_TX_RESERVED_2] = CNTR_ELEM("Tx Egress Reserved 2", 0, 0,
+                       CNTR_NORMAL,
+                       access_egress_reserved_2_err_cnt),
+[C_TX_PKT_INTEGRITY_MEM_UNC_ERR] = CNTR_ELEM("TxPktIntegrityMemUncErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_tx_pkt_integrity_mem_unc_err_cnt),
+[C_TX_PKT_INTEGRITY_MEM_COR_ERR] = CNTR_ELEM("TxPktIntegrityMemCorErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_tx_pkt_integrity_mem_cor_err_cnt),
+/* SendErrStatus */
+[C_SEND_CSR_WRITE_BAD_ADDR_ERR] = CNTR_ELEM("SendCsrWriteBadAddrErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_send_csr_write_bad_addr_err_cnt),
+[C_SEND_CSR_READ_BAD_ADD_ERR] = CNTR_ELEM("SendCsrReadBadAddrErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_send_csr_read_bad_addr_err_cnt),
+[C_SEND_CSR_PARITY_ERR] = CNTR_ELEM("SendCsrParityErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_send_csr_parity_cnt),
+/* SendCtxtErrStatus */
+[C_PIO_WRITE_OUT_OF_BOUNDS_ERR] = CNTR_ELEM("PioWriteOutOfBoundsErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_pio_write_out_of_bounds_err_cnt),
+[C_PIO_WRITE_OVERFLOW_ERR] = CNTR_ELEM("PioWriteOverflowErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_pio_write_overflow_err_cnt),
+[C_PIO_WRITE_CROSSES_BOUNDARY_ERR] = CNTR_ELEM("PioWriteCrossesBoundaryErr",
+                       0, 0, CNTR_NORMAL,
+                       access_pio_write_crosses_boundary_err_cnt),
+[C_PIO_DISALLOWED_PACKET_ERR] = CNTR_ELEM("PioDisallowedPacketErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_pio_disallowed_packet_err_cnt),
+[C_PIO_INCONSISTENT_SOP_ERR] = CNTR_ELEM("PioInconsistentSopErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_pio_inconsistent_sop_err_cnt),
+/* SendDmaEngErrStatus */
+[C_SDMA_HEADER_REQUEST_FIFO_COR_ERR] = CNTR_ELEM("SDmaHeaderRequestFifoCorErr",
+                       0, 0, CNTR_NORMAL,
+                       access_sdma_header_request_fifo_cor_err_cnt),
+[C_SDMA_HEADER_STORAGE_COR_ERR] = CNTR_ELEM("SDmaHeaderStorageCorErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_sdma_header_storage_cor_err_cnt),
+[C_SDMA_PACKET_TRACKING_COR_ERR] = CNTR_ELEM("SDmaPacketTrackingCorErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_sdma_packet_tracking_cor_err_cnt),
+[C_SDMA_ASSEMBLY_COR_ERR] = CNTR_ELEM("SDmaAssemblyCorErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_sdma_assembly_cor_err_cnt),
+[C_SDMA_DESC_TABLE_COR_ERR] = CNTR_ELEM("SDmaDescTableCorErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_sdma_desc_table_cor_err_cnt),
+[C_SDMA_HEADER_REQUEST_FIFO_UNC_ERR] = CNTR_ELEM("SDmaHeaderRequestFifoUncErr",
+                       0, 0, CNTR_NORMAL,
+                       access_sdma_header_request_fifo_unc_err_cnt),
+[C_SDMA_HEADER_STORAGE_UNC_ERR] = CNTR_ELEM("SDmaHeaderStorageUncErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_sdma_header_storage_unc_err_cnt),
+[C_SDMA_PACKET_TRACKING_UNC_ERR] = CNTR_ELEM("SDmaPacketTrackingUncErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_sdma_packet_tracking_unc_err_cnt),
+[C_SDMA_ASSEMBLY_UNC_ERR] = CNTR_ELEM("SDmaAssemblyUncErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_sdma_assembly_unc_err_cnt),
+[C_SDMA_DESC_TABLE_UNC_ERR] = CNTR_ELEM("SDmaDescTableUncErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_sdma_desc_table_unc_err_cnt),
+[C_SDMA_TIMEOUT_ERR] = CNTR_ELEM("SDmaTimeoutErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_sdma_timeout_err_cnt),
+[C_SDMA_HEADER_LENGTH_ERR] = CNTR_ELEM("SDmaHeaderLengthErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_sdma_header_length_err_cnt),
+[C_SDMA_HEADER_ADDRESS_ERR] = CNTR_ELEM("SDmaHeaderAddressErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_sdma_header_address_err_cnt),
+[C_SDMA_HEADER_SELECT_ERR] = CNTR_ELEM("SDmaHeaderSelectErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_sdma_header_select_err_cnt),
+[C_SMDA_RESERVED_9] = CNTR_ELEM("SDma Reserved 9", 0, 0,
+                       CNTR_NORMAL,
+                       access_sdma_reserved_9_err_cnt),
+[C_SDMA_PACKET_DESC_OVERFLOW_ERR] = CNTR_ELEM("SDmaPacketDescOverflowErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_sdma_packet_desc_overflow_err_cnt),
+[C_SDMA_LENGTH_MISMATCH_ERR] = CNTR_ELEM("SDmaLengthMismatchErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_sdma_length_mismatch_err_cnt),
+[C_SDMA_HALT_ERR] = CNTR_ELEM("SDmaHaltErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_sdma_halt_err_cnt),
+[C_SDMA_MEM_READ_ERR] = CNTR_ELEM("SDmaMemReadErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_sdma_mem_read_err_cnt),
+[C_SDMA_FIRST_DESC_ERR] = CNTR_ELEM("SDmaFirstDescErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_sdma_first_desc_err_cnt),
+[C_SDMA_TAIL_OUT_OF_BOUNDS_ERR] = CNTR_ELEM("SDmaTailOutOfBoundsErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_sdma_tail_out_of_bounds_err_cnt),
+[C_SDMA_TOO_LONG_ERR] = CNTR_ELEM("SDmaTooLongErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_sdma_too_long_err_cnt),
+[C_SDMA_GEN_MISMATCH_ERR] = CNTR_ELEM("SDmaGenMismatchErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_sdma_gen_mismatch_err_cnt),
+[C_SDMA_WRONG_DW_ERR] = CNTR_ELEM("SDmaWrongDwErr", 0, 0,
+                       CNTR_NORMAL,
+                       access_sdma_wrong_dw_err_cnt),
 };
 
 static struct cntr_entry port_cntrs[PORT_CNTR_LAST] = {
@@ -1762,6 +4890,8 @@ static struct cntr_entry port_cntrs[PORT_CNTR_LAST] = {
                        access_sw_link_dn_cnt),
 [C_SW_LINK_UP] = CNTR_ELEM("SwLinkUp", 0, 0, CNTR_SYNTH | CNTR_32BIT,
                        access_sw_link_up_cnt),
+[C_SW_UNKNOWN_FRAME] = CNTR_ELEM("UnknownFrame", 0, 0, CNTR_NORMAL,
+                                access_sw_unknown_frame_cnt),
 [C_SW_XMIT_DSCD] = CNTR_ELEM("XmitDscd", 0, 0, CNTR_SYNTH | CNTR_32BIT,
                        access_sw_xmit_discards),
 [C_SW_XMIT_DSCD_VL] = CNTR_ELEM("XmitDscdVl", 0, 0,
@@ -1873,13 +5003,6 @@ static struct cntr_entry port_cntrs[PORT_CNTR_LAST] = {
 
 /* ======================================================================== */
 
-/* return true if this is chip revision revision a0 */
-int is_a0(struct hfi1_devdata *dd)
-{
-       return ((dd->revision >> CCE_REVISION_CHIP_REV_MINOR_SHIFT)
-                       & CCE_REVISION_CHIP_REV_MINOR_MASK) == 0;
-}
-
 /* return true if this is chip revision revision a */
 int is_ax(struct hfi1_devdata *dd)
 {
@@ -1895,7 +5018,7 @@ int is_bx(struct hfi1_devdata *dd)
        u8 chip_rev_minor =
                dd->revision >> CCE_REVISION_CHIP_REV_MINOR_SHIFT
                        & CCE_REVISION_CHIP_REV_MINOR_MASK;
-       return !!(chip_rev_minor & 0x10);
+       return (chip_rev_minor & 0xF0) == 0x10;
 }
 
 /*
@@ -2182,6 +5305,7 @@ static char *send_err_status_string(char *buf, int buf_len, u64 flags)
 static void handle_cce_err(struct hfi1_devdata *dd, u32 unused, u64 reg)
 {
        char buf[96];
+       int i = 0;
 
        /*
         * For most these errors, there is nothing that can be done except
@@ -2190,13 +5314,20 @@ static void handle_cce_err(struct hfi1_devdata *dd, u32 unused, u64 reg)
        dd_dev_info(dd, "CCE Error: %s\n",
                cce_err_status_string(buf, sizeof(buf), reg));
 
-       if ((reg & CCE_ERR_STATUS_CCE_CLI2_ASYNC_FIFO_PARITY_ERR_SMASK)
-                       && is_a0(dd)
-                       && (dd->icode != ICODE_FUNCTIONAL_SIMULATOR)) {
+       if ((reg & CCE_ERR_STATUS_CCE_CLI2_ASYNC_FIFO_PARITY_ERR_SMASK) &&
+           is_ax(dd) && (dd->icode != ICODE_FUNCTIONAL_SIMULATOR)) {
                /* this error requires a manual drop into SPC freeze mode */
                /* then a fix up */
                start_freeze_handling(dd->pport, FREEZE_SELF);
        }
+
+       for (i = 0; i < NUM_CCE_ERR_STATUS_COUNTERS; i++) {
+               if (reg & (1ull << i)) {
+                       incr_cntr64(&dd->cce_err_status_cnt[i]);
+                       /* maintain a counter over all cce_err_status errors */
+                       incr_cntr64(&dd->sw_cce_err_status_aggregate);
+               }
+       }
 }
 
 /*
@@ -2241,6 +5372,7 @@ static void free_rcverr(struct hfi1_devdata *dd)
 static void handle_rxe_err(struct hfi1_devdata *dd, u32 unused, u64 reg)
 {
        char buf[96];
+       int i = 0;
 
        dd_dev_info(dd, "Receive Error: %s\n",
                rxe_err_status_string(buf, sizeof(buf), reg));
@@ -2252,41 +5384,63 @@ static void handle_rxe_err(struct hfi1_devdata *dd, u32 unused, u64 reg)
                 * Freeze mode recovery is disabled for the errors
                 * in RXE_FREEZE_ABORT_MASK
                 */
-               if (is_a0(dd) && (reg & RXE_FREEZE_ABORT_MASK))
+               if (is_ax(dd) && (reg & RXE_FREEZE_ABORT_MASK))
                        flags = FREEZE_ABORT;
 
                start_freeze_handling(dd->pport, flags);
        }
+
+       for (i = 0; i < NUM_RCV_ERR_STATUS_COUNTERS; i++) {
+               if (reg & (1ull << i))
+                       incr_cntr64(&dd->rcv_err_status_cnt[i]);
+       }
 }
 
 static void handle_misc_err(struct hfi1_devdata *dd, u32 unused, u64 reg)
 {
        char buf[96];
+       int i = 0;
 
        dd_dev_info(dd, "Misc Error: %s",
                misc_err_status_string(buf, sizeof(buf), reg));
+       for (i = 0; i < NUM_MISC_ERR_STATUS_COUNTERS; i++) {
+               if (reg & (1ull << i))
+                       incr_cntr64(&dd->misc_err_status_cnt[i]);
+       }
 }
 
 static void handle_pio_err(struct hfi1_devdata *dd, u32 unused, u64 reg)
 {
        char buf[96];
+       int i = 0;
 
        dd_dev_info(dd, "PIO Error: %s\n",
                pio_err_status_string(buf, sizeof(buf), reg));
 
        if (reg & ALL_PIO_FREEZE_ERR)
                start_freeze_handling(dd->pport, 0);
+
+       for (i = 0; i < NUM_SEND_PIO_ERR_STATUS_COUNTERS; i++) {
+               if (reg & (1ull << i))
+                       incr_cntr64(&dd->send_pio_err_status_cnt[i]);
+       }
 }
 
 static void handle_sdma_err(struct hfi1_devdata *dd, u32 unused, u64 reg)
 {
        char buf[96];
+       int i = 0;
 
        dd_dev_info(dd, "SDMA Error: %s\n",
                sdma_err_status_string(buf, sizeof(buf), reg));
 
        if (reg & ALL_SDMA_FREEZE_ERR)
                start_freeze_handling(dd->pport, 0);
+
+       for (i = 0; i < NUM_SEND_DMA_ERR_STATUS_COUNTERS; i++) {
+               if (reg & (1ull << i))
+                       incr_cntr64(&dd->send_dma_err_status_cnt[i]);
+       }
 }
 
 static void count_port_inactive(struct hfi1_devdata *dd)
@@ -2352,10 +5506,11 @@ static void handle_egress_err(struct hfi1_devdata *dd, u32 unused, u64 reg)
 {
        u64 reg_copy = reg, handled = 0;
        char buf[96];
+       int i = 0;
 
        if (reg & ALL_TXE_EGRESS_FREEZE_ERR)
                start_freeze_handling(dd->pport, 0);
-       if (is_a0(dd) && (reg &
+       if (is_ax(dd) && (reg &
                    SEND_EGRESS_ERR_STATUS_TX_CREDIT_RETURN_VL_ERR_SMASK)
                    && (dd->icode != ICODE_FUNCTIONAL_SIMULATOR))
                start_freeze_handling(dd->pport, 0);
@@ -2383,15 +5538,25 @@ static void handle_egress_err(struct hfi1_devdata *dd, u32 unused, u64 reg)
        if (reg)
                dd_dev_info(dd, "Egress Error: %s\n",
                        egress_err_status_string(buf, sizeof(buf), reg));
+
+       for (i = 0; i < NUM_SEND_EGRESS_ERR_STATUS_COUNTERS; i++) {
+               if (reg & (1ull << i))
+                       incr_cntr64(&dd->send_egress_err_status_cnt[i]);
+       }
 }
 
 static void handle_txe_err(struct hfi1_devdata *dd, u32 unused, u64 reg)
 {
        char buf[96];
+       int i = 0;
 
        dd_dev_info(dd, "Send Error: %s\n",
                send_err_status_string(buf, sizeof(buf), reg));
 
+       for (i = 0; i < NUM_SEND_ERR_STATUS_COUNTERS; i++) {
+               if (reg & (1ull << i))
+                       incr_cntr64(&dd->send_err_status_cnt[i]);
+       }
 }
 
 /*
@@ -2483,6 +5648,7 @@ static void is_sendctxt_err_int(struct hfi1_devdata *dd,
        char flags[96];
        u64 status;
        u32 sw_index;
+       int i = 0;
 
        sw_index = dd->hw_to_sw[hw_context];
        if (sw_index >= dd->num_send_contexts) {
@@ -2516,12 +5682,23 @@ static void is_sendctxt_err_int(struct hfi1_devdata *dd,
         */
        if (sc->type != SC_USER)
                queue_work(dd->pport->hfi1_wq, &sc->halt_work);
+
+       /*
+        * Update the counters for the corresponding status bits.
+        * Note that these particular counters are aggregated over all
+        * 160 contexts.
+        */
+       for (i = 0; i < NUM_SEND_CTXT_ERR_STATUS_COUNTERS; i++) {
+               if (status & (1ull << i))
+                       incr_cntr64(&dd->sw_ctxt_err_status_cnt[i]);
+       }
 }
 
 static void handle_sdma_eng_err(struct hfi1_devdata *dd,
                                unsigned int source, u64 status)
 {
        struct sdma_engine *sde;
+       int i = 0;
 
        sde = &dd->per_sdma[source];
 #ifdef CONFIG_SDMA_VERBOSITY
@@ -2531,6 +5708,16 @@ static void handle_sdma_eng_err(struct hfi1_devdata *dd,
                   sde->this_idx, source, (unsigned long long)status);
 #endif
        sdma_engine_error(sde, status);
+
+       /*
+       * Update the counters for the corresponding status bits.
+       * Note that these particular counters are aggregated over
+       * all 16 DMA engines.
+       */
+       for (i = 0; i < NUM_SEND_DMA_ENG_ERR_STATUS_COUNTERS; i++) {
+               if (status & (1ull << i))
+                       incr_cntr64(&dd->sw_send_dma_eng_err_status_cnt[i]);
+       }
 }
 
 /*
@@ -3050,7 +6237,7 @@ static void adjust_lcb_for_fpga_serdes(struct hfi1_devdata *dd)
        /* else this is _p */
 
        version = emulator_rev(dd);
-       if (!is_a0(dd))
+       if (!is_ax(dd))
                version = 0x2d; /* all B0 use 0x2d or higher settings */
 
        if (version <= 0x12) {
@@ -3313,7 +6500,6 @@ void handle_freeze(struct work_struct *work)
        struct hfi1_devdata *dd = ppd->dd;
 
        /* wait for freeze indicators on all affected blocks */
-       dd_dev_info(dd, "Entering SPC freeze\n");
        wait_for_freeze_status(dd, 1);
 
        /* SPC is now frozen */
@@ -3336,7 +6522,7 @@ void handle_freeze(struct work_struct *work)
        write_csr(dd, CCE_CTRL, CCE_CTRL_SPC_UNFREEZE_SMASK);
        wait_for_freeze_status(dd, 0);
 
-       if (is_a0(dd)) {
+       if (is_ax(dd)) {
                write_csr(dd, CCE_CTRL, CCE_CTRL_SPC_FREEZE_SMASK);
                wait_for_freeze_status(dd, 1);
                write_csr(dd, CCE_CTRL, CCE_CTRL_SPC_UNFREEZE_SMASK);
@@ -3371,7 +6557,6 @@ void handle_freeze(struct work_struct *work)
        wake_up(&dd->event_queue);
 
        /* no longer frozen */
-       dd_dev_err(dd, "Exiting SPC freeze\n");
 }
 
 /*
@@ -3542,10 +6727,10 @@ static void add_full_mgmt_pkey(struct hfi1_pportdata *ppd)
 {
        struct hfi1_devdata *dd = ppd->dd;
 
-       /* Sanity check - ppd->pkeys[2] should be 0 */
-       if (ppd->pkeys[2] != 0)
-               dd_dev_err(dd, "%s pkey[2] already set to 0x%x, resetting it to 0x%x\n",
-                          __func__, ppd->pkeys[2], FULL_MGMT_P_KEY);
+       /* Sanity check - ppd->pkeys[2] should be 0, or already initalized */
+       if (!((ppd->pkeys[2] == 0) || (ppd->pkeys[2] == FULL_MGMT_P_KEY)))
+               dd_dev_warn(dd, "%s pkey[2] already set to 0x%x, resetting it to 0x%x\n",
+                           __func__, ppd->pkeys[2], FULL_MGMT_P_KEY);
        ppd->pkeys[2] = FULL_MGMT_P_KEY;
        (void)hfi1_set_ib_cfg(ppd, HFI1_IB_CFG_PKEYS, 0);
 }
@@ -3864,7 +7049,7 @@ void handle_verify_cap(struct work_struct *work)
         *      REPLAY_BUF_MBE_SMASK
         *      FLIT_INPUT_BUF_MBE_SMASK
         */
-       if (is_a0(dd)) {                        /* fixed in B0 */
+       if (is_ax(dd)) {                        /* fixed in B0 */
                reg = read_csr(dd, DC_LCB_CFG_LINK_KILL_EN);
                reg |= DC_LCB_CFG_LINK_KILL_EN_REPLAY_BUF_MBE_SMASK
                        | DC_LCB_CFG_LINK_KILL_EN_FLIT_INPUT_BUF_MBE_SMASK;
@@ -3907,18 +7092,32 @@ void handle_verify_cap(struct work_struct *work)
  */
 void apply_link_downgrade_policy(struct hfi1_pportdata *ppd, int refresh_widths)
 {
-       int skip = 1;
        int do_bounce = 0;
-       u16 lwde = ppd->link_width_downgrade_enabled;
+       int tries;
+       u16 lwde;
        u16 tx, rx;
 
+       /* use the hls lock to avoid a race with actual link up */
+       tries = 0;
+retry:
        mutex_lock(&ppd->hls_lock);
        /* only apply if the link is up */
-       if (ppd->host_link_state & HLS_UP)
-               skip = 0;
-       mutex_unlock(&ppd->hls_lock);
-       if (skip)
-               return;
+       if (!(ppd->host_link_state & HLS_UP)) {
+               /* still going up..wait and retry */
+               if (ppd->host_link_state & HLS_GOING_UP) {
+                       if (++tries < 1000) {
+                               mutex_unlock(&ppd->hls_lock);
+                               usleep_range(100, 120); /* arbitrary */
+                               goto retry;
+                       }
+                       dd_dev_err(ppd->dd,
+                                  "%s: giving up waiting for link state change\n",
+                                  __func__);
+               }
+               goto done;
+       }
+
+       lwde = ppd->link_width_downgrade_enabled;
 
        if (refresh_widths) {
                get_link_widths(ppd->dd, &tx, &rx);
@@ -3956,6 +7155,9 @@ void apply_link_downgrade_policy(struct hfi1_pportdata *ppd, int refresh_widths)
                do_bounce = 1;
        }
 
+done:
+       mutex_unlock(&ppd->hls_lock);
+
        if (do_bounce) {
                set_link_down_reason(ppd, OPA_LINKDOWN_REASON_WIDTH_POLICY, 0,
                  OPA_LINKDOWN_REASON_WIDTH_POLICY);
@@ -4046,6 +7248,11 @@ static void handle_8051_interrupt(struct hfi1_devdata *dd, u32 unused, u64 reg)
                        }
                        err &= ~(u64)FAILED_LNI;
                }
+               /* unknown frames can happen durning LNI, just count */
+               if (err & UNKNOWN_FRAME) {
+                       ppd->unknown_frame_count++;
+                       err &= ~(u64)UNKNOWN_FRAME;
+               }
                if (err) {
                        /* report remaining errors, but do not do anything */
                        dd_dev_err(dd, "8051 info error: %s\n",
@@ -5888,6 +9095,23 @@ void init_qsfp(struct hfi1_pportdata *ppd)
        }
 }
 
+/*
+ * Do a one-time initialize of the LCB block.
+ */
+static void init_lcb(struct hfi1_devdata *dd)
+{
+       /* the DC has been reset earlier in the driver load */
+
+       /* set LCB for cclk loopback on the port */
+       write_csr(dd, DC_LCB_CFG_TX_FIFOS_RESET, 0x01);
+       write_csr(dd, DC_LCB_CFG_LANE_WIDTH, 0x00);
+       write_csr(dd, DC_LCB_CFG_REINIT_AS_SLAVE, 0x00);
+       write_csr(dd, DC_LCB_CFG_CNT_FOR_SKIP_STALL, 0x110);
+       write_csr(dd, DC_LCB_CFG_CLK_CNTR, 0x08);
+       write_csr(dd, DC_LCB_CFG_LOOPBACK, 0x02);
+       write_csr(dd, DC_LCB_CFG_TX_FIFOS_RESET, 0x00);
+}
+
 int bringup_serdes(struct hfi1_pportdata *ppd)
 {
        struct hfi1_devdata *dd = ppd->dd;
@@ -5909,6 +9133,9 @@ int bringup_serdes(struct hfi1_pportdata *ppd)
        /* Set linkinit_reason on power up per OPA spec */
        ppd->linkinit_reason = OPA_LINKINIT_REASON_LINKUP;
 
+       /* one-time init of the LCB */
+       init_lcb(dd);
+
        if (loopback) {
                ret = init_loopback(dd);
                if (ret < 0)
@@ -6180,7 +9407,8 @@ u32 lrh_max_header_bytes(struct hfi1_devdata *dd)
 static void set_send_length(struct hfi1_pportdata *ppd)
 {
        struct hfi1_devdata *dd = ppd->dd;
-       u32 max_hb = lrh_max_header_bytes(dd), maxvlmtu = 0, dcmtu;
+       u32 max_hb = lrh_max_header_bytes(dd), dcmtu;
+       u32 maxvlmtu = dd->vld[15].mtu;
        u64 len1 = 0, len2 = (((dd->vld[15].mtu + max_hb) >> 2)
                              & SEND_LEN_CHECK1_LEN_VL15_MASK) <<
                SEND_LEN_CHECK1_LEN_VL15_SHIFT;
@@ -6351,9 +9579,10 @@ static int goto_offline(struct hfi1_pportdata *ppd, u8 rem_reason)
         * depending on how the link went down.  The 8051 firmware
         * will observe the needed wait time and only move to ready
         * when that is completed.  The largest of the quiet timeouts
-        * is 2.5s, so wait that long and then a bit more.
+        * is 6s, so wait that long and then at least 0.5s more for
+        * other transitions, and another 0.5s for a buffer.
         */
-       ret = wait_fm_ready(dd, 3000);
+       ret = wait_fm_ready(dd, 7000);
        if (ret) {
                dd_dev_err(dd,
                        "After going offline, timed out waiting for the 8051 to become ready to accept host requests\n");
@@ -7267,8 +10496,7 @@ static int set_buffer_control(struct hfi1_devdata *dd,
                new_bc->vl[i].shared = 0;
        }
        new_total += be16_to_cpu(new_bc->overall_shared_limit);
-       if (new_total > (u32)dd->link_credits)
-               return -EINVAL;
+
        /* fetch the current values */
        get_buffer_control(dd, &cur_bc, &cur_total);
 
@@ -7314,8 +10542,8 @@ static int set_buffer_control(struct hfi1_devdata *dd,
         */
        use_all_mask = 0;
        if ((be16_to_cpu(new_bc->overall_shared_limit) <
-                               be16_to_cpu(cur_bc.overall_shared_limit))
-                       || (is_a0(dd) && any_shared_limit_changing)) {
+            be16_to_cpu(cur_bc.overall_shared_limit)) ||
+           (is_ax(dd) && any_shared_limit_changing)) {
                set_global_shared(dd, 0);
                cur_bc.overall_shared_limit = 0;
                use_all_mask = 1;
@@ -7489,7 +10717,7 @@ int fm_set_table(struct hfi1_pportdata *ppd, int which, void *t)
  */
 static int disable_data_vls(struct hfi1_devdata *dd)
 {
-       if (is_a0(dd))
+       if (is_ax(dd))
                return 1;
 
        pio_send_control(dd, PSC_DATA_VL_DISABLE);
@@ -7507,7 +10735,7 @@ static int disable_data_vls(struct hfi1_devdata *dd)
  */
 int open_fill_data_vls(struct hfi1_devdata *dd)
 {
-       if (is_a0(dd))
+       if (is_ax(dd))
                return 1;
 
        pio_send_control(dd, PSC_DATA_VL_ENABLE);
@@ -8888,8 +12116,8 @@ static int request_intx_irq(struct hfi1_devdata *dd)
 {
        int ret;
 
-       snprintf(dd->intx_name, sizeof(dd->intx_name), DRIVER_NAME"_%d",
-               dd->unit);
+       snprintf(dd->intx_name, sizeof(dd->intx_name), DRIVER_NAME "_%d",
+                dd->unit);
        ret = request_irq(dd->pcidev->irq, general_interrupt,
                                  IRQF_SHARED, dd->intx_name, dd);
        if (ret)
@@ -8988,7 +12216,7 @@ static int request_msix_irqs(struct hfi1_devdata *dd)
                        handler = general_interrupt;
                        arg = dd;
                        snprintf(me->name, sizeof(me->name),
-                               DRIVER_NAME"_%d", dd->unit);
+                                DRIVER_NAME "_%d", dd->unit);
                        err_info = "general";
                } else if (first_sdma <= i && i < last_sdma) {
                        idx = i - first_sdma;
@@ -8996,7 +12224,7 @@ static int request_msix_irqs(struct hfi1_devdata *dd)
                        handler = sdma_interrupt;
                        arg = sde;
                        snprintf(me->name, sizeof(me->name),
-                               DRIVER_NAME"_%d sdma%d", dd->unit, idx);
+                                DRIVER_NAME "_%d sdma%d", dd->unit, idx);
                        err_info = "sdma";
                        remap_sdma_interrupts(dd, idx, i);
                } else if (first_rx <= i && i < last_rx) {
@@ -9016,7 +12244,7 @@ static int request_msix_irqs(struct hfi1_devdata *dd)
                        thread = receive_context_thread;
                        arg = rcd;
                        snprintf(me->name, sizeof(me->name),
-                               DRIVER_NAME"_%d kctxt%d", dd->unit, idx);
+                                DRIVER_NAME "_%d kctxt%d", dd->unit, idx);
                        err_info = "receive context";
                        remap_intr(dd, IS_RCVAVAIL_START + idx, i);
                } else {
@@ -9197,7 +12425,6 @@ fail:
 static int set_up_context_variables(struct hfi1_devdata *dd)
 {
        int num_kernel_contexts;
-       int num_user_contexts;
        int total_contexts;
        int ret;
        unsigned ngroups;
@@ -9234,12 +12461,10 @@ static int set_up_context_variables(struct hfi1_devdata *dd)
        }
        /*
         * User contexts: (to be fixed later)
-        *      - set to num_rcv_contexts if non-zero
-        *      - default to 1 user context per CPU
+        *      - default to 1 user context per CPU if num_user_contexts is
+        *        negative
         */
-       if (num_rcv_contexts)
-               num_user_contexts = num_rcv_contexts;
-       else
+       if (num_user_contexts < 0)
                num_user_contexts = num_online_cpus();
 
        total_contexts = num_kernel_contexts + num_user_contexts;
@@ -9957,7 +13182,7 @@ static void init_chip(struct hfi1_devdata *dd)
                /* restore command and BARs */
                restore_pci_variables(dd);
 
-               if (is_a0(dd)) {
+               if (is_ax(dd)) {
                        dd_dev_info(dd, "Resetting CSRs with FLR\n");
                        hfi1_pcie_flr(dd);
                        restore_pci_variables(dd);
@@ -9976,7 +13201,7 @@ static void init_chip(struct hfi1_devdata *dd)
        write_csr(dd, CCE_DC_CTRL, 0);
 
        /* Set the LED off */
-       if (is_a0(dd))
+       if (is_ax(dd))
                setextled(dd, 0);
        /*
         * Clear the QSFP reset.
@@ -9999,7 +13224,7 @@ static void init_early_variables(struct hfi1_devdata *dd)
        /* assign link credit variables */
        dd->vau = CM_VAU;
        dd->link_credits = CM_GLOBAL_CREDITS;
-       if (is_a0(dd))
+       if (is_ax(dd))
                dd->link_credits--;
        dd->vcu = cu_to_vcu(hfi1_cu);
        /* enough room for 8 MAD packets plus header - 17K */
@@ -10107,7 +13332,7 @@ static void init_qos(struct hfi1_devdata *dd, u32 first_ctxt)
        unsigned qpns_per_vl, ctxt, i, qpn, n = 1, m;
        u64 *rsmmap;
        u64 reg;
-       u8  rxcontext = is_a0(dd) ? 0 : 0xff;  /* 0 is default if a0 ver. */
+       u8  rxcontext = is_ax(dd) ? 0 : 0xff;  /* 0 is default if a0 ver. */
 
        /* validate */
        if (dd->n_krcv_queues <= MIN_KERNEL_KCTXTS ||
@@ -10129,6 +13354,8 @@ static void init_qos(struct hfi1_devdata *dd, u32 first_ctxt)
        if (num_vls * qpns_per_vl > dd->chip_rcv_contexts)
                goto bail;
        rsmmap = kmalloc_array(NUM_MAP_REGS, sizeof(u64), GFP_KERNEL);
+       if (!rsmmap)
+               goto bail;
        memset(rsmmap, rxcontext, NUM_MAP_REGS * sizeof(u64));
        /* init the local copy of the table */
        for (i = 0, ctxt = first_ctxt; i < num_vls; i++) {
@@ -10312,7 +13539,7 @@ int hfi1_set_ctxt_jkey(struct hfi1_devdata *dd, unsigned ctxt, u16 jkey)
         * Enable send-side J_KEY integrity check, unless this is A0 h/w
         * (due to A0 erratum).
         */
-       if (!is_a0(dd)) {
+       if (!is_ax(dd)) {
                reg = read_kctxt_csr(dd, sctxt, SEND_CTXT_CHECK_ENABLE);
                reg |= SEND_CTXT_CHECK_ENABLE_CHECK_JOB_KEY_SMASK;
                write_kctxt_csr(dd, sctxt, SEND_CTXT_CHECK_ENABLE, reg);
@@ -10345,7 +13572,7 @@ int hfi1_clear_ctxt_jkey(struct hfi1_devdata *dd, unsigned ctxt)
         * This check would not have been enabled for A0 h/w, see
         * set_ctxt_jkey().
         */
-       if (!is_a0(dd)) {
+       if (!is_ax(dd)) {
                reg = read_kctxt_csr(dd, sctxt, SEND_CTXT_CHECK_ENABLE);
                reg &= ~SEND_CTXT_CHECK_ENABLE_CHECK_JOB_KEY_SMASK;
                write_kctxt_csr(dd, sctxt, SEND_CTXT_CHECK_ENABLE, reg);
@@ -10454,6 +13681,32 @@ static void asic_should_init(struct hfi1_devdata *dd)
        spin_unlock_irqrestore(&hfi1_devs_lock, flags);
 }
 
+/*
+ * Set dd->boardname.  Use a generic name if a name is not returned from
+ * EFI variable space.
+ *
+ * Return 0 on success, -ENOMEM if space could not be allocated.
+ */
+static int obtain_boardname(struct hfi1_devdata *dd)
+{
+       /* generic board description */
+       const char generic[] =
+               "Intel Omni-Path Host Fabric Interface Adapter 100 Series";
+       unsigned long size;
+       int ret;
+
+       ret = read_hfi1_efi_var(dd, "description", &size,
+                               (void **)&dd->boardname);
+       if (ret) {
+               dd_dev_err(dd, "Board description not found\n");
+               /* use generic description */
+               dd->boardname = kstrdup(generic, GFP_KERNEL);
+               if (!dd->boardname)
+                       return -ENOMEM;
+       }
+       return 0;
+}
+
 /**
  * Allocate and initialize the device structure for the hfi.
  * @dev: the pci_dev for hfi1_ib device
@@ -10590,9 +13843,9 @@ struct hfi1_devdata *hfi1_init_dd(struct pci_dev *pdev,
        /* insure num_vls isn't larger than number of sdma engines */
        if (HFI1_CAP_IS_KSET(SDMA) && num_vls > dd->chip_sdma_engines) {
                dd_dev_err(dd, "num_vls %u too large, using %u VLs\n",
-                               num_vls, HFI1_MAX_VLS_SUPPORTED);
-               ppd->vls_supported = num_vls = HFI1_MAX_VLS_SUPPORTED;
-               ppd->vls_operational = ppd->vls_supported;
+                          num_vls, dd->chip_sdma_engines);
+               num_vls = dd->chip_sdma_engines;
+               ppd->vls_supported = dd->chip_sdma_engines;
        }
 
        /*
@@ -10651,18 +13904,13 @@ struct hfi1_devdata *hfi1_init_dd(struct pci_dev *pdev,
 
        parse_platform_config(dd);
 
-       /* add board names as they are defined */
-       dd->boardname = kmalloc(64, GFP_KERNEL);
-       if (!dd->boardname)
+       ret = obtain_boardname(dd);
+       if (ret)
                goto bail_cleanup;
-       snprintf(dd->boardname, 64, "Board ID 0x%llx",
-                dd->revision >> CCE_REVISION_BOARD_ID_LOWER_NIBBLE_SHIFT
-                   & CCE_REVISION_BOARD_ID_LOWER_NIBBLE_MASK);
 
        snprintf(dd->boardversion, BOARD_VERS_MAX,
-                "ChipABI %u.%u, %s, ChipRev %u.%u, SW Compat %llu\n",
+                "ChipABI %u.%u, ChipRev %u.%u, SW Compat %llu\n",
                 HFI1_CHIP_VERS_MAJ, HFI1_CHIP_VERS_MIN,
-                dd->boardname,
                 (u32)dd->majrev,
                 (u32)dd->minrev,
                 (dd->revision >> CCE_REVISION_SW_SHIFT)
index d74aed8ccc18db7d380d38949fbdc5093880d9c1..5b375ddc345d88bb8441f20bd1c7274669f8722e 100644 (file)
@@ -664,7 +664,6 @@ void get_linkup_link_widths(struct hfi1_pportdata *ppd);
 void read_ltp_rtt(struct hfi1_devdata *dd);
 void clear_linkup_counters(struct hfi1_devdata *dd);
 u32 hdrqempty(struct hfi1_ctxtdata *rcd);
-int is_a0(struct hfi1_devdata *dd);
 int is_ax(struct hfi1_devdata *dd);
 int is_bx(struct hfi1_devdata *dd);
 u32 read_physical_state(struct hfi1_devdata *dd);
@@ -722,7 +721,6 @@ enum {
        C_RX_TID_FULL,
        C_RX_TID_INVALID,
        C_RX_TID_FLGMS,
-       C_RX_CTX_RHQS,
        C_RX_CTX_EGRS,
        C_RCV_TID_FLSMS,
        C_CCE_PCI_CR_ST,
@@ -789,6 +787,275 @@ enum {
        C_SW_PIO_WAIT,
        C_SW_KMEM_WAIT,
        C_SW_SEND_SCHED,
+/* MISC_ERR_STATUS */
+       C_MISC_PLL_LOCK_FAIL_ERR,
+       C_MISC_MBIST_FAIL_ERR,
+       C_MISC_INVALID_EEP_CMD_ERR,
+       C_MISC_EFUSE_DONE_PARITY_ERR,
+       C_MISC_EFUSE_WRITE_ERR,
+       C_MISC_EFUSE_READ_BAD_ADDR_ERR,
+       C_MISC_EFUSE_CSR_PARITY_ERR,
+       C_MISC_FW_AUTH_FAILED_ERR,
+       C_MISC_KEY_MISMATCH_ERR,
+       C_MISC_SBUS_WRITE_FAILED_ERR,
+       C_MISC_CSR_WRITE_BAD_ADDR_ERR,
+       C_MISC_CSR_READ_BAD_ADDR_ERR,
+       C_MISC_CSR_PARITY_ERR,
+/* CceErrStatus */
+       /*
+       * A special counter that is the aggregate count
+       * of all the cce_err_status errors.  The remainder
+       * are actual bits in the CceErrStatus register.
+       */
+       C_CCE_ERR_STATUS_AGGREGATED_CNT,
+       C_CCE_MSIX_CSR_PARITY_ERR,
+       C_CCE_INT_MAP_UNC_ERR,
+       C_CCE_INT_MAP_COR_ERR,
+       C_CCE_MSIX_TABLE_UNC_ERR,
+       C_CCE_MSIX_TABLE_COR_ERR,
+       C_CCE_RXDMA_CONV_FIFO_PARITY_ERR,
+       C_CCE_RCPL_ASYNC_FIFO_PARITY_ERR,
+       C_CCE_SEG_WRITE_BAD_ADDR_ERR,
+       C_CCE_SEG_READ_BAD_ADDR_ERR,
+       C_LA_TRIGGERED,
+       C_CCE_TRGT_CPL_TIMEOUT_ERR,
+       C_PCIC_RECEIVE_PARITY_ERR,
+       C_PCIC_TRANSMIT_BACK_PARITY_ERR,
+       C_PCIC_TRANSMIT_FRONT_PARITY_ERR,
+       C_PCIC_CPL_DAT_Q_UNC_ERR,
+       C_PCIC_CPL_HD_Q_UNC_ERR,
+       C_PCIC_POST_DAT_Q_UNC_ERR,
+       C_PCIC_POST_HD_Q_UNC_ERR,
+       C_PCIC_RETRY_SOT_MEM_UNC_ERR,
+       C_PCIC_RETRY_MEM_UNC_ERR,
+       C_PCIC_N_POST_DAT_Q_PARITY_ERR,
+       C_PCIC_N_POST_H_Q_PARITY_ERR,
+       C_PCIC_CPL_DAT_Q_COR_ERR,
+       C_PCIC_CPL_HD_Q_COR_ERR,
+       C_PCIC_POST_DAT_Q_COR_ERR,
+       C_PCIC_POST_HD_Q_COR_ERR,
+       C_PCIC_RETRY_SOT_MEM_COR_ERR,
+       C_PCIC_RETRY_MEM_COR_ERR,
+       C_CCE_CLI1_ASYNC_FIFO_DBG_PARITY_ERR,
+       C_CCE_CLI1_ASYNC_FIFO_RXDMA_PARITY_ERR,
+       C_CCE_CLI1_ASYNC_FIFO_SDMA_HD_PARITY_ERR,
+       C_CCE_CLI1_ASYNC_FIFO_PIO_CRDT_PARITY_ERR,
+       C_CCE_CLI2_ASYNC_FIFO_PARITY_ERR,
+       C_CCE_CSR_CFG_BUS_PARITY_ERR,
+       C_CCE_CLI0_ASYNC_FIFO_PARTIY_ERR,
+       C_CCE_RSPD_DATA_PARITY_ERR,
+       C_CCE_TRGT_ACCESS_ERR,
+       C_CCE_TRGT_ASYNC_FIFO_PARITY_ERR,
+       C_CCE_CSR_WRITE_BAD_ADDR_ERR,
+       C_CCE_CSR_READ_BAD_ADDR_ERR,
+       C_CCE_CSR_PARITY_ERR,
+/* RcvErrStatus */
+       C_RX_CSR_PARITY_ERR,
+       C_RX_CSR_WRITE_BAD_ADDR_ERR,
+       C_RX_CSR_READ_BAD_ADDR_ERR,
+       C_RX_DMA_CSR_UNC_ERR,
+       C_RX_DMA_DQ_FSM_ENCODING_ERR,
+       C_RX_DMA_EQ_FSM_ENCODING_ERR,
+       C_RX_DMA_CSR_PARITY_ERR,
+       C_RX_RBUF_DATA_COR_ERR,
+       C_RX_RBUF_DATA_UNC_ERR,
+       C_RX_DMA_DATA_FIFO_RD_COR_ERR,
+       C_RX_DMA_DATA_FIFO_RD_UNC_ERR,
+       C_RX_DMA_HDR_FIFO_RD_COR_ERR,
+       C_RX_DMA_HDR_FIFO_RD_UNC_ERR,
+       C_RX_RBUF_DESC_PART2_COR_ERR,
+       C_RX_RBUF_DESC_PART2_UNC_ERR,
+       C_RX_RBUF_DESC_PART1_COR_ERR,
+       C_RX_RBUF_DESC_PART1_UNC_ERR,
+       C_RX_HQ_INTR_FSM_ERR,
+       C_RX_HQ_INTR_CSR_PARITY_ERR,
+       C_RX_LOOKUP_CSR_PARITY_ERR,
+       C_RX_LOOKUP_RCV_ARRAY_COR_ERR,
+       C_RX_LOOKUP_RCV_ARRAY_UNC_ERR,
+       C_RX_LOOKUP_DES_PART2_PARITY_ERR,
+       C_RX_LOOKUP_DES_PART1_UNC_COR_ERR,
+       C_RX_LOOKUP_DES_PART1_UNC_ERR,
+       C_RX_RBUF_NEXT_FREE_BUF_COR_ERR,
+       C_RX_RBUF_NEXT_FREE_BUF_UNC_ERR,
+       C_RX_RBUF_FL_INIT_WR_ADDR_PARITY_ERR,
+       C_RX_RBUF_FL_INITDONE_PARITY_ERR,
+       C_RX_RBUF_FL_WRITE_ADDR_PARITY_ERR,
+       C_RX_RBUF_FL_RD_ADDR_PARITY_ERR,
+       C_RX_RBUF_EMPTY_ERR,
+       C_RX_RBUF_FULL_ERR,
+       C_RX_RBUF_BAD_LOOKUP_ERR,
+       C_RX_RBUF_CTX_ID_PARITY_ERR,
+       C_RX_RBUF_CSR_QEOPDW_PARITY_ERR,
+       C_RX_RBUF_CSR_Q_NUM_OF_PKT_PARITY_ERR,
+       C_RX_RBUF_CSR_Q_T1_PTR_PARITY_ERR,
+       C_RX_RBUF_CSR_Q_HD_PTR_PARITY_ERR,
+       C_RX_RBUF_CSR_Q_VLD_BIT_PARITY_ERR,
+       C_RX_RBUF_CSR_Q_NEXT_BUF_PARITY_ERR,
+       C_RX_RBUF_CSR_Q_ENT_CNT_PARITY_ERR,
+       C_RX_RBUF_CSR_Q_HEAD_BUF_NUM_PARITY_ERR,
+       C_RX_RBUF_BLOCK_LIST_READ_COR_ERR,
+       C_RX_RBUF_BLOCK_LIST_READ_UNC_ERR,
+       C_RX_RBUF_LOOKUP_DES_COR_ERR,
+       C_RX_RBUF_LOOKUP_DES_UNC_ERR,
+       C_RX_RBUF_LOOKUP_DES_REG_UNC_COR_ERR,
+       C_RX_RBUF_LOOKUP_DES_REG_UNC_ERR,
+       C_RX_RBUF_FREE_LIST_COR_ERR,
+       C_RX_RBUF_FREE_LIST_UNC_ERR,
+       C_RX_RCV_FSM_ENCODING_ERR,
+       C_RX_DMA_FLAG_COR_ERR,
+       C_RX_DMA_FLAG_UNC_ERR,
+       C_RX_DC_SOP_EOP_PARITY_ERR,
+       C_RX_RCV_CSR_PARITY_ERR,
+       C_RX_RCV_QP_MAP_TABLE_COR_ERR,
+       C_RX_RCV_QP_MAP_TABLE_UNC_ERR,
+       C_RX_RCV_DATA_COR_ERR,
+       C_RX_RCV_DATA_UNC_ERR,
+       C_RX_RCV_HDR_COR_ERR,
+       C_RX_RCV_HDR_UNC_ERR,
+       C_RX_DC_INTF_PARITY_ERR,
+       C_RX_DMA_CSR_COR_ERR,
+/* SendPioErrStatus */
+       C_PIO_PEC_SOP_HEAD_PARITY_ERR,
+       C_PIO_PCC_SOP_HEAD_PARITY_ERR,
+       C_PIO_LAST_RETURNED_CNT_PARITY_ERR,
+       C_PIO_CURRENT_FREE_CNT_PARITY_ERR,
+       C_PIO_RSVD_31_ERR,
+       C_PIO_RSVD_30_ERR,
+       C_PIO_PPMC_SOP_LEN_ERR,
+       C_PIO_PPMC_BQC_MEM_PARITY_ERR,
+       C_PIO_VL_FIFO_PARITY_ERR,
+       C_PIO_VLF_SOP_PARITY_ERR,
+       C_PIO_VLF_V1_LEN_PARITY_ERR,
+       C_PIO_BLOCK_QW_COUNT_PARITY_ERR,
+       C_PIO_WRITE_QW_VALID_PARITY_ERR,
+       C_PIO_STATE_MACHINE_ERR,
+       C_PIO_WRITE_DATA_PARITY_ERR,
+       C_PIO_HOST_ADDR_MEM_COR_ERR,
+       C_PIO_HOST_ADDR_MEM_UNC_ERR,
+       C_PIO_PKT_EVICT_SM_OR_ARM_SM_ERR,
+       C_PIO_INIT_SM_IN_ERR,
+       C_PIO_PPMC_PBL_FIFO_ERR,
+       C_PIO_CREDIT_RET_FIFO_PARITY_ERR,
+       C_PIO_V1_LEN_MEM_BANK1_COR_ERR,
+       C_PIO_V1_LEN_MEM_BANK0_COR_ERR,
+       C_PIO_V1_LEN_MEM_BANK1_UNC_ERR,
+       C_PIO_V1_LEN_MEM_BANK0_UNC_ERR,
+       C_PIO_SM_PKT_RESET_PARITY_ERR,
+       C_PIO_PKT_EVICT_FIFO_PARITY_ERR,
+       C_PIO_SBRDCTRL_CRREL_FIFO_PARITY_ERR,
+       C_PIO_SBRDCTL_CRREL_PARITY_ERR,
+       C_PIO_PEC_FIFO_PARITY_ERR,
+       C_PIO_PCC_FIFO_PARITY_ERR,
+       C_PIO_SB_MEM_FIFO1_ERR,
+       C_PIO_SB_MEM_FIFO0_ERR,
+       C_PIO_CSR_PARITY_ERR,
+       C_PIO_WRITE_ADDR_PARITY_ERR,
+       C_PIO_WRITE_BAD_CTXT_ERR,
+/* SendDmaErrStatus */
+       C_SDMA_PCIE_REQ_TRACKING_COR_ERR,
+       C_SDMA_PCIE_REQ_TRACKING_UNC_ERR,
+       C_SDMA_CSR_PARITY_ERR,
+       C_SDMA_RPY_TAG_ERR,
+/* SendEgressErrStatus */
+       C_TX_READ_PIO_MEMORY_CSR_UNC_ERR,
+       C_TX_READ_SDMA_MEMORY_CSR_UNC_ERR,
+       C_TX_EGRESS_FIFO_COR_ERR,
+       C_TX_READ_PIO_MEMORY_COR_ERR,
+       C_TX_READ_SDMA_MEMORY_COR_ERR,
+       C_TX_SB_HDR_COR_ERR,
+       C_TX_CREDIT_OVERRUN_ERR,
+       C_TX_LAUNCH_FIFO8_COR_ERR,
+       C_TX_LAUNCH_FIFO7_COR_ERR,
+       C_TX_LAUNCH_FIFO6_COR_ERR,
+       C_TX_LAUNCH_FIFO5_COR_ERR,
+       C_TX_LAUNCH_FIFO4_COR_ERR,
+       C_TX_LAUNCH_FIFO3_COR_ERR,
+       C_TX_LAUNCH_FIFO2_COR_ERR,
+       C_TX_LAUNCH_FIFO1_COR_ERR,
+       C_TX_LAUNCH_FIFO0_COR_ERR,
+       C_TX_CREDIT_RETURN_VL_ERR,
+       C_TX_HCRC_INSERTION_ERR,
+       C_TX_EGRESS_FIFI_UNC_ERR,
+       C_TX_READ_PIO_MEMORY_UNC_ERR,
+       C_TX_READ_SDMA_MEMORY_UNC_ERR,
+       C_TX_SB_HDR_UNC_ERR,
+       C_TX_CREDIT_RETURN_PARITY_ERR,
+       C_TX_LAUNCH_FIFO8_UNC_OR_PARITY_ERR,
+       C_TX_LAUNCH_FIFO7_UNC_OR_PARITY_ERR,
+       C_TX_LAUNCH_FIFO6_UNC_OR_PARITY_ERR,
+       C_TX_LAUNCH_FIFO5_UNC_OR_PARITY_ERR,
+       C_TX_LAUNCH_FIFO4_UNC_OR_PARITY_ERR,
+       C_TX_LAUNCH_FIFO3_UNC_OR_PARITY_ERR,
+       C_TX_LAUNCH_FIFO2_UNC_OR_PARITY_ERR,
+       C_TX_LAUNCH_FIFO1_UNC_OR_PARITY_ERR,
+       C_TX_LAUNCH_FIFO0_UNC_OR_PARITY_ERR,
+       C_TX_SDMA15_DISALLOWED_PACKET_ERR,
+       C_TX_SDMA14_DISALLOWED_PACKET_ERR,
+       C_TX_SDMA13_DISALLOWED_PACKET_ERR,
+       C_TX_SDMA12_DISALLOWED_PACKET_ERR,
+       C_TX_SDMA11_DISALLOWED_PACKET_ERR,
+       C_TX_SDMA10_DISALLOWED_PACKET_ERR,
+       C_TX_SDMA9_DISALLOWED_PACKET_ERR,
+       C_TX_SDMA8_DISALLOWED_PACKET_ERR,
+       C_TX_SDMA7_DISALLOWED_PACKET_ERR,
+       C_TX_SDMA6_DISALLOWED_PACKET_ERR,
+       C_TX_SDMA5_DISALLOWED_PACKET_ERR,
+       C_TX_SDMA4_DISALLOWED_PACKET_ERR,
+       C_TX_SDMA3_DISALLOWED_PACKET_ERR,
+       C_TX_SDMA2_DISALLOWED_PACKET_ERR,
+       C_TX_SDMA1_DISALLOWED_PACKET_ERR,
+       C_TX_SDMA0_DISALLOWED_PACKET_ERR,
+       C_TX_CONFIG_PARITY_ERR,
+       C_TX_SBRD_CTL_CSR_PARITY_ERR,
+       C_TX_LAUNCH_CSR_PARITY_ERR,
+       C_TX_ILLEGAL_CL_ERR,
+       C_TX_SBRD_CTL_STATE_MACHINE_PARITY_ERR,
+       C_TX_RESERVED_10,
+       C_TX_RESERVED_9,
+       C_TX_SDMA_LAUNCH_INTF_PARITY_ERR,
+       C_TX_PIO_LAUNCH_INTF_PARITY_ERR,
+       C_TX_RESERVED_6,
+       C_TX_INCORRECT_LINK_STATE_ERR,
+       C_TX_LINK_DOWN_ERR,
+       C_TX_EGRESS_FIFO_UNDERRUN_OR_PARITY_ERR,
+       C_TX_RESERVED_2,
+       C_TX_PKT_INTEGRITY_MEM_UNC_ERR,
+       C_TX_PKT_INTEGRITY_MEM_COR_ERR,
+/* SendErrStatus */
+       C_SEND_CSR_WRITE_BAD_ADDR_ERR,
+       C_SEND_CSR_READ_BAD_ADD_ERR,
+       C_SEND_CSR_PARITY_ERR,
+/* SendCtxtErrStatus */
+       C_PIO_WRITE_OUT_OF_BOUNDS_ERR,
+       C_PIO_WRITE_OVERFLOW_ERR,
+       C_PIO_WRITE_CROSSES_BOUNDARY_ERR,
+       C_PIO_DISALLOWED_PACKET_ERR,
+       C_PIO_INCONSISTENT_SOP_ERR,
+/*SendDmaEngErrStatus */
+       C_SDMA_HEADER_REQUEST_FIFO_COR_ERR,
+       C_SDMA_HEADER_STORAGE_COR_ERR,
+       C_SDMA_PACKET_TRACKING_COR_ERR,
+       C_SDMA_ASSEMBLY_COR_ERR,
+       C_SDMA_DESC_TABLE_COR_ERR,
+       C_SDMA_HEADER_REQUEST_FIFO_UNC_ERR,
+       C_SDMA_HEADER_STORAGE_UNC_ERR,
+       C_SDMA_PACKET_TRACKING_UNC_ERR,
+       C_SDMA_ASSEMBLY_UNC_ERR,
+       C_SDMA_DESC_TABLE_UNC_ERR,
+       C_SDMA_TIMEOUT_ERR,
+       C_SDMA_HEADER_LENGTH_ERR,
+       C_SDMA_HEADER_ADDRESS_ERR,
+       C_SDMA_HEADER_SELECT_ERR,
+       C_SMDA_RESERVED_9,
+       C_SDMA_PACKET_DESC_OVERFLOW_ERR,
+       C_SDMA_LENGTH_MISMATCH_ERR,
+       C_SDMA_HALT_ERR,
+       C_SDMA_MEM_READ_ERR,
+       C_SDMA_FIRST_DESC_ERR,
+       C_SDMA_TAIL_OUT_OF_BOUNDS_ERR,
+       C_SDMA_TOO_LONG_ERR,
+       C_SDMA_GEN_MISMATCH_ERR,
+       C_SDMA_WRONG_DW_ERR,
        DEV_CNTR_LAST  /* Must be kept last */
 };
 
@@ -811,6 +1078,7 @@ enum {
        C_RX_WORDS,
        C_SW_LINK_DOWN,
        C_SW_LINK_UP,
+       C_SW_UNKNOWN_FRAME,
        C_SW_XMIT_DSCD,
        C_SW_XMIT_DSCD_VL,
        C_SW_XMIT_CSTR_ERR,
index bf45de29d8bd759ec8677f553659994001d951ea..701e9e1012a6c5469b4d130cf95d63fd97970ed0 100644 (file)
 #define DC_LCB_CFG_TX_FIFOS_RADR_RST_VAL_SHIFT 0
 #define DC_LCB_CFG_TX_FIFOS_RESET (DC_LCB_CSRS + 0x000000000008)
 #define DC_LCB_CFG_TX_FIFOS_RESET_VAL_SHIFT 0
+#define DC_LCB_CFG_REINIT_AS_SLAVE (DC_LCB_CSRS + 0x000000000030)
+#define DC_LCB_CFG_CNT_FOR_SKIP_STALL (DC_LCB_CSRS + 0x000000000040)
+#define DC_LCB_CFG_CLK_CNTR (DC_LCB_CSRS + 0x000000000110)
 #define DC_LCB_ERR_CLR (DC_LCB_CSRS + 0x000000000308)
 #define DC_LCB_ERR_EN (DC_LCB_CSRS + 0x000000000310)
 #define DC_LCB_ERR_FLG (DC_LCB_CSRS + 0x000000000300)
 #define DC_LCB_STS_ROUND_TRIP_LTP_CNT (DC_LCB_CSRS + 0x0000000004B0)
 #define RCV_BUF_OVFL_CNT 10
 #define RCV_CONTEXT_EGR_STALL 22
-#define RCV_CONTEXT_RHQ_STALL 21
 #define RCV_DATA_PKT_CNT 0
 #define RCV_DWORD_CNT 1
 #define RCV_TID_FLOW_GEN_MISMATCH_CNT 20
index 0aaad7412842bdeb967fe68422f116ea98367994..0c8831705664c24d2e0c936dd3d27a7a8aca5db3 100644 (file)
@@ -78,8 +78,8 @@
        hfi1_cdbg(SNOOP, fmt, ##__VA_ARGS__)
 
 /* Snoop option mask */
-#define SNOOP_DROP_SEND        (1 << 0)
-#define SNOOP_USE_METADATA     (1 << 1)
+#define SNOOP_DROP_SEND                BIT(0)
+#define SNOOP_USE_METADATA     BIT(1)
 
 static u8 snoop_flags;
 
@@ -135,7 +135,7 @@ static struct cdev diagpkt_cdev;
 static struct device *diagpkt_device;
 
 static ssize_t diagpkt_write(struct file *fp, const char __user *data,
-                                size_t count, loff_t *off);
+                            size_t count, loff_t *off);
 
 static const struct file_operations diagpkt_file_ops = {
        .owner = THIS_MODULE,
@@ -177,37 +177,37 @@ struct hfi1_link_info {
 #define HFI1_SNOOP_IOCGETLINKSTATE \
        _IO(HFI1_SNOOP_IOC_MAGIC, HFI1_SNOOP_IOC_BASE_SEQ)
 #define HFI1_SNOOP_IOCSETLINKSTATE \
-       _IO(HFI1_SNOOP_IOC_MAGIC, HFI1_SNOOP_IOC_BASE_SEQ+1)
+       _IO(HFI1_SNOOP_IOC_MAGIC, HFI1_SNOOP_IOC_BASE_SEQ + 1)
 #define HFI1_SNOOP_IOCCLEARQUEUE \
-       _IO(HFI1_SNOOP_IOC_MAGIC, HFI1_SNOOP_IOC_BASE_SEQ+2)
+       _IO(HFI1_SNOOP_IOC_MAGIC, HFI1_SNOOP_IOC_BASE_SEQ + 2)
 #define HFI1_SNOOP_IOCCLEARFILTER \
-       _IO(HFI1_SNOOP_IOC_MAGIC, HFI1_SNOOP_IOC_BASE_SEQ+3)
+       _IO(HFI1_SNOOP_IOC_MAGIC, HFI1_SNOOP_IOC_BASE_SEQ + 3)
 #define HFI1_SNOOP_IOCSETFILTER \
-       _IO(HFI1_SNOOP_IOC_MAGIC, HFI1_SNOOP_IOC_BASE_SEQ+4)
+       _IO(HFI1_SNOOP_IOC_MAGIC, HFI1_SNOOP_IOC_BASE_SEQ + 4)
 #define HFI1_SNOOP_IOCGETVERSION \
-       _IO(HFI1_SNOOP_IOC_MAGIC, HFI1_SNOOP_IOC_BASE_SEQ+5)
+       _IO(HFI1_SNOOP_IOC_MAGIC, HFI1_SNOOP_IOC_BASE_SEQ + 5)
 #define HFI1_SNOOP_IOCSET_OPTS \
-       _IO(HFI1_SNOOP_IOC_MAGIC, HFI1_SNOOP_IOC_BASE_SEQ+6)
+       _IO(HFI1_SNOOP_IOC_MAGIC, HFI1_SNOOP_IOC_BASE_SEQ + 6)
 
 /*
  * These offsets +6/+7 could change, but these are already known and used
  * IOCTL numbers so don't change them without a good reason.
  */
 #define HFI1_SNOOP_IOCGETLINKSTATE_EXTRA \
-       _IOWR(HFI1_SNOOP_IOC_MAGIC, HFI1_SNOOP_IOC_BASE_SEQ+6, \
+       _IOWR(HFI1_SNOOP_IOC_MAGIC, HFI1_SNOOP_IOC_BASE_SEQ + 6, \
                struct hfi1_link_info)
 #define HFI1_SNOOP_IOCSETLINKSTATE_EXTRA \
-       _IOWR(HFI1_SNOOP_IOC_MAGIC, HFI1_SNOOP_IOC_BASE_SEQ+7, \
+       _IOWR(HFI1_SNOOP_IOC_MAGIC, HFI1_SNOOP_IOC_BASE_SEQ + 7, \
                struct hfi1_link_info)
 
 static int hfi1_snoop_open(struct inode *in, struct file *fp);
 static ssize_t hfi1_snoop_read(struct file *fp, char __user *data,
-                               size_t pkt_len, loff_t *off);
+                              size_t pkt_len, loff_t *off);
 static ssize_t hfi1_snoop_write(struct file *fp, const char __user *data,
-                                size_t count, loff_t *off);
+                               size_t count, loff_t *off);
 static long hfi1_ioctl(struct file *fp, unsigned int cmd, unsigned long arg);
 static unsigned int hfi1_snoop_poll(struct file *fp,
-                                       struct poll_table_struct *wait);
+                                   struct poll_table_struct *wait);
 static int hfi1_snoop_release(struct inode *in, struct file *fp);
 
 struct hfi1_packet_filter_command {
@@ -323,14 +323,12 @@ static void hfi1_snoop_remove(struct hfi1_devdata *dd)
 
 void hfi1_diag_remove(struct hfi1_devdata *dd)
 {
-
        hfi1_snoop_remove(dd);
        if (atomic_dec_and_test(&diagpkt_count))
                hfi1_cdev_cleanup(&diagpkt_cdev, &diagpkt_device);
        hfi1_cdev_cleanup(&dd->diag_cdev, &dd->diag_device);
 }
 
-
 /*
  * Allocated structure shared between the credit return mechanism and
  * diagpkt_send().
@@ -379,6 +377,7 @@ static ssize_t diagpkt_send(struct diag_pkt *dp)
        pio_release_cb credit_cb = NULL;
        void *credit_arg = NULL;
        struct diagpkt_wait *wait = NULL;
+       int trycount = 0;
 
        dd = hfi1_lookup(dp->unit);
        if (!dd || !(dd->flags & HFI1_PRESENT) || !dd->kregbase) {
@@ -393,7 +392,7 @@ static ssize_t diagpkt_send(struct diag_pkt *dp)
 
        if (dp->version != _DIAG_PKT_VERS) {
                dd_dev_err(dd, "Invalid version %u for diagpkt_write\n",
-                           dp->version);
+                          dp->version);
                ret = -EINVAL;
                goto bail;
        }
@@ -440,7 +439,7 @@ static ssize_t diagpkt_send(struct diag_pkt *dp)
        }
 
        if (copy_from_user(tmpbuf,
-                          (const void __user *) (unsigned long) dp->data,
+                          (const void __user *)(unsigned long)dp->data,
                           dp->len)) {
                ret = -EFAULT;
                goto bail;
@@ -493,8 +492,15 @@ static ssize_t diagpkt_send(struct diag_pkt *dp)
                credit_arg = wait;
        }
 
+retry:
        pbuf = sc_buffer_alloc(sc, total_len, credit_cb, credit_arg);
        if (!pbuf) {
+               if (trycount == 0) {
+                       /* force a credit return and try again */
+                       sc_return_credits(sc);
+                       trycount = 1;
+                       goto retry;
+               }
                /*
                 * No send buffer means no credit callback.  Undo
                 * the wait set-up that was done above.  We free wait
@@ -530,9 +536,9 @@ static ssize_t diagpkt_send(struct diag_pkt *dp)
                 * NOTE: PRC_FILL_ERR is at best informational and cannot
                 * be depended on.
                 */
-               if (!ret && (((wait->code & PRC_STATUS_ERR)
-                               || (wait->code & PRC_FILL_ERR)
-                               || (wait->code & PRC_SC_DISABLE))))
+               if (!ret && (((wait->code & PRC_STATUS_ERR) ||
+                             (wait->code & PRC_FILL_ERR) ||
+                             (wait->code & PRC_SC_DISABLE))))
                        ret = -EIO;
 
                put_diagpkt_wait(wait); /* finished with the structure */
@@ -545,7 +551,7 @@ bail:
 }
 
 static ssize_t diagpkt_write(struct file *fp, const char __user *data,
-                                size_t count, loff_t *off)
+                            size_t count, loff_t *off)
 {
        struct hfi1_devdata *dd;
        struct send_context *sc;
@@ -565,7 +571,7 @@ static ssize_t diagpkt_write(struct file *fp, const char __user *data,
        */
        if (dp.pbc) {
                dd = hfi1_lookup(dp.unit);
-               if (dd == NULL)
+               if (!dd)
                        return -ENODEV;
                vl = (dp.pbc >> PBC_VL_SHIFT) & PBC_VL_MASK;
                sc = dd->vld[vl].sc;
@@ -598,7 +604,7 @@ static int hfi1_snoop_add(struct hfi1_devdata *dd, const char *name)
        if (ret) {
                dd_dev_err(dd, "Couldn't create %s device: %d", name, ret);
                hfi1_cdev_cleanup(&dd->hfi1_snoop.cdev,
-                                &dd->hfi1_snoop.class_dev);
+                                 &dd->hfi1_snoop.class_dev);
        }
 
        return ret;
@@ -611,7 +617,6 @@ static struct hfi1_devdata *hfi1_dd_from_sc_inode(struct inode *in)
 
        dd = hfi1_lookup(unit);
        return dd;
-
 }
 
 /* clear or restore send context integrity checks */
@@ -652,7 +657,7 @@ static int hfi1_snoop_open(struct inode *in, struct file *fp)
        mutex_lock(&hfi1_mutex);
 
        dd = hfi1_dd_from_sc_inode(in);
-       if (dd == NULL) {
+       if (!dd) {
                ret = -ENODEV;
                goto bail;
        }
@@ -739,7 +744,7 @@ static int hfi1_snoop_release(struct inode *in, struct file *fp)
        int mode_flag;
 
        dd = hfi1_dd_from_sc_inode(in);
-       if (dd == NULL)
+       if (!dd)
                return -ENODEV;
 
        spin_lock_irqsave(&dd->hfi1_snoop.snoop_lock, flags);
@@ -794,7 +799,7 @@ static unsigned int hfi1_snoop_poll(struct file *fp,
        struct hfi1_devdata *dd;
 
        dd = hfi1_dd_from_sc_inode(fp->f_inode);
-       if (dd == NULL)
+       if (!dd)
                return -ENODEV;
 
        spin_lock_irqsave(&dd->hfi1_snoop.snoop_lock, flags);
@@ -805,7 +810,6 @@ static unsigned int hfi1_snoop_poll(struct file *fp,
 
        spin_unlock_irqrestore(&dd->hfi1_snoop.snoop_lock, flags);
        return ret;
-
 }
 
 static ssize_t hfi1_snoop_write(struct file *fp, const char __user *data,
@@ -822,7 +826,7 @@ static ssize_t hfi1_snoop_write(struct file *fp, const char __user *data,
        struct hfi1_pportdata *ppd;
 
        dd = hfi1_dd_from_sc_inode(fp->f_inode);
-       if (dd == NULL)
+       if (!dd)
                return -ENODEV;
 
        ppd = dd->pport;
@@ -847,7 +851,7 @@ static ssize_t hfi1_snoop_write(struct file *fp, const char __user *data,
                if (copy_from_user(&byte_one, data, 1))
                        return -EINVAL;
 
-               if (copy_from_user(&byte_two, data+1, 1))
+               if (copy_from_user(&byte_two, data + 1, 1))
                        return -EINVAL;
 
                sc4 = (byte_one >> 4) & 0xf;
@@ -920,7 +924,7 @@ static ssize_t hfi1_snoop_read(struct file *fp, char __user *data,
        struct hfi1_devdata *dd;
 
        dd = hfi1_dd_from_sc_inode(fp->f_inode);
-       if (dd == NULL)
+       if (!dd)
                return -ENODEV;
 
        spin_lock_irqsave(&dd->hfi1_snoop.snoop_lock, flags);
@@ -946,16 +950,18 @@ static ssize_t hfi1_snoop_read(struct file *fp, char __user *data,
                spin_unlock_irqrestore(&dd->hfi1_snoop.snoop_lock, flags);
                if (pkt_len >= packet->total_len) {
                        if (copy_to_user(data, packet->data,
-                               packet->total_len))
+                                        packet->total_len))
                                ret = -EFAULT;
                        else
                                ret = packet->total_len;
-               } else
+               } else {
                        ret = -EINVAL;
+               }
 
                kfree(packet);
-       } else
+       } else {
                spin_unlock_irqrestore(&dd->hfi1_snoop.snoop_lock, flags);
+       }
 
        return ret;
 }
@@ -966,9 +972,9 @@ static long hfi1_ioctl(struct file *fp, unsigned int cmd, unsigned long arg)
        void *filter_value = NULL;
        long ret = 0;
        int value = 0;
-       u8 physState = 0;
-       u8 linkState = 0;
-       u16 devState = 0;
+       u8 phys_state = 0;
+       u8 link_state = 0;
+       u16 dev_state = 0;
        unsigned long flags = 0;
        unsigned long *argp = NULL;
        struct hfi1_packet_filter_command filter_cmd = {0};
@@ -976,237 +982,221 @@ static long hfi1_ioctl(struct file *fp, unsigned int cmd, unsigned long arg)
        struct hfi1_pportdata *ppd = NULL;
        unsigned int index;
        struct hfi1_link_info link_info;
+       int read_cmd, write_cmd, read_ok, write_ok;
 
        dd = hfi1_dd_from_sc_inode(fp->f_inode);
-       if (dd == NULL)
+       if (!dd)
                return -ENODEV;
 
-       spin_lock_irqsave(&dd->hfi1_snoop.snoop_lock, flags);
-
        mode_flag = dd->hfi1_snoop.mode_flag;
+       read_cmd = _IOC_DIR(cmd) & _IOC_READ;
+       write_cmd = _IOC_DIR(cmd) & _IOC_WRITE;
+       write_ok = access_ok(VERIFY_WRITE, (void __user *)arg, _IOC_SIZE(cmd));
+       read_ok = access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd));
 
-       if (((_IOC_DIR(cmd) & _IOC_READ)
-           && !access_ok(VERIFY_WRITE, (void __user *)arg, _IOC_SIZE(cmd)))
-           || ((_IOC_DIR(cmd) & _IOC_WRITE)
-           && !access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd)))) {
-               ret = -EFAULT;
-       } else if (!capable(CAP_SYS_ADMIN)) {
-               ret = -EPERM;
-       } else if ((mode_flag & HFI1_PORT_CAPTURE_MODE) &&
-                  (cmd != HFI1_SNOOP_IOCCLEARQUEUE) &&
-                  (cmd != HFI1_SNOOP_IOCCLEARFILTER) &&
-                  (cmd != HFI1_SNOOP_IOCSETFILTER)) {
+       if ((read_cmd && !write_ok) || (write_cmd && !read_ok))
+               return -EFAULT;
+
+       if (!capable(CAP_SYS_ADMIN))
+               return -EPERM;
+
+       if ((mode_flag & HFI1_PORT_CAPTURE_MODE) &&
+           (cmd != HFI1_SNOOP_IOCCLEARQUEUE) &&
+           (cmd != HFI1_SNOOP_IOCCLEARFILTER) &&
+           (cmd != HFI1_SNOOP_IOCSETFILTER))
                /* Capture devices are allowed only 3 operations
                 * 1.Clear capture queue
                 * 2.Clear capture filter
                 * 3.Set capture filter
                 * Other are invalid.
                 */
-               ret = -EINVAL;
-       } else {
-               switch (cmd) {
-               case HFI1_SNOOP_IOCSETLINKSTATE:
-                       snoop_dbg("HFI1_SNOOP_IOCSETLINKSTATE is not valid");
-                       ret = -EINVAL;
-                       break;
+               return -EINVAL;
 
-               case HFI1_SNOOP_IOCSETLINKSTATE_EXTRA:
-                       memset(&link_info, 0, sizeof(link_info));
+       switch (cmd) {
+       case HFI1_SNOOP_IOCSETLINKSTATE_EXTRA:
+               memset(&link_info, 0, sizeof(link_info));
 
-                       if (copy_from_user(&link_info,
-                               (struct hfi1_link_info __user *)arg,
-                               sizeof(link_info)))
-                               ret = -EFAULT;
+               if (copy_from_user(&link_info,
+                                  (struct hfi1_link_info __user *)arg,
+                                  sizeof(link_info)))
+                       return -EFAULT;
 
-                       value = link_info.port_state;
-                       index = link_info.port_number;
-                       if (index > dd->num_pports - 1) {
-                               ret = -EINVAL;
-                               break;
-                       }
+               value = link_info.port_state;
+               index = link_info.port_number;
+               if (index > dd->num_pports - 1)
+                       return -EINVAL;
 
-                       ppd = &dd->pport[index];
-                       if (!ppd) {
-                               ret = -EINVAL;
-                               break;
-                       }
+               ppd = &dd->pport[index];
+               if (!ppd)
+                       return -EINVAL;
 
-                       /* What we want to transition to */
-                       physState = (value >> 4) & 0xF;
-                       linkState = value & 0xF;
-                       snoop_dbg("Setting link state 0x%x", value);
-
-                       switch (linkState) {
-                       case IB_PORT_NOP:
-                               if (physState == 0)
-                                       break;
-                                       /* fall through */
-                       case IB_PORT_DOWN:
-                               switch (physState) {
-                               case 0:
-                                       devState = HLS_DN_DOWNDEF;
-                                       break;
-                               case 2:
-                                       devState = HLS_DN_POLL;
-                                       break;
-                               case 3:
-                                       devState = HLS_DN_DISABLE;
-                                       break;
-                               default:
-                                       ret = -EINVAL;
-                                       goto done;
-                               }
-                               ret = set_link_state(ppd, devState);
-                               break;
-                       case IB_PORT_ARMED:
-                               ret = set_link_state(ppd, HLS_UP_ARMED);
-                               if (!ret)
-                                       send_idle_sma(dd, SMA_IDLE_ARM);
-                               break;
-                       case IB_PORT_ACTIVE:
-                               ret = set_link_state(ppd, HLS_UP_ACTIVE);
-                               if (!ret)
-                                       send_idle_sma(dd, SMA_IDLE_ACTIVE);
-                               break;
-                       default:
-                               ret = -EINVAL;
-                               break;
-                       }
+               /* What we want to transition to */
+               phys_state = (value >> 4) & 0xF;
+               link_state = value & 0xF;
+               snoop_dbg("Setting link state 0x%x", value);
 
-                       if (ret)
+               switch (link_state) {
+               case IB_PORT_NOP:
+                       if (phys_state == 0)
                                break;
-                       /* fall through */
-               case HFI1_SNOOP_IOCGETLINKSTATE:
-               case HFI1_SNOOP_IOCGETLINKSTATE_EXTRA:
-                       if (cmd == HFI1_SNOOP_IOCGETLINKSTATE_EXTRA) {
-                               memset(&link_info, 0, sizeof(link_info));
-                               if (copy_from_user(&link_info,
-                                       (struct hfi1_link_info __user *)arg,
-                                       sizeof(link_info)))
-                                       ret = -EFAULT;
-                               index = link_info.port_number;
-                       } else {
-                               ret = __get_user(index, (int __user *) arg);
-                               if (ret !=  0)
-                                       break;
-                       }
-
-                       if (index > dd->num_pports - 1) {
-                               ret = -EINVAL;
+                               /* fall through */
+               case IB_PORT_DOWN:
+                       switch (phys_state) {
+                       case 0:
+                               dev_state = HLS_DN_DOWNDEF;
                                break;
-                       }
-
-                       ppd = &dd->pport[index];
-                       if (!ppd) {
-                               ret = -EINVAL;
+                       case 2:
+                               dev_state = HLS_DN_POLL;
                                break;
+                       case 3:
+                               dev_state = HLS_DN_DISABLE;
+                               break;
+                       default:
+                               return -EINVAL;
                        }
-                       value = hfi1_ibphys_portstate(ppd);
-                       value <<= 4;
-                       value |= driver_lstate(ppd);
-
-                       snoop_dbg("Link port | Link State: %d", value);
-
-                       if ((cmd == HFI1_SNOOP_IOCGETLINKSTATE_EXTRA) ||
-                           (cmd == HFI1_SNOOP_IOCSETLINKSTATE_EXTRA)) {
-                               link_info.port_state = value;
-                               link_info.node_guid = cpu_to_be64(ppd->guid);
-                               link_info.link_speed_active =
-                                                       ppd->link_speed_active;
-                               link_info.link_width_active =
-                                                       ppd->link_width_active;
-                               if (copy_to_user(
-                                       (struct hfi1_link_info __user *)arg,
-                                       &link_info, sizeof(link_info)))
-                                       ret = -EFAULT;
-                       } else {
-                               ret = __put_user(value, (int __user *)arg);
-                       }
+                       ret = set_link_state(ppd, dev_state);
                        break;
-
-               case HFI1_SNOOP_IOCCLEARQUEUE:
-                       snoop_dbg("Clearing snoop queue");
-                       drain_snoop_list(&dd->hfi1_snoop.queue);
+               case IB_PORT_ARMED:
+                       ret = set_link_state(ppd, HLS_UP_ARMED);
+                       if (!ret)
+                               send_idle_sma(dd, SMA_IDLE_ARM);
                        break;
-
-               case HFI1_SNOOP_IOCCLEARFILTER:
-                       snoop_dbg("Clearing filter");
-                       if (dd->hfi1_snoop.filter_callback) {
-                               /* Drain packets first */
-                               drain_snoop_list(&dd->hfi1_snoop.queue);
-                               dd->hfi1_snoop.filter_callback = NULL;
-                       }
-                       kfree(dd->hfi1_snoop.filter_value);
-                       dd->hfi1_snoop.filter_value = NULL;
+               case IB_PORT_ACTIVE:
+                       ret = set_link_state(ppd, HLS_UP_ACTIVE);
+                       if (!ret)
+                               send_idle_sma(dd, SMA_IDLE_ACTIVE);
                        break;
+               default:
+                       return -EINVAL;
+               }
 
-               case HFI1_SNOOP_IOCSETFILTER:
-                       snoop_dbg("Setting filter");
-                       /* just copy command structure */
-                       argp = (unsigned long *)arg;
-                       if (copy_from_user(&filter_cmd, (void __user *)argp,
-                                            sizeof(filter_cmd))) {
-                               ret = -EFAULT;
-                               break;
-                       }
-                       if (filter_cmd.opcode >= HFI1_MAX_FILTERS) {
-                               pr_alert("Invalid opcode in request\n");
-                               ret = -EINVAL;
+               if (ret)
+                       break;
+               /* fall through */
+       case HFI1_SNOOP_IOCGETLINKSTATE:
+       case HFI1_SNOOP_IOCGETLINKSTATE_EXTRA:
+               if (cmd == HFI1_SNOOP_IOCGETLINKSTATE_EXTRA) {
+                       memset(&link_info, 0, sizeof(link_info));
+                       if (copy_from_user(&link_info,
+                                          (struct hfi1_link_info __user *)arg,
+                                          sizeof(link_info)))
+                               return -EFAULT;
+                       index = link_info.port_number;
+               } else {
+                       ret = __get_user(index, (int __user *)arg);
+                       if (ret !=  0)
                                break;
-                       }
+               }
 
-                       snoop_dbg("Opcode %d Len %d Ptr %p",
-                                  filter_cmd.opcode, filter_cmd.length,
-                                  filter_cmd.value_ptr);
+               if (index > dd->num_pports - 1)
+                       return -EINVAL;
 
-                       filter_value = kcalloc(filter_cmd.length, sizeof(u8),
-                                              GFP_KERNEL);
-                       if (!filter_value) {
-                               pr_alert("Not enough memory\n");
-                               ret = -ENOMEM;
-                               break;
-                       }
-                       /* copy remaining data from userspace */
-                       if (copy_from_user((u8 *)filter_value,
-                                       (void __user *)filter_cmd.value_ptr,
-                                       filter_cmd.length)) {
-                               kfree(filter_value);
-                               ret = -EFAULT;
-                               break;
-                       }
+               ppd = &dd->pport[index];
+               if (!ppd)
+                       return -EINVAL;
+
+               value = hfi1_ibphys_portstate(ppd);
+               value <<= 4;
+               value |= driver_lstate(ppd);
+
+               snoop_dbg("Link port | Link State: %d", value);
+
+               if ((cmd == HFI1_SNOOP_IOCGETLINKSTATE_EXTRA) ||
+                   (cmd == HFI1_SNOOP_IOCSETLINKSTATE_EXTRA)) {
+                       link_info.port_state = value;
+                       link_info.node_guid = cpu_to_be64(ppd->guid);
+                       link_info.link_speed_active =
+                                               ppd->link_speed_active;
+                       link_info.link_width_active =
+                                               ppd->link_width_active;
+                       if (copy_to_user((struct hfi1_link_info __user *)arg,
+                                        &link_info, sizeof(link_info)))
+                               return -EFAULT;
+               } else {
+                       ret = __put_user(value, (int __user *)arg);
+               }
+               break;
+
+       case HFI1_SNOOP_IOCCLEARQUEUE:
+               snoop_dbg("Clearing snoop queue");
+               spin_lock_irqsave(&dd->hfi1_snoop.snoop_lock, flags);
+               drain_snoop_list(&dd->hfi1_snoop.queue);
+               spin_unlock_irqrestore(&dd->hfi1_snoop.snoop_lock, flags);
+               break;
+
+       case HFI1_SNOOP_IOCCLEARFILTER:
+               snoop_dbg("Clearing filter");
+               spin_lock_irqsave(&dd->hfi1_snoop.snoop_lock, flags);
+               if (dd->hfi1_snoop.filter_callback) {
                        /* Drain packets first */
                        drain_snoop_list(&dd->hfi1_snoop.queue);
-                       dd->hfi1_snoop.filter_callback =
-                               hfi1_filters[filter_cmd.opcode].filter;
-                       /* just in case we see back to back sets */
-                       kfree(dd->hfi1_snoop.filter_value);
-                       dd->hfi1_snoop.filter_value = filter_value;
+                       dd->hfi1_snoop.filter_callback = NULL;
+               }
+               kfree(dd->hfi1_snoop.filter_value);
+               dd->hfi1_snoop.filter_value = NULL;
+               spin_unlock_irqrestore(&dd->hfi1_snoop.snoop_lock, flags);
+               break;
 
-                       break;
-               case HFI1_SNOOP_IOCGETVERSION:
-                       value = SNOOP_CAPTURE_VERSION;
-                       snoop_dbg("Getting version: %d", value);
-                       ret = __put_user(value, (int __user *)arg);
-                       break;
-               case HFI1_SNOOP_IOCSET_OPTS:
-                       snoop_flags = 0;
-                       ret = __get_user(value, (int __user *) arg);
-                       if (ret != 0)
-                               break;
+       case HFI1_SNOOP_IOCSETFILTER:
+               snoop_dbg("Setting filter");
+               /* just copy command structure */
+               argp = (unsigned long *)arg;
+               if (copy_from_user(&filter_cmd, (void __user *)argp,
+                                  sizeof(filter_cmd)))
+                       return -EFAULT;
 
-                       snoop_dbg("Setting snoop option %d", value);
-                       if (value & SNOOP_DROP_SEND)
-                               snoop_flags |= SNOOP_DROP_SEND;
-                       if (value & SNOOP_USE_METADATA)
-                               snoop_flags |= SNOOP_USE_METADATA;
-                       break;
-               default:
-                       ret = -ENOTTY;
-                       break;
+               if (filter_cmd.opcode >= HFI1_MAX_FILTERS) {
+                       pr_alert("Invalid opcode in request\n");
+                       return -EINVAL;
+               }
+
+               snoop_dbg("Opcode %d Len %d Ptr %p",
+                         filter_cmd.opcode, filter_cmd.length,
+                         filter_cmd.value_ptr);
+
+               filter_value = kcalloc(filter_cmd.length, sizeof(u8),
+                                      GFP_KERNEL);
+               if (!filter_value)
+                       return -ENOMEM;
+
+               /* copy remaining data from userspace */
+               if (copy_from_user((u8 *)filter_value,
+                                  (void __user *)filter_cmd.value_ptr,
+                                  filter_cmd.length)) {
+                       kfree(filter_value);
+                       return -EFAULT;
                }
+               /* Drain packets first */
+               spin_lock_irqsave(&dd->hfi1_snoop.snoop_lock, flags);
+               drain_snoop_list(&dd->hfi1_snoop.queue);
+               dd->hfi1_snoop.filter_callback =
+                       hfi1_filters[filter_cmd.opcode].filter;
+               /* just in case we see back to back sets */
+               kfree(dd->hfi1_snoop.filter_value);
+               dd->hfi1_snoop.filter_value = filter_value;
+               spin_unlock_irqrestore(&dd->hfi1_snoop.snoop_lock, flags);
+               break;
+       case HFI1_SNOOP_IOCGETVERSION:
+               value = SNOOP_CAPTURE_VERSION;
+               snoop_dbg("Getting version: %d", value);
+               ret = __put_user(value, (int __user *)arg);
+               break;
+       case HFI1_SNOOP_IOCSET_OPTS:
+               snoop_flags = 0;
+               ret = __get_user(value, (int __user *)arg);
+               if (ret != 0)
+                       break;
+
+               snoop_dbg("Setting snoop option %d", value);
+               if (value & SNOOP_DROP_SEND)
+                       snoop_flags |= SNOOP_DROP_SEND;
+               if (value & SNOOP_USE_METADATA)
+                       snoop_flags |= SNOOP_USE_METADATA;
+               break;
+       default:
+               return -ENOTTY;
        }
-done:
-       spin_unlock_irqrestore(&dd->hfi1_snoop.snoop_lock, flags);
+
        return ret;
 }
 
@@ -1321,7 +1311,6 @@ static int hfi1_filter_mad_mgmt_class(void *ibhdr, void *packet_data,
 
 static int hfi1_filter_qp_number(void *ibhdr, void *packet_data, void *value)
 {
-
        struct hfi1_ib_header *hdr;
        struct hfi1_other_headers *ohdr = NULL;
        int ret;
@@ -1404,7 +1393,6 @@ static int hfi1_filter_ib_service_level(void *ibhdr, void *packet_data,
 
 static int hfi1_filter_ib_pkey(void *ibhdr, void *packet_data, void *value)
 {
-
        u32 lnh = 0;
        struct hfi1_ib_header *hdr;
        struct hfi1_other_headers *ohdr = NULL;
@@ -1476,16 +1464,14 @@ static struct snoop_packet *allocate_snoop_packet(u32 hdr_len,
                                                  u32 data_len,
                                                  u32 md_len)
 {
-
        struct snoop_packet *packet;
 
-       packet = kzalloc(sizeof(struct snoop_packet) + hdr_len + data_len
+       packet = kzalloc(sizeof(*packet) + hdr_len + data_len
                         + md_len,
                         GFP_ATOMIC | __GFP_NOWARN);
        if (likely(packet))
                INIT_LIST_HEAD(&packet->list);
 
-
        return packet;
 }
 
@@ -1542,12 +1528,11 @@ int snoop_recv_handler(struct hfi1_packet *packet)
                    unlikely(snoop_flags & SNOOP_USE_METADATA))
                        md_len = sizeof(struct capture_md);
 
-
                s_packet = allocate_snoop_packet(header_size,
                                                 tlen - header_size,
                                                 md_len);
 
-               if (unlikely(s_packet == NULL)) {
+               if (unlikely(!s_packet)) {
                        dd_dev_warn_ratelimited(ppd->dd, "Unable to allocate snoop/capture packet\n");
                        break;
                }
@@ -1668,7 +1653,7 @@ int snoop_send_pio_handler(struct hfi1_qp *qp, struct hfi1_pkt_state *ps,
        /* not using ss->total_len as arg 2 b/c that does not count CRC */
        s_packet = allocate_snoop_packet(hdr_len, tlen - hdr_len, md_len);
 
-       if (unlikely(s_packet == NULL)) {
+       if (unlikely(!s_packet)) {
                dd_dev_warn_ratelimited(ppd->dd, "Unable to allocate snoop/capture packet\n");
                goto out;
        }
@@ -1837,7 +1822,7 @@ void snoop_inline_pio_send(struct hfi1_devdata *dd, struct pio_buf *pbuf,
 
                s_packet = allocate_snoop_packet(packet_len, 0, md_len);
 
-               if (unlikely(s_packet == NULL)) {
+               if (unlikely(!s_packet)) {
                        dd_dev_warn_ratelimited(dd, "Unable to allocate snoop/capture packet\n");
                        goto inline_pio_out;
                }
@@ -1869,5 +1854,4 @@ void snoop_inline_pio_send(struct hfi1_devdata *dd, struct pio_buf *pbuf,
 
 inline_pio_out:
        pio_copy(dd, pbuf, pbc, from, count);
-
 }
index 4c52e785de68eefa48e2132a9a46ae93ea41db71..8485de1fce0869630baa8be780c2b8e906d14b53 100644 (file)
@@ -158,7 +158,7 @@ const char *get_unit_name(int unit)
 {
        static char iname[16];
 
-       snprintf(iname, sizeof(iname), DRIVER_NAME"_%u", unit);
+       snprintf(iname, sizeof(iname), DRIVER_NAME "_%u", unit);
        return iname;
 }
 
@@ -633,6 +633,7 @@ next:
                update_ps_mdata(&mdata, rcd);
        }
 }
+#endif /* CONFIG_PRESCAN_RXQ */
 
 static inline int skip_rcv_packet(struct hfi1_packet *packet, int thread)
 {
@@ -659,7 +660,6 @@ static inline int skip_rcv_packet(struct hfi1_packet *packet, int thread)
 
        return ret;
 }
-#endif /* CONFIG_PRESCAN_RXQ */
 
 static inline int process_rcv_packet(struct hfi1_packet *packet, int thread)
 {
diff --git a/drivers/staging/rdma/hfi1/efivar.c b/drivers/staging/rdma/hfi1/efivar.c
new file mode 100644 (file)
index 0000000..7dc5bae
--- /dev/null
@@ -0,0 +1,169 @@
+/*
+ *
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2015 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2015 Intel Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *  - Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  - Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *  - Neither the name of Intel Corporation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 "efivar.h"
+
+/* GUID for HFI1 variables in EFI */
+#define HFI1_EFIVAR_GUID EFI_GUID(0xc50a953e, 0xa8b2, 0x42a6, \
+               0xbf, 0x89, 0xd3, 0x33, 0xa6, 0xe9, 0xe6, 0xd4)
+/* largest EFI data size we expect */
+#define EFI_DATA_SIZE 4096
+
+/*
+ * Read the named EFI variable.  Return the size of the actual data in *size
+ * and a kmalloc'ed buffer in *return_data.  The caller must free the
+ * data.  It is guaranteed that *return_data will be NULL and *size = 0
+ * if this routine fails.
+ *
+ * Return 0 on success, -errno on failure.
+ */
+static int read_efi_var(const char *name, unsigned long *size,
+                       void **return_data)
+{
+       efi_status_t status;
+       efi_char16_t *uni_name;
+       efi_guid_t guid;
+       unsigned long temp_size;
+       void *temp_buffer;
+       void *data;
+       int i;
+       int ret;
+
+       /* set failure return values */
+       *size = 0;
+       *return_data = NULL;
+
+       if (!efi_enabled(EFI_RUNTIME_SERVICES))
+               return -EOPNOTSUPP;
+
+       uni_name = kzalloc(sizeof(efi_char16_t) * (strlen(name) + 1),
+                          GFP_KERNEL);
+       temp_buffer = kzalloc(EFI_DATA_SIZE, GFP_KERNEL);
+
+       if (!uni_name || !temp_buffer) {
+               ret = -ENOMEM;
+               goto fail;
+       }
+
+       /* input: the size of the buffer */
+       temp_size = EFI_DATA_SIZE;
+
+       /* convert ASCII to unicode - it is a 1:1 mapping */
+       for (i = 0; name[i]; i++)
+               uni_name[i] = name[i];
+
+       /* need a variable for our GUID */
+       guid = HFI1_EFIVAR_GUID;
+
+       /* call into EFI runtime services */
+       status = efi.get_variable(
+                       uni_name,
+                       &guid,
+                       NULL,
+                       &temp_size,
+                       temp_buffer);
+
+       /*
+        * It would be nice to call efi_status_to_err() here, but that
+        * is in the EFIVAR_FS code and may not be compiled in.
+        * However, even that is insufficient since it does not cover
+        * EFI_BUFFER_TOO_SMALL which could be an important return.
+        * For now, just split out succces or not found.
+        */
+       ret = status == EFI_SUCCESS   ? 0 :
+             status == EFI_NOT_FOUND ? -ENOENT :
+                                       -EINVAL;
+       if (ret)
+               goto fail;
+
+       /*
+        * We have successfully read the EFI variable into our
+        * temporary buffer.  Now allocate a correctly sized
+        * buffer.
+        */
+       data = kmalloc(temp_size, GFP_KERNEL);
+       if (!data) {
+               ret = -ENOMEM;
+               goto fail;
+       }
+
+       memcpy(data, temp_buffer, temp_size);
+       *size = temp_size;
+       *return_data = data;
+
+fail:
+       kfree(uni_name);
+       kfree(temp_buffer);
+
+       return ret;
+}
+
+/*
+ * Read an HFI1 EFI variable of the form:
+ *     <PCIe address>-<kind>
+ * Return an kalloc'ed array and size of the data.
+ *
+ * Returns 0 on success, -errno on failure.
+ */
+int read_hfi1_efi_var(struct hfi1_devdata *dd, const char *kind,
+                     unsigned long *size, void **return_data)
+{
+       char name[64];
+
+       /* create a common prefix */
+       snprintf(name, sizeof(name), "%04x:%02x:%02x.%x-%s",
+                pci_domain_nr(dd->pcidev->bus),
+                dd->pcidev->bus->number,
+                PCI_SLOT(dd->pcidev->devfn),
+                PCI_FUNC(dd->pcidev->devfn),
+                kind);
+
+       return read_efi_var(name, size, return_data);
+}
diff --git a/drivers/staging/rdma/hfi1/efivar.h b/drivers/staging/rdma/hfi1/efivar.h
new file mode 100644 (file)
index 0000000..0707062
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ *
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2015 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2015 Intel Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *  - Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  - Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *  - Neither the name of Intel Corporation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef _HFI1_EFIVAR_H
+#define _HFI1_EFIVAR_H
+
+#include <linux/efi.h>
+
+#include "hfi.h"
+
+int read_hfi1_efi_var(struct hfi1_devdata *dd, const char *kind,
+                     unsigned long *size, void **return_data);
+
+#endif /* _HFI1_EFIVAR_H */
index b61d3ae93ed13591d335e848d9ff8fd18e7cf04a..fb620c97f592dffe4a72c0b1bb6044bbacc2b890 100644 (file)
 #include "eprom.h"
 
 /*
- * The EPROM is logically divided into two partitions:
+ * The EPROM is logically divided into three partitions:
  *     partition 0: the first 128K, visible from PCI ROM BAR
- *     partition 1: the rest
+ *     partition 1: 4K config file (sector size)
+ *     partition 2: the rest
  */
 #define P0_SIZE (128 * 1024)
+#define P1_SIZE   (4 * 1024)
 #define P1_START P0_SIZE
+#define P2_START (P0_SIZE + P1_SIZE)
+
+/* erase sizes supported by the controller */
+#define SIZE_4KB (4 * 1024)
+#define MASK_4KB (SIZE_4KB - 1)
 
-/* largest erase size supported by the controller */
 #define SIZE_32KB (32 * 1024)
 #define MASK_32KB (SIZE_32KB - 1)
 
+#define SIZE_64KB (64 * 1024)
+#define MASK_64KB (SIZE_64KB - 1)
+
 /* controller page size, in bytes */
 #define EP_PAGE_SIZE 256
 #define EEP_PAGE_MASK (EP_PAGE_SIZE - 1)
 #define CMD_READ_DATA(addr)        ((0x03 << CMD_SHIFT) | addr)
 #define CMD_READ_SR1               ((0x05 << CMD_SHIFT))
 #define CMD_WRITE_ENABLE           ((0x06 << CMD_SHIFT))
+#define CMD_SECTOR_ERASE_4KB(addr)  ((0x20 << CMD_SHIFT) | addr)
 #define CMD_SECTOR_ERASE_32KB(addr) ((0x52 << CMD_SHIFT) | addr)
 #define CMD_CHIP_ERASE             ((0x60 << CMD_SHIFT))
 #define CMD_READ_MANUF_DEV_ID      ((0x90 << CMD_SHIFT))
 #define CMD_RELEASE_POWERDOWN_NOID  ((0xab << CMD_SHIFT))
+#define CMD_SECTOR_ERASE_64KB(addr) ((0xd8 << CMD_SHIFT) | addr)
 
 /* controller interface speeds */
 #define EP_SPEED_FULL 0x2      /* full speed */
@@ -188,28 +199,43 @@ static int erase_chip(struct hfi1_devdata *dd)
 }
 
 /*
- * Erase a range using the 32KB erase command.
+ * Erase a range.
  */
-static int erase_32kb_range(struct hfi1_devdata *dd, u32 start, u32 end)
+static int erase_range(struct hfi1_devdata *dd, u32 start, u32 len)
 {
+       u32 end = start + len;
        int ret = 0;
 
        if (end < start)
                return -EINVAL;
 
-       if ((start & MASK_32KB) || (end & MASK_32KB)) {
+       /* check the end points for the minimum erase */
+       if ((start & MASK_4KB) || (end & MASK_4KB)) {
                dd_dev_err(dd,
-                       "%s: non-aligned range (0x%x,0x%x) for a 32KB erase\n",
+                       "%s: non-aligned range (0x%x,0x%x) for a 4KB erase\n",
                        __func__, start, end);
                return -EINVAL;
        }
 
        write_enable(dd);
 
-       for (; start < end; start += SIZE_32KB) {
+       while (start < end) {
                write_csr(dd, ASIC_EEP_ADDR_CMD, CMD_WRITE_ENABLE);
-               write_csr(dd, ASIC_EEP_ADDR_CMD,
-                                               CMD_SECTOR_ERASE_32KB(start));
+               /* check in order of largest to smallest */
+               if (((start & MASK_64KB) == 0) && (start + SIZE_64KB <= end)) {
+                       write_csr(dd, ASIC_EEP_ADDR_CMD,
+                                 CMD_SECTOR_ERASE_64KB(start));
+                       start += SIZE_64KB;
+               } else if (((start & MASK_32KB) == 0) &&
+                          (start + SIZE_32KB <= end)) {
+                       write_csr(dd, ASIC_EEP_ADDR_CMD,
+                                 CMD_SECTOR_ERASE_32KB(start));
+                       start += SIZE_32KB;
+               } else {        /* 4KB will work */
+                       write_csr(dd, ASIC_EEP_ADDR_CMD,
+                                 CMD_SECTOR_ERASE_4KB(start));
+                       start += SIZE_4KB;
+               }
                ret = wait_for_not_busy(dd);
                if (ret)
                        goto done;
@@ -309,6 +335,18 @@ done:
        return ret;
 }
 
+/* convert an range composite to a length, in bytes */
+static inline u32 extract_rlen(u32 composite)
+{
+       return (composite & 0xffff) * EP_PAGE_SIZE;
+}
+
+/* convert an range composite to a start, in bytes */
+static inline u32 extract_rstart(u32 composite)
+{
+       return (composite >> 16) * EP_PAGE_SIZE;
+}
+
 /*
  * Perform the given operation on the EPROM.  Called from user space.  The
  * user credentials have already been checked.
@@ -319,6 +357,8 @@ int handle_eprom_command(const struct hfi1_cmd *cmd)
 {
        struct hfi1_devdata *dd;
        u32 dev_id;
+       u32 rlen;       /* range length */
+       u32 rstart;     /* range start */
        int ret = 0;
 
        /*
@@ -364,54 +404,29 @@ int handle_eprom_command(const struct hfi1_cmd *cmd)
                                                                sizeof(u32)))
                        ret = -EFAULT;
                break;
+
        case HFI1_CMD_EP_ERASE_CHIP:
                ret = erase_chip(dd);
                break;
-       case HFI1_CMD_EP_ERASE_P0:
-               if (cmd->len != P0_SIZE) {
-                       ret = -ERANGE;
-                       break;
-               }
-               ret = erase_32kb_range(dd, 0, cmd->len);
-               break;
-       case HFI1_CMD_EP_ERASE_P1:
-               /* check for overflow */
-               if (P1_START + cmd->len > ASIC_EEP_ADDR_CMD_EP_ADDR_MASK) {
-                       ret = -ERANGE;
-                       break;
-               }
-               ret = erase_32kb_range(dd, P1_START, P1_START + cmd->len);
-               break;
-       case HFI1_CMD_EP_READ_P0:
-               if (cmd->len != P0_SIZE) {
-                       ret = -ERANGE;
-                       break;
-               }
-               ret = read_length(dd, 0, cmd->len, cmd->addr);
-               break;
-       case HFI1_CMD_EP_READ_P1:
-               /* check for overflow */
-               if (P1_START + cmd->len > ASIC_EEP_ADDR_CMD_EP_ADDR_MASK) {
-                       ret = -ERANGE;
-                       break;
-               }
-               ret = read_length(dd, P1_START, cmd->len, cmd->addr);
+
+       case HFI1_CMD_EP_ERASE_RANGE:
+               rlen = extract_rlen(cmd->len);
+               rstart = extract_rstart(cmd->len);
+               ret = erase_range(dd, rstart, rlen);
                break;
-       case HFI1_CMD_EP_WRITE_P0:
-               if (cmd->len > P0_SIZE) {
-                       ret = -ERANGE;
-                       break;
-               }
-               ret = write_length(dd, 0, cmd->len, cmd->addr);
+
+       case HFI1_CMD_EP_READ_RANGE:
+               rlen = extract_rlen(cmd->len);
+               rstart = extract_rstart(cmd->len);
+               ret = read_length(dd, rstart, rlen, cmd->addr);
                break;
-       case HFI1_CMD_EP_WRITE_P1:
-               /* check for overflow */
-               if (P1_START + cmd->len > ASIC_EEP_ADDR_CMD_EP_ADDR_MASK) {
-                       ret = -ERANGE;
-                       break;
-               }
-               ret = write_length(dd, P1_START, cmd->len, cmd->addr);
+
+       case HFI1_CMD_EP_WRITE_RANGE:
+               rlen = extract_rlen(cmd->len);
+               rstart = extract_rstart(cmd->len);
+               ret = write_length(dd, rstart, rlen, cmd->addr);
                break;
+
        default:
                dd_dev_err(dd, "%s: unexpected command %d\n",
                        __func__, cmd->type);
index 22037ce984c83e3ffddf36e7c223af4536215fb8..d57d549052c8fcfe9a5adfbae46a5cf01f6dd985 100644 (file)
@@ -234,12 +234,9 @@ static ssize_t hfi1_file_write(struct file *fp, const char __user *data,
                break;
        case HFI1_CMD_EP_INFO:
        case HFI1_CMD_EP_ERASE_CHIP:
-       case HFI1_CMD_EP_ERASE_P0:
-       case HFI1_CMD_EP_ERASE_P1:
-       case HFI1_CMD_EP_READ_P0:
-       case HFI1_CMD_EP_READ_P1:
-       case HFI1_CMD_EP_WRITE_P0:
-       case HFI1_CMD_EP_WRITE_P1:
+       case HFI1_CMD_EP_ERASE_RANGE:
+       case HFI1_CMD_EP_READ_RANGE:
+       case HFI1_CMD_EP_WRITE_RANGE:
                uctxt_required = 0;     /* assigned user context not required */
                must_be_root = 1;       /* validate user */
                copy = 0;
@@ -393,12 +390,9 @@ static ssize_t hfi1_file_write(struct file *fp, const char __user *data,
        }
        case HFI1_CMD_EP_INFO:
        case HFI1_CMD_EP_ERASE_CHIP:
-       case HFI1_CMD_EP_ERASE_P0:
-       case HFI1_CMD_EP_ERASE_P1:
-       case HFI1_CMD_EP_READ_P0:
-       case HFI1_CMD_EP_READ_P1:
-       case HFI1_CMD_EP_WRITE_P0:
-       case HFI1_CMD_EP_WRITE_P1:
+       case HFI1_CMD_EP_ERASE_RANGE:
+       case HFI1_CMD_EP_READ_RANGE:
+       case HFI1_CMD_EP_WRITE_RANGE:
                ret = handle_eprom_command(&cmd);
                break;
        }
@@ -737,8 +731,7 @@ static int hfi1_file_close(struct inode *inode, struct file *fp)
 
        flush_wc();
        /* drain user sdma queue */
-       if (fdata->pq)
-               hfi1_user_sdma_free_queues(fdata);
+       hfi1_user_sdma_free_queues(fdata);
 
        /*
         * Clear any left over, unhandled events so the next process that
@@ -1670,8 +1663,8 @@ static int exp_tid_setup(struct file *fp, struct hfi1_tid_info *tinfo)
                 * Now that we know how many free RcvArray entries we have,
                 * we can pin that many user pages.
                 */
-               ret = hfi1_get_user_pages(vaddr + (mapped * PAGE_SIZE),
-                                         pinned, pages);
+               ret = hfi1_acquire_user_pages(vaddr + (mapped * PAGE_SIZE),
+                                             pinned, true, pages);
                if (ret) {
                        /*
                         * We can't continue because the pages array won't be
@@ -1840,7 +1833,7 @@ static int exp_tid_free(struct file *fp, struct hfi1_tid_info *tinfo)
                                }
                        }
                        flush_wc();
-                       hfi1_release_user_pages(pshadow, pcount);
+                       hfi1_release_user_pages(pshadow, pcount, true);
                        clear_bit(bitidx, &uctxt->tidusemap[idx]);
                        map &= ~(1ULL<<bitidx);
                }
@@ -1869,7 +1862,7 @@ static void unlock_exp_tids(struct hfi1_ctxtdata *uctxt)
                uctxt->physshadow[tid] = 0;
                uctxt->tid_pg_list[tid] = NULL;
                pci_unmap_page(dd->pcidev, phys, PAGE_SIZE, PCI_DMA_FROMDEVICE);
-               hfi1_release_user_pages(&p, 1);
+               hfi1_release_user_pages(&p, 1, true);
        }
 }
 
index f3112821cf4759f5199f04e85107e120bee98bb9..28ae42faa0187885119fc82c54c328738ada5d0d 100644 (file)
 #define DEFAULT_FW_SBUS_NAME "hfi1_sbus.fw"
 #define DEFAULT_FW_PCIE_NAME "hfi1_pcie.fw"
 #define DEFAULT_PLATFORM_CONFIG_NAME "hfi1_platform.dat"
+#define ALT_FW_8051_NAME_ASIC "hfi1_dc8051_d.fw"
+#define ALT_FW_FABRIC_NAME "hfi1_fabric_d.fw"
+#define ALT_FW_SBUS_NAME "hfi1_sbus_d.fw"
+#define ALT_FW_PCIE_NAME "hfi1_pcie_d.fw"
 
 static uint fw_8051_load = 1;
 static uint fw_fabric_serdes_load = 1;
@@ -158,7 +162,8 @@ struct firmware_details {
 static DEFINE_MUTEX(fw_mutex);
 enum fw_state {
        FW_EMPTY,
-       FW_ACQUIRED,
+       FW_TRY,
+       FW_FINAL,
        FW_ERR
 };
 static enum fw_state fw_state = FW_EMPTY;
@@ -428,8 +433,8 @@ static int obtain_one_firmware(struct hfi1_devdata *dd, const char *name,
 
        ret = request_firmware(&fdet->fw, name, &dd->pcidev->dev);
        if (ret) {
-               dd_dev_err(dd, "cannot load firmware \"%s\", err %d\n",
-                       name, ret);
+               dd_dev_err(dd, "cannot find firmware \"%s\", err %d\n",
+                          name, ret);
                return ret;
        }
 
@@ -539,28 +544,53 @@ done:
 static void dispose_one_firmware(struct firmware_details *fdet)
 {
        release_firmware(fdet->fw);
-       fdet->fw = NULL;
+       /* erase all previous information */
+       memset(fdet, 0, sizeof(*fdet));
 }
 
 /*
- * Called by all HFIs when loading their firmware - i.e. device probe time.
- * The first one will do the actual firmware load.  Use a mutex to resolve
- * any possible race condition.
+ * Obtain the 4 firmwares from the OS.  All must be obtained at once or not
+ * at all.  If called with the firmware state in FW_TRY, use alternate names.
+ * On exit, this routine will have set the firmware state to one of FW_TRY,
+ * FW_FINAL, or FW_ERR.
  *
- * The call to this routine cannot be moved to driver load because the kernel
- * call request_firmware() requires a device which is only available after
- * the first device probe.
+ * Must be holding fw_mutex.
  */
-static int obtain_firmware(struct hfi1_devdata *dd)
+static void __obtain_firmware(struct hfi1_devdata *dd)
 {
        int err = 0;
 
-       mutex_lock(&fw_mutex);
-       if (fw_state == FW_ACQUIRED) {
-               goto done;      /* already acquired */
-       } else if (fw_state == FW_ERR) {
-               err = fw_err;
-               goto done;      /* already tried and failed */
+       if (fw_state == FW_FINAL)       /* nothing more to obtain */
+               return;
+       if (fw_state == FW_ERR)         /* already in error */
+               return;
+
+       /* fw_state is FW_EMPTY or FW_TRY */
+retry:
+       if (fw_state == FW_TRY) {
+               /*
+                * We tried the original and it failed.  Move to the
+                * alternate.
+                */
+               dd_dev_info(dd, "using alternate firmware names\n");
+               /*
+                * Let others run.  Some systems, when missing firmware, does
+                * something that holds for 30 seconds.  If we do that twice
+                * in a row it triggers task blocked warning.
+                */
+               cond_resched();
+               if (fw_8051_load)
+                       dispose_one_firmware(&fw_8051);
+               if (fw_fabric_serdes_load)
+                       dispose_one_firmware(&fw_fabric);
+               if (fw_sbus_load)
+                       dispose_one_firmware(&fw_sbus);
+               if (fw_pcie_serdes_load)
+                       dispose_one_firmware(&fw_pcie);
+               fw_8051_name = ALT_FW_8051_NAME_ASIC;
+               fw_fabric_serdes_name = ALT_FW_FABRIC_NAME;
+               fw_sbus_name = ALT_FW_SBUS_NAME;
+               fw_pcie_serdes_name = ALT_FW_PCIE_NAME;
        }
 
        if (fw_8051_load) {
@@ -588,27 +618,82 @@ static int obtain_firmware(struct hfi1_devdata *dd)
                        goto done;
        }
 
+done:
+       if (err) {
+               /* oops, had problems obtaining a firmware */
+               if (fw_state == FW_EMPTY) {
+                       /* retry with alternate */
+                       fw_state = FW_TRY;
+                       goto retry;
+               }
+               fw_state = FW_ERR;
+               fw_err = -ENOENT;
+       } else {
+               /* success */
+               if (fw_state == FW_EMPTY)
+                       fw_state = FW_TRY;      /* may retry later */
+               else
+                       fw_state = FW_FINAL;    /* cannot try again */
+       }
+}
+
+/*
+ * Called by all HFIs when loading their firmware - i.e. device probe time.
+ * The first one will do the actual firmware load.  Use a mutex to resolve
+ * any possible race condition.
+ *
+ * The call to this routine cannot be moved to driver load because the kernel
+ * call request_firmware() requires a device which is only available after
+ * the first device probe.
+ */
+static int obtain_firmware(struct hfi1_devdata *dd)
+{
+       unsigned long timeout;
+       int err = 0;
+
+       mutex_lock(&fw_mutex);
+
+       /* 40s delay due to long delay on missing firmware on some systems */
+       timeout = jiffies + msecs_to_jiffies(40000);
+       while (fw_state == FW_TRY) {
+               /*
+                * Another device is trying the firmware.  Wait until it
+                * decides what works (or not).
+                */
+               if (time_after(jiffies, timeout)) {
+                       /* waited too long */
+                       dd_dev_err(dd, "Timeout waiting for firmware try");
+                       fw_state = FW_ERR;
+                       fw_err = -ETIMEDOUT;
+                       break;
+               }
+               mutex_unlock(&fw_mutex);
+               msleep(20);     /* arbitrary delay */
+               mutex_lock(&fw_mutex);
+       }
+       /* not in FW_TRY state */
+
+       if (fw_state == FW_FINAL)
+               goto done;      /* already acquired */
+       else if (fw_state == FW_ERR)
+               goto done;      /* already tried and failed */
+       /* fw_state is FW_EMPTY */
+
+       /* set fw_state to FW_TRY, FW_FINAL, or FW_ERR, and fw_err */
+       __obtain_firmware(dd);
+
        if (platform_config_load) {
                platform_config = NULL;
                err = request_firmware(&platform_config, platform_config_name,
                                                &dd->pcidev->dev);
-               if (err) {
-                       err = 0;
+               if (err)
                        platform_config = NULL;
-               }
        }
 
-       /* success */
-       fw_state = FW_ACQUIRED;
-
 done:
-       if (err) {
-               fw_err = err;
-               fw_state = FW_ERR;
-       }
        mutex_unlock(&fw_mutex);
 
-       return err;
+       return fw_err;
 }
 
 /*
@@ -637,6 +722,38 @@ void dispose_firmware(void)
                fw_state = FW_EMPTY;
 }
 
+/*
+ * Called with the result of a firmware download.
+ *
+ * Return 1 to retry loading the firmware, 0 to stop.
+ */
+static int retry_firmware(struct hfi1_devdata *dd, int load_result)
+{
+       int retry;
+
+       mutex_lock(&fw_mutex);
+
+       if (load_result == 0) {
+               /*
+                * The load succeeded, so expect all others to do the same.
+                * Do not retry again.
+                */
+               if (fw_state == FW_TRY)
+                       fw_state = FW_FINAL;
+               retry = 0;      /* do NOT retry */
+       } else if (fw_state == FW_TRY) {
+               /* load failed, obtain alternate firmware */
+               __obtain_firmware(dd);
+               retry = (fw_state == FW_FINAL);
+       } else {
+               /* else in FW_FINAL or FW_ERR, no retry in either case */
+               retry = 0;
+       }
+
+       mutex_unlock(&fw_mutex);
+       return retry;
+}
+
 /*
  * Write a block of data to a given array CSR.  All calls will be in
  * multiples of 8 bytes.
@@ -951,7 +1068,7 @@ void sbus_request(struct hfi1_devdata *dd,
 static void turn_off_spicos(struct hfi1_devdata *dd, int flags)
 {
        /* only needed on A0 */
-       if (!is_a0(dd))
+       if (!is_ax(dd))
                return;
 
        dd_dev_info(dd, "Turning off spicos:%s%s\n",
@@ -1248,7 +1365,9 @@ int load_firmware(struct hfi1_devdata *dd)
                                fabric_serdes_addrs[dd->hfi1_id],
                                NUM_FABRIC_SERDES);
                turn_off_spicos(dd, SPICO_FABRIC);
-               ret = load_fabric_serdes_firmware(dd, &fw_fabric);
+               do {
+                       ret = load_fabric_serdes_firmware(dd, &fw_fabric);
+               } while (retry_firmware(dd, ret));
 
                clear_sbus_fast_mode(dd);
                release_hw_mutex(dd);
@@ -1257,7 +1376,9 @@ int load_firmware(struct hfi1_devdata *dd)
        }
 
        if (fw_8051_load) {
-               ret = load_8051_firmware(dd, &fw_8051);
+               do {
+                       ret = load_8051_firmware(dd, &fw_8051);
+               } while (retry_firmware(dd, ret));
                if (ret)
                        return ret;
        }
@@ -1570,7 +1691,9 @@ int load_pcie_firmware(struct hfi1_devdata *dd)
 
        if (fw_sbus_load) {
                turn_off_spicos(dd, SPICO_SBUS);
-               ret = load_sbus_firmware(dd, &fw_sbus);
+               do {
+                       ret = load_sbus_firmware(dd, &fw_sbus);
+               } while (retry_firmware(dd, ret));
                if (ret)
                        goto done;
        }
@@ -1581,7 +1704,9 @@ int load_pcie_firmware(struct hfi1_devdata *dd)
                                        pcie_serdes_broadcast[dd->hfi1_id],
                                        pcie_serdes_addrs[dd->hfi1_id],
                                        NUM_PCIE_SERDES);
-               ret = load_pcie_serdes_firmware(dd, &fw_pcie);
+               do {
+                       ret = load_pcie_serdes_firmware(dd, &fw_pcie);
+               } while (retry_firmware(dd, ret));
                if (ret)
                        goto done;
        }
index 54ed6b36c1a78ed63daa9f20c9cd387bafbfdd47..2611bb2e764d84ef354c8910f8554ae4ca49035c 100644 (file)
@@ -105,6 +105,20 @@ extern unsigned long hfi1_cap_mask;
  */
 #define HFI1_CTRL_CTXT    0
 
+/*
+ * Driver context will store software counters for each of the events
+ * associated with these status registers
+ */
+#define NUM_CCE_ERR_STATUS_COUNTERS 41
+#define NUM_RCV_ERR_STATUS_COUNTERS 64
+#define NUM_MISC_ERR_STATUS_COUNTERS 13
+#define NUM_SEND_PIO_ERR_STATUS_COUNTERS 36
+#define NUM_SEND_DMA_ERR_STATUS_COUNTERS 4
+#define NUM_SEND_EGRESS_ERR_STATUS_COUNTERS 64
+#define NUM_SEND_ERR_STATUS_COUNTERS 3
+#define NUM_SEND_CTXT_ERR_STATUS_COUNTERS 5
+#define NUM_SEND_DMA_ENG_ERR_STATUS_COUNTERS 24
+
 /*
  * per driver stats, either not device nor port-specific, or
  * summed over all of the devices and ports.
@@ -699,6 +713,8 @@ struct hfi1_pportdata {
        u64 link_downed;
        /* number of times link retrained successfully */
        u64 link_up;
+       /* number of times a link unknown frame was reported */
+       u64 unknown_frame_count;
        /* port_ltp_crc_mode is returned in 'portinfo' MADs */
        u16 port_ltp_crc_mode;
        /* port_crc_mode_enabled is the crc we support */
@@ -1046,6 +1062,26 @@ struct hfi1_devdata {
        atomic_t drop_packet;
        u8 do_drop;
 
+       /*
+        * Software counters for the status bits defined by the
+        * associated error status registers
+        */
+       u64 cce_err_status_cnt[NUM_CCE_ERR_STATUS_COUNTERS];
+       u64 rcv_err_status_cnt[NUM_RCV_ERR_STATUS_COUNTERS];
+       u64 misc_err_status_cnt[NUM_MISC_ERR_STATUS_COUNTERS];
+       u64 send_pio_err_status_cnt[NUM_SEND_PIO_ERR_STATUS_COUNTERS];
+       u64 send_dma_err_status_cnt[NUM_SEND_DMA_ERR_STATUS_COUNTERS];
+       u64 send_egress_err_status_cnt[NUM_SEND_EGRESS_ERR_STATUS_COUNTERS];
+       u64 send_err_status_cnt[NUM_SEND_ERR_STATUS_COUNTERS];
+
+       /* Software counter that spans all contexts */
+       u64 sw_ctxt_err_status_cnt[NUM_SEND_CTXT_ERR_STATUS_COUNTERS];
+       /* Software counter that spans all DMA engines */
+       u64 sw_send_dma_eng_err_status_cnt[
+               NUM_SEND_DMA_ENG_ERR_STATUS_COUNTERS];
+       /* Software counter that aggregates all cce_err_status errors */
+       u64 sw_cce_err_status_aggregate;
+
        /* receive interrupt functions */
        rhf_rcv_function_ptr *rhf_rcv_function_map;
        rhf_rcv_function_ptr normal_rhf_rcv_functions[8];
@@ -1551,8 +1587,8 @@ void hfi1_set_led_override(struct hfi1_pportdata *ppd, unsigned int val);
  */
 #define DEFAULT_RCVHDR_ENTSIZE 32
 
-int hfi1_get_user_pages(unsigned long, size_t, struct page **);
-void hfi1_release_user_pages(struct page **, size_t);
+int hfi1_acquire_user_pages(unsigned long, size_t, bool, struct page **);
+void hfi1_release_user_pages(struct page **, size_t, bool);
 
 static inline void clear_rcvhdrtail(const struct hfi1_ctxtdata *rcd)
 {
@@ -1629,7 +1665,7 @@ void update_sge(struct hfi1_sge_state *ss, u32 length);
 extern unsigned int hfi1_max_mtu;
 extern unsigned int hfi1_cu;
 extern unsigned int user_credit_return_threshold;
-extern uint num_rcv_contexts;
+extern int num_user_contexts;
 extern unsigned n_krcvqs;
 extern u8 krcvqs[];
 extern int krcvqsset;
@@ -1693,7 +1729,7 @@ static inline u64 hfi1_pkt_default_send_ctxt_mask(struct hfi1_devdata *dd,
        else
                base_sc_integrity |= HFI1_PKT_KERNEL_SC_INTEGRITY;
 
-       if (is_a0(dd))
+       if (is_ax(dd))
                /* turn off send-side job key checks - A0 erratum */
                return base_sc_integrity &
                       ~SEND_CTXT_CHECK_ENABLE_CHECK_JOB_KEY_SMASK;
@@ -1720,7 +1756,7 @@ static inline u64 hfi1_pkt_base_sdma_integrity(struct hfi1_devdata *dd)
        | SEND_DMA_CHECK_ENABLE_CHECK_VL_SMASK
        | SEND_DMA_CHECK_ENABLE_CHECK_ENABLE_SMASK;
 
-       if (is_a0(dd))
+       if (is_ax(dd))
                /* turn off send-side job key checks - A0 erratum */
                return base_sdma_integrity &
                       ~SEND_DMA_CHECK_ENABLE_CHECK_JOB_KEY_SMASK;
index 1c8286f4c00cab1f7ef9da61569866753ced511f..4dd8051aba7ef7868ac12f6405742a3f476ccb89 100644 (file)
  * Number of user receive contexts we are configured to use (to allow for more
  * pio buffers per ctxt, etc.)  Zero means use one user context per CPU.
  */
-uint num_rcv_contexts;
-module_param_named(num_rcv_contexts, num_rcv_contexts, uint, S_IRUGO);
+int num_user_contexts = -1;
+module_param_named(num_user_contexts, num_user_contexts, uint, S_IRUGO);
 MODULE_PARM_DESC(
-       num_rcv_contexts, "Set max number of user receive contexts to use");
+       num_user_contexts, "Set max number of user contexts to use");
 
 u8 krcvqs[RXE_NUM_DATA_VL];
 int krcvqsset;
@@ -113,7 +113,7 @@ MODULE_PARM_DESC(hdrq_entsize, "Size of header queue entries: 2 - 8B, 16 - 64B (
 
 unsigned int user_credit_return_threshold = 33;        /* default is 33% */
 module_param(user_credit_return_threshold, uint, S_IRUGO);
-MODULE_PARM_DESC(user_credit_return_theshold, "Credit return threshold for user send contexts, return when unreturned credits passes this many blocks (in percent of allocated blocks, 0 is off)");
+MODULE_PARM_DESC(user_credit_return_threshold, "Credit return threshold for user send contexts, return when unreturned credits passes this many blocks (in percent of allocated blocks, 0 is off)");
 
 static inline u64 encode_rcv_header_entry_size(u16);
 
@@ -678,7 +678,7 @@ int hfi1_init(struct hfi1_devdata *dd, int reinit)
        dd->process_dma_send = hfi1_verbs_send_dma;
        dd->pio_inline_send = pio_copy;
 
-       if (is_a0(dd)) {
+       if (is_ax(dd)) {
                atomic_set(&dd->drop_packet, DROP_PACKET_ON);
                dd->do_drop = 1;
        } else {
@@ -1336,6 +1336,7 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
        int ret = 0, j, pidx, initfail;
        struct hfi1_devdata *dd = NULL;
+       struct hfi1_pportdata *ppd;
 
        /* First, lock the non-writable module parameters */
        HFI1_CAP_LOCK();
@@ -1350,6 +1351,7 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        if (!encode_rcv_header_entry_size(hfi1_hdrq_entsize)) {
                hfi1_early_err(&pdev->dev, "Invalid HdrQ Entry size %u\n",
                               hfi1_hdrq_entsize);
+               ret = -EINVAL;
                goto bail;
        }
 
@@ -1431,8 +1433,14 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        if (initfail || ret) {
                stop_timers(dd);
                flush_workqueue(ib_wq);
-               for (pidx = 0; pidx < dd->num_pports; ++pidx)
+               for (pidx = 0; pidx < dd->num_pports; ++pidx) {
                        hfi1_quiet_serdes(dd->pport + pidx);
+                       ppd = dd->pport + pidx;
+                       if (ppd->hfi1_wq) {
+                               destroy_workqueue(ppd->hfi1_wq);
+                               ppd->hfi1_wq = NULL;
+                       }
+               }
                if (!j)
                        hfi1_device_remove(dd);
                if (!ret)
index a1225651005c164804fc2f63f5bf8cb03352bd53..4f5dbd14b5de8a689f84caa8432a3d77357d611e 100644 (file)
@@ -84,7 +84,7 @@ static void send_trap(struct hfi1_ibport *ibp, void *data, unsigned len)
 {
        struct ib_mad_send_buf *send_buf;
        struct ib_mad_agent *agent;
-       struct ib_smp *smp;
+       struct opa_smp *smp;
        int ret;
        unsigned long flags;
        unsigned long timeout;
@@ -117,15 +117,15 @@ static void send_trap(struct hfi1_ibport *ibp, void *data, unsigned len)
                return;
 
        smp = send_buf->mad;
-       smp->base_version = IB_MGMT_BASE_VERSION;
+       smp->base_version = OPA_MGMT_BASE_VERSION;
        smp->mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED;
-       smp->class_version = 1;
+       smp->class_version = OPA_SMI_CLASS_VERSION;
        smp->method = IB_MGMT_METHOD_TRAP;
        ibp->tid++;
        smp->tid = cpu_to_be64(ibp->tid);
        smp->attr_id = IB_SMP_ATTR_NOTICE;
        /* o14-1: smp->mkey = 0; */
-       memcpy(smp->data, data, len);
+       memcpy(smp->route.lid.data, data, len);
 
        spin_lock_irqsave(&ibp->lock, flags);
        if (!ibp->sm_ah) {
@@ -164,11 +164,16 @@ static void send_trap(struct hfi1_ibport *ibp, void *data, unsigned len)
  * Send a bad [PQ]_Key trap (ch. 14.3.8).
  */
 void hfi1_bad_pqkey(struct hfi1_ibport *ibp, __be16 trap_num, u32 key, u32 sl,
-                   u32 qp1, u32 qp2, __be16 lid1, __be16 lid2)
+                   u32 qp1, u32 qp2, u16 lid1, u16 lid2)
 {
-       struct ib_mad_notice_attr data;
+       struct opa_mad_notice_attr data;
+       u32 lid = ppd_from_ibp(ibp)->lid;
+       u32 _lid1 = lid1;
+       u32 _lid2 = lid2;
 
-       if (trap_num == IB_NOTICE_TRAP_BAD_PKEY)
+       memset(&data, 0, sizeof(data));
+
+       if (trap_num == OPA_TRAP_BAD_P_KEY)
                ibp->pkey_violations++;
        else
                ibp->qkey_violations++;
@@ -176,17 +181,15 @@ void hfi1_bad_pqkey(struct hfi1_ibport *ibp, __be16 trap_num, u32 key, u32 sl,
 
        /* Send violation trap */
        data.generic_type = IB_NOTICE_TYPE_SECURITY;
-       data.prod_type_msb = 0;
        data.prod_type_lsb = IB_NOTICE_PROD_CA;
        data.trap_num = trap_num;
-       data.issuer_lid = cpu_to_be16(ppd_from_ibp(ibp)->lid);
-       data.toggle_count = 0;
-       memset(&data.details, 0, sizeof(data.details));
-       data.details.ntc_257_258.lid1 = lid1;
-       data.details.ntc_257_258.lid2 = lid2;
-       data.details.ntc_257_258.key = cpu_to_be32(key);
-       data.details.ntc_257_258.sl_qp1 = cpu_to_be32((sl << 28) | qp1);
-       data.details.ntc_257_258.qp2 = cpu_to_be32(qp2);
+       data.issuer_lid = cpu_to_be32(lid);
+       data.ntc_257_258.lid1 = cpu_to_be32(_lid1);
+       data.ntc_257_258.lid2 = cpu_to_be32(_lid2);
+       data.ntc_257_258.key = cpu_to_be32(key);
+       data.ntc_257_258.sl = sl << 3;
+       data.ntc_257_258.qp1 = cpu_to_be32(qp1);
+       data.ntc_257_258.qp2 = cpu_to_be32(qp2);
 
        send_trap(ibp, &data, sizeof(data));
 }
@@ -197,32 +200,30 @@ void hfi1_bad_pqkey(struct hfi1_ibport *ibp, __be16 trap_num, u32 key, u32 sl,
 static void bad_mkey(struct hfi1_ibport *ibp, struct ib_mad_hdr *mad,
                     __be64 mkey, __be32 dr_slid, u8 return_path[], u8 hop_cnt)
 {
-       struct ib_mad_notice_attr data;
+       struct opa_mad_notice_attr data;
+       u32 lid = ppd_from_ibp(ibp)->lid;
 
+       memset(&data, 0, sizeof(data));
        /* Send violation trap */
        data.generic_type = IB_NOTICE_TYPE_SECURITY;
-       data.prod_type_msb = 0;
        data.prod_type_lsb = IB_NOTICE_PROD_CA;
-       data.trap_num = IB_NOTICE_TRAP_BAD_MKEY;
-       data.issuer_lid = cpu_to_be16(ppd_from_ibp(ibp)->lid);
-       data.toggle_count = 0;
-       memset(&data.details, 0, sizeof(data.details));
-       data.details.ntc_256.lid = data.issuer_lid;
-       data.details.ntc_256.method = mad->method;
-       data.details.ntc_256.attr_id = mad->attr_id;
-       data.details.ntc_256.attr_mod = mad->attr_mod;
-       data.details.ntc_256.mkey = mkey;
+       data.trap_num = OPA_TRAP_BAD_M_KEY;
+       data.issuer_lid = cpu_to_be32(lid);
+       data.ntc_256.lid = data.issuer_lid;
+       data.ntc_256.method = mad->method;
+       data.ntc_256.attr_id = mad->attr_id;
+       data.ntc_256.attr_mod = mad->attr_mod;
+       data.ntc_256.mkey = mkey;
        if (mad->mgmt_class == IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE) {
-
-               data.details.ntc_256.dr_slid = (__force __be16)dr_slid;
-               data.details.ntc_256.dr_trunc_hop = IB_NOTICE_TRAP_DR_NOTICE;
-               if (hop_cnt > ARRAY_SIZE(data.details.ntc_256.dr_rtn_path)) {
-                       data.details.ntc_256.dr_trunc_hop |=
+               data.ntc_256.dr_slid = dr_slid;
+               data.ntc_256.dr_trunc_hop = IB_NOTICE_TRAP_DR_NOTICE;
+               if (hop_cnt > ARRAY_SIZE(data.ntc_256.dr_rtn_path)) {
+                       data.ntc_256.dr_trunc_hop |=
                                IB_NOTICE_TRAP_DR_TRUNC;
-                       hop_cnt = ARRAY_SIZE(data.details.ntc_256.dr_rtn_path);
+                       hop_cnt = ARRAY_SIZE(data.ntc_256.dr_rtn_path);
                }
-               data.details.ntc_256.dr_trunc_hop |= hop_cnt;
-               memcpy(data.details.ntc_256.dr_rtn_path, return_path,
+               data.ntc_256.dr_trunc_hop |= hop_cnt;
+               memcpy(data.ntc_256.dr_rtn_path, return_path,
                       hop_cnt);
        }
 
@@ -234,17 +235,17 @@ static void bad_mkey(struct hfi1_ibport *ibp, struct ib_mad_hdr *mad,
  */
 void hfi1_cap_mask_chg(struct hfi1_ibport *ibp)
 {
-       struct ib_mad_notice_attr data;
+       struct opa_mad_notice_attr data;
+       u32 lid = ppd_from_ibp(ibp)->lid;
+
+       memset(&data, 0, sizeof(data));
 
        data.generic_type = IB_NOTICE_TYPE_INFO;
-       data.prod_type_msb = 0;
        data.prod_type_lsb = IB_NOTICE_PROD_CA;
-       data.trap_num = IB_NOTICE_TRAP_CAP_MASK_CHG;
-       data.issuer_lid = cpu_to_be16(ppd_from_ibp(ibp)->lid);
-       data.toggle_count = 0;
-       memset(&data.details, 0, sizeof(data.details));
-       data.details.ntc_144.lid = data.issuer_lid;
-       data.details.ntc_144.new_cap_mask = cpu_to_be32(ibp->port_cap_flags);
+       data.trap_num = OPA_TRAP_CHANGE_CAPABILITY;
+       data.issuer_lid = cpu_to_be32(lid);
+       data.ntc_144.lid = data.issuer_lid;
+       data.ntc_144.new_cap_mask = cpu_to_be32(ibp->port_cap_flags);
 
        send_trap(ibp, &data, sizeof(data));
 }
@@ -254,17 +255,17 @@ void hfi1_cap_mask_chg(struct hfi1_ibport *ibp)
  */
 void hfi1_sys_guid_chg(struct hfi1_ibport *ibp)
 {
-       struct ib_mad_notice_attr data;
+       struct opa_mad_notice_attr data;
+       u32 lid = ppd_from_ibp(ibp)->lid;
+
+       memset(&data, 0, sizeof(data));
 
        data.generic_type = IB_NOTICE_TYPE_INFO;
-       data.prod_type_msb = 0;
        data.prod_type_lsb = IB_NOTICE_PROD_CA;
-       data.trap_num = IB_NOTICE_TRAP_SYS_GUID_CHG;
-       data.issuer_lid = cpu_to_be16(ppd_from_ibp(ibp)->lid);
-       data.toggle_count = 0;
-       memset(&data.details, 0, sizeof(data.details));
-       data.details.ntc_145.lid = data.issuer_lid;
-       data.details.ntc_145.new_sys_guid = ib_hfi1_sys_image_guid;
+       data.trap_num = OPA_TRAP_CHANGE_SYSGUID;
+       data.issuer_lid = cpu_to_be32(lid);
+       data.ntc_145.new_sys_guid = ib_hfi1_sys_image_guid;
+       data.ntc_145.lid = data.issuer_lid;
 
        send_trap(ibp, &data, sizeof(data));
 }
@@ -274,18 +275,18 @@ void hfi1_sys_guid_chg(struct hfi1_ibport *ibp)
  */
 void hfi1_node_desc_chg(struct hfi1_ibport *ibp)
 {
-       struct ib_mad_notice_attr data;
+       struct opa_mad_notice_attr data;
+       u32 lid = ppd_from_ibp(ibp)->lid;
+
+       memset(&data, 0, sizeof(data));
 
        data.generic_type = IB_NOTICE_TYPE_INFO;
-       data.prod_type_msb = 0;
        data.prod_type_lsb = IB_NOTICE_PROD_CA;
-       data.trap_num = IB_NOTICE_TRAP_CAP_MASK_CHG;
-       data.issuer_lid = cpu_to_be16(ppd_from_ibp(ibp)->lid);
-       data.toggle_count = 0;
-       memset(&data.details, 0, sizeof(data.details));
-       data.details.ntc_144.lid = data.issuer_lid;
-       data.details.ntc_144.local_changes = 1;
-       data.details.ntc_144.change_flags = IB_NOTICE_TRAP_NODE_DESC_CHG;
+       data.trap_num = OPA_TRAP_CHANGE_CAPABILITY;
+       data.issuer_lid = cpu_to_be32(lid);
+       data.ntc_144.lid = data.issuer_lid;
+       data.ntc_144.change_flags =
+               cpu_to_be16(OPA_NOTICE_TRAP_NODE_DESC_CHG);
 
        send_trap(ibp, &data, sizeof(data));
 }
@@ -2076,13 +2077,20 @@ struct opa_aggregate {
        u8 data[0];
 };
 
-/* Request contains first two fields, response contains those plus the rest */
+#define MSK_LLI 0x000000f0
+#define MSK_LLI_SFT 4
+#define MSK_LER 0x0000000f
+#define MSK_LER_SFT 0
+#define ADD_LLI 8
+#define ADD_LER 2
+
+/* Request contains first three fields, response contains those plus the rest */
 struct opa_port_data_counters_msg {
        __be64 port_select_mask[4];
        __be32 vl_select_mask;
+       __be32 resolution;
 
        /* Response fields follow */
-       __be32 reserved1;
        struct _port_dctrs {
                u8 port_number;
                u8 reserved2[3];
@@ -2271,34 +2279,8 @@ static void a0_portstatus(struct hfi1_pportdata *ppd,
 {
        if (!is_bx(ppd->dd)) {
                unsigned long vl;
-               int vfi = 0;
                u64 max_vl_xmit_wait = 0, tmp;
                u32 vl_all_mask = VL_MASK_ALL;
-               u64 rcv_data, rcv_bubble;
-
-               rcv_data = be64_to_cpu(rsp->port_rcv_data);
-               rcv_bubble = be64_to_cpu(rsp->port_rcv_bubble);
-               /* In the measured time period, calculate the total number
-                * of flits that were received. Subtract out one false
-                * rcv_bubble increment for every 32 received flits but
-                * don't let the number go negative.
-                */
-               if (rcv_bubble >= (rcv_data>>5)) {
-                       rcv_bubble -= (rcv_data>>5);
-                       rsp->port_rcv_bubble = cpu_to_be64(rcv_bubble);
-               }
-               for_each_set_bit(vl, (unsigned long *)&(vl_select_mask),
-                                8 * sizeof(vl_select_mask)) {
-                       rcv_data = be64_to_cpu(rsp->vls[vfi].port_vl_rcv_data);
-                       rcv_bubble =
-                               be64_to_cpu(rsp->vls[vfi].port_vl_rcv_bubble);
-                       if (rcv_bubble >= (rcv_data>>5)) {
-                               rcv_bubble -= (rcv_data>>5);
-                               rsp->vls[vfi].port_vl_rcv_bubble =
-                                                       cpu_to_be64(rcv_bubble);
-                       }
-                       vfi++;
-               }
 
                for_each_set_bit(vl, (unsigned long *)&(vl_all_mask),
                                 8 * sizeof(vl_all_mask)) {
@@ -2363,8 +2345,6 @@ static int pma_get_opa_portstatus(struct opa_pma_mad *pmp,
                                          CNTR_INVALID_VL));
        rsp->port_rcv_data = cpu_to_be64(read_dev_cntr(dd, C_DC_RCV_FLITS,
                                         CNTR_INVALID_VL));
-       rsp->port_rcv_bubble =
-               cpu_to_be64(read_dev_cntr(dd, C_DC_RCV_BBL, CNTR_INVALID_VL));
        rsp->port_xmit_pkts = cpu_to_be64(read_dev_cntr(dd, C_DC_XMIT_PKTS,
                                          CNTR_INVALID_VL));
        rsp->port_rcv_pkts = cpu_to_be64(read_dev_cntr(dd, C_DC_RCV_PKTS,
@@ -2434,9 +2414,6 @@ static int pma_get_opa_portstatus(struct opa_pma_mad *pmp,
 
                tmp = read_dev_cntr(dd, C_DC_RX_FLIT_VL, idx_from_vl(vl));
                rsp->vls[vfi].port_vl_rcv_data = cpu_to_be64(tmp);
-               rsp->vls[vfi].port_vl_rcv_bubble =
-                       cpu_to_be64(read_dev_cntr(dd, C_DC_RCV_BBL_VL,
-                                       idx_from_vl(vl)));
 
                rsp->vls[vfi].port_vl_rcv_pkts =
                        cpu_to_be64(read_dev_cntr(dd, C_DC_RX_PKT_VL,
@@ -2474,7 +2451,8 @@ static int pma_get_opa_portstatus(struct opa_pma_mad *pmp,
        return reply((struct ib_mad_hdr *)pmp);
 }
 
-static u64 get_error_counter_summary(struct ib_device *ibdev, u8 port)
+static u64 get_error_counter_summary(struct ib_device *ibdev, u8 port,
+                                    u8 res_lli, u8 res_ler)
 {
        struct hfi1_devdata *dd = dd_from_ibdev(ibdev);
        struct hfi1_ibport *ibp = to_iport(ibdev, port);
@@ -2490,14 +2468,14 @@ static u64 get_error_counter_summary(struct ib_device *ibdev, u8 port)
                                                CNTR_INVALID_VL);
        error_counter_summary += read_dev_cntr(dd, C_DC_RMT_PHY_ERR,
                                                CNTR_INVALID_VL);
-       error_counter_summary += read_dev_cntr(dd, C_DC_TX_REPLAY,
-                                               CNTR_INVALID_VL);
-       error_counter_summary += read_dev_cntr(dd, C_DC_RX_REPLAY,
-                                               CNTR_INVALID_VL);
-       error_counter_summary += read_dev_cntr(dd, C_DC_SEQ_CRC_CNT,
-                                               CNTR_INVALID_VL);
-       error_counter_summary += read_dev_cntr(dd, C_DC_REINIT_FROM_PEER_CNT,
-                                               CNTR_INVALID_VL);
+       /* local link integrity must be right-shifted by the lli resolution */
+       tmp = read_dev_cntr(dd, C_DC_RX_REPLAY, CNTR_INVALID_VL);
+       tmp += read_dev_cntr(dd, C_DC_TX_REPLAY, CNTR_INVALID_VL);
+       error_counter_summary += (tmp >> res_lli);
+       /* link error recovery must b right-shifted by the ler resolution */
+       tmp = read_dev_cntr(dd, C_DC_SEQ_CRC_CNT, CNTR_INVALID_VL);
+       tmp += read_dev_cntr(dd, C_DC_REINIT_FROM_PEER_CNT, CNTR_INVALID_VL);
+       error_counter_summary += (tmp >> res_ler);
        error_counter_summary += read_dev_cntr(dd, C_DC_RCV_ERR,
                                                CNTR_INVALID_VL);
        error_counter_summary += read_dev_cntr(dd, C_RCV_OVF, CNTR_INVALID_VL);
@@ -2519,32 +2497,8 @@ static void a0_datacounters(struct hfi1_devdata *dd, struct _port_dctrs *rsp,
        if (!is_bx(dd)) {
                unsigned long vl;
                int vfi = 0;
-               u64 rcv_data, rcv_bubble, sum_vl_xmit_wait = 0;
-
-               rcv_data = be64_to_cpu(rsp->port_rcv_data);
-               rcv_bubble = be64_to_cpu(rsp->port_rcv_bubble);
-               /* In the measured time period, calculate the total number
-                * of flits that were received. Subtract out one false
-                * rcv_bubble increment for every 32 received flits but
-                * don't let the number go negative.
-                */
-               if (rcv_bubble >= (rcv_data>>5)) {
-                       rcv_bubble -= (rcv_data>>5);
-                       rsp->port_rcv_bubble = cpu_to_be64(rcv_bubble);
-               }
-               for_each_set_bit(vl, (unsigned long *)&(vl_select_mask),
-                               8 * sizeof(vl_select_mask)) {
-                       rcv_data = be64_to_cpu(rsp->vls[vfi].port_vl_rcv_data);
-                       rcv_bubble =
-                               be64_to_cpu(rsp->vls[vfi].port_vl_rcv_bubble);
-                       if (rcv_bubble >= (rcv_data>>5)) {
-                               rcv_bubble -= (rcv_data>>5);
-                               rsp->vls[vfi].port_vl_rcv_bubble =
-                                                       cpu_to_be64(rcv_bubble);
-                       }
-                       vfi++;
-               }
-               vfi = 0;
+               u64 sum_vl_xmit_wait = 0;
+
                for_each_set_bit(vl, (unsigned long *)&(vl_select_mask),
                                8 * sizeof(vl_select_mask)) {
                        u64 tmp = sum_vl_xmit_wait +
@@ -2575,6 +2529,7 @@ static int pma_get_opa_datacounters(struct opa_pma_mad *pmp,
        u32 num_ports;
        u8 num_pslm;
        u8 lq, num_vls;
+       u8 res_lli, res_ler;
        u64 port_mask;
        unsigned long port_num;
        unsigned long vl;
@@ -2585,6 +2540,10 @@ static int pma_get_opa_datacounters(struct opa_pma_mad *pmp,
        num_pslm = hweight64(be64_to_cpu(req->port_select_mask[3]));
        num_vls = hweight32(be32_to_cpu(req->vl_select_mask));
        vl_select_mask = be32_to_cpu(req->vl_select_mask);
+       res_lli = (u8)(be32_to_cpu(req->resolution) & MSK_LLI) >> MSK_LLI_SFT;
+       res_lli = res_lli ? res_lli + ADD_LLI : 0;
+       res_ler = (u8)(be32_to_cpu(req->resolution) & MSK_LER) >> MSK_LER_SFT;
+       res_ler = res_ler ? res_ler + ADD_LER : 0;
 
        if (num_ports != 1 || (vl_select_mask & ~VL_MASK_ALL)) {
                pmp->mad_hdr.status |= IB_SMP_INVALID_FIELD;
@@ -2635,8 +2594,6 @@ static int pma_get_opa_datacounters(struct opa_pma_mad *pmp,
                                                CNTR_INVALID_VL));
        rsp->port_rcv_data = cpu_to_be64(read_dev_cntr(dd, C_DC_RCV_FLITS,
                                                CNTR_INVALID_VL));
-       rsp->port_rcv_bubble =
-               cpu_to_be64(read_dev_cntr(dd, C_DC_RCV_BBL, CNTR_INVALID_VL));
        rsp->port_xmit_pkts = cpu_to_be64(read_dev_cntr(dd, C_DC_XMIT_PKTS,
                                                CNTR_INVALID_VL));
        rsp->port_rcv_pkts = cpu_to_be64(read_dev_cntr(dd, C_DC_RCV_PKTS,
@@ -2655,7 +2612,8 @@ static int pma_get_opa_datacounters(struct opa_pma_mad *pmp,
                cpu_to_be64(read_dev_cntr(dd, C_DC_RCV_BCN, CNTR_INVALID_VL));
 
        rsp->port_error_counter_summary =
-               cpu_to_be64(get_error_counter_summary(ibdev, port));
+               cpu_to_be64(get_error_counter_summary(ibdev, port,
+                                                     res_lli, res_ler));
 
        vlinfo = &(rsp->vls[0]);
        vfi = 0;
@@ -2675,9 +2633,6 @@ static int pma_get_opa_datacounters(struct opa_pma_mad *pmp,
                rsp->vls[vfi].port_vl_rcv_data =
                        cpu_to_be64(read_dev_cntr(dd, C_DC_RX_FLIT_VL,
                                                        idx_from_vl(vl)));
-               rsp->vls[vfi].port_vl_rcv_bubble =
-                       cpu_to_be64(read_dev_cntr(dd, C_DC_RCV_BBL_VL,
-                                       idx_from_vl(vl)));
 
                rsp->vls[vfi].port_vl_xmit_pkts =
                        cpu_to_be64(read_port_cntr(ppd, C_TX_PKT_VL,
index 47457501c0440c547a20f561c3a97075ce454cb2..f0317750e2fc9916a3b9fde28bccb623fbab1a1b 100644 (file)
 #endif
 #include "opa_compat.h"
 
+/*
+ * OPA Traps
+ */
+#define OPA_TRAP_GID_NOW_IN_SERVICE             cpu_to_be16(64)
+#define OPA_TRAP_GID_OUT_OF_SERVICE             cpu_to_be16(65)
+#define OPA_TRAP_ADD_MULTICAST_GROUP            cpu_to_be16(66)
+#define OPA_TRAL_DEL_MULTICAST_GROUP            cpu_to_be16(67)
+#define OPA_TRAP_UNPATH                         cpu_to_be16(68)
+#define OPA_TRAP_REPATH                         cpu_to_be16(69)
+#define OPA_TRAP_PORT_CHANGE_STATE              cpu_to_be16(128)
+#define OPA_TRAP_LINK_INTEGRITY                 cpu_to_be16(129)
+#define OPA_TRAP_EXCESSIVE_BUFFER_OVERRUN       cpu_to_be16(130)
+#define OPA_TRAP_FLOW_WATCHDOG                  cpu_to_be16(131)
+#define OPA_TRAP_CHANGE_CAPABILITY              cpu_to_be16(144)
+#define OPA_TRAP_CHANGE_SYSGUID                 cpu_to_be16(145)
+#define OPA_TRAP_BAD_M_KEY                      cpu_to_be16(256)
+#define OPA_TRAP_BAD_P_KEY                      cpu_to_be16(257)
+#define OPA_TRAP_BAD_Q_KEY                      cpu_to_be16(258)
+#define OPA_TRAP_SWITCH_BAD_PKEY                cpu_to_be16(259)
+#define OPA_SMA_TRAP_DATA_LINK_WIDTH            cpu_to_be16(2048)
 
+/*
+ * Generic trap/notice other local changes flags (trap 144).
+ */
+#define        OPA_NOTICE_TRAP_LWDE_CHG        0x08 /* Link Width Downgrade Enable
+                                             * changed
+                                             */
+#define OPA_NOTICE_TRAP_LSE_CHG         0x04 /* Link Speed Enable changed */
+#define OPA_NOTICE_TRAP_LWE_CHG         0x02 /* Link Width Enable changed */
+#define OPA_NOTICE_TRAP_NODE_DESC_CHG   0x01
+
+struct opa_mad_notice_attr {
+       u8 generic_type;
+       u8 prod_type_msb;
+       __be16 prod_type_lsb;
+       __be16 trap_num;
+       __be16 toggle_count;
+       __be32 issuer_lid;
+       __be32 reserved1;
+       union ib_gid issuer_gid;
+
+       union {
+               struct {
+                       u8      details[64];
+               } raw_data;
+
+               struct {
+                       union ib_gid    gid;
+               } __packed ntc_64_65_66_67;
+
+               struct {
+                       __be32  lid;
+               } __packed ntc_128;
+
+               struct {
+                       __be32  lid;            /* where violation happened */
+                       u8      port_num;       /* where violation happened */
+               } __packed ntc_129_130_131;
+
+               struct {
+                       __be32  lid;            /* LID where change occurred */
+                       __be32  new_cap_mask;   /* new capability mask */
+                       __be16  reserved2;
+                       __be16  cap_mask;
+                       __be16  change_flags;   /* low 4 bits only */
+               } __packed ntc_144;
+
+               struct {
+                       __be64  new_sys_guid;
+                       __be32  lid;            /* lid where sys guid changed */
+               } __packed ntc_145;
+
+               struct {
+                       __be32  lid;
+                       __be32  dr_slid;
+                       u8      method;
+                       u8      dr_trunc_hop;
+                       __be16  attr_id;
+                       __be32  attr_mod;
+                       __be64  mkey;
+                       u8      dr_rtn_path[30];
+               } __packed ntc_256;
+
+               struct {
+                       __be32          lid1;
+                       __be32          lid2;
+                       __be32          key;
+                       u8              sl;     /* SL: high 5 bits */
+                       u8              reserved3[3];
+                       union ib_gid    gid1;
+                       union ib_gid    gid2;
+                       __be32          qp1;    /* high 8 bits reserved */
+                       __be32          qp2;    /* high 8 bits reserved */
+               } __packed ntc_257_258;
+
+               struct {
+                       __be16          flags;  /* low 8 bits reserved */
+                       __be16          pkey;
+                       __be32          lid1;
+                       __be32          lid2;
+                       u8              sl;     /* SL: high 5 bits */
+                       u8              reserved4[3];
+                       union ib_gid    gid1;
+                       union ib_gid    gid2;
+                       __be32          qp1;    /* high 8 bits reserved */
+                       __be32          qp2;    /* high 8 bits reserved */
+               } __packed ntc_259;
+
+               struct {
+                       __be32  lid;
+               } __packed ntc_2048;
+
+       };
+       u8      class_data[0];
+};
 
 #define IB_VLARB_LOWPRI_0_31    1
 #define IB_VLARB_LOWPRI_32_63   2
index 0b7eafb0fc705045a4b888c2485c2e80bd72a8f4..8317b07d722a5ebcdb9ebe07d60fc437cfc2d690 100644 (file)
@@ -917,7 +917,7 @@ int do_pcie_gen3_transition(struct hfi1_devdata *dd)
        /*
         * A0 needs an additional SBR
         */
-       if (is_a0(dd))
+       if (is_ax(dd))
                nsbr++;
 
        /*
@@ -1193,7 +1193,7 @@ retry:
        write_csr(dd, CCE_DC_CTRL, 0);
 
        /* Set the LED off */
-       if (is_a0(dd))
+       if (is_ax(dd))
                setextled(dd, 0);
 
        /* check for any per-lane errors */
index eab58c12d91599e11ef47434193574b04071ced6..b51a4416312b8215db724a8d9592df6dfa72410d 100644 (file)
@@ -660,6 +660,24 @@ void set_pio_integrity(struct send_context *sc)
        write_kctxt_csr(dd, hw_context, SC(CHECK_ENABLE), reg);
 }
 
+static u32 get_buffers_allocated(struct send_context *sc)
+{
+       int cpu;
+       u32 ret = 0;
+
+       for_each_possible_cpu(cpu)
+               ret += *per_cpu_ptr(sc->buffers_allocated, cpu);
+       return ret;
+}
+
+static void reset_buffers_allocated(struct send_context *sc)
+{
+       int cpu;
+
+       for_each_possible_cpu(cpu)
+               (*per_cpu_ptr(sc->buffers_allocated, cpu)) = 0;
+}
+
 /*
  * Allocate a NUMA relative send context structure of the given type along
  * with a HW context.
@@ -668,7 +686,7 @@ struct send_context *sc_alloc(struct hfi1_devdata *dd, int type,
                              uint hdrqentsize, int numa)
 {
        struct send_context_info *sci;
-       struct send_context *sc;
+       struct send_context *sc = NULL;
        dma_addr_t pa;
        unsigned long flags;
        u64 reg;
@@ -686,10 +704,20 @@ struct send_context *sc_alloc(struct hfi1_devdata *dd, int type,
        if (!sc)
                return NULL;
 
+       sc->buffers_allocated = alloc_percpu(u32);
+       if (!sc->buffers_allocated) {
+               kfree(sc);
+               dd_dev_err(dd,
+                          "Cannot allocate buffers_allocated per cpu counters\n"
+                         );
+               return NULL;
+       }
+
        spin_lock_irqsave(&dd->sc_lock, flags);
        ret = sc_hw_alloc(dd, type, &sw_index, &hw_context);
        if (ret) {
                spin_unlock_irqrestore(&dd->sc_lock, flags);
+               free_percpu(sc->buffers_allocated);
                kfree(sc);
                return NULL;
        }
@@ -705,7 +733,6 @@ struct send_context *sc_alloc(struct hfi1_devdata *dd, int type,
        spin_lock_init(&sc->credit_ctrl_lock);
        INIT_LIST_HEAD(&sc->piowait);
        INIT_WORK(&sc->halt_work, sc_halted);
-       atomic_set(&sc->buffers_allocated, 0);
        init_waitqueue_head(&sc->halt_wait);
 
        /* grouping is always single context for now */
@@ -866,6 +893,7 @@ void sc_free(struct send_context *sc)
        spin_unlock_irqrestore(&dd->sc_lock, flags);
 
        kfree(sc->sr);
+       free_percpu(sc->buffers_allocated);
        kfree(sc);
 }
 
@@ -1029,7 +1057,7 @@ int sc_restart(struct send_context *sc)
                /* kernel context */
                loop = 0;
                while (1) {
-                       count = atomic_read(&sc->buffers_allocated);
+                       count = get_buffers_allocated(sc);
                        if (count == 0)
                                break;
                        if (loop > 100) {
@@ -1197,7 +1225,8 @@ int sc_enable(struct send_context *sc)
        sc->sr_head = 0;
        sc->sr_tail = 0;
        sc->flags = 0;
-       atomic_set(&sc->buffers_allocated, 0);
+       /* the alloc lock insures no fast path allocation */
+       reset_buffers_allocated(sc);
 
        /*
         * Clear all per-context errors.  Some of these will be set when
@@ -1373,7 +1402,8 @@ retry:
 
        /* there is enough room */
 
-       atomic_inc(&sc->buffers_allocated);
+       preempt_disable();
+       this_cpu_inc(*sc->buffers_allocated);
 
        /* read this once */
        head = sc->sr_head;
@@ -1565,6 +1595,7 @@ void sc_release_update(struct send_context *sc)
        u64 hw_free;
        u32 head, tail;
        unsigned long old_free;
+       unsigned long free;
        unsigned long extra;
        unsigned long flags;
        int code;
@@ -1579,7 +1610,7 @@ void sc_release_update(struct send_context *sc)
        extra = (((hw_free & CR_COUNTER_SMASK) >> CR_COUNTER_SHIFT)
                        - (old_free & CR_COUNTER_MASK))
                                & CR_COUNTER_MASK;
-       sc->free = old_free + extra;
+       free = old_free + extra;
        trace_hfi1_piofree(sc, extra);
 
        /* call sent buffer callbacks */
@@ -1589,7 +1620,7 @@ void sc_release_update(struct send_context *sc)
        while (head != tail) {
                pbuf = &sc->sr[tail].pbuf;
 
-               if (sent_before(sc->free, pbuf->sent_at)) {
+               if (sent_before(free, pbuf->sent_at)) {
                        /* not sent yet */
                        break;
                }
@@ -1603,8 +1634,10 @@ void sc_release_update(struct send_context *sc)
                if (tail >= sc->sr_size)
                        tail = 0;
        }
-       /* update tail, in case we moved it */
        sc->sr_tail = tail;
+       /* make sure tail is updated before free */
+       smp_wmb();
+       sc->free = free;
        spin_unlock_irqrestore(&sc->release_lock, flags);
        sc_piobufavail(sc);
 }
index 0bb885ca3cfb9b026c41e44b85ca2c40567e291d..53d3e0a79375773ec85e4f0e820fd3d4f2388264 100644 (file)
@@ -130,7 +130,7 @@ struct send_context {
        spinlock_t credit_ctrl_lock ____cacheline_aligned_in_smp;
        u64 credit_ctrl;                /* cache for credit control */
        u32 credit_intr_count;          /* count of credit intr users */
-       atomic_t buffers_allocated;     /* count of buffers allocated */
+       u32 __percpu *buffers_allocated;/* count of buffers allocated */
        wait_queue_head_t halt_wait;    /* wait until kernel sees interrupt */
 };
 
index 8972bbc0203854210305011c928e14e011fb653f..ebb0bafc68cb09e3bdd29ad6909045f5fd5d9951 100644 (file)
@@ -160,7 +160,8 @@ void pio_copy(struct hfi1_devdata *dd, struct pio_buf *pbuf, u64 pbc,
        }
 
        /* finished with this buffer */
-       atomic_dec(&pbuf->sc->buffers_allocated);
+       this_cpu_dec(*pbuf->sc->buffers_allocated);
+       preempt_enable();
 }
 
 /* USE_SHIFTS is faster in user-space tests on a Xeon X5570 @ 2.93GHz */
@@ -854,5 +855,6 @@ void seg_pio_copy_end(struct pio_buf *pbuf)
        }
 
        /* finished with this buffer */
-       atomic_dec(&pbuf->sc->buffers_allocated);
+       this_cpu_dec(*pbuf->sc->buffers_allocated);
+       preempt_enable();
 }
index 94fd748a00a614291e89677b5d514a5c5626d264..62a94c5d7dcaab9bc12182064440543e69fddea5 100644 (file)
@@ -211,7 +211,7 @@ int hfi1_qp_init(struct hfi1_ibdev *dev);
 void hfi1_qp_exit(struct hfi1_ibdev *dev);
 
 /**
- * hfi1_qp_waitup - wake up on the indicated event
+ * hfi1_qp_wakeup - wake up on the indicated event
  * @qp: the QP
  * @flag: flag the qp on which the qp is stalled
  */
@@ -222,19 +222,19 @@ struct sdma_engine *qp_to_sdma_engine(struct hfi1_qp *qp, u8 sc5);
 struct qp_iter;
 
 /**
- * qp_iter_init - wake up on the indicated event
+ * qp_iter_init - initialize the iterator for the qp hash list
  * @dev: the hfi1_ibdev
  */
 struct qp_iter *qp_iter_init(struct hfi1_ibdev *dev);
 
 /**
- * qp_iter_next - wakeup on the indicated event
+ * qp_iter_next - Find the next qp in the hash list
  * @iter: the iterator for the qp hash list
  */
 int qp_iter_next(struct qp_iter *iter);
 
 /**
- * qp_iter_next - wake up on the indicated event
+ * qp_iter_print - print the qp information to seq_file
  * @s: the seq_file to emit the qp information on
  * @iter: the iterator for the qp hash list
  */
index 317bf6ff46a8609af8b82a249aea9948346c336e..4a91975b68d7e936c3f611e9dc9584cc2d6f01f0 100644 (file)
@@ -288,11 +288,12 @@ int hfi1_ruc_check_hdr(struct hfi1_ibport *ibp, struct hfi1_ib_header *hdr,
                }
                if (unlikely(rcv_pkey_check(ppd_from_ibp(ibp), (u16)bth0,
                                            sc5, be16_to_cpu(hdr->lrh[3])))) {
-                       hfi1_bad_pqkey(ibp, IB_NOTICE_TRAP_BAD_PKEY,
+                       hfi1_bad_pqkey(ibp, OPA_TRAP_BAD_P_KEY,
                                       (u16)bth0,
                                       (be16_to_cpu(hdr->lrh[0]) >> 4) & 0xF,
                                       0, qp->ibqp.qp_num,
-                                      hdr->lrh[3], hdr->lrh[1]);
+                                      be16_to_cpu(hdr->lrh[3]),
+                                      be16_to_cpu(hdr->lrh[1]));
                        goto err;
                }
                /* Validate the SLID. See Ch. 9.6.1.5 and 17.2.8 */
@@ -320,11 +321,12 @@ int hfi1_ruc_check_hdr(struct hfi1_ibport *ibp, struct hfi1_ib_header *hdr,
                }
                if (unlikely(rcv_pkey_check(ppd_from_ibp(ibp), (u16)bth0,
                                            sc5, be16_to_cpu(hdr->lrh[3])))) {
-                       hfi1_bad_pqkey(ibp, IB_NOTICE_TRAP_BAD_PKEY,
+                       hfi1_bad_pqkey(ibp, OPA_TRAP_BAD_P_KEY,
                                       (u16)bth0,
                                       (be16_to_cpu(hdr->lrh[0]) >> 4) & 0xF,
                                       0, qp->ibqp.qp_num,
-                                      hdr->lrh[3], hdr->lrh[1]);
+                                      be16_to_cpu(hdr->lrh[3]),
+                                      be16_to_cpu(hdr->lrh[1]));
                        goto err;
                }
                /* Validate the SLID. See Ch. 9.6.1.5 */
index 90b7072a99698a6b30d4caf68f4495e63b31b09b..9a15f1f32b45d5dbdea1d446e287dbf1bf2a36de 100644 (file)
@@ -765,8 +765,14 @@ struct sdma_engine *sdma_select_engine_vl(
        struct sdma_map_elem *e;
        struct sdma_engine *rval;
 
-       if (WARN_ON(vl > 8))
-               return &dd->per_sdma[0];
+       /* NOTE This should only happen if SC->VL changed after the initial
+        *      checks on the QP/AH
+        *      Default will return engine 0 below
+        */
+       if (vl >= num_vls) {
+               rval = NULL;
+               goto done;
+       }
 
        rcu_read_lock();
        m = rcu_dereference(dd->sdma_map);
@@ -778,6 +784,7 @@ struct sdma_engine *sdma_select_engine_vl(
        rval = e->sde[selector & e->mask];
        rcu_read_unlock();
 
+done:
        rval =  !rval ? &dd->per_sdma[0] : rval;
        trace_hfi1_sdma_engine_select(dd, selector, vl, rval->this_idx);
        return rval;
@@ -2724,22 +2731,21 @@ static int _extend_sdma_tx_descs(struct hfi1_devdata *dd, struct sdma_txreq *tx)
                        tx->coalesce_buf = kmalloc(tx->tlen + sizeof(u32),
                                                   GFP_ATOMIC);
                        if (!tx->coalesce_buf)
-                               return -ENOMEM;
-
+                               goto enomem;
                        tx->coalesce_idx = 0;
                }
                return 0;
        }
 
        if (unlikely(tx->num_desc == MAX_DESC))
-               return -ENOMEM;
+               goto enomem;
 
        tx->descp = kmalloc_array(
                        MAX_DESC,
                        sizeof(struct sdma_desc),
                        GFP_ATOMIC);
        if (!tx->descp)
-               return -ENOMEM;
+               goto enomem;
 
        /* reserve last descriptor for coalescing */
        tx->desc_limit = MAX_DESC - 1;
@@ -2747,6 +2753,9 @@ static int _extend_sdma_tx_descs(struct hfi1_devdata *dd, struct sdma_txreq *tx)
        for (i = 0; i < tx->num_desc; i++)
                tx->descp[i] = tx->descs[i];
        return 0;
+enomem:
+       sdma_txclean(dd, tx);
+       return -ENOMEM;
 }
 
 /*
index 85701eed15858993670cad0c1d47ecc889201cad..da89e6458162445d0cd1ec5fcfb048ea75a75991 100644 (file)
@@ -774,10 +774,13 @@ static inline int _sdma_txadd_daddr(
        tx->tlen -= len;
        /* special cases for last */
        if (!tx->tlen) {
-               if (tx->packet_len & (sizeof(u32) - 1))
+               if (tx->packet_len & (sizeof(u32) - 1)) {
                        rval = _pad_sdma_tx_descs(dd, tx);
-               else
+                       if (rval)
+                               return rval;
+               } else {
                        _sdma_close_tx(dd, tx);
+               }
        }
        tx->num_desc++;
        return rval;
index f55b75194847db4edf09e738d301a22d942eecb0..10122e84cb2fa3198a9af6a3bf31645a43d11a33 100644 (file)
@@ -67,7 +67,7 @@ u8 ibhdr_exhdr_len(struct hfi1_ib_header *hdr)
 
 #define IMM_PRN  "imm %d"
 #define RETH_PRN "reth vaddr 0x%.16llx rkey 0x%.8x dlen 0x%.8x"
-#define AETH_PRN "aeth syn 0x%.2x msn 0x%.8x"
+#define AETH_PRN "aeth syn 0x%.2x %s msn 0x%.8x"
 #define DETH_PRN "deth qkey 0x%.8x sqpn 0x%.6x"
 #define ATOMICACKETH_PRN "origdata %lld"
 #define ATOMICETH_PRN "vaddr 0x%llx rkey 0x%.8x sdata %lld cdata %lld"
@@ -79,6 +79,19 @@ static u64 ib_u64_get(__be32 *p)
        return ((u64)be32_to_cpu(p[0]) << 32) | be32_to_cpu(p[1]);
 }
 
+static const char *parse_syndrome(u8 syndrome)
+{
+       switch (syndrome >> 5) {
+       case 0:
+               return "ACK";
+       case 1:
+               return "RNRNAK";
+       case 3:
+               return "NAK";
+       }
+       return "";
+}
+
 const char *parse_everbs_hdrs(
        struct trace_seq *p,
        u8 opcode,
@@ -124,16 +137,18 @@ const char *parse_everbs_hdrs(
        case OP(RC, RDMA_READ_RESPONSE_LAST):
        case OP(RC, RDMA_READ_RESPONSE_ONLY):
        case OP(RC, ACKNOWLEDGE):
-               trace_seq_printf(p, AETH_PRN,
-                       be32_to_cpu(eh->aeth) >> 24,
-                       be32_to_cpu(eh->aeth) & HFI1_MSN_MASK);
+               trace_seq_printf(p, AETH_PRN, be32_to_cpu(eh->aeth) >> 24,
+                                parse_syndrome(be32_to_cpu(eh->aeth) >> 24),
+                                be32_to_cpu(eh->aeth) & HFI1_MSN_MASK);
                break;
        /* aeth + atomicacketh */
        case OP(RC, ATOMIC_ACKNOWLEDGE):
                trace_seq_printf(p, AETH_PRN " " ATOMICACKETH_PRN,
-                       (be32_to_cpu(eh->at.aeth) >> 24) & 0xff,
-                       be32_to_cpu(eh->at.aeth) & HFI1_MSN_MASK,
-                       (unsigned long long)ib_u64_get(eh->at.atomic_ack_eth));
+                                be32_to_cpu(eh->at.aeth) >> 24,
+                                parse_syndrome(be32_to_cpu(eh->at.aeth) >> 24),
+                                be32_to_cpu(eh->at.aeth) & HFI1_MSN_MASK,
+                                (unsigned long long)
+                                ib_u64_get(eh->at.atomic_ack_eth));
                break;
        /* atomiceth */
        case OP(RC, COMPARE_SWAP):
index 57430295c40409d3d2629449ebc73327810267fc..86c12ebfd4f0b8e88f57c9eb0fdf932c540819e8 100644 (file)
@@ -417,7 +417,8 @@ __print_symbolic(opcode,                                   \
        ib_opcode_name(UC_RDMA_WRITE_ONLY),                \
        ib_opcode_name(UC_RDMA_WRITE_ONLY_WITH_IMMEDIATE), \
        ib_opcode_name(UD_SEND_ONLY),                      \
-       ib_opcode_name(UD_SEND_ONLY_WITH_IMMEDIATE))
+       ib_opcode_name(UD_SEND_ONLY_WITH_IMMEDIATE),       \
+       ib_opcode_name(CNP))
 
 
 #define LRH_PRN "vl %d lver %d sl %d lnh %d,%s dlid %.4x len %d slid %.4x"
index 54ff1f5416d4920692e928a1ee1c6b87ab08a630..bd1b402c1e149f2c7acdf3cfbcff84dcfaf81c49 100644 (file)
@@ -111,11 +111,10 @@ static void ud_loopback(struct hfi1_qp *sqp, struct hfi1_swqe *swqe)
                                   ((1 << ppd->lmc) - 1));
                if (unlikely(ingress_pkey_check(ppd, pkey, sc5,
                                                qp->s_pkey_index, slid))) {
-                       hfi1_bad_pqkey(ibp, IB_NOTICE_TRAP_BAD_PKEY, pkey,
+                       hfi1_bad_pqkey(ibp, OPA_TRAP_BAD_P_KEY, pkey,
                                       ah_attr->sl,
                                       sqp->ibqp.qp_num, qp->ibqp.qp_num,
-                                      cpu_to_be16(slid),
-                                      cpu_to_be16(ah_attr->dlid));
+                                      slid, ah_attr->dlid);
                        goto drop;
                }
        }
@@ -135,11 +134,11 @@ static void ud_loopback(struct hfi1_qp *sqp, struct hfi1_swqe *swqe)
 
                        lid = ppd->lid | (ah_attr->src_path_bits &
                                          ((1 << ppd->lmc) - 1));
-                       hfi1_bad_pqkey(ibp, IB_NOTICE_TRAP_BAD_QKEY, qkey,
+                       hfi1_bad_pqkey(ibp, OPA_TRAP_BAD_Q_KEY, qkey,
                                       ah_attr->sl,
                                       sqp->ibqp.qp_num, qp->ibqp.qp_num,
-                                      cpu_to_be16(lid),
-                                      cpu_to_be16(ah_attr->dlid));
+                                      lid,
+                                      ah_attr->dlid);
                        goto drop;
                }
        }
@@ -737,12 +736,13 @@ void hfi1_ud_rcv(struct hfi1_packet *packet)
                                 * for invalid pkeys is optional according to
                                 * IB spec (release 1.3, section 10.9.4)
                                 */
-                               hfi1_bad_pqkey(ibp, IB_NOTICE_TRAP_BAD_PKEY,
+                               hfi1_bad_pqkey(ibp, OPA_TRAP_BAD_P_KEY,
                                               pkey,
                                               (be16_to_cpu(hdr->lrh[0]) >> 4) &
                                                0xF,
                                               src_qp, qp->ibqp.qp_num,
-                                              hdr->lrh[3], hdr->lrh[1]);
+                                              be16_to_cpu(hdr->lrh[3]),
+                                              be16_to_cpu(hdr->lrh[1]));
                                return;
                        }
                } else {
@@ -753,10 +753,11 @@ void hfi1_ud_rcv(struct hfi1_packet *packet)
 
                }
                if (unlikely(qkey != qp->qkey)) {
-                       hfi1_bad_pqkey(ibp, IB_NOTICE_TRAP_BAD_QKEY, qkey,
+                       hfi1_bad_pqkey(ibp, OPA_TRAP_BAD_Q_KEY, qkey,
                                       (be16_to_cpu(hdr->lrh[0]) >> 4) & 0xF,
                                       src_qp, qp->ibqp.qp_num,
-                                      hdr->lrh[3], hdr->lrh[1]);
+                                      be16_to_cpu(hdr->lrh[3]),
+                                      be16_to_cpu(hdr->lrh[1]));
                        return;
                }
                /* Drop invalid MAD packets (see 13.5.3.1). */
index 9071afbd7bf44d271aef8072074af869df77fa5c..692de658f0dce6dcb4b2a34a65aa0eab1873f409 100644 (file)
  */
 
 #include <linux/mm.h>
+#include <linux/sched.h>
 #include <linux/device.h>
 
 #include "hfi.h"
 
-static void __hfi1_release_user_pages(struct page **p, size_t num_pages,
-                                     int dirty)
-{
-       size_t i;
-
-       for (i = 0; i < num_pages; i++) {
-               if (dirty)
-                       set_page_dirty_lock(p[i]);
-               put_page(p[i]);
-       }
-}
-
-/*
- * Call with current->mm->mmap_sem held.
- */
-static int __hfi1_get_user_pages(unsigned long start_page, size_t num_pages,
-                                struct page **p)
-{
-       unsigned long lock_limit;
-       size_t got;
-       int ret;
-
-       lock_limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT;
-
-       if (num_pages > lock_limit && !capable(CAP_IPC_LOCK)) {
-               ret = -ENOMEM;
-               goto bail;
-       }
-
-       for (got = 0; got < num_pages; got += ret) {
-               ret = get_user_pages(current, current->mm,
-                                    start_page + got * PAGE_SIZE,
-                                    num_pages - got, 1, 1,
-                                    p + got, NULL);
-               if (ret < 0)
-                       goto bail_release;
-       }
-
-       current->mm->pinned_vm += num_pages;
-
-       ret = 0;
-       goto bail;
-
-bail_release:
-       __hfi1_release_user_pages(p, got, 0);
-bail:
-       return ret;
-}
-
 /**
  * hfi1_map_page - a safety wrapper around pci_map_page()
  *
@@ -116,41 +68,44 @@ dma_addr_t hfi1_map_page(struct pci_dev *hwdev, struct page *page,
        return phys;
 }
 
-/**
- * hfi1_get_user_pages - lock user pages into memory
- * @start_page: the start page
- * @num_pages: the number of pages
- * @p: the output page structures
- *
- * This function takes a given start page (page aligned user virtual
- * address) and pins it and the following specified number of pages.  For
- * now, num_pages is always 1, but that will probably change at some point
- * (because caller is doing expected sends on a single virtually contiguous
- * buffer, so we can do all pages at once).
- */
-int hfi1_get_user_pages(unsigned long start_page, size_t num_pages,
-                       struct page **p)
+int hfi1_acquire_user_pages(unsigned long vaddr, size_t npages, bool writable,
+                           struct page **pages)
 {
+       unsigned long pinned, lock_limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT;
+       bool can_lock = capable(CAP_IPC_LOCK);
        int ret;
 
-       down_write(&current->mm->mmap_sem);
+       down_read(&current->mm->mmap_sem);
+       pinned = current->mm->pinned_vm;
+       up_read(&current->mm->mmap_sem);
 
-       ret = __hfi1_get_user_pages(start_page, num_pages, p);
+       if (pinned + npages > lock_limit && !can_lock)
+               return -ENOMEM;
 
+       ret = get_user_pages_fast(vaddr, npages, writable, pages);
+       if (ret < 0)
+               return ret;
+
+       down_write(&current->mm->mmap_sem);
+       current->mm->pinned_vm += ret;
        up_write(&current->mm->mmap_sem);
 
        return ret;
 }
 
-void hfi1_release_user_pages(struct page **p, size_t num_pages)
+void hfi1_release_user_pages(struct page **p, size_t npages, bool dirty)
 {
-       if (current->mm) /* during close after signal, mm can be NULL */
-               down_write(&current->mm->mmap_sem);
+       size_t i;
 
-       __hfi1_release_user_pages(p, num_pages, 1);
+       for (i = 0; i < npages; i++) {
+               if (dirty)
+                       set_page_dirty_lock(p[i]);
+               put_page(p[i]);
+       }
 
-       if (current->mm) {
-               current->mm->pinned_vm -= num_pages;
+       if (current->mm) { /* during close after signal, mm can be NULL */
+               down_write(&current->mm->mmap_sem);
+               current->mm->pinned_vm -= npages;
                up_write(&current->mm->mmap_sem);
        }
 }
index 41408f82afe87016f4b92cebe0fcbf36c9505040..d3de771a0770860b7cbc678654300cdd2a05e690 100644 (file)
@@ -213,12 +213,6 @@ struct user_sdma_request {
         * to 0.
         */
        u8 omfactor;
-       /*
-        * pointer to the user's task_struct. We are going to
-        * get a reference to it so we can process io vectors
-        * at a later time.
-        */
-       struct task_struct *user_proc;
        /*
         * pointer to the user's mm_struct. We are going to
         * get a reference to it so it doesn't get freed
@@ -245,9 +239,13 @@ struct user_sdma_request {
        u16 tididx;
        u32 sent;
        u64 seqnum;
-       spinlock_t list_lock;
        struct list_head txps;
+       spinlock_t txcmp_lock;  /* protect txcmp list */
+       struct list_head txcmp;
        unsigned long flags;
+       /* status of the last txreq completed */
+       int status;
+       struct work_struct worker;
 };
 
 /*
@@ -260,6 +258,7 @@ struct user_sdma_txreq {
        /* Packet header for the txreq */
        struct hfi1_pkt_header hdr;
        struct sdma_txreq txreq;
+       struct list_head list;
        struct user_sdma_request *req;
        struct {
                struct user_sdma_iovec *vec;
@@ -282,10 +281,12 @@ struct user_sdma_txreq {
 static int user_sdma_send_pkts(struct user_sdma_request *, unsigned);
 static int num_user_pages(const struct iovec *);
 static void user_sdma_txreq_cb(struct sdma_txreq *, int, int);
+static void user_sdma_delayed_completion(struct work_struct *);
 static void user_sdma_free_request(struct user_sdma_request *);
 static int pin_vector_pages(struct user_sdma_request *,
                            struct user_sdma_iovec *);
-static void unpin_vector_pages(struct user_sdma_iovec *);
+static void unpin_vector_pages(struct user_sdma_request *,
+                              struct user_sdma_iovec *);
 static int check_header_template(struct user_sdma_request *,
                                 struct hfi1_pkt_header *, u32, u32);
 static int set_txreq_header(struct user_sdma_request *,
@@ -391,6 +392,7 @@ int hfi1_user_sdma_alloc_queues(struct hfi1_ctxtdata *uctxt, struct file *fp)
        pq->n_max_reqs = hfi1_sdma_comp_ring_size;
        pq->state = SDMA_PKT_Q_INACTIVE;
        atomic_set(&pq->n_reqs, 0);
+       init_waitqueue_head(&pq->wait);
 
        iowait_init(&pq->busy, 0, NULL, defer_packet_queue,
                    activate_packet_queue);
@@ -451,26 +453,16 @@ int hfi1_user_sdma_free_queues(struct hfi1_filedata *fd)
                  uctxt->ctxt, fd->subctxt);
        pq = fd->pq;
        if (pq) {
-               u16 i, j;
-
                spin_lock_irqsave(&uctxt->sdma_qlock, flags);
                if (!list_empty(&pq->list))
                        list_del_init(&pq->list);
                spin_unlock_irqrestore(&uctxt->sdma_qlock, flags);
                iowait_sdma_drain(&pq->busy);
-               if (pq->reqs) {
-                       for (i = 0, j = 0; i < atomic_read(&pq->n_reqs) &&
-                                    j < pq->n_max_reqs; j++) {
-                               struct user_sdma_request *req = &pq->reqs[j];
-
-                               if (test_bit(SDMA_REQ_IN_USE, &req->flags)) {
-                                       set_comp_state(req, ERROR, -ECOMM);
-                                       user_sdma_free_request(req);
-                                       i++;
-                               }
-                       }
-                       kfree(pq->reqs);
-               }
+               /* Wait until all requests have been freed. */
+               wait_event_interruptible(
+                       pq->wait,
+                       (ACCESS_ONCE(pq->state) == SDMA_PKT_Q_INACTIVE));
+               kfree(pq->reqs);
                kmem_cache_destroy(pq->txreq_cache);
                kfree(pq);
                fd->pq = NULL;
@@ -505,15 +497,13 @@ int hfi1_user_sdma_process_request(struct file *fp, struct iovec *iovec,
                   "[%u:%u:%u] First vector not big enough for header %lu/%lu",
                   dd->unit, uctxt->ctxt, fd->subctxt,
                   iovec[idx].iov_len, sizeof(info) + sizeof(req->hdr));
-               ret = -EINVAL;
-               goto done;
+               return -EINVAL;
        }
        ret = copy_from_user(&info, iovec[idx].iov_base, sizeof(info));
        if (ret) {
                hfi1_cdbg(SDMA, "[%u:%u:%u] Failed to copy info QW (%d)",
                          dd->unit, uctxt->ctxt, fd->subctxt, ret);
-               ret = -EFAULT;
-               goto done;
+               return -EFAULT;
        }
        trace_hfi1_sdma_user_reqinfo(dd, uctxt->ctxt, fd->subctxt,
                                     (u16 *)&info);
@@ -521,15 +511,13 @@ int hfi1_user_sdma_process_request(struct file *fp, struct iovec *iovec,
                hfi1_cdbg(SDMA, "[%u:%u:%u] Entry %u is in QUEUED state",
                          dd->unit, uctxt->ctxt, fd->subctxt,
                          info.comp_idx);
-               ret = -EBADSLT;
-               goto done;
+               return -EBADSLT;
        }
        if (!info.fragsize) {
                hfi1_cdbg(SDMA,
                          "[%u:%u:%u:%u] Request does not specify fragsize",
                          dd->unit, uctxt->ctxt, fd->subctxt, info.comp_idx);
-               ret = -EINVAL;
-               goto done;
+               return -EINVAL;
        }
        /*
         * We've done all the safety checks that we can up to this point,
@@ -544,8 +532,12 @@ int hfi1_user_sdma_process_request(struct file *fp, struct iovec *iovec,
        req->data_iovs = req_iovcnt(info.ctrl) - 1;
        req->pq = pq;
        req->cq = cq;
+       req->status = -1;
        INIT_LIST_HEAD(&req->txps);
-       spin_lock_init(&req->list_lock);
+       INIT_LIST_HEAD(&req->txcmp);
+       INIT_WORK(&req->worker, user_sdma_delayed_completion);
+
+       spin_lock_init(&req->txcmp_lock);
        memcpy(&req->info, &info, sizeof(info));
 
        if (req_opcode(info.ctrl) == EXPECTED)
@@ -554,8 +546,7 @@ int hfi1_user_sdma_process_request(struct file *fp, struct iovec *iovec,
        if (!info.npkts || req->data_iovs > MAX_VECTORS_PER_REQ) {
                SDMA_DBG(req, "Too many vectors (%u/%u)", req->data_iovs,
                         MAX_VECTORS_PER_REQ);
-               ret = -EINVAL;
-               goto done;
+               return -EINVAL;
        }
        /* Copy the header from the user buffer */
        ret = copy_from_user(&req->hdr, iovec[idx].iov_base + sizeof(info),
@@ -685,18 +676,16 @@ int hfi1_user_sdma_process_request(struct file *fp, struct iovec *iovec,
        sent = user_sdma_send_pkts(req, pcount);
        if (unlikely(sent < 0)) {
                if (sent != -EBUSY) {
-                       ret = sent;
-                       goto send_err;
+                       req->status = sent;
+                       set_comp_state(req, ERROR, req->status);
+                       return sent;
                } else
                        sent = 0;
        }
        atomic_inc(&pq->n_reqs);
+       xchg(&pq->state, SDMA_PKT_Q_ACTIVE);
 
        if (sent < req->info.npkts) {
-               /* Take the references to the user's task and mm_struct */
-               get_task_struct(current);
-               req->user_proc = current;
-
                /*
                 * This is a somewhat blocking send implementation.
                 * The driver will block the caller until all packets of the
@@ -706,8 +695,10 @@ int hfi1_user_sdma_process_request(struct file *fp, struct iovec *iovec,
                while (!test_bit(SDMA_REQ_SEND_DONE, &req->flags)) {
                        ret = user_sdma_send_pkts(req, pcount);
                        if (ret < 0) {
-                               if (ret != -EBUSY)
-                                       goto send_err;
+                               if (ret != -EBUSY) {
+                                       req->status = ret;
+                                       return ret;
+                               }
                                wait_event_interruptible_timeout(
                                        pq->busy.wait_dma,
                                        (pq->state == SDMA_PKT_Q_ACTIVE),
@@ -717,14 +708,10 @@ int hfi1_user_sdma_process_request(struct file *fp, struct iovec *iovec,
                }
 
        }
-       ret = 0;
        *count += idx;
-       goto done;
-send_err:
-       set_comp_state(req, ERROR, ret);
+       return 0;
 free_req:
        user_sdma_free_request(req);
-done:
        return ret;
 }
 
@@ -782,20 +769,24 @@ static int user_sdma_send_pkts(struct user_sdma_request *req, unsigned maxpkts)
        struct hfi1_user_sdma_pkt_q *pq = NULL;
        struct user_sdma_iovec *iovec = NULL;
 
-       if (!req->pq) {
-               ret = -EINVAL;
-               goto done;
-       }
+       if (!req->pq)
+               return -EINVAL;
 
        pq = req->pq;
 
+       /* If tx completion has reported an error, we are done. */
+       if (test_bit(SDMA_REQ_HAS_ERROR, &req->flags)) {
+               set_bit(SDMA_REQ_DONE_ERROR, &req->flags);
+               return -EFAULT;
+       }
+
        /*
         * Check if we might have sent the entire request already
         */
        if (unlikely(req->seqnum == req->info.npkts)) {
                if (!list_empty(&req->txps))
                        goto dosend;
-               goto done;
+               return ret;
        }
 
        if (!maxpkts || maxpkts > req->info.npkts - req->seqnum)
@@ -812,19 +803,18 @@ static int user_sdma_send_pkts(struct user_sdma_request *req, unsigned maxpkts)
                 */
                if (test_bit(SDMA_REQ_HAS_ERROR, &req->flags)) {
                        set_bit(SDMA_REQ_DONE_ERROR, &req->flags);
-                       ret = -EFAULT;
-                       goto done;
+                       return -EFAULT;
                }
 
                tx = kmem_cache_alloc(pq->txreq_cache, GFP_KERNEL);
-               if (!tx) {
-                       ret = -ENOMEM;
-                       goto done;
-               }
+               if (!tx)
+                       return -ENOMEM;
+
                tx->flags = 0;
                tx->req = req;
                tx->busycount = 0;
                tx->idx = -1;
+               INIT_LIST_HEAD(&tx->list);
                memset(tx->iovecs, 0, sizeof(tx->iovecs));
 
                if (req->seqnum == req->info.npkts - 1)
@@ -949,9 +939,8 @@ static int user_sdma_send_pkts(struct user_sdma_request *req, unsigned maxpkts)
                        if (ret) {
                                int i;
 
-                               dd_dev_err(pq->dd,
-                                          "SDMA txreq add page failed %d\n",
-                                          ret);
+                               SDMA_DBG(req, "SDMA txreq add page failed %d\n",
+                                        ret);
                                /* Mark all assigned vectors as complete so they
                                 * are unpinned in the callback. */
                                for (i = tx->idx; i >= 0; i--) {
@@ -1021,12 +1010,12 @@ dosend:
                        if (test_bit(SDMA_REQ_HAVE_AHG, &req->flags))
                                sdma_ahg_free(req->sde, req->ahg_idx);
                }
-       goto done;
+       return ret;
+
 free_txreq:
        sdma_txclean(pq->dd, &tx->txreq);
 free_tx:
        kmem_cache_free(pq->txreq_cache, tx);
-done:
        return ret;
 }
 
@@ -1045,52 +1034,58 @@ static inline int num_user_pages(const struct iovec *iov)
 
 static int pin_vector_pages(struct user_sdma_request *req,
                            struct user_sdma_iovec *iovec) {
-       int ret = 0;
-       unsigned pinned;
+       int pinned, npages;
 
-       iovec->npages = num_user_pages(&iovec->iov);
-       iovec->pages = kcalloc(iovec->npages, sizeof(*iovec->pages),
-                              GFP_KERNEL);
+       npages = num_user_pages(&iovec->iov);
+       iovec->pages = kcalloc(npages, sizeof(*iovec->pages), GFP_KERNEL);
        if (!iovec->pages) {
                SDMA_DBG(req, "Failed page array alloc");
-               ret = -ENOMEM;
-               goto done;
+               return -ENOMEM;
        }
-       /* If called by the kernel thread, use the user's mm */
-       if (current->flags & PF_KTHREAD)
-               use_mm(req->user_proc->mm);
-       pinned = get_user_pages_fast(
-               (unsigned long)iovec->iov.iov_base,
-               iovec->npages, 0, iovec->pages);
-       /* If called by the kernel thread, unuse the user's mm */
-       if (current->flags & PF_KTHREAD)
-               unuse_mm(req->user_proc->mm);
-       if (pinned != iovec->npages) {
-               SDMA_DBG(req, "Failed to pin pages (%u/%u)", pinned,
-                        iovec->npages);
-               ret = -EFAULT;
-               goto pfree;
+
+       /*
+        * Get a reference to the process's mm so we can use it when
+        * unpinning the io vectors.
+        */
+       req->pq->user_mm = get_task_mm(current);
+
+       pinned = hfi1_acquire_user_pages((unsigned long)iovec->iov.iov_base,
+                                        npages, 0, iovec->pages);
+
+       if (pinned < 0)
+               return pinned;
+
+       iovec->npages = pinned;
+       if (pinned != npages) {
+               SDMA_DBG(req, "Failed to pin pages (%d/%u)", pinned, npages);
+               unpin_vector_pages(req, iovec);
+               return -EFAULT;
        }
-       goto done;
-pfree:
-       unpin_vector_pages(iovec);
-done:
-       return ret;
+       return 0;
 }
 
-static void unpin_vector_pages(struct user_sdma_iovec *iovec)
+static void unpin_vector_pages(struct user_sdma_request *req,
+                              struct user_sdma_iovec *iovec)
 {
-       unsigned i;
+       /*
+        * Unpinning is done through the workqueue so use the
+        * process's mm if we have a reference to it.
+        */
+       if ((current->flags & PF_KTHREAD) && req->pq->user_mm)
+               use_mm(req->pq->user_mm);
 
-       if (ACCESS_ONCE(iovec->offset) != iovec->iov.iov_len) {
-               hfi1_cdbg(SDMA,
-                         "the complete vector has not been sent yet %llu %zu",
-                         iovec->offset, iovec->iov.iov_len);
-               return;
+       hfi1_release_user_pages(iovec->pages, iovec->npages, 0);
+
+       /*
+        * Unuse the user's mm (see above) and release the
+        * reference to it.
+        */
+       if (req->pq->user_mm) {
+               if (current->flags & PF_KTHREAD)
+                       unuse_mm(req->pq->user_mm);
+               mmput(req->pq->user_mm);
        }
-       for (i = 0; i < iovec->npages; i++)
-               if (iovec->pages[i])
-                       put_page(iovec->pages[i]);
+
        kfree(iovec->pages);
        iovec->pages = NULL;
        iovec->npages = 0;
@@ -1358,54 +1353,116 @@ static int set_txreq_header_ahg(struct user_sdma_request *req,
        return diff;
 }
 
+/*
+ * SDMA tx request completion callback. Called when the SDMA progress
+ * state machine gets notification that the SDMA descriptors for this
+ * tx request have been processed by the DMA engine. Called in
+ * interrupt context.
+ */
 static void user_sdma_txreq_cb(struct sdma_txreq *txreq, int status,
                               int drain)
 {
        struct user_sdma_txreq *tx =
                container_of(txreq, struct user_sdma_txreq, txreq);
-       struct user_sdma_request *req = tx->req;
-       struct hfi1_user_sdma_pkt_q *pq = req ? req->pq : NULL;
-       u64 tx_seqnum;
+       struct user_sdma_request *req;
+       bool defer;
+       int i;
 
-       if (unlikely(!req || !pq))
+       if (!tx->req)
                return;
 
-       /* If we have any io vectors associated with this txreq,
-        * check whether they need to be 'freed'. */
-       if (tx->idx != -1) {
-               int i;
+       req = tx->req;
+       /*
+        * If this is the callback for the last packet of the request,
+        * queue up the request for clean up.
+        */
+       defer = (tx->seqnum == req->info.npkts - 1);
 
-               for (i = tx->idx; i >= 0; i--) {
-                       if (tx->iovecs[i].flags & TXREQ_FLAGS_IOVEC_LAST_PKT)
-                               unpin_vector_pages(tx->iovecs[i].vec);
+       /*
+        * If we have any io vectors associated with this txreq,
+        * check whether they need to be 'freed'. We can't free them
+        * here because the unpin function needs to be able to sleep.
+        */
+       for (i = tx->idx; i >= 0; i--) {
+               if (tx->iovecs[i].flags & TXREQ_FLAGS_IOVEC_LAST_PKT) {
+                       defer = true;
+                       break;
                }
        }
 
-       tx_seqnum = tx->seqnum;
-       kmem_cache_free(pq->txreq_cache, tx);
-
+       req->status = status;
        if (status != SDMA_TXREQ_S_OK) {
-               dd_dev_err(pq->dd, "SDMA completion with error %d", status);
-               set_comp_state(req, ERROR, status);
+               SDMA_DBG(req, "SDMA completion with error %d",
+                        status);
                set_bit(SDMA_REQ_HAS_ERROR, &req->flags);
-               /* Do not free the request until the sender loop has ack'ed
-                * the error and we've seen all txreqs. */
-               if (tx_seqnum == ACCESS_ONCE(req->seqnum) &&
-                   test_bit(SDMA_REQ_DONE_ERROR, &req->flags)) {
-                       atomic_dec(&pq->n_reqs);
-                       user_sdma_free_request(req);
-               }
+               defer = true;
+       }
+
+       /*
+        * Defer the clean up of the iovectors and the request until later
+        * so it can be done outside of interrupt context.
+        */
+       if (defer) {
+               spin_lock(&req->txcmp_lock);
+               list_add_tail(&tx->list, &req->txcmp);
+               spin_unlock(&req->txcmp_lock);
+               schedule_work(&req->worker);
        } else {
-               if (tx_seqnum == req->info.npkts - 1) {
-                       /* We've sent and completed all packets in this
-                        * request. Signal completion to the user */
-                       atomic_dec(&pq->n_reqs);
-                       set_comp_state(req, COMPLETE, 0);
-                       user_sdma_free_request(req);
+               kmem_cache_free(req->pq->txreq_cache, tx);
+       }
+}
+
+static void user_sdma_delayed_completion(struct work_struct *work)
+{
+       struct user_sdma_request *req =
+               container_of(work, struct user_sdma_request, worker);
+       struct hfi1_user_sdma_pkt_q *pq = req->pq;
+       struct user_sdma_txreq *tx = NULL;
+       unsigned long flags;
+       u64 seqnum;
+       int i;
+
+       while (1) {
+               spin_lock_irqsave(&req->txcmp_lock, flags);
+               if (!list_empty(&req->txcmp)) {
+                       tx = list_first_entry(&req->txcmp,
+                                             struct user_sdma_txreq, list);
+                       list_del(&tx->list);
+               }
+               spin_unlock_irqrestore(&req->txcmp_lock, flags);
+               if (!tx)
+                       break;
+
+               for (i = tx->idx; i >= 0; i--)
+                       if (tx->iovecs[i].flags & TXREQ_FLAGS_IOVEC_LAST_PKT)
+                               unpin_vector_pages(req, tx->iovecs[i].vec);
+
+               seqnum = tx->seqnum;
+               kmem_cache_free(pq->txreq_cache, tx);
+               tx = NULL;
+
+               if (req->status != SDMA_TXREQ_S_OK) {
+                       if (seqnum == ACCESS_ONCE(req->seqnum) &&
+                           test_bit(SDMA_REQ_DONE_ERROR, &req->flags)) {
+                               atomic_dec(&pq->n_reqs);
+                               set_comp_state(req, ERROR, req->status);
+                               user_sdma_free_request(req);
+                               break;
+                       }
+               } else {
+                       if (seqnum == req->info.npkts - 1) {
+                               atomic_dec(&pq->n_reqs);
+                               set_comp_state(req, COMPLETE, 0);
+                               user_sdma_free_request(req);
+                               break;
+                       }
                }
        }
-       if (!atomic_read(&pq->n_reqs))
+
+       if (!atomic_read(&pq->n_reqs)) {
                xchg(&pq->state, SDMA_PKT_Q_INACTIVE);
+               wake_up(&pq->wait);
+       }
 }
 
 static void user_sdma_free_request(struct user_sdma_request *req)
@@ -1426,10 +1483,8 @@ static void user_sdma_free_request(struct user_sdma_request *req)
 
                for (i = 0; i < req->data_iovs; i++)
                        if (req->iovs[i].npages && req->iovs[i].pages)
-                               unpin_vector_pages(&req->iovs[i]);
+                               unpin_vector_pages(req, &req->iovs[i]);
        }
-       if (req->user_proc)
-               put_task_struct(req->user_proc);
        kfree(req->tids);
        clear_bit(SDMA_REQ_IN_USE, &req->flags);
 }
index 0046ffa774fefe330ad574cc9308f70932bf9de8..0afa28508a8a3335c0e040cdf46e89c221b90de0 100644 (file)
@@ -68,6 +68,8 @@ struct hfi1_user_sdma_pkt_q {
        struct user_sdma_request *reqs;
        struct iowait busy;
        unsigned state;
+       wait_queue_head_t wait;
+       struct mm_struct *user_mm;
 };
 
 struct hfi1_user_sdma_comp_q {
index 7e27531c430a3d5dfbf44a3987c29767854f3581..72106e5362b9862d448be822220f2ee7b0aa30f4 100644 (file)
@@ -861,7 +861,7 @@ static inline int hfi1_send_ok(struct hfi1_qp *qp)
  * This must be called with s_lock held.
  */
 void hfi1_bad_pqkey(struct hfi1_ibport *ibp, __be16 trap_num, u32 key, u32 sl,
-                   u32 qp1, u32 qp2, __be16 lid1, __be16 lid2);
+                   u32 qp1, u32 qp2, u16 lid1, u16 lid2);
 void hfi1_cap_mask_chg(struct hfi1_ibport *ibp);
 void hfi1_sys_guid_chg(struct hfi1_ibport *ibp);
 void hfi1_node_desc_chg(struct hfi1_ibport *ibp);
index ee51b4278088994f5cb50df7ed7a99dfcbef2f84..dce9cee9134a73403df0d097caf273e6c03e15a8 100644 (file)
@@ -1,41 +1,12 @@
-config WILC1000_DRIVER
-       bool "WILC1000 support (WiFi only)"
-       depends on CFG80211 && WEXT_CORE && INET
-       ---help---
-         This module only support IEEE 802.11n WiFi.
-
-if WILC1000_DRIVER
-
 config WILC1000
        tristate
-
-choice
-        prompt "Memory Allocation"
-        default WILC1000_PREALLOCATE_AT_LOADING_DRIVER
-
-config WILC1000_PREALLOCATE_AT_LOADING_DRIVER
-       bool "Preallocate memory at loading driver"
+       select WIRELESS_EXT
        ---help---
-         This choice supports static allocation of the memory
-         for the receive buffer. The driver will allocate the RX buffer
-         during initial time. The driver will also free the buffer
-         by calling network device stop.
-
-config WILC1000_DYNAMICALLY_ALLOCATE_MEMROY
-        bool "Dynamically allocate memory in real time"
-        ---help---
-         This choice supports dynamic allocation of the memory
-         for the receive buffer. The driver will allocate the RX buffer
-         when it is required.
-endchoice
-
-choice
-       prompt "Bus Type"
-       default WILC1000_SDIO
+         This module only support IEEE 802.11n WiFi.
 
 config WILC1000_SDIO
-       bool "SDIO support"
-       depends on MMC
+       tristate "Atmel WILC1000 SDIO (WiFi only)"
+       depends on CFG80211 && INET && MMC
        select WILC1000
        ---help---
          This module adds support for the SDIO interface of adapters using
@@ -48,9 +19,9 @@ config WILC1000_SDIO
          this if your platform is using the SDIO bus.
 
 config WILC1000_SPI
-       depends on SPI
+       tristate "Atmel WILC1000 SPI (WiFi only)"
+       depends on CFG80211 && INET && SPI
        select WILC1000
-       bool "SPI support"
        ---help---
          This module adds support for the SPI interface of adapters using
          WILC1000 chipset. The Atmel WILC1000 has a Serial Peripheral
@@ -59,10 +30,9 @@ config WILC1000_SPI
          full-duplex slave synchronous serial interface that is available
          immediately following reset when pin 9 (SDIO_SPI_CFG) is tied to
          VDDIO. Select this if your platform is using the SPI bus.
-endchoice
 
 config WILC1000_HW_OOB_INTR
-       bool "Use out of band interrupt"
+       bool "WILC1000 out of band interrupt"
        depends on WILC1000_SDIO
        default n
        ---help---
@@ -71,5 +41,3 @@ config WILC1000_HW_OOB_INTR
          mechanism for SDIO host controllers that don't support SDIO interrupt.
          Select this option If the SDIO host controller in your platform
          doesn't support SDIO time devision interrupt.
-
-endif
index 650123df0b4c1f02a3cebf142bf91a2996bf4b3c..20a5cb9d4f4c818d486bcd2cd649e0a206b3f11c 100644 (file)
@@ -1,28 +1,20 @@
 obj-$(CONFIG_WILC1000) += wilc1000.o
 
-ccflags-$(CONFIG_WILC1000_SDIO) += -DWILC_SDIO -DCOMPLEMENT_BOOT
-ccflags-$(CONFIG_WILC1000_HW_OOB_INTR) += -DWILC_SDIO_IRQ_GPIO
-ccflags-$(CONFIG_WILC1000_SPI) += -DWILC_SPI
-
 ccflags-y += -DSTA_FIRMWARE=\"atmel/wilc1000_fw.bin\" \
                -DAP_FIRMWARE=\"atmel/wilc1000_ap_fw.bin\" \
                -DP2P_CONCURRENCY_FIRMWARE=\"atmel/wilc1000_p2p_fw.bin\"
 
-ccflags-y += -I$(src)/ -D__CHECK_ENDIAN__ -DWILC_ASIC_A0 \
-               -Wno-unused-function -DWILC_DEBUGFS
+ccflags-y += -I$(src)/ -DWILC_ASIC_A0 -DWILC_DEBUGFS
 #ccflags-y += -DTCP_ACK_FILTER
 
-ccflags-$(CONFIG_WILC1000_PREALLOCATE_AT_LOADING_DRIVER) += -DMEMORY_STATIC \
-                                                               -DWILC_PREALLOC_AT_INSMOD
-
-ccflags-$(CONFIG_WILC1000_DYNAMICALLY_ALLOCATE_MEMROY) += -DWILC_NORMAL_ALLOC
-
-
 wilc1000-objs := wilc_wfi_cfgoperations.o linux_wlan.o linux_mon.o \
                        wilc_msgqueue.o \
                        coreconfigurator.o host_interface.o \
                        wilc_wlan_cfg.o wilc_debugfs.o \
                        wilc_wlan.o
 
-wilc1000-$(CONFIG_WILC1000_SDIO) += linux_wlan_sdio.o wilc_sdio.o
-wilc1000-$(CONFIG_WILC1000_SPI) += linux_wlan_spi.o wilc_spi.o
+obj-$(CONFIG_WILC1000_SDIO) += wilc1000-sdio.o
+wilc1000-sdio-objs += wilc_sdio.o
+
+obj-$(CONFIG_WILC1000_SPI) += wilc1000-spi.o
+wilc1000-spi-objs += wilc_spi.o
index 56e0cf90fde6cc4685725ca8509dc01d925eef04..2d4d3f190c01317d0a514cb9aa301011ca69fcf4 100644 (file)
@@ -287,7 +287,7 @@ static inline u16 get_asoc_id(u8 *data)
        return asoc_id;
 }
 
-u8 *get_tim_elm(u8 *pu8msa, u16 u16RxLen, u16 u16TagParamOffset)
+static u8 *get_tim_elm(u8 *pu8msa, u16 u16RxLen, u16 u16TagParamOffset)
 {
        u16 u16index;
 
@@ -315,7 +315,7 @@ u8 *get_tim_elm(u8 *pu8msa, u16 u16RxLen, u16 u16TagParamOffset)
 
 /* This function gets the current channel information from
  * the 802.11n beacon/probe response frame */
-u8 get_current_channel_802_11n(u8 *pu8msa, u16 u16RxLen)
+static u8 get_current_channel_802_11n(u8 *pu8msa, u16 u16RxLen)
 {
        u16 index;
 
@@ -344,7 +344,7 @@ u8 get_current_channel_802_11n(u8 *pu8msa, u16 u16RxLen)
  *  @date                      1 Mar 2012
  *  @version           1.0
  */
-s32 parse_network_info(u8 *pu8MsgBuffer, tstrNetworkInfo **ppstrNetworkInfo)
+s32 wilc_parse_network_info(u8 *pu8MsgBuffer, tstrNetworkInfo **ppstrNetworkInfo)
 {
        tstrNetworkInfo *pstrNetworkInfo = NULL;
        u8 u8MsgType = 0;
@@ -436,7 +436,7 @@ s32 parse_network_info(u8 *pu8MsgBuffer, tstrNetworkInfo **ppstrNetworkInfo)
 
                /* Get DTIM Period */
                pu8TimElm = get_tim_elm(pu8msa, u16RxLen + FCS_LEN, u8index);
-               if (pu8TimElm != NULL)
+               if (pu8TimElm)
                        pstrNetworkInfo->u8DtimPeriod = pu8TimElm[3];
                pu8IEs = &pu8msa[MAC_HDR_LEN + TIME_STAMP_LEN + BEACON_INTERVAL_LEN + CAP_INFO_LEN];
                u16IEsLen = u16RxLen - (MAC_HDR_LEN + TIME_STAMP_LEN + BEACON_INTERVAL_LEN + CAP_INFO_LEN);
@@ -466,12 +466,12 @@ s32 parse_network_info(u8 *pu8MsgBuffer, tstrNetworkInfo **ppstrNetworkInfo)
  *  @date              1 Mar 2012
  *  @version           1.0
  */
-s32 DeallocateNetworkInfo(tstrNetworkInfo *pstrNetworkInfo)
+s32 wilc_dealloc_network_info(tstrNetworkInfo *pstrNetworkInfo)
 {
        s32 s32Error = 0;
 
-       if (pstrNetworkInfo != NULL) {
-               if (pstrNetworkInfo->pu8IEs != NULL) {
+       if (pstrNetworkInfo) {
+               if (pstrNetworkInfo->pu8IEs) {
                        kfree(pstrNetworkInfo->pu8IEs);
                        pstrNetworkInfo->pu8IEs = NULL;
                } else {
@@ -499,7 +499,7 @@ s32 DeallocateNetworkInfo(tstrNetworkInfo *pstrNetworkInfo)
  *  @date                      2 Apr 2012
  *  @version           1.0
  */
-s32 ParseAssocRespInfo(u8 *pu8Buffer, u32 u32BufferLen,
+s32 wilc_parse_assoc_resp_info(u8 *pu8Buffer, u32 u32BufferLen,
                               tstrConnectRespInfo **ppstrConnectRespInfo)
 {
        s32 s32Error = 0;
@@ -551,12 +551,12 @@ s32 ParseAssocRespInfo(u8 *pu8Buffer, u32 u32BufferLen,
  *  @date                      2 Apr 2012
  *  @version           1.0
  */
-s32 DeallocateAssocRespInfo(tstrConnectRespInfo *pstrConnectRespInfo)
+s32 wilc_dealloc_assoc_resp_info(tstrConnectRespInfo *pstrConnectRespInfo)
 {
        s32 s32Error = 0;
 
-       if (pstrConnectRespInfo != NULL) {
-               if (pstrConnectRespInfo->pu8RespIEs != NULL) {
+       if (pstrConnectRespInfo) {
+               if (pstrConnectRespInfo->pu8RespIEs) {
                        kfree(pstrConnectRespInfo->pu8RespIEs);
                        pstrConnectRespInfo->pu8RespIEs = NULL;
                } else {
@@ -588,7 +588,8 @@ s32 DeallocateAssocRespInfo(tstrConnectRespInfo *pstrConnectRespInfo)
  *  @date              1 Mar 2012
  *  @version   1.0
  */
-s32 send_config_pkt(u8 mode, struct wid *wids, u32 count, u32 drv)
+s32 wilc_send_config_pkt(struct wilc *wilc, u8 mode, struct wid *wids,
+                        u32 count, u32 drv)
 {
        s32 counter = 0, ret = 0;
 
@@ -596,11 +597,11 @@ s32 send_config_pkt(u8 mode, struct wid *wids, u32 count, u32 drv)
                for (counter = 0; counter < count; counter++) {
                        PRINT_INFO(CORECONFIG_DBG, "Sending CFG packet [%d][%d]\n", !counter,
                                   (counter == count - 1));
-                       if (!wilc_wlan_cfg_get(!counter,
+                       if (!wilc_wlan_cfg_get(wilc, !counter,
                                               wids[counter].id,
                                               (counter == count - 1),
                                               drv)) {
-                               ret = -1;
+                               ret = -ETIMEDOUT;
                                printk("[Sendconfigpkt]Get Timed out\n");
                                break;
                        }
@@ -615,13 +616,13 @@ s32 send_config_pkt(u8 mode, struct wid *wids, u32 count, u32 drv)
        } else if (mode == SET_CFG) {
                for (counter = 0; counter < count; counter++) {
                        PRINT_D(CORECONFIG_DBG, "Sending config SET PACKET WID:%x\n", wids[counter].id);
-                       if (!wilc_wlan_cfg_set(!counter,
+                       if (!wilc_wlan_cfg_set(wilc, !counter,
                                               wids[counter].id,
                                               wids[counter].val,
                                               wids[counter].size,
                                               (counter == count - 1),
                                               drv)) {
-                               ret = -1;
+                               ret = -ETIMEDOUT;
                                printk("[Sendconfigpkt]Set Timed out\n");
                                break;
                        }
index 3253f6f1393ae21472d8c83f5e5ca0b7ba8eda55..fc43d04ca1dab651ab70e53116378e138ec78229 100644 (file)
@@ -127,16 +127,18 @@ typedef struct {
        size_t ie_len;
 } tstrDisconnectNotifInfo;
 
-s32 send_config_pkt(u8 mode, struct wid *wids, u32 count, u32 drv);
-s32 parse_network_info(u8 *pu8MsgBuffer, tstrNetworkInfo **ppstrNetworkInfo);
-s32 DeallocateNetworkInfo(tstrNetworkInfo *pstrNetworkInfo);
+s32 wilc_send_config_pkt(struct wilc *wilc, u8 mode, struct wid *wids,
+                        u32 count, u32 drv);
+s32 wilc_parse_network_info(u8 *pu8MsgBuffer, tstrNetworkInfo **ppstrNetworkInfo);
+s32 wilc_dealloc_network_info(tstrNetworkInfo *pstrNetworkInfo);
 
-s32 ParseAssocRespInfo(u8 *pu8Buffer, u32 u32BufferLen,
+s32 wilc_parse_assoc_resp_info(u8 *pu8Buffer, u32 u32BufferLen,
                       tstrConnectRespInfo **ppstrConnectRespInfo);
-s32 DeallocateAssocRespInfo(tstrConnectRespInfo *pstrConnectRespInfo);
-
-void NetworkInfoReceived(u8 *pu8Buffer, u32 u32Length);
-void GnrlAsyncInfoReceived(u8 *pu8Buffer, u32 u32Length);
-void host_int_ScanCompleteReceived(u8 *pu8Buffer, u32 u32Length);
-
+s32 wilc_dealloc_assoc_resp_info(tstrConnectRespInfo *pstrConnectRespInfo);
+void wilc_scan_complete_received(struct wilc *wilc, u8 *pu8Buffer,
+                                u32 u32Length);
+void wilc_network_info_received(struct wilc *wilc, u8 *pu8Buffer,
+                               u32 u32Length);
+void wilc_gnrl_async_info_received(struct wilc *wilc, u8 *pu8Buffer,
+                                  u32 u32Length);
 #endif
index d5b7725ec2bf530ffac8f875a39ecbdfb22b3994..8c7752034032b804e267fb48f4513740e476eb63 100644 (file)
@@ -4,17 +4,12 @@
 #include <linux/delay.h>
 #include "host_interface.h"
 #include "coreconfigurator.h"
+#include "wilc_wlan.h"
 #include "wilc_wlan_if.h"
 #include "wilc_msgqueue.h"
 #include <linux/etherdevice.h>
 #include "wilc_wfi_netdevice.h"
 
-extern u8 connecting;
-
-extern struct timer_list hDuringIpTimer;
-
-extern u8 g_wilc_initialized;
-
 #define HOST_IF_MSG_SCAN                        0
 #define HOST_IF_MSG_CONNECT                     1
 #define HOST_IF_MSG_RCVD_GNRL_ASYNC_INFO        2
@@ -48,7 +43,6 @@ extern u8 g_wilc_initialized;
 #define HOST_IF_MSG_FLUSH_CONNECT               30
 #define HOST_IF_MSG_GET_STATISTICS              31
 #define HOST_IF_MSG_SET_MULTICAST_FILTER        32
-#define HOST_IF_MSG_ADD_BA_SESSION              33
 #define HOST_IF_MSG_DEL_BA_SESSION              34
 #define HOST_IF_MSG_Q_IDLE                      35
 #define HOST_IF_MSG_DEL_ALL_STA                 36
@@ -199,7 +193,7 @@ union message_body {
 struct host_if_msg {
        u16 id;
        union message_body body;
-       struct host_if_drv *drv;
+       struct wilc_vif *vif;
 };
 
 struct join_bss_param {
@@ -231,10 +225,9 @@ struct join_bss_param {
        u8 start_time[4];
 };
 
-static struct host_if_drv *wfidrv_list[NUM_CONCURRENT_IFC + 1];
 struct host_if_drv *terminated_handle;
-bool g_obtainingIP;
-u8 P2P_LISTEN_STATE;
+bool wilc_optaining_ip;
+static u8 P2P_LISTEN_STATE;
 static struct task_struct *hif_thread_handler;
 static WILC_MsgQueueHandle hif_msg_q;
 static struct semaphore hif_sema_thread;
@@ -243,7 +236,7 @@ static struct semaphore hif_sema_wait_response;
 static struct semaphore hif_sema_deinit;
 static struct timer_list periodic_rssi;
 
-u8 multicast_mac_addr_list[WILC_MULTICAST_TABLE_SIZE][ETH_ALEN];
+u8 wilc_multicast_mac_addr_list[WILC_MULTICAST_TABLE_SIZE][ETH_ALEN];
 
 static u8 rcv_assoc_resp[MAX_ASSOC_RESP_FRAME_SIZE];
 
@@ -259,71 +252,43 @@ static u8 del_beacon;
 static u32 clients_count;
 
 static u8 *join_req;
-u8 *info_element;
+static u8 *info_element;
 static u8 mode_11i;
-u8 auth_type;
-u32 join_req_size;
+static u8 auth_type;
+static u32 join_req_size;
 static u32 info_element_size;
-static struct host_if_drv *join_req_drv;
+static struct wilc_vif *join_req_vif;
 #define REAL_JOIN_REQ 0
 #define FLUSHED_JOIN_REQ 1
 #define FLUSHED_BYTE_POS 79
 
 static void *host_int_ParseJoinBssParam(tstrNetworkInfo *ptstrNetworkInfo);
 
-extern int linux_wlan_get_num_conn_ifcs(void);
-
-static int add_handler_in_list(struct host_if_drv *handler)
-{
-       int i;
-
-       for (i = 1; i < ARRAY_SIZE(wfidrv_list); i++) {
-               if (!wfidrv_list[i]) {
-                       wfidrv_list[i] = handler;
-                       return 0;
-               }
-       }
-
-       return -ENOBUFS;
-}
-
-static int remove_handler_in_list(struct host_if_drv *handler)
+/* The u8IfIdx starts from 0 to NUM_CONCURRENT_IFC -1, but 0 index used as
+ * special purpose in wilc device, so we add 1 to the index to starts from 1.
+ * As a result, the returned index will be 1 to NUM_CONCURRENT_IFC.
+ */
+int wilc_get_vif_idx(struct wilc_vif *vif)
 {
-       int i;
-
-       for (i = 1; i < ARRAY_SIZE(wfidrv_list); i++) {
-               if (wfidrv_list[i] == handler) {
-                       wfidrv_list[i] = NULL;
-                       return 0;
-               }
-       }
-
-       return -EINVAL;
+       return vif->u8IfIdx + 1;
 }
 
-static int get_id_from_handler(struct host_if_drv *handler)
+/* We need to minus 1 from idx which is from wilc device to get real index
+ * of wilc->vif[], because we add 1 when pass to wilc device in the function
+ * wilc_get_vif_idx.
+ * As a result, the index should be between 0 and NUM_CONCURRENT_IFC -1.
+ */
+static struct wilc_vif *wilc_get_vif_from_idx(struct wilc *wilc, int idx)
 {
-       int i;
-
-       if (!handler)
-               return 0;
+       int index = idx - 1;
 
-       for (i = 1; i < ARRAY_SIZE(wfidrv_list); i++) {
-               if (wfidrv_list[i] == handler)
-                       return i;
-       }
-
-       return 0;
-}
-
-static struct host_if_drv *get_handler_from_id(int id)
-{
-       if (id <= 0 || id >= ARRAY_SIZE(wfidrv_list))
+       if (index < 0 || index >= NUM_CONCURRENT_IFC)
                return NULL;
-       return wfidrv_list[id];
+
+       return wilc->vif[index];
 }
 
-static s32 handle_set_channel(struct host_if_drv *hif_drv,
+static s32 handle_set_channel(struct wilc_vif *vif,
                              struct channel_attr *hif_set_ch)
 {
        s32 result = 0;
@@ -336,8 +301,8 @@ static s32 handle_set_channel(struct host_if_drv *hif_drv,
 
        PRINT_D(HOSTINF_DBG, "Setting channel\n");
 
-       result = send_config_pkt(SET_CFG, &wid, 1,
-                                get_id_from_handler(hif_drv));
+       result = wilc_send_config_pkt(vif->wilc, SET_CFG, &wid, 1,
+                                wilc_get_vif_idx(vif));
 
        if (result) {
                PRINT_ER("Failed to set channel\n");
@@ -347,7 +312,7 @@ static s32 handle_set_channel(struct host_if_drv *hif_drv,
        return result;
 }
 
-static s32 handle_set_wfi_drv_handler(struct host_if_drv *hif_drv,
+static s32 handle_set_wfi_drv_handler(struct wilc_vif *vif,
                                      struct drv_handler *hif_drv_handler)
 {
        s32 result = 0;
@@ -358,9 +323,10 @@ static s32 handle_set_wfi_drv_handler(struct host_if_drv *hif_drv,
        wid.val = (s8 *)&hif_drv_handler->handler;
        wid.size = sizeof(u32);
 
-       result = send_config_pkt(SET_CFG, &wid, 1, hif_drv_handler->handler);
+       result = wilc_send_config_pkt(vif->wilc, SET_CFG, &wid, 1,
+                                     hif_drv_handler->handler);
 
-       if (!hif_drv)
+       if (!hif_drv_handler->handler)
                up(&hif_sema_driver);
 
        if (result) {
@@ -371,7 +337,7 @@ static s32 handle_set_wfi_drv_handler(struct host_if_drv *hif_drv,
        return result;
 }
 
-static s32 handle_set_operation_mode(struct host_if_drv *hif_drv,
+static s32 handle_set_operation_mode(struct wilc_vif *vif,
                                     struct op_mode *hif_op_mode)
 {
        s32 result = 0;
@@ -382,8 +348,8 @@ static s32 handle_set_operation_mode(struct host_if_drv *hif_drv,
        wid.val = (s8 *)&hif_op_mode->mode;
        wid.size = sizeof(u32);
 
-       result = send_config_pkt(SET_CFG, &wid, 1,
-                                get_id_from_handler(hif_drv));
+       result = wilc_send_config_pkt(vif->wilc, SET_CFG, &wid, 1,
+                                wilc_get_vif_idx(vif));
 
        if ((hif_op_mode->mode) == IDLE_MODE)
                up(&hif_sema_driver);
@@ -396,11 +362,16 @@ static s32 handle_set_operation_mode(struct host_if_drv *hif_drv,
        return result;
 }
 
-s32 handle_set_ip_address(struct host_if_drv *hif_drv, u8 *ip_addr, u8 idx)
+static s32 host_int_get_ipaddress(struct wilc_vif *vif,
+                                 struct host_if_drv *hif_drv,
+                                 u8 *u16ipadd, u8 idx);
+
+static s32 handle_set_ip_address(struct wilc_vif *vif, u8 *ip_addr, u8 idx)
 {
        s32 result = 0;
        struct wid wid;
        char firmware_ip_addr[4] = {0};
+       struct host_if_drv *hif_drv = vif->hif_drv;
 
        if (ip_addr[0] < 192)
                ip_addr[0] = 0;
@@ -415,10 +386,10 @@ s32 handle_set_ip_address(struct host_if_drv *hif_drv, u8 *ip_addr, u8 idx)
        wid.val = (u8 *)ip_addr;
        wid.size = IP_ALEN;
 
-       result = send_config_pkt(SET_CFG, &wid, 1,
-                                get_id_from_handler(hif_drv));
+       result = wilc_send_config_pkt(vif->wilc, SET_CFG, &wid, 1,
+                                wilc_get_vif_idx(vif));
 
-       host_int_get_ipaddress(hif_drv, firmware_ip_addr, idx);
+       host_int_get_ipaddress(vif, hif_drv, firmware_ip_addr, idx);
 
        if (result) {
                PRINT_ER("Failed to set IP address\n");
@@ -430,7 +401,7 @@ s32 handle_set_ip_address(struct host_if_drv *hif_drv, u8 *ip_addr, u8 idx)
        return result;
 }
 
-s32 handle_get_ip_address(struct host_if_drv *hif_drv, u8 idx)
+static s32 handle_get_ip_address(struct wilc_vif *vif, u8 idx)
 {
        s32 result = 0;
        struct wid wid;
@@ -440,8 +411,8 @@ s32 handle_get_ip_address(struct host_if_drv *hif_drv, u8 idx)
        wid.val = kmalloc(IP_ALEN, GFP_KERNEL);
        wid.size = IP_ALEN;
 
-       result = send_config_pkt(GET_CFG, &wid, 1,
-                                get_id_from_handler(hif_drv));
+       result = wilc_send_config_pkt(vif->wilc, GET_CFG, &wid, 1,
+                                wilc_get_vif_idx(vif));
 
        PRINT_INFO(HOSTINF_DBG, "%pI4\n", wid.val);
 
@@ -450,7 +421,7 @@ s32 handle_get_ip_address(struct host_if_drv *hif_drv, u8 idx)
        kfree(wid.val);
 
        if (memcmp(get_ip[idx], set_ip[idx], IP_ALEN) != 0)
-               host_int_setup_ipaddress(hif_drv, set_ip[idx], idx);
+               wilc_setup_ipaddress(vif, set_ip[idx], idx);
 
        if (result != 0) {
                PRINT_ER("Failed to get IP address\n");
@@ -464,7 +435,7 @@ s32 handle_get_ip_address(struct host_if_drv *hif_drv, u8 idx)
        return result;
 }
 
-static s32 handle_set_mac_address(struct host_if_drv *hif_drv,
+static s32 handle_set_mac_address(struct wilc_vif *vif,
                                  struct set_mac_addr *set_mac_addr)
 {
        s32 result = 0;
@@ -483,8 +454,8 @@ static s32 handle_set_mac_address(struct host_if_drv *hif_drv,
        wid.size = ETH_ALEN;
        PRINT_D(GENERIC_DBG, "mac addr = :%pM\n", wid.val);
 
-       result = send_config_pkt(SET_CFG, &wid, 1,
-                                get_id_from_handler(hif_drv));
+       result = wilc_send_config_pkt(vif->wilc, SET_CFG, &wid, 1,
+                                wilc_get_vif_idx(vif));
        if (result) {
                PRINT_ER("Failed to set mac address\n");
                result = -EFAULT;
@@ -494,7 +465,7 @@ static s32 handle_set_mac_address(struct host_if_drv *hif_drv,
        return result;
 }
 
-static s32 handle_get_mac_address(struct host_if_drv *hif_drv,
+static s32 handle_get_mac_address(struct wilc_vif *vif,
                                  struct get_mac_addr *get_mac_addr)
 {
        s32 result = 0;
@@ -505,8 +476,8 @@ static s32 handle_get_mac_address(struct host_if_drv *hif_drv,
        wid.val = get_mac_addr->mac_addr;
        wid.size = ETH_ALEN;
 
-       result = send_config_pkt(GET_CFG, &wid, 1,
-                                get_id_from_handler(hif_drv));
+       result = wilc_send_config_pkt(vif->wilc, GET_CFG, &wid, 1,
+                                wilc_get_vif_idx(vif));
 
        if (result) {
                PRINT_ER("Failed to get mac address\n");
@@ -517,11 +488,12 @@ static s32 handle_get_mac_address(struct host_if_drv *hif_drv,
        return result;
 }
 
-static s32 handle_cfg_param(struct host_if_drv *hif_drv,
+static s32 handle_cfg_param(struct wilc_vif *vif,
                            struct cfg_param_attr *cfg_param_attr)
 {
        s32 result = 0;
        struct wid wid_list[32];
+       struct host_if_drv *hif_drv = vif->hif_drv;
        u8 wid_cnt = 0;
 
        down(&hif_drv->sem_cfg_values);
@@ -800,8 +772,8 @@ static s32 handle_cfg_param(struct host_if_drv *hif_drv,
                wid_cnt++;
        }
 
-       result = send_config_pkt(SET_CFG, wid_list, wid_cnt,
-                                get_id_from_handler(hif_drv));
+       result = wilc_send_config_pkt(vif->wilc, SET_CFG, wid_list,
+                                     wid_cnt, wilc_get_vif_idx(vif));
 
        if (result)
                PRINT_ER("Error in setting CFG params\n");
@@ -813,11 +785,14 @@ ERRORHANDLER:
 
 static void Handle_wait_msg_q_empty(void)
 {
-       g_wilc_initialized = 0;
+       wilc_initialized = 0;
        up(&hif_sema_wait_response);
 }
 
-static s32 Handle_Scan(struct host_if_drv *hif_drv,
+static s32 Handle_ScanDone(struct wilc_vif *vif,
+                          enum scan_event enuEvent);
+
+static s32 Handle_Scan(struct wilc_vif *vif,
                       struct scan_attr *pstrHostIFscanAttr)
 {
        s32 result = 0;
@@ -827,6 +802,7 @@ static s32 Handle_Scan(struct host_if_drv *hif_drv,
        u8 *pu8Buffer;
        u8 valuesize = 0;
        u8 *pu8HdnNtwrksWidVal = NULL;
+       struct host_if_drv *hif_drv = vif->hif_drv;
 
        PRINT_D(HOSTINF_DBG, "Setting SCAN params\n");
        PRINT_D(HOSTINF_DBG, "Scanning: In [%d] state\n", hif_drv->hif_state);
@@ -843,7 +819,7 @@ static s32 Handle_Scan(struct host_if_drv *hif_drv,
                goto ERRORHANDLER;
        }
 
-       if (g_obtainingIP || connecting) {
+       if (wilc_optaining_ip || wilc_connecting) {
                PRINT_D(GENERIC_DBG, "[handle_scan]: Don't do obss scan until IP adresss is obtained\n");
                PRINT_ER("Don't do obss scan\n");
                result = -EBUSY;
@@ -920,8 +896,9 @@ static s32 Handle_Scan(struct host_if_drv *hif_drv,
        else if (hif_drv->hif_state == HOST_IF_IDLE)
                scan_while_connected = false;
 
-       result = send_config_pkt(SET_CFG, strWIDList, u32WidsCount,
-                                get_id_from_handler(hif_drv));
+       result = wilc_send_config_pkt(vif->wilc, SET_CFG, strWIDList,
+                                     u32WidsCount,
+                                     wilc_get_vif_idx(vif));
 
        if (result)
                PRINT_ER("Failed to send scan paramters config packet\n");
@@ -931,7 +908,7 @@ static s32 Handle_Scan(struct host_if_drv *hif_drv,
 ERRORHANDLER:
        if (result) {
                del_timer(&hif_drv->scan_timer);
-               Handle_ScanDone(hif_drv, SCAN_EVENT_ABORTED);
+               Handle_ScanDone(vif, SCAN_EVENT_ABORTED);
        }
 
        kfree(pstrHostIFscanAttr->ch_freq_list);
@@ -947,12 +924,13 @@ ERRORHANDLER:
        return result;
 }
 
-static s32 Handle_ScanDone(struct host_if_drv *hif_drv,
+static s32 Handle_ScanDone(struct wilc_vif *vif,
                           enum scan_event enuEvent)
 {
        s32 result = 0;
        u8 u8abort_running_scan;
        struct wid wid;
+       struct host_if_drv *hif_drv = vif->hif_drv;
 
        PRINT_D(HOSTINF_DBG, "in Handle_ScanDone()\n");
 
@@ -964,8 +942,8 @@ static s32 Handle_ScanDone(struct host_if_drv *hif_drv,
                wid.val = (s8 *)&u8abort_running_scan;
                wid.size = sizeof(char);
 
-               result = send_config_pkt(SET_CFG, &wid, 1,
-                                        get_id_from_handler(hif_drv));
+               result = wilc_send_config_pkt(vif->wilc, SET_CFG, &wid, 1,
+                                        wilc_get_vif_idx(vif));
 
                if (result) {
                        PRINT_ER("Failed to set abort running scan\n");
@@ -987,8 +965,8 @@ static s32 Handle_ScanDone(struct host_if_drv *hif_drv,
        return result;
 }
 
-u8 u8ConnectedSSID[6] = {0};
-static s32 Handle_Connect(struct host_if_drv *hif_drv,
+u8 wilc_connected_ssid[6] = {0};
+static s32 Handle_Connect(struct wilc_vif *vif,
                          struct connect_attr *pstrHostIFconnectAttr)
 {
        s32 result = 0;
@@ -996,10 +974,11 @@ static s32 Handle_Connect(struct host_if_drv *hif_drv,
        u32 u32WidsCount = 0, dummyval = 0;
        u8 *pu8CurrByte = NULL;
        struct join_bss_param *ptstrJoinBssParam;
+       struct host_if_drv *hif_drv = vif->hif_drv;
 
        PRINT_D(GENERIC_DBG, "Handling connect request\n");
 
-       if (memcmp(pstrHostIFconnectAttr->bssid, u8ConnectedSSID, ETH_ALEN) == 0) {
+       if (memcmp(pstrHostIFconnectAttr->bssid, wilc_connected_ssid, ETH_ALEN) == 0) {
                result = 0;
                PRINT_ER("Trying to connect to an already connected AP, Discard connect request\n");
                return result;
@@ -1206,20 +1185,22 @@ static s32 Handle_Connect(struct host_if_drv *hif_drv,
 
        if (memcmp("DIRECT-", pstrHostIFconnectAttr->ssid, 7)) {
                memcpy(join_req, pu8CurrByte, join_req_size);
-               join_req_drv = hif_drv;
+               join_req_vif = vif;
        }
 
        PRINT_D(GENERIC_DBG, "send HOST_IF_WAITING_CONN_RESP\n");
 
        if (pstrHostIFconnectAttr->bssid) {
-               memcpy(u8ConnectedSSID, pstrHostIFconnectAttr->bssid, ETH_ALEN);
-
-               PRINT_D(GENERIC_DBG, "save Bssid = %pM\n", pstrHostIFconnectAttr->bssid);
-               PRINT_D(GENERIC_DBG, "save bssid = %pM\n", u8ConnectedSSID);
+               memcpy(wilc_connected_ssid,
+                      pstrHostIFconnectAttr->bssid, ETH_ALEN);
+               PRINT_D(GENERIC_DBG, "save Bssid = %pM\n",
+                       pstrHostIFconnectAttr->bssid);
+               PRINT_D(GENERIC_DBG, "save bssid = %pM\n", wilc_connected_ssid);
        }
 
-       result = send_config_pkt(SET_CFG, strWIDList, u32WidsCount,
-                                get_id_from_handler(hif_drv));
+       result = wilc_send_config_pkt(vif->wilc, SET_CFG, strWIDList,
+                                     u32WidsCount,
+                                     wilc_get_vif_idx(vif));
        if (result) {
                PRINT_ER("failed to send config packet\n");
                result = -EFAULT;
@@ -1235,7 +1216,7 @@ ERRORHANDLER:
 
                del_timer(&hif_drv->connect_timer);
 
-               PRINT_D(HOSTINF_DBG, "could not start connecting to the required network\n");
+               PRINT_D(HOSTINF_DBG, "could not start wilc_connecting to the required network\n");
 
                memset(&strConnectInfo, 0, sizeof(tstrConnectInfo));
 
@@ -1279,7 +1260,7 @@ ERRORHANDLER:
        return result;
 }
 
-static s32 Handle_FlushConnect(struct host_if_drv *hif_drv)
+static s32 Handle_FlushConnect(struct wilc_vif *vif)
 {
        s32 result = 0;
        struct wid strWIDList[5];
@@ -1315,8 +1296,9 @@ static s32 Handle_FlushConnect(struct host_if_drv *hif_drv)
 
        u32WidsCount++;
 
-       result = send_config_pkt(SET_CFG, strWIDList, u32WidsCount,
-                                get_id_from_handler(join_req_drv));
+       result = wilc_send_config_pkt(vif->wilc, SET_CFG, strWIDList,
+                                     u32WidsCount,
+                                     wilc_get_vif_idx(join_req_vif));
        if (result) {
                PRINT_ER("failed to send config packet\n");
                result = -EINVAL;
@@ -1325,12 +1307,13 @@ static s32 Handle_FlushConnect(struct host_if_drv *hif_drv)
        return result;
 }
 
-static s32 Handle_ConnectTimeout(struct host_if_drv *hif_drv)
+static s32 Handle_ConnectTimeout(struct wilc_vif *vif)
 {
        s32 result = 0;
        tstrConnectInfo strConnectInfo;
        struct wid wid;
        u16 u16DummyReasonCode = 0;
+       struct host_if_drv *hif_drv = vif->hif_drv;
 
        if (!hif_drv) {
                PRINT_ER("Driver handler is NULL\n");
@@ -1376,25 +1359,28 @@ static s32 Handle_ConnectTimeout(struct host_if_drv *hif_drv)
 
        PRINT_D(HOSTINF_DBG, "Sending disconnect request\n");
 
-       result = send_config_pkt(SET_CFG, &wid, 1,
-                                get_id_from_handler(hif_drv));
+       result = wilc_send_config_pkt(vif->wilc, SET_CFG, &wid, 1,
+                                wilc_get_vif_idx(vif));
        if (result)
                PRINT_ER("Failed to send dissconect config packet\n");
 
        hif_drv->usr_conn_req.ssid_len = 0;
        kfree(hif_drv->usr_conn_req.pu8ssid);
+       hif_drv->usr_conn_req.pu8ssid = NULL;
        kfree(hif_drv->usr_conn_req.pu8bssid);
+       hif_drv->usr_conn_req.pu8bssid = NULL;
        hif_drv->usr_conn_req.ies_len = 0;
        kfree(hif_drv->usr_conn_req.ies);
+       hif_drv->usr_conn_req.ies = NULL;
 
-       eth_zero_addr(u8ConnectedSSID);
+       eth_zero_addr(wilc_connected_ssid);
 
-       if (join_req && join_req_drv == hif_drv) {
+       if (join_req && join_req_vif == vif) {
                kfree(join_req);
                join_req = NULL;
        }
 
-       if (info_element && join_req_drv == hif_drv) {
+       if (info_element && join_req_vif == vif) {
                kfree(info_element);
                info_element = NULL;
        }
@@ -1402,7 +1388,7 @@ static s32 Handle_ConnectTimeout(struct host_if_drv *hif_drv)
        return result;
 }
 
-static s32 Handle_RcvdNtwrkInfo(struct host_if_drv *hif_drv,
+static s32 Handle_RcvdNtwrkInfo(struct wilc_vif *vif,
                                struct rcvd_net_info *pstrRcvdNetworkInfo)
 {
        u32 i;
@@ -1410,13 +1396,14 @@ static s32 Handle_RcvdNtwrkInfo(struct host_if_drv *hif_drv,
        s32 result = 0;
        tstrNetworkInfo *pstrNetworkInfo = NULL;
        void *pJoinParams = NULL;
+       struct host_if_drv *hif_drv = vif->hif_drv;
 
        bNewNtwrkFound = true;
        PRINT_INFO(HOSTINF_DBG, "Handling received network info\n");
 
        if (hif_drv->usr_scan_req.scan_result) {
                PRINT_D(HOSTINF_DBG, "State: Scanning, parsing network information received\n");
-               parse_network_info(pstrRcvdNetworkInfo->buffer, &pstrNetworkInfo);
+               wilc_parse_network_info(pstrRcvdNetworkInfo->buffer, &pstrNetworkInfo);
                if ((!pstrNetworkInfo) ||
                    (!hif_drv->usr_scan_req.scan_result)) {
                        PRINT_ER("driver is null\n");
@@ -1476,14 +1463,19 @@ done:
        pstrRcvdNetworkInfo->buffer = NULL;
 
        if (pstrNetworkInfo) {
-               DeallocateNetworkInfo(pstrNetworkInfo);
+               wilc_dealloc_network_info(pstrNetworkInfo);
                pstrNetworkInfo = NULL;
        }
 
        return result;
 }
 
-static s32 Handle_RcvdGnrlAsyncInfo(struct host_if_drv *hif_drv,
+static s32 host_int_get_assoc_res_info(struct wilc_vif *vif,
+                                      u8 *pu8AssocRespInfo,
+                                      u32 u32MaxAssocRespInfoLen,
+                                      u32 *pu32RcvdAssocRespInfoLen);
+
+static s32 Handle_RcvdGnrlAsyncInfo(struct wilc_vif *vif,
                                    struct rcvd_async_info *pstrRcvdGnrlAsyncInfo)
 {
        s32 result = 0;
@@ -1498,6 +1490,7 @@ static s32 Handle_RcvdGnrlAsyncInfo(struct host_if_drv *hif_drv,
        tstrConnectInfo strConnectInfo;
        tstrDisconnectNotifInfo strDisconnectNotifInfo;
        s32 s32Err = 0;
+       struct host_if_drv *hif_drv = vif->hif_drv;
 
        if (!hif_drv) {
                PRINT_ER("Driver handler is NULL\n");
@@ -1531,7 +1524,7 @@ static s32 Handle_RcvdGnrlAsyncInfo(struct host_if_drv *hif_drv,
                u8MacStatusAdditionalInfo = pstrRcvdGnrlAsyncInfo->buffer[9];
                PRINT_INFO(HOSTINF_DBG, "Recieved MAC status = %d with Reason = %d , Info = %d\n", u8MacStatus, u8MacStatusReasonCode, u8MacStatusAdditionalInfo);
                if (hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP) {
-                       u32 u32RcvdAssocRespInfoLen;
+                       u32 u32RcvdAssocRespInfoLen = 0;
                        tstrConnectRespInfo *pstrConnectRespInfo = NULL;
 
                        PRINT_D(HOSTINF_DBG, "Recieved MAC status = %d with Reason = %d , Code = %d\n", u8MacStatus, u8MacStatusReasonCode, u8MacStatusAdditionalInfo);
@@ -1541,7 +1534,7 @@ static s32 Handle_RcvdGnrlAsyncInfo(struct host_if_drv *hif_drv,
                        if (u8MacStatus == MAC_CONNECTED) {
                                memset(rcv_assoc_resp, 0, MAX_ASSOC_RESP_FRAME_SIZE);
 
-                               host_int_get_assoc_res_info(hif_drv,
+                               host_int_get_assoc_res_info(vif,
                                                            rcv_assoc_resp,
                                                            MAX_ASSOC_RESP_FRAME_SIZE,
                                                            &u32RcvdAssocRespInfoLen);
@@ -1550,10 +1543,10 @@ static s32 Handle_RcvdGnrlAsyncInfo(struct host_if_drv *hif_drv,
 
                                if (u32RcvdAssocRespInfoLen != 0) {
                                        PRINT_D(HOSTINF_DBG, "Parsing association response\n");
-                                       s32Err = ParseAssocRespInfo(rcv_assoc_resp, u32RcvdAssocRespInfoLen,
+                                       s32Err = wilc_parse_assoc_resp_info(rcv_assoc_resp, u32RcvdAssocRespInfoLen,
                                                                    &pstrConnectRespInfo);
                                        if (s32Err) {
-                                               PRINT_ER("ParseAssocRespInfo() returned error %d\n", s32Err);
+                                               PRINT_ER("wilc_parse_assoc_resp_info() returned error %d\n", s32Err);
                                        } else {
                                                strConnectInfo.u16ConnectStatus = pstrConnectRespInfo->u16ConnectStatus;
 
@@ -1568,7 +1561,7 @@ static s32 Handle_RcvdGnrlAsyncInfo(struct host_if_drv *hif_drv,
                                                }
 
                                                if (pstrConnectRespInfo) {
-                                                       DeallocateAssocRespInfo(pstrConnectRespInfo);
+                                                       wilc_dealloc_assoc_resp_info(pstrConnectRespInfo);
                                                        pstrConnectRespInfo = NULL;
                                                }
                                        }
@@ -1578,11 +1571,10 @@ static s32 Handle_RcvdGnrlAsyncInfo(struct host_if_drv *hif_drv,
                        if ((u8MacStatus == MAC_CONNECTED) &&
                            (strConnectInfo.u16ConnectStatus != SUCCESSFUL_STATUSCODE)) {
                                PRINT_ER("Received MAC status is MAC_CONNECTED while the received status code in Asoc Resp is not SUCCESSFUL_STATUSCODE\n");
-                               eth_zero_addr(u8ConnectedSSID);
-
+                               eth_zero_addr(wilc_connected_ssid);
                        } else if (u8MacStatus == MAC_DISCONNECTED)    {
                                PRINT_ER("Received MAC status is MAC_DISCONNECTED\n");
-                               eth_zero_addr(u8ConnectedSSID);
+                               eth_zero_addr(wilc_connected_ssid);
                        }
 
                        if (hif_drv->usr_conn_req.pu8bssid) {
@@ -1613,14 +1605,14 @@ static s32 Handle_RcvdGnrlAsyncInfo(struct host_if_drv *hif_drv,
 
                        if ((u8MacStatus == MAC_CONNECTED) &&
                            (strConnectInfo.u16ConnectStatus == SUCCESSFUL_STATUSCODE)) {
-                               host_int_set_power_mgmt(hif_drv, 0, 0);
+                               wilc_set_power_mgmt(vif, 0, 0);
 
                                PRINT_D(HOSTINF_DBG, "MAC status : CONNECTED and Connect Status : Successful\n");
                                hif_drv->hif_state = HOST_IF_CONNECTED;
 
                                PRINT_D(GENERIC_DBG, "Obtaining an IP, Disable Scan\n");
-                               g_obtainingIP = true;
-                               mod_timer(&hDuringIpTimer,
+                               wilc_optaining_ip = true;
+                               mod_timer(&wilc_during_ip_timer,
                                          jiffies + msecs_to_jiffies(10000));
                        } else {
                                PRINT_D(HOSTINF_DBG, "MAC status : %d and Connect Status : %d\n", u8MacStatus, strConnectInfo.u16ConnectStatus);
@@ -1635,9 +1627,12 @@ static s32 Handle_RcvdGnrlAsyncInfo(struct host_if_drv *hif_drv,
                        strConnectInfo.pu8ReqIEs = NULL;
                        hif_drv->usr_conn_req.ssid_len = 0;
                        kfree(hif_drv->usr_conn_req.pu8ssid);
+                       hif_drv->usr_conn_req.pu8ssid = NULL;
                        kfree(hif_drv->usr_conn_req.pu8bssid);
+                       hif_drv->usr_conn_req.pu8bssid = NULL;
                        hif_drv->usr_conn_req.ies_len = 0;
                        kfree(hif_drv->usr_conn_req.ies);
+                       hif_drv->usr_conn_req.ies = NULL;
                } else if ((u8MacStatus == MAC_DISCONNECTED) &&
                           (hif_drv->hif_state == HOST_IF_CONNECTED)) {
                        PRINT_D(HOSTINF_DBG, "Received MAC_DISCONNECTED from the FW\n");
@@ -1647,7 +1642,7 @@ static s32 Handle_RcvdGnrlAsyncInfo(struct host_if_drv *hif_drv,
                        if (hif_drv->usr_scan_req.scan_result) {
                                PRINT_D(HOSTINF_DBG, "\n\n<< Abort the running OBSS Scan >>\n\n");
                                del_timer(&hif_drv->scan_timer);
-                               Handle_ScanDone((void *)hif_drv, SCAN_EVENT_ABORTED);
+                               Handle_ScanDone(vif, SCAN_EVENT_ABORTED);
                        }
 
                        strDisconnectNotifInfo.u16reason = 0;
@@ -1655,8 +1650,8 @@ static s32 Handle_RcvdGnrlAsyncInfo(struct host_if_drv *hif_drv,
                        strDisconnectNotifInfo.ie_len = 0;
 
                        if (hif_drv->usr_conn_req.conn_result) {
-                               g_obtainingIP = false;
-                               host_int_set_power_mgmt(hif_drv, 0, 0);
+                               wilc_optaining_ip = false;
+                               wilc_set_power_mgmt(vif, 0, 0);
 
                                hif_drv->usr_conn_req.conn_result(CONN_DISCONN_EVENT_DISCONN_NOTIF,
                                                                  NULL,
@@ -1671,16 +1666,19 @@ static s32 Handle_RcvdGnrlAsyncInfo(struct host_if_drv *hif_drv,
 
                        hif_drv->usr_conn_req.ssid_len = 0;
                        kfree(hif_drv->usr_conn_req.pu8ssid);
+                       hif_drv->usr_conn_req.pu8ssid = NULL;
                        kfree(hif_drv->usr_conn_req.pu8bssid);
+                       hif_drv->usr_conn_req.pu8bssid = NULL;
                        hif_drv->usr_conn_req.ies_len = 0;
                        kfree(hif_drv->usr_conn_req.ies);
+                       hif_drv->usr_conn_req.ies = NULL;
 
-                       if (join_req && join_req_drv == hif_drv) {
+                       if (join_req && join_req_vif == vif) {
                                kfree(join_req);
                                join_req = NULL;
                        }
 
-                       if (info_element && join_req_drv == hif_drv) {
+                       if (info_element && join_req_vif == vif) {
                                kfree(info_element);
                                info_element = NULL;
                        }
@@ -1695,7 +1693,7 @@ static s32 Handle_RcvdGnrlAsyncInfo(struct host_if_drv *hif_drv,
 
                        del_timer(&hif_drv->scan_timer);
                        if (hif_drv->usr_scan_req.scan_result)
-                               Handle_ScanDone(hif_drv, SCAN_EVENT_ABORTED);
+                               Handle_ScanDone(vif, SCAN_EVENT_ABORTED);
                }
        }
 
@@ -1705,7 +1703,7 @@ static s32 Handle_RcvdGnrlAsyncInfo(struct host_if_drv *hif_drv,
        return result;
 }
 
-static int Handle_Key(struct host_if_drv *hif_drv,
+static int Handle_Key(struct wilc_vif *vif,
                      struct key_attr *pstrHostIFkeyAttr)
 {
        s32 result = 0;
@@ -1715,6 +1713,7 @@ static int Handle_Key(struct host_if_drv *hif_drv,
        u8 *pu8keybuf;
        s8 s8idxarray[1];
        s8 ret = 0;
+       struct host_if_drv *hif_drv = vif->hif_drv;
 
        switch (pstrHostIFkeyAttr->type) {
        case WEP:
@@ -1754,12 +1753,11 @@ static int Handle_Key(struct host_if_drv *hif_drv,
                        strWIDList[3].size = pstrHostIFkeyAttr->attr.wep.key_len;
                        strWIDList[3].val = (s8 *)pu8keybuf;
 
-                       result = send_config_pkt(SET_CFG, strWIDList, 4,
-                                                get_id_from_handler(hif_drv));
+                       result = wilc_send_config_pkt(vif->wilc, SET_CFG,
+                                               strWIDList, 4,
+                                               wilc_get_vif_idx(vif));
                        kfree(pu8keybuf);
-               }
-
-               if (pstrHostIFkeyAttr->action & ADDKEY) {
+               } else if (pstrHostIFkeyAttr->action & ADDKEY) {
                        PRINT_D(HOSTINF_DBG, "Handling WEP key\n");
                        pu8keybuf = kmalloc(pstrHostIFkeyAttr->attr.wep.key_len + 2, GFP_KERNEL);
                        if (!pu8keybuf) {
@@ -1777,8 +1775,9 @@ static int Handle_Key(struct host_if_drv *hif_drv,
                        wid.val = (s8 *)pu8keybuf;
                        wid.size = pstrHostIFkeyAttr->attr.wep.key_len + 2;
 
-                       result = send_config_pkt(SET_CFG, &wid, 1,
-                                                get_id_from_handler(hif_drv));
+                       result = wilc_send_config_pkt(vif->wilc, SET_CFG,
+                                               &wid, 1,
+                                               wilc_get_vif_idx(vif));
                        kfree(pu8keybuf);
                } else if (pstrHostIFkeyAttr->action & REMOVEKEY) {
                        PRINT_D(HOSTINF_DBG, "Removing key\n");
@@ -1789,8 +1788,9 @@ static int Handle_Key(struct host_if_drv *hif_drv,
                        wid.val = s8idxarray;
                        wid.size = 1;
 
-                       result = send_config_pkt(SET_CFG, &wid, 1,
-                                                get_id_from_handler(hif_drv));
+                       result = wilc_send_config_pkt(vif->wilc, SET_CFG,
+                                               &wid, 1,
+                                               wilc_get_vif_idx(vif));
                } else {
                        wid.id = (u16)WID_KEY_ID;
                        wid.type = WID_CHAR;
@@ -1799,8 +1799,9 @@ static int Handle_Key(struct host_if_drv *hif_drv,
 
                        PRINT_D(HOSTINF_DBG, "Setting default key index\n");
 
-                       result = send_config_pkt(SET_CFG, &wid, 1,
-                                                get_id_from_handler(hif_drv));
+                       result = wilc_send_config_pkt(vif->wilc, SET_CFG,
+                                               &wid, 1,
+                                               wilc_get_vif_idx(vif));
                }
                up(&hif_drv->sem_test_key_block);
                break;
@@ -1832,14 +1833,13 @@ static int Handle_Key(struct host_if_drv *hif_drv,
                        strWIDList[1].val = (s8 *)pu8keybuf;
                        strWIDList[1].size = RX_MIC_KEY_MSG_LEN;
 
-                       result = send_config_pkt(SET_CFG, strWIDList, 2,
-                                                get_id_from_handler(hif_drv));
+                       result = wilc_send_config_pkt(vif->wilc, SET_CFG,
+                                               strWIDList, 2,
+                                               wilc_get_vif_idx(vif));
 
                        kfree(pu8keybuf);
                        up(&hif_drv->sem_test_key_block);
-               }
-
-               if (pstrHostIFkeyAttr->action & ADDKEY) {
+               } else if (pstrHostIFkeyAttr->action & ADDKEY) {
                        PRINT_D(HOSTINF_DBG, "Handling group key(Rx) function\n");
 
                        pu8keybuf = kzalloc(RX_MIC_KEY_MSG_LEN, GFP_KERNEL);
@@ -1865,8 +1865,9 @@ static int Handle_Key(struct host_if_drv *hif_drv,
                        wid.val = (s8 *)pu8keybuf;
                        wid.size = RX_MIC_KEY_MSG_LEN;
 
-                       result = send_config_pkt(SET_CFG, &wid, 1,
-                                                get_id_from_handler(hif_drv));
+                       result = wilc_send_config_pkt(vif->wilc, SET_CFG,
+                                               &wid, 1,
+                                               wilc_get_vif_idx(vif));
 
                        kfree(pu8keybuf);
                        up(&hif_drv->sem_test_key_block);
@@ -1904,12 +1905,12 @@ _WPARxGtk_end_case_:
                        strWIDList[1].val = (s8 *)pu8keybuf;
                        strWIDList[1].size = PTK_KEY_MSG_LEN + 1;
 
-                       result = send_config_pkt(SET_CFG, strWIDList, 2,
-                                                get_id_from_handler(hif_drv));
+                       result = wilc_send_config_pkt(vif->wilc, SET_CFG,
+                                               strWIDList, 2,
+                                               wilc_get_vif_idx(vif));
                        kfree(pu8keybuf);
                        up(&hif_drv->sem_test_key_block);
-               }
-               if (pstrHostIFkeyAttr->action & ADDKEY) {
+               } else if (pstrHostIFkeyAttr->action & ADDKEY) {
                        pu8keybuf = kmalloc(PTK_KEY_MSG_LEN, GFP_KERNEL);
                        if (!pu8keybuf) {
                                PRINT_ER("No buffer to send PTK Key\n");
@@ -1927,8 +1928,9 @@ _WPARxGtk_end_case_:
                        wid.val = (s8 *)pu8keybuf;
                        wid.size = PTK_KEY_MSG_LEN;
 
-                       result = send_config_pkt(SET_CFG, &wid, 1,
-                                                get_id_from_handler(hif_drv));
+                       result = wilc_send_config_pkt(vif->wilc, SET_CFG,
+                                               &wid, 1,
+                                               wilc_get_vif_idx(vif));
                        kfree(pu8keybuf);
                        up(&hif_drv->sem_test_key_block);
                }
@@ -1962,8 +1964,8 @@ _WPAPtk_end_case_:
                wid.val = (s8 *)pu8keybuf;
                wid.size = (pstrHostIFkeyAttr->attr.pmkid.numpmkid * PMKSA_KEY_LEN) + 1;
 
-               result = send_config_pkt(SET_CFG, &wid, 1,
-                                        get_id_from_handler(hif_drv));
+               result = wilc_send_config_pkt(vif->wilc, SET_CFG, &wid, 1,
+                                        wilc_get_vif_idx(vif));
 
                kfree(pu8keybuf);
                break;
@@ -1975,9 +1977,10 @@ _WPAPtk_end_case_:
        return result;
 }
 
-static void Handle_Disconnect(struct host_if_drv *hif_drv)
+static void Handle_Disconnect(struct wilc_vif *vif)
 {
        struct wid wid;
+       struct host_if_drv *hif_drv = vif->hif_drv;
 
        s32 result = 0;
        u16 u16DummyReasonCode = 0;
@@ -1989,13 +1992,13 @@ static void Handle_Disconnect(struct host_if_drv *hif_drv)
 
        PRINT_D(HOSTINF_DBG, "Sending disconnect request\n");
 
-       g_obtainingIP = false;
-       host_int_set_power_mgmt(hif_drv, 0, 0);
+       wilc_optaining_ip = false;
+       wilc_set_power_mgmt(vif, 0, 0);
 
-       eth_zero_addr(u8ConnectedSSID);
+       eth_zero_addr(wilc_connected_ssid);
 
-       result = send_config_pkt(SET_CFG, &wid, 1,
-                                get_id_from_handler(hif_drv));
+       result = wilc_send_config_pkt(vif->wilc, SET_CFG, &wid, 1,
+                                wilc_get_vif_idx(vif));
 
        if (result) {
                PRINT_ER("Failed to send dissconect config packet\n");
@@ -2040,16 +2043,19 @@ static void Handle_Disconnect(struct host_if_drv *hif_drv)
 
                hif_drv->usr_conn_req.ssid_len = 0;
                kfree(hif_drv->usr_conn_req.pu8ssid);
+               hif_drv->usr_conn_req.pu8ssid = NULL;
                kfree(hif_drv->usr_conn_req.pu8bssid);
+               hif_drv->usr_conn_req.pu8bssid = NULL;
                hif_drv->usr_conn_req.ies_len = 0;
                kfree(hif_drv->usr_conn_req.ies);
+               hif_drv->usr_conn_req.ies = NULL;
 
-               if (join_req && join_req_drv == hif_drv) {
+               if (join_req && join_req_vif == vif) {
                        kfree(join_req);
                        join_req = NULL;
                }
 
-               if (info_element && join_req_drv == hif_drv) {
+               if (info_element && join_req_vif == vif) {
                        kfree(info_element);
                        info_element = NULL;
                }
@@ -2058,21 +2064,22 @@ static void Handle_Disconnect(struct host_if_drv *hif_drv)
        up(&hif_drv->sem_test_disconn_block);
 }
 
-void resolve_disconnect_aberration(struct host_if_drv *hif_drv)
+void wilc_resolve_disconnect_aberration(struct wilc_vif *vif)
 {
-       if (!hif_drv)
+       if (!vif->hif_drv)
                return;
-       if ((hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP) ||
-           (hif_drv->hif_state == HOST_IF_CONNECTING)) {
+       if ((vif->hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP) ||
+           (vif->hif_drv->hif_state == HOST_IF_CONNECTING)) {
                PRINT_D(HOSTINF_DBG, "\n\n<< correcting Supplicant state machine >>\n\n");
-               host_int_disconnect(hif_drv, 1);
+               wilc_disconnect(vif, 1);
        }
 }
 
-static s32 Handle_GetChnl(struct host_if_drv *hif_drv)
+static s32 Handle_GetChnl(struct wilc_vif *vif)
 {
        s32 result = 0;
        struct wid wid;
+       struct host_if_drv *hif_drv = vif->hif_drv;
 
        wid.id = (u16)WID_CURRENT_CHANNEL;
        wid.type = WID_CHAR;
@@ -2081,8 +2088,8 @@ static s32 Handle_GetChnl(struct host_if_drv *hif_drv)
 
        PRINT_D(HOSTINF_DBG, "Getting channel value\n");
 
-       result = send_config_pkt(GET_CFG, &wid, 1,
-                                get_id_from_handler(hif_drv));
+       result = wilc_send_config_pkt(vif->wilc, GET_CFG, &wid, 1,
+                                wilc_get_vif_idx(vif));
 
        if (result) {
                PRINT_ER("Failed to get channel number\n");
@@ -2094,7 +2101,7 @@ static s32 Handle_GetChnl(struct host_if_drv *hif_drv)
        return result;
 }
 
-static void Handle_GetRssi(struct host_if_drv *hif_drv)
+static void Handle_GetRssi(struct wilc_vif *vif)
 {
        s32 result = 0;
        struct wid wid;
@@ -2106,20 +2113,21 @@ static void Handle_GetRssi(struct host_if_drv *hif_drv)
 
        PRINT_D(HOSTINF_DBG, "Getting RSSI value\n");
 
-       result = send_config_pkt(GET_CFG, &wid, 1,
-                                get_id_from_handler(hif_drv));
+       result = wilc_send_config_pkt(vif->wilc, GET_CFG, &wid, 1,
+                                wilc_get_vif_idx(vif));
        if (result) {
                PRINT_ER("Failed to get RSSI value\n");
                result = -EFAULT;
        }
 
-       up(&hif_drv->sem_get_rssi);
+       up(&vif->hif_drv->sem_get_rssi);
 }
 
-static void Handle_GetLinkspeed(struct host_if_drv *hif_drv)
+static void Handle_GetLinkspeed(struct wilc_vif *vif)
 {
        s32 result = 0;
        struct wid wid;
+       struct host_if_drv *hif_drv = vif->hif_drv;
 
        link_speed = 0;
 
@@ -2130,8 +2138,8 @@ static void Handle_GetLinkspeed(struct host_if_drv *hif_drv)
 
        PRINT_D(HOSTINF_DBG, "Getting LINKSPEED value\n");
 
-       result = send_config_pkt(GET_CFG, &wid, 1,
-                                get_id_from_handler(hif_drv));
+       result = wilc_send_config_pkt(vif->wilc, GET_CFG, &wid, 1,
+                                wilc_get_vif_idx(vif));
        if (result) {
                PRINT_ER("Failed to get LINKSPEED value\n");
                result = -EFAULT;
@@ -2140,7 +2148,8 @@ static void Handle_GetLinkspeed(struct host_if_drv *hif_drv)
        up(&hif_drv->sem_get_link_speed);
 }
 
-s32 Handle_GetStatistics(struct host_if_drv *hif_drv, struct rf_info *pstrStatistics)
+static s32 Handle_GetStatistics(struct wilc_vif *vif,
+                               struct rf_info *pstrStatistics)
 {
        struct wid strWIDList[5];
        u32 u32WidsCount = 0, result = 0;
@@ -2175,8 +2184,9 @@ s32 Handle_GetStatistics(struct host_if_drv *hif_drv, struct rf_info *pstrStatis
        strWIDList[u32WidsCount].val = (s8 *)&pstrStatistics->tx_fail_cnt;
        u32WidsCount++;
 
-       result = send_config_pkt(GET_CFG, strWIDList, u32WidsCount,
-                                get_id_from_handler(hif_drv));
+       result = wilc_send_config_pkt(vif->wilc, GET_CFG, strWIDList,
+                               u32WidsCount,
+                               wilc_get_vif_idx(vif));
 
        if (result)
                PRINT_ER("Failed to send scan paramters config packet\n");
@@ -2185,12 +2195,13 @@ s32 Handle_GetStatistics(struct host_if_drv *hif_drv, struct rf_info *pstrStatis
        return 0;
 }
 
-static s32 Handle_Get_InActiveTime(struct host_if_drv *hif_drv,
+static s32 Handle_Get_InActiveTime(struct wilc_vif *vif,
                                   struct sta_inactive_t *strHostIfStaInactiveT)
 {
        s32 result = 0;
        u8 *stamac;
        struct wid wid;
+       struct host_if_drv *hif_drv = vif->hif_drv;
 
        wid.id = (u16)WID_SET_STA_MAC_INACTIVE_TIME;
        wid.type = WID_STR;
@@ -2202,8 +2213,8 @@ static s32 Handle_Get_InActiveTime(struct host_if_drv *hif_drv,
 
        PRINT_D(CFG80211_DBG, "SETING STA inactive time\n");
 
-       result = send_config_pkt(SET_CFG, &wid, 1,
-                                get_id_from_handler(hif_drv));
+       result = wilc_send_config_pkt(vif->wilc, SET_CFG, &wid, 1,
+                                wilc_get_vif_idx(vif));
 
        if (result) {
                PRINT_ER("Failed to SET incative time\n");
@@ -2215,8 +2226,8 @@ static s32 Handle_Get_InActiveTime(struct host_if_drv *hif_drv,
        wid.val = (s8 *)&inactive_time;
        wid.size = sizeof(u32);
 
-       result = send_config_pkt(GET_CFG, &wid, 1,
-                                get_id_from_handler(hif_drv));
+       result = wilc_send_config_pkt(vif->wilc, GET_CFG, &wid, 1,
+                                wilc_get_vif_idx(vif));
 
        if (result) {
                PRINT_ER("Failed to get incative time\n");
@@ -2230,7 +2241,7 @@ static s32 Handle_Get_InActiveTime(struct host_if_drv *hif_drv,
        return result;
 }
 
-static void Handle_AddBeacon(struct host_if_drv *hif_drv,
+static void Handle_AddBeacon(struct wilc_vif *vif,
                             struct beacon_attr *pstrSetBeaconParam)
 {
        s32 result = 0;
@@ -2270,12 +2281,12 @@ static void Handle_AddBeacon(struct host_if_drv *hif_drv,
        *pu8CurrByte++ = ((pstrSetBeaconParam->tail_len >> 16) & 0xFF);
        *pu8CurrByte++ = ((pstrSetBeaconParam->tail_len >> 24) & 0xFF);
 
-       if (pstrSetBeaconParam->tail > 0)
+       if (pstrSetBeaconParam->tail)
                memcpy(pu8CurrByte, pstrSetBeaconParam->tail, pstrSetBeaconParam->tail_len);
        pu8CurrByte += pstrSetBeaconParam->tail_len;
 
-       result = send_config_pkt(SET_CFG, &wid, 1,
-                                get_id_from_handler(hif_drv));
+       result = wilc_send_config_pkt(vif->wilc, SET_CFG, &wid, 1,
+                                wilc_get_vif_idx(vif));
        if (result)
                PRINT_ER("Failed to send add beacon config packet\n");
 
@@ -2285,7 +2296,7 @@ ERRORHANDLER:
        kfree(pstrSetBeaconParam->tail);
 }
 
-static void Handle_DelBeacon(struct host_if_drv *hif_drv)
+static void Handle_DelBeacon(struct wilc_vif *vif)
 {
        s32 result = 0;
        struct wid wid;
@@ -2303,8 +2314,8 @@ static void Handle_DelBeacon(struct host_if_drv *hif_drv)
 
        PRINT_D(HOSTINF_DBG, "Deleting BEACON\n");
 
-       result = send_config_pkt(SET_CFG, &wid, 1,
-                                get_id_from_handler(hif_drv));
+       result = wilc_send_config_pkt(vif->wilc, SET_CFG, &wid, 1,
+                                wilc_get_vif_idx(vif));
        if (result)
                PRINT_ER("Failed to send delete beacon config packet\n");
 }
@@ -2357,7 +2368,7 @@ static u32 WILC_HostIf_PackStaParam(u8 *pu8Buffer,
        return pu8CurrByte - pu8Buffer;
 }
 
-static void Handle_AddStation(struct host_if_drv *hif_drv,
+static void Handle_AddStation(struct wilc_vif *vif,
                              struct add_sta_param *pstrStationParam)
 {
        s32 result = 0;
@@ -2376,8 +2387,8 @@ static void Handle_AddStation(struct host_if_drv *hif_drv,
        pu8CurrByte = wid.val;
        pu8CurrByte += WILC_HostIf_PackStaParam(pu8CurrByte, pstrStationParam);
 
-       result = send_config_pkt(SET_CFG, &wid, 1,
-                                get_id_from_handler(hif_drv));
+       result = wilc_send_config_pkt(vif->wilc, SET_CFG, &wid, 1,
+                                wilc_get_vif_idx(vif));
        if (result != 0)
                PRINT_ER("Failed to send add station config packet\n");
 
@@ -2386,7 +2397,7 @@ ERRORHANDLER:
        kfree(wid.val);
 }
 
-static void Handle_DelAllSta(struct host_if_drv *hif_drv,
+static void Handle_DelAllSta(struct wilc_vif *vif,
                             struct del_all_sta *pstrDelAllStaParam)
 {
        s32 result = 0;
@@ -2418,8 +2429,8 @@ static void Handle_DelAllSta(struct host_if_drv *hif_drv,
                pu8CurrByte += ETH_ALEN;
        }
 
-       result = send_config_pkt(SET_CFG, &wid, 1,
-                                get_id_from_handler(hif_drv));
+       result = wilc_send_config_pkt(vif->wilc, SET_CFG, &wid, 1,
+                                wilc_get_vif_idx(vif));
        if (result)
                PRINT_ER("Failed to send add station config packet\n");
 
@@ -2429,7 +2440,7 @@ ERRORHANDLER:
        up(&hif_sema_wait_response);
 }
 
-static void Handle_DelStation(struct host_if_drv *hif_drv,
+static void Handle_DelStation(struct wilc_vif *vif,
                              struct del_sta *pstrDelStaParam)
 {
        s32 result = 0;
@@ -2450,8 +2461,8 @@ static void Handle_DelStation(struct host_if_drv *hif_drv,
 
        memcpy(pu8CurrByte, pstrDelStaParam->mac_addr, ETH_ALEN);
 
-       result = send_config_pkt(SET_CFG, &wid, 1,
-                                get_id_from_handler(hif_drv));
+       result = wilc_send_config_pkt(vif->wilc, SET_CFG, &wid, 1,
+                                wilc_get_vif_idx(vif));
        if (result)
                PRINT_ER("Failed to send add station config packet\n");
 
@@ -2459,7 +2470,7 @@ ERRORHANDLER:
        kfree(wid.val);
 }
 
-static void Handle_EditStation(struct host_if_drv *hif_drv,
+static void Handle_EditStation(struct wilc_vif *vif,
                               struct add_sta_param *pstrStationParam)
 {
        s32 result = 0;
@@ -2478,8 +2489,8 @@ static void Handle_EditStation(struct host_if_drv *hif_drv,
        pu8CurrByte = wid.val;
        pu8CurrByte += WILC_HostIf_PackStaParam(pu8CurrByte, pstrStationParam);
 
-       result = send_config_pkt(SET_CFG, &wid, 1,
-                                get_id_from_handler(hif_drv));
+       result = wilc_send_config_pkt(vif->wilc, SET_CFG, &wid, 1,
+                                wilc_get_vif_idx(vif));
        if (result)
                PRINT_ER("Failed to send edit station config packet\n");
 
@@ -2488,12 +2499,13 @@ ERRORHANDLER:
        kfree(wid.val);
 }
 
-static int Handle_RemainOnChan(struct host_if_drv *hif_drv,
+static int Handle_RemainOnChan(struct wilc_vif *vif,
                               struct remain_ch *pstrHostIfRemainOnChan)
 {
        s32 result = 0;
        u8 u8remain_on_chan_flag;
        struct wid wid;
+       struct host_if_drv *hif_drv = vif->hif_drv;
 
        if (!hif_drv->remain_on_ch_pending) {
                hif_drv->remain_on_ch.arg = pstrHostIfRemainOnChan->arg;
@@ -2517,7 +2529,7 @@ static int Handle_RemainOnChan(struct host_if_drv *hif_drv,
                goto ERRORHANDLER;
        }
 
-       if (g_obtainingIP || connecting) {
+       if (wilc_optaining_ip || wilc_connecting) {
                PRINT_D(GENERIC_DBG, "[handle_scan]: Don't do obss scan until IP adresss is obtained\n");
                result = -EBUSY;
                goto ERRORHANDLER;
@@ -2539,15 +2551,15 @@ static int Handle_RemainOnChan(struct host_if_drv *hif_drv,
        wid.val[0] = u8remain_on_chan_flag;
        wid.val[1] = (s8)pstrHostIfRemainOnChan->ch;
 
-       result = send_config_pkt(SET_CFG, &wid, 1,
-                                get_id_from_handler(hif_drv));
+       result = wilc_send_config_pkt(vif->wilc, SET_CFG, &wid, 1,
+                                wilc_get_vif_idx(vif));
        if (result != 0)
                PRINT_ER("Failed to set remain on channel\n");
 
 ERRORHANDLER:
        {
                P2P_LISTEN_STATE = 1;
-               hif_drv->remain_on_ch_timer.data = (unsigned long)hif_drv;
+               hif_drv->remain_on_ch_timer.data = (unsigned long)vif;
                mod_timer(&hif_drv->remain_on_ch_timer,
                          jiffies +
                          msecs_to_jiffies(pstrHostIfRemainOnChan->u32duration));
@@ -2562,7 +2574,7 @@ ERRORHANDLER:
        return result;
 }
 
-static int Handle_RegisterFrame(struct host_if_drv *hif_drv,
+static int Handle_RegisterFrame(struct wilc_vif *vif,
                                struct reg_frame *pstrHostIfRegisterFrame)
 {
        s32 result = 0;
@@ -2587,8 +2599,8 @@ static int Handle_RegisterFrame(struct host_if_drv *hif_drv,
 
        wid.size = sizeof(u16) + 2;
 
-       result = send_config_pkt(SET_CFG, &wid, 1,
-                                get_id_from_handler(hif_drv));
+       result = wilc_send_config_pkt(vif->wilc, SET_CFG, &wid, 1,
+                                wilc_get_vif_idx(vif));
        if (result) {
                PRINT_ER("Failed to frame register config packet\n");
                result = -EINVAL;
@@ -2597,12 +2609,13 @@ static int Handle_RegisterFrame(struct host_if_drv *hif_drv,
        return result;
 }
 
-static u32 Handle_ListenStateExpired(struct host_if_drv *hif_drv,
+static u32 Handle_ListenStateExpired(struct wilc_vif *vif,
                                     struct remain_ch *pstrHostIfRemainOnChan)
 {
        u8 u8remain_on_chan_flag;
        struct wid wid;
        s32 result = 0;
+       struct host_if_drv *hif_drv = vif->hif_drv;
 
        PRINT_D(HOSTINF_DBG, "CANCEL REMAIN ON CHAN\n");
 
@@ -2613,14 +2626,16 @@ static u32 Handle_ListenStateExpired(struct host_if_drv *hif_drv,
                wid.size = 2;
                wid.val = kmalloc(wid.size, GFP_KERNEL);
 
-               if (!wid.val)
+               if (!wid.val) {
                        PRINT_ER("Failed to allocate memory\n");
+                       return -ENOMEM;
+               }
 
                wid.val[0] = u8remain_on_chan_flag;
                wid.val[1] = FALSE_FRMWR_CHANNEL;
 
-               result = send_config_pkt(SET_CFG, &wid, 1,
-                                        get_id_from_handler(hif_drv));
+               result = wilc_send_config_pkt(vif->wilc, SET_CFG, &wid, 1,
+                                        wilc_get_vif_idx(vif));
                if (result != 0) {
                        PRINT_ER("Failed to set remain on channel\n");
                        goto _done_;
@@ -2644,21 +2659,21 @@ static void ListenTimerCB(unsigned long arg)
 {
        s32 result = 0;
        struct host_if_msg msg;
-       struct host_if_drv *hif_drv = (struct host_if_drv *)arg;
+       struct wilc_vif *vif = (struct wilc_vif *)arg;
 
-       del_timer(&hif_drv->remain_on_ch_timer);
+       del_timer(&vif->hif_drv->remain_on_ch_timer);
 
        memset(&msg, 0, sizeof(struct host_if_msg));
        msg.id = HOST_IF_MSG_LISTEN_TIMER_FIRED;
-       msg.drv = hif_drv;
-       msg.body.remain_on_ch.id = hif_drv->remain_on_ch.id;
+       msg.vif = vif;
+       msg.body.remain_on_ch.id = vif->hif_drv->remain_on_ch.id;
 
        result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
        if (result)
                PRINT_ER("wilc_mq_send fail\n");
 }
 
-static void Handle_PowerManagement(struct host_if_drv *hif_drv,
+static void Handle_PowerManagement(struct wilc_vif *vif,
                                   struct power_mgmt_param *strPowerMgmtParam)
 {
        s32 result = 0;
@@ -2677,13 +2692,13 @@ static void Handle_PowerManagement(struct host_if_drv *hif_drv,
 
        PRINT_D(HOSTINF_DBG, "Handling Power Management\n");
 
-       result = send_config_pkt(SET_CFG, &wid, 1,
-                                get_id_from_handler(hif_drv));
+       result = wilc_send_config_pkt(vif->wilc, SET_CFG, &wid, 1,
+                                wilc_get_vif_idx(vif));
        if (result)
                PRINT_ER("Failed to send power management config packet\n");
 }
 
-static void Handle_SetMulticastFilter(struct host_if_drv *hif_drv,
+static void Handle_SetMulticastFilter(struct wilc_vif *vif,
                                      struct set_multicast *strHostIfSetMulti)
 {
        s32 result = 0;
@@ -2701,9 +2716,9 @@ static void Handle_SetMulticastFilter(struct host_if_drv *hif_drv,
 
        pu8CurrByte = wid.val;
        *pu8CurrByte++ = (strHostIfSetMulti->enabled & 0xFF);
-       *pu8CurrByte++ = ((strHostIfSetMulti->enabled >> 8) & 0xFF);
-       *pu8CurrByte++ = ((strHostIfSetMulti->enabled >> 16) & 0xFF);
-       *pu8CurrByte++ = ((strHostIfSetMulti->enabled >> 24) & 0xFF);
+       *pu8CurrByte++ = 0;
+       *pu8CurrByte++ = 0;
+       *pu8CurrByte++ = 0;
 
        *pu8CurrByte++ = (strHostIfSetMulti->cnt & 0xFF);
        *pu8CurrByte++ = ((strHostIfSetMulti->cnt >> 8) & 0xFF);
@@ -2711,11 +2726,11 @@ static void Handle_SetMulticastFilter(struct host_if_drv *hif_drv,
        *pu8CurrByte++ = ((strHostIfSetMulti->cnt >> 24) & 0xFF);
 
        if ((strHostIfSetMulti->cnt) > 0)
-               memcpy(pu8CurrByte, multicast_mac_addr_list,
+               memcpy(pu8CurrByte, wilc_multicast_mac_addr_list,
                       ((strHostIfSetMulti->cnt) * ETH_ALEN));
 
-       result = send_config_pkt(SET_CFG, &wid, 1,
-                                get_id_from_handler(hif_drv));
+       result = wilc_send_config_pkt(vif->wilc, SET_CFG, &wid, 1,
+                                wilc_get_vif_idx(vif));
        if (result)
                PRINT_ER("Failed to send setup multicast config packet\n");
 
@@ -2723,71 +2738,7 @@ ERRORHANDLER:
        kfree(wid.val);
 }
 
-static s32 Handle_AddBASession(struct host_if_drv *hif_drv,
-                              struct ba_session_info *strHostIfBASessionInfo)
-{
-       s32 result = 0;
-       struct wid wid;
-       int AddbaTimeout = 100;
-       char *ptr = NULL;
-
-       PRINT_D(HOSTINF_DBG, "Opening Block Ack session with\nBSSID = %.2x:%.2x:%.2x\nTID=%d\nBufferSize == %d\nSessionTimeOut = %d\n",
-               strHostIfBASessionInfo->bssid[0],
-               strHostIfBASessionInfo->bssid[1],
-               strHostIfBASessionInfo->bssid[2],
-               strHostIfBASessionInfo->buf_size,
-               strHostIfBASessionInfo->time_out,
-               strHostIfBASessionInfo->tid);
-
-       wid.id = (u16)WID_11E_P_ACTION_REQ;
-       wid.type = WID_STR;
-       wid.val = kmalloc(BLOCK_ACK_REQ_SIZE, GFP_KERNEL);
-       wid.size = BLOCK_ACK_REQ_SIZE;
-       ptr = wid.val;
-       *ptr++ = 0x14;
-       *ptr++ = 0x3;
-       *ptr++ = 0x0;
-       memcpy(ptr, strHostIfBASessionInfo->bssid, ETH_ALEN);
-       ptr += ETH_ALEN;
-       *ptr++ = strHostIfBASessionInfo->tid;
-       *ptr++ = 1;
-       *ptr++ = (strHostIfBASessionInfo->buf_size & 0xFF);
-       *ptr++ = ((strHostIfBASessionInfo->buf_size >> 16) & 0xFF);
-       *ptr++ = (strHostIfBASessionInfo->time_out & 0xFF);
-       *ptr++ = ((strHostIfBASessionInfo->time_out >> 16) & 0xFF);
-       *ptr++ = (AddbaTimeout & 0xFF);
-       *ptr++ = ((AddbaTimeout >> 16) & 0xFF);
-       *ptr++ = 8;
-       *ptr++ = 0;
-
-       result = send_config_pkt(SET_CFG, &wid, 1,
-                                get_id_from_handler(hif_drv));
-       if (result)
-               PRINT_D(HOSTINF_DBG, "Couldn't open BA Session\n");
-
-       wid.id = (u16)WID_11E_P_ACTION_REQ;
-       wid.type = WID_STR;
-       wid.size = 15;
-       ptr = wid.val;
-       *ptr++ = 15;
-       *ptr++ = 7;
-       *ptr++ = 0x2;
-       memcpy(ptr, strHostIfBASessionInfo->bssid, ETH_ALEN);
-       ptr += ETH_ALEN;
-       *ptr++ = strHostIfBASessionInfo->tid;
-       *ptr++ = 8;
-       *ptr++ = (strHostIfBASessionInfo->buf_size & 0xFF);
-       *ptr++ = ((strHostIfBASessionInfo->time_out >> 16) & 0xFF);
-       *ptr++ = 3;
-       result = send_config_pkt(SET_CFG, &wid, 1,
-                                get_id_from_handler(hif_drv));
-
-       kfree(wid.val);
-
-       return result;
-}
-
-static s32 Handle_DelAllRxBASessions(struct host_if_drv *hif_drv,
+static s32 Handle_DelAllRxBASessions(struct wilc_vif *vif,
                                     struct ba_session_info *strHostIfBASessionInfo)
 {
        s32 result = 0;
@@ -2814,8 +2765,8 @@ static s32 Handle_DelAllRxBASessions(struct host_if_drv *hif_drv,
        *ptr++ = 0;
        *ptr++ = 32;
 
-       result = send_config_pkt(SET_CFG, &wid, 1,
-                                get_id_from_handler(hif_drv));
+       result = wilc_send_config_pkt(vif->wilc, SET_CFG, &wid, 1,
+                                wilc_get_vif_idx(vif));
        if (result)
                PRINT_D(HOSTINF_DBG, "Couldn't delete BA Session\n");
 
@@ -2830,19 +2781,20 @@ static int hostIFthread(void *pvArg)
 {
        u32 u32Ret;
        struct host_if_msg msg;
-       struct host_if_drv *hif_drv;
+       struct wilc *wilc = (struct wilc*)pvArg;
+       struct wilc_vif *vif;
 
        memset(&msg, 0, sizeof(struct host_if_msg));
 
        while (1) {
                wilc_mq_recv(&hif_msg_q, &msg, sizeof(struct host_if_msg), &u32Ret);
-               hif_drv = (struct host_if_drv *)msg.drv;
+               vif = msg.vif;
                if (msg.id == HOST_IF_MSG_EXIT) {
                        PRINT_D(GENERIC_DBG, "THREAD: Exiting HostIfThread\n");
                        break;
                }
 
-               if ((!g_wilc_initialized)) {
+               if ((!wilc_initialized)) {
                        PRINT_D(GENERIC_DBG, "--WAIT--");
                        usleep_range(200 * 1000, 200 * 1000);
                        wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
@@ -2850,7 +2802,7 @@ static int hostIFthread(void *pvArg)
                }
 
                if (msg.id == HOST_IF_MSG_CONNECT &&
-                   hif_drv->usr_scan_req.scan_result) {
+                   vif->hif_drv->usr_scan_req.scan_result) {
                        PRINT_D(HOSTINF_DBG, "Requeue connect request till scan done received\n");
                        wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
                        usleep_range(2 * 1000, 2 * 1000);
@@ -2863,169 +2815,169 @@ static int hostIFthread(void *pvArg)
                        break;
 
                case HOST_IF_MSG_SCAN:
-                       Handle_Scan(msg.drv, &msg.body.scan_info);
+                       Handle_Scan(msg.vif, &msg.body.scan_info);
                        break;
 
                case HOST_IF_MSG_CONNECT:
-                       Handle_Connect(msg.drv, &msg.body.con_info);
+                       Handle_Connect(msg.vif, &msg.body.con_info);
                        break;
 
                case HOST_IF_MSG_FLUSH_CONNECT:
-                       Handle_FlushConnect(msg.drv);
+                       Handle_FlushConnect(msg.vif);
                        break;
 
                case HOST_IF_MSG_RCVD_NTWRK_INFO:
-                       Handle_RcvdNtwrkInfo(msg.drv, &msg.body.net_info);
+                       Handle_RcvdNtwrkInfo(msg.vif, &msg.body.net_info);
                        break;
 
                case HOST_IF_MSG_RCVD_GNRL_ASYNC_INFO:
-                       Handle_RcvdGnrlAsyncInfo(msg.drv, &msg.body.async_info);
+                       Handle_RcvdGnrlAsyncInfo(vif,
+                                                &msg.body.async_info);
                        break;
 
                case HOST_IF_MSG_KEY:
-                       Handle_Key(msg.drv, &msg.body.key_info);
+                       Handle_Key(msg.vif, &msg.body.key_info);
                        break;
 
                case HOST_IF_MSG_CFG_PARAMS:
-                       handle_cfg_param(msg.drv, &msg.body.cfg_info);
+                       handle_cfg_param(msg.vif, &msg.body.cfg_info);
                        break;
 
                case HOST_IF_MSG_SET_CHANNEL:
-                       handle_set_channel(msg.drv, &msg.body.channel_info);
+                       handle_set_channel(msg.vif, &msg.body.channel_info);
                        break;
 
                case HOST_IF_MSG_DISCONNECT:
-                       Handle_Disconnect(msg.drv);
+                       Handle_Disconnect(msg.vif);
                        break;
 
                case HOST_IF_MSG_RCVD_SCAN_COMPLETE:
-                       del_timer(&hif_drv->scan_timer);
+                       del_timer(&vif->hif_drv->scan_timer);
                        PRINT_D(HOSTINF_DBG, "scan completed successfully\n");
 
-                       if (!linux_wlan_get_num_conn_ifcs())
-                               chip_sleep_manually();
+                       if (!wilc_wlan_get_num_conn_ifcs(wilc))
+                               wilc_chip_sleep_manually(wilc);
 
-                       Handle_ScanDone(msg.drv, SCAN_EVENT_DONE);
+                       Handle_ScanDone(msg.vif, SCAN_EVENT_DONE);
 
-                       if (hif_drv->remain_on_ch_pending)
-                               Handle_RemainOnChan(msg.drv, &msg.body.remain_on_ch);
+                       if (vif->hif_drv->remain_on_ch_pending)
+                               Handle_RemainOnChan(msg.vif,
+                                                   &msg.body.remain_on_ch);
 
                        break;
 
                case HOST_IF_MSG_GET_RSSI:
-                       Handle_GetRssi(msg.drv);
+                       Handle_GetRssi(msg.vif);
                        break;
 
                case HOST_IF_MSG_GET_LINKSPEED:
-                       Handle_GetLinkspeed(msg.drv);
+                       Handle_GetLinkspeed(msg.vif);
                        break;
 
                case HOST_IF_MSG_GET_STATISTICS:
-                       Handle_GetStatistics(msg.drv, (struct rf_info *)msg.body.data);
+                       Handle_GetStatistics(msg.vif,
+                                            (struct rf_info *)msg.body.data);
                        break;
 
                case HOST_IF_MSG_GET_CHNL:
-                       Handle_GetChnl(msg.drv);
+                       Handle_GetChnl(msg.vif);
                        break;
 
                case HOST_IF_MSG_ADD_BEACON:
-                       Handle_AddBeacon(msg.drv, &msg.body.beacon_info);
+                       Handle_AddBeacon(msg.vif, &msg.body.beacon_info);
                        break;
 
                case HOST_IF_MSG_DEL_BEACON:
-                       Handle_DelBeacon(msg.drv);
+                       Handle_DelBeacon(msg.vif);
                        break;
 
                case HOST_IF_MSG_ADD_STATION:
-                       Handle_AddStation(msg.drv, &msg.body.add_sta_info);
+                       Handle_AddStation(msg.vif, &msg.body.add_sta_info);
                        break;
 
                case HOST_IF_MSG_DEL_STATION:
-                       Handle_DelStation(msg.drv, &msg.body.del_sta_info);
+                       Handle_DelStation(msg.vif, &msg.body.del_sta_info);
                        break;
 
                case HOST_IF_MSG_EDIT_STATION:
-                       Handle_EditStation(msg.drv, &msg.body.edit_sta_info);
+                       Handle_EditStation(msg.vif, &msg.body.edit_sta_info);
                        break;
 
                case HOST_IF_MSG_GET_INACTIVETIME:
-                       Handle_Get_InActiveTime(msg.drv, &msg.body.mac_info);
+                       Handle_Get_InActiveTime(msg.vif, &msg.body.mac_info);
                        break;
 
                case HOST_IF_MSG_SCAN_TIMER_FIRED:
                        PRINT_D(HOSTINF_DBG, "Scan Timeout\n");
 
-                       Handle_ScanDone(msg.drv, SCAN_EVENT_ABORTED);
+                       Handle_ScanDone(msg.vif, SCAN_EVENT_ABORTED);
                        break;
 
                case HOST_IF_MSG_CONNECT_TIMER_FIRED:
                        PRINT_D(HOSTINF_DBG, "Connect Timeout\n");
-                       Handle_ConnectTimeout(msg.drv);
+                       Handle_ConnectTimeout(msg.vif);
                        break;
 
                case HOST_IF_MSG_POWER_MGMT:
-                       Handle_PowerManagement(msg.drv, &msg.body.pwr_mgmt_info);
+                       Handle_PowerManagement(msg.vif,
+                                              &msg.body.pwr_mgmt_info);
                        break;
 
                case HOST_IF_MSG_SET_WFIDRV_HANDLER:
-                       handle_set_wfi_drv_handler(msg.drv, &msg.body.drv);
+                       handle_set_wfi_drv_handler(msg.vif, &msg.body.drv);
                        break;
 
                case HOST_IF_MSG_SET_OPERATION_MODE:
-                       handle_set_operation_mode(msg.drv, &msg.body.mode);
+                       handle_set_operation_mode(msg.vif, &msg.body.mode);
                        break;
 
                case HOST_IF_MSG_SET_IPADDRESS:
                        PRINT_D(HOSTINF_DBG, "HOST_IF_MSG_SET_IPADDRESS\n");
-                       handle_set_ip_address(msg.drv,
+                       handle_set_ip_address(vif,
                                              msg.body.ip_info.ip_addr,
                                              msg.body.ip_info.idx);
                        break;
 
                case HOST_IF_MSG_GET_IPADDRESS:
                        PRINT_D(HOSTINF_DBG, "HOST_IF_MSG_SET_IPADDRESS\n");
-                       handle_get_ip_address(msg.drv, msg.body.ip_info.idx);
+                       handle_get_ip_address(vif, msg.body.ip_info.idx);
                        break;
 
                case HOST_IF_MSG_SET_MAC_ADDRESS:
-                       handle_set_mac_address(msg.drv,
+                       handle_set_mac_address(msg.vif,
                                               &msg.body.set_mac_info);
                        break;
 
                case HOST_IF_MSG_GET_MAC_ADDRESS:
-                       handle_get_mac_address(msg.drv,
+                       handle_get_mac_address(msg.vif,
                                               &msg.body.get_mac_info);
                        break;
 
                case HOST_IF_MSG_REMAIN_ON_CHAN:
                        PRINT_D(HOSTINF_DBG, "HOST_IF_MSG_REMAIN_ON_CHAN\n");
-                       Handle_RemainOnChan(msg.drv, &msg.body.remain_on_ch);
+                       Handle_RemainOnChan(msg.vif, &msg.body.remain_on_ch);
                        break;
 
                case HOST_IF_MSG_REGISTER_FRAME:
                        PRINT_D(HOSTINF_DBG, "HOST_IF_MSG_REGISTER_FRAME\n");
-                       Handle_RegisterFrame(msg.drv, &msg.body.reg_frame);
+                       Handle_RegisterFrame(msg.vif, &msg.body.reg_frame);
                        break;
 
                case HOST_IF_MSG_LISTEN_TIMER_FIRED:
-                       Handle_ListenStateExpired(msg.drv, &msg.body.remain_on_ch);
+                       Handle_ListenStateExpired(msg.vif, &msg.body.remain_on_ch);
                        break;
 
                case HOST_IF_MSG_SET_MULTICAST_FILTER:
                        PRINT_D(HOSTINF_DBG, "HOST_IF_MSG_SET_MULTICAST_FILTER\n");
-                       Handle_SetMulticastFilter(msg.drv, &msg.body.multicast_info);
-                       break;
-
-               case HOST_IF_MSG_ADD_BA_SESSION:
-                       Handle_AddBASession(msg.drv, &msg.body.session_info);
+                       Handle_SetMulticastFilter(msg.vif, &msg.body.multicast_info);
                        break;
 
                case HOST_IF_MSG_DEL_ALL_RX_BA_SESSIONS:
-                       Handle_DelAllRxBASessions(msg.drv, &msg.body.session_info);
+                       Handle_DelAllRxBASessions(msg.vif, &msg.body.session_info);
                        break;
 
                case HOST_IF_MSG_DEL_ALL_STA:
-                       Handle_DelAllSta(msg.drv, &msg.body.del_all_sta_info);
+                       Handle_DelAllSta(msg.vif, &msg.body.del_all_sta_info);
                        break;
 
                default:
@@ -3041,11 +2993,11 @@ static int hostIFthread(void *pvArg)
 
 static void TimerCB_Scan(unsigned long arg)
 {
-       void *pvArg = (void *)arg;
+       struct wilc_vif *vif = (struct wilc_vif *)arg;
        struct host_if_msg msg;
 
        memset(&msg, 0, sizeof(struct host_if_msg));
-       msg.drv = pvArg;
+       msg.vif = vif;
        msg.id = HOST_IF_MSG_SCAN_TIMER_FIRED;
 
        wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
@@ -3053,17 +3005,17 @@ static void TimerCB_Scan(unsigned long arg)
 
 static void TimerCB_Connect(unsigned long arg)
 {
-       void *pvArg = (void *)arg;
+       struct wilc_vif *vif = (struct wilc_vif *)arg;
        struct host_if_msg msg;
 
        memset(&msg, 0, sizeof(struct host_if_msg));
-       msg.drv = pvArg;
+       msg.vif = vif;
        msg.id = HOST_IF_MSG_CONNECT_TIMER_FIRED;
 
        wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
 }
 
-s32 host_int_remove_key(struct host_if_drv *hif_drv, const u8 *pu8StaAddress)
+s32 wilc_remove_key(struct host_if_drv *hif_drv, const u8 *pu8StaAddress)
 {
        struct wid wid;
 
@@ -3075,10 +3027,11 @@ s32 host_int_remove_key(struct host_if_drv *hif_drv, const u8 *pu8StaAddress)
        return 0;
 }
 
-int host_int_remove_wep_key(struct host_if_drv *hif_drv, u8 index)
+int wilc_remove_wep_key(struct wilc_vif *vif, u8 index)
 {
        int result = 0;
        struct host_if_msg msg;
+       struct host_if_drv *hif_drv = vif->hif_drv;
 
        if (!hif_drv) {
                result = -EFAULT;
@@ -3091,7 +3044,7 @@ int host_int_remove_wep_key(struct host_if_drv *hif_drv, u8 index)
        msg.id = HOST_IF_MSG_KEY;
        msg.body.key_info.type = WEP;
        msg.body.key_info.action = REMOVEKEY;
-       msg.drv = hif_drv;
+       msg.vif = vif;
        msg.body.key_info.attr.wep.index = index;
 
        result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
@@ -3102,10 +3055,11 @@ int host_int_remove_wep_key(struct host_if_drv *hif_drv, u8 index)
        return result;
 }
 
-int host_int_set_wep_default_key(struct host_if_drv *hif_drv, u8 index)
+int wilc_set_wep_default_keyid(struct wilc_vif *vif, u8 index)
 {
        int result = 0;
        struct host_if_msg msg;
+       struct host_if_drv *hif_drv = vif->hif_drv;
 
        if (!hif_drv) {
                result = -EFAULT;
@@ -3118,7 +3072,7 @@ int host_int_set_wep_default_key(struct host_if_drv *hif_drv, u8 index)
        msg.id = HOST_IF_MSG_KEY;
        msg.body.key_info.type = WEP;
        msg.body.key_info.action = DEFAULTKEY;
-       msg.drv = hif_drv;
+       msg.vif = vif;
        msg.body.key_info.attr.wep.index = index;
 
        result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
@@ -3129,13 +3083,12 @@ int host_int_set_wep_default_key(struct host_if_drv *hif_drv, u8 index)
        return result;
 }
 
-int host_int_add_wep_key_bss_sta(struct host_if_drv *hif_drv,
-                                const u8 *key,
-                                u8 len,
-                                u8 index)
+int wilc_add_wep_key_bss_sta(struct wilc_vif *vif, const u8 *key, u8 len,
+                            u8 index)
 {
        int result = 0;
        struct host_if_msg msg;
+       struct host_if_drv *hif_drv = vif->hif_drv;
 
        if (!hif_drv) {
                PRINT_ER("driver is null\n");
@@ -3147,7 +3100,7 @@ int host_int_add_wep_key_bss_sta(struct host_if_drv *hif_drv,
        msg.id = HOST_IF_MSG_KEY;
        msg.body.key_info.type = WEP;
        msg.body.key_info.action = ADDKEY;
-       msg.drv = hif_drv;
+       msg.vif = vif;
        msg.body.key_info.attr.wep.key = kmemdup(key, len, GFP_KERNEL);
        if (!msg.body.key_info.attr.wep.key)
                return -ENOMEM;
@@ -3163,15 +3116,12 @@ int host_int_add_wep_key_bss_sta(struct host_if_drv *hif_drv,
        return result;
 }
 
-int host_int_add_wep_key_bss_ap(struct host_if_drv *hif_drv,
-                               const u8 *key,
-                               u8 len,
-                               u8 index,
-                               u8 mode,
-                               enum AUTHTYPE auth_type)
+int wilc_add_wep_key_bss_ap(struct wilc_vif *vif, const u8 *key, u8 len,
+                           u8 index, u8 mode, enum AUTHTYPE auth_type)
 {
        int result = 0;
        struct host_if_msg msg;
+       struct host_if_drv *hif_drv = vif->hif_drv;
        int i;
 
        if (!hif_drv) {
@@ -3188,7 +3138,7 @@ int host_int_add_wep_key_bss_ap(struct host_if_drv *hif_drv,
        msg.id = HOST_IF_MSG_KEY;
        msg.body.key_info.type = WEP;
        msg.body.key_info.action = ADDKEY_AP;
-       msg.drv = hif_drv;
+       msg.vif = vif;
        msg.body.key_info.attr.wep.key = kmemdup(key, len, GFP_KERNEL);
        if (!msg.body.key_info.attr.wep.key)
                return -ENOMEM;
@@ -3207,26 +3157,26 @@ int host_int_add_wep_key_bss_ap(struct host_if_drv *hif_drv,
        return result;
 }
 
-s32 host_int_add_ptk(struct host_if_drv *hif_drv, const u8 *pu8Ptk,
-                    u8 u8PtkKeylen, const u8 *mac_addr,
-                    const u8 *pu8RxMic, const u8 *pu8TxMic,
-                    u8 mode, u8 u8Ciphermode, u8 u8Idx)
+int wilc_add_ptk(struct wilc_vif *vif, const u8 *ptk, u8 ptk_key_len,
+                const u8 *mac_addr, const u8 *rx_mic, const u8 *tx_mic,
+                u8 mode, u8 cipher_mode, u8 index)
 {
-       s32 result = 0;
+       int result = 0;
        struct host_if_msg msg;
-       u8 u8KeyLen = u8PtkKeylen;
-       u32 i;
+       struct host_if_drv *hif_drv = vif->hif_drv;
+       u8 key_len = ptk_key_len;
+       int i;
 
        if (!hif_drv) {
                PRINT_ER("driver is null\n");
                return -EFAULT;
        }
 
-       if (pu8RxMic)
-               u8KeyLen += RX_MIC_KEY_LEN;
+       if (rx_mic)
+               key_len += RX_MIC_KEY_LEN;
 
-       if (pu8TxMic)
-               u8KeyLen += TX_MIC_KEY_LEN;
+       if (tx_mic)
+               key_len += TX_MIC_KEY_LEN;
 
        memset(&msg, 0, sizeof(struct host_if_msg));
 
@@ -3234,33 +3184,34 @@ s32 host_int_add_ptk(struct host_if_drv *hif_drv, const u8 *pu8Ptk,
        msg.body.key_info.type = WPA_PTK;
        if (mode == AP_MODE) {
                msg.body.key_info.action = ADDKEY_AP;
-               msg.body.key_info.attr.wpa.index = u8Idx;
+               msg.body.key_info.attr.wpa.index = index;
        }
        if (mode == STATION_MODE)
                msg.body.key_info.action = ADDKEY;
 
-       msg.body.key_info.attr.wpa.key = kmalloc(u8PtkKeylen, GFP_KERNEL);
-       memcpy(msg.body.key_info.attr.wpa.key, pu8Ptk, u8PtkKeylen);
+       msg.body.key_info.attr.wpa.key = kmemdup(ptk, ptk_key_len, GFP_KERNEL);
+       if (!msg.body.key_info.attr.wpa.key)
+               return -ENOMEM;
 
-       if (pu8RxMic) {
-               memcpy(msg.body.key_info.attr.wpa.key + 16, pu8RxMic, RX_MIC_KEY_LEN);
+       if (rx_mic) {
+               memcpy(msg.body.key_info.attr.wpa.key + 16, rx_mic, RX_MIC_KEY_LEN);
                if (INFO) {
                        for (i = 0; i < RX_MIC_KEY_LEN; i++)
-                               PRINT_INFO(CFG80211_DBG, "PairwiseRx[%d] = %x\n", i, pu8RxMic[i]);
+                               PRINT_INFO(CFG80211_DBG, "PairwiseRx[%d] = %x\n", i, rx_mic[i]);
                }
        }
-       if (pu8TxMic) {
-               memcpy(msg.body.key_info.attr.wpa.key + 24, pu8TxMic, TX_MIC_KEY_LEN);
+       if (tx_mic) {
+               memcpy(msg.body.key_info.attr.wpa.key + 24, tx_mic, TX_MIC_KEY_LEN);
                if (INFO) {
                        for (i = 0; i < TX_MIC_KEY_LEN; i++)
-                               PRINT_INFO(CFG80211_DBG, "PairwiseTx[%d] = %x\n", i, pu8TxMic[i]);
+                               PRINT_INFO(CFG80211_DBG, "PairwiseTx[%d] = %x\n", i, tx_mic[i]);
                }
        }
 
-       msg.body.key_info.attr.wpa.key_len = u8KeyLen;
+       msg.body.key_info.attr.wpa.key_len = key_len;
        msg.body.key_info.attr.wpa.mac_addr = mac_addr;
-       msg.body.key_info.attr.wpa.mode = u8Ciphermode;
-       msg.drv = hif_drv;
+       msg.body.key_info.attr.wpa.mode = cipher_mode;
+       msg.vif = vif;
 
        result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
 
@@ -3272,15 +3223,15 @@ s32 host_int_add_ptk(struct host_if_drv *hif_drv, const u8 *pu8Ptk,
        return result;
 }
 
-s32 host_int_add_rx_gtk(struct host_if_drv *hif_drv, const u8 *pu8RxGtk,
-                       u8 u8GtkKeylen, u8 u8KeyIdx,
-                       u32 u32KeyRSClen, const u8 *KeyRSC,
-                       const u8 *pu8RxMic, const u8 *pu8TxMic,
-                       u8 mode, u8 u8Ciphermode)
+int wilc_add_rx_gtk(struct wilc_vif *vif, const u8 *rx_gtk, u8 gtk_key_len,
+                   u8 index, u32 key_rsc_len, const u8 *key_rsc,
+                   const u8 *rx_mic, const u8 *tx_mic, u8 mode,
+                   u8 cipher_mode)
 {
-       s32 result = 0;
+       int result = 0;
        struct host_if_msg msg;
-       u8 u8KeyLen = u8GtkKeylen;
+       struct host_if_drv *hif_drv = vif->hif_drv;
+       u8 key_len = gtk_key_len;
 
        if (!hif_drv) {
                PRINT_ER("driver is null\n");
@@ -3288,42 +3239,48 @@ s32 host_int_add_rx_gtk(struct host_if_drv *hif_drv, const u8 *pu8RxGtk,
        }
        memset(&msg, 0, sizeof(struct host_if_msg));
 
-       if (pu8RxMic)
-               u8KeyLen += RX_MIC_KEY_LEN;
+       if (rx_mic)
+               key_len += RX_MIC_KEY_LEN;
 
-       if (pu8TxMic)
-               u8KeyLen += TX_MIC_KEY_LEN;
+       if (tx_mic)
+               key_len += TX_MIC_KEY_LEN;
 
-       if (KeyRSC) {
-               msg.body.key_info.attr.wpa.seq = kmalloc(u32KeyRSClen, GFP_KERNEL);
-               memcpy(msg.body.key_info.attr.wpa.seq, KeyRSC, u32KeyRSClen);
+       if (key_rsc) {
+               msg.body.key_info.attr.wpa.seq = kmemdup(key_rsc,
+                                                        key_rsc_len,
+                                                        GFP_KERNEL);
+               if (!msg.body.key_info.attr.wpa.seq)
+                       return -ENOMEM;
        }
 
        msg.id = HOST_IF_MSG_KEY;
        msg.body.key_info.type = WPA_RX_GTK;
-       msg.drv = hif_drv;
+       msg.vif = vif;
 
        if (mode == AP_MODE) {
                msg.body.key_info.action = ADDKEY_AP;
-               msg.body.key_info.attr.wpa.mode = u8Ciphermode;
+               msg.body.key_info.attr.wpa.mode = cipher_mode;
        }
        if (mode == STATION_MODE)
                msg.body.key_info.action = ADDKEY;
 
-       msg.body.key_info.attr.wpa.key = kmalloc(u8KeyLen, GFP_KERNEL);
-       memcpy(msg.body.key_info.attr.wpa.key, pu8RxGtk, u8GtkKeylen);
+       msg.body.key_info.attr.wpa.key = kmemdup(rx_gtk,
+                                                key_len,
+                                                GFP_KERNEL);
+       if (!msg.body.key_info.attr.wpa.key)
+               return -ENOMEM;
 
-       if (pu8RxMic)
-               memcpy(msg.body.key_info.attr.wpa.key + 16, pu8RxMic,
+       if (rx_mic)
+               memcpy(msg.body.key_info.attr.wpa.key + 16, rx_mic,
                       RX_MIC_KEY_LEN);
 
-       if (pu8TxMic)
-               memcpy(msg.body.key_info.attr.wpa.key + 24, pu8TxMic,
+       if (tx_mic)
+               memcpy(msg.body.key_info.attr.wpa.key + 24, tx_mic,
                       TX_MIC_KEY_LEN);
 
-       msg.body.key_info.attr.wpa.index = u8KeyIdx;
-       msg.body.key_info.attr.wpa.key_len = u8KeyLen;
-       msg.body.key_info.attr.wpa.seq_len = u32KeyRSClen;
+       msg.body.key_info.attr.wpa.index = index;
+       msg.body.key_info.attr.wpa.key_len = key_len;
+       msg.body.key_info.attr.wpa.seq_len = key_rsc_len;
 
        result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
        if (result)
@@ -3334,10 +3291,12 @@ s32 host_int_add_rx_gtk(struct host_if_drv *hif_drv, const u8 *pu8RxGtk,
        return result;
 }
 
-s32 host_int_set_pmkid_info(struct host_if_drv *hif_drv, struct host_if_pmkid_attr *pu8PmkidInfoArray)
+s32 wilc_set_pmkid_info(struct wilc_vif *vif,
+                       struct host_if_pmkid_attr *pu8PmkidInfoArray)
 {
        s32 result = 0;
        struct host_if_msg msg;
+       struct host_if_drv *hif_drv = vif->hif_drv;
        u32 i;
 
        if (!hif_drv) {
@@ -3350,7 +3309,7 @@ s32 host_int_set_pmkid_info(struct host_if_drv *hif_drv, struct host_if_pmkid_at
        msg.id = HOST_IF_MSG_KEY;
        msg.body.key_info.type = PMKSA;
        msg.body.key_info.action = ADDKEY;
-       msg.drv = hif_drv;
+       msg.vif = vif;
 
        for (i = 0; i < pu8PmkidInfoArray->numpmkid; i++) {
                memcpy(msg.body.key_info.attr.pmkid.pmkidlist[i].bssid,
@@ -3366,37 +3325,7 @@ s32 host_int_set_pmkid_info(struct host_if_drv *hif_drv, struct host_if_pmkid_at
        return result;
 }
 
-s32 host_int_get_pmkid_info(struct host_if_drv *hif_drv,
-                           u8 *pu8PmkidInfoArray,
-                           u32 u32PmkidInfoLen)
-{
-       struct wid wid;
-
-       wid.id = (u16)WID_PMKID_INFO;
-       wid.type = WID_STR;
-       wid.size = u32PmkidInfoLen;
-       wid.val = pu8PmkidInfoArray;
-
-       return 0;
-}
-
-s32 host_int_set_RSNAConfigPSKPassPhrase(struct host_if_drv *hif_drv,
-                                        u8 *pu8PassPhrase,
-                                        u8 u8Psklength)
-{
-       struct wid wid;
-
-       if ((u8Psklength > 7) && (u8Psklength < 65)) {
-               wid.id = (u16)WID_11I_PSK;
-               wid.type = WID_STR;
-               wid.val = pu8PassPhrase;
-               wid.size = u8Psklength;
-       }
-
-       return 0;
-}
-
-s32 hif_get_mac_address(struct host_if_drv *hif_drv, u8 *pu8MacAddress)
+s32 wilc_get_mac_address(struct wilc_vif *vif, u8 *pu8MacAddress)
 {
        s32 result = 0;
        struct host_if_msg msg;
@@ -3405,7 +3334,7 @@ s32 hif_get_mac_address(struct host_if_drv *hif_drv, u8 *pu8MacAddress)
 
        msg.id = HOST_IF_MSG_GET_MAC_ADDRESS;
        msg.body.get_mac_info.mac_addr = pu8MacAddress;
-       msg.drv = hif_drv;
+       msg.vif = vif;
 
        result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
        if (result) {
@@ -3417,7 +3346,7 @@ s32 hif_get_mac_address(struct host_if_drv *hif_drv, u8 *pu8MacAddress)
        return result;
 }
 
-s32 host_int_set_MacAddress(struct host_if_drv *hif_drv, u8 *pu8MacAddress)
+s32 wilc_set_mac_address(struct wilc_vif *vif, u8 *pu8MacAddress)
 {
        s32 result = 0;
        struct host_if_msg msg;
@@ -3427,7 +3356,7 @@ s32 host_int_set_MacAddress(struct host_if_drv *hif_drv, u8 *pu8MacAddress)
        memset(&msg, 0, sizeof(struct host_if_msg));
        msg.id = HOST_IF_MSG_SET_MAC_ADDRESS;
        memcpy(msg.body.set_mac_info.mac_addr, pu8MacAddress, ETH_ALEN);
-       msg.drv = hif_drv;
+       msg.vif = vif;
 
        result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
        if (result)
@@ -3436,52 +3365,15 @@ s32 host_int_set_MacAddress(struct host_if_drv *hif_drv, u8 *pu8MacAddress)
        return result;
 }
 
-s32 host_int_get_RSNAConfigPSKPassPhrase(struct host_if_drv *hif_drv,
-                                        u8 *pu8PassPhrase, u8 u8Psklength)
-{
-       struct wid wid;
-
-       wid.id = (u16)WID_11I_PSK;
-       wid.type = WID_STR;
-       wid.size = u8Psklength;
-       wid.val = pu8PassPhrase;
-
-       return 0;
-}
-
-s32 host_int_set_start_scan_req(struct host_if_drv *hif_drv, u8 scanSource)
-{
-       struct wid wid;
-
-       wid.id = (u16)WID_START_SCAN_REQ;
-       wid.type = WID_CHAR;
-       wid.val = (s8 *)&scanSource;
-       wid.size = sizeof(char);
-
-       return 0;
-}
-
-s32 host_int_get_start_scan_req(struct host_if_drv *hif_drv, u8 *pu8ScanSource)
-{
-       struct wid wid;
-
-       wid.id = (u16)WID_START_SCAN_REQ;
-       wid.type = WID_CHAR;
-       wid.val = (s8 *)pu8ScanSource;
-       wid.size = sizeof(char);
-
-       return 0;
-}
-
-s32 host_int_set_join_req(struct host_if_drv *hif_drv, u8 *pu8bssid,
-                         const u8 *pu8ssid, size_t ssidLen,
-                         const u8 *pu8IEs, size_t IEsLen,
-                         wilc_connect_result pfConnectResult, void *pvUserArg,
-                         u8 u8security, enum AUTHTYPE tenuAuth_type,
-                         u8 u8channel, void *pJoinParams)
+s32 wilc_set_join_req(struct wilc_vif *vif, u8 *pu8bssid, const u8 *pu8ssid,
+                     size_t ssidLen, const u8 *pu8IEs, size_t IEsLen,
+                     wilc_connect_result pfConnectResult, void *pvUserArg,
+                     u8 u8security, enum AUTHTYPE tenuAuth_type,
+                     u8 u8channel, void *pJoinParams)
 {
        s32 result = 0;
        struct host_if_msg msg;
+       struct host_if_drv *hif_drv = vif->hif_drv;
 
        if (!hif_drv || !pfConnectResult) {
                PRINT_ER("Driver is null\n");
@@ -3503,7 +3395,7 @@ s32 host_int_set_join_req(struct host_if_drv *hif_drv, u8 *pu8bssid,
        msg.body.con_info.result = pfConnectResult;
        msg.body.con_info.arg = pvUserArg;
        msg.body.con_info.params = pJoinParams;
-       msg.drv = hif_drv ;
+       msg.vif = vif;
 
        if (pu8bssid) {
                msg.body.con_info.bssid = kmalloc(6, GFP_KERNEL);
@@ -3533,17 +3425,18 @@ s32 host_int_set_join_req(struct host_if_drv *hif_drv, u8 *pu8bssid,
                return -EFAULT;
        }
 
-       hif_drv->connect_timer.data = (unsigned long)hif_drv;
+       hif_drv->connect_timer.data = (unsigned long)vif;
        mod_timer(&hif_drv->connect_timer,
                  jiffies + msecs_to_jiffies(HOST_IF_CONNECT_TIMEOUT));
 
        return result;
 }
 
-s32 host_int_flush_join_req(struct host_if_drv *hif_drv)
+s32 wilc_flush_join_req(struct wilc_vif *vif)
 {
        s32 result = 0;
        struct host_if_msg msg;
+       struct host_if_drv *hif_drv = vif->hif_drv;
 
        if (!join_req)
                return -EFAULT;
@@ -3554,7 +3447,7 @@ s32 host_int_flush_join_req(struct host_if_drv *hif_drv)
        }
 
        msg.id = HOST_IF_MSG_FLUSH_CONNECT;
-       msg.drv = hif_drv;
+       msg.vif = vif;
 
        result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
        if (result) {
@@ -3565,10 +3458,11 @@ s32 host_int_flush_join_req(struct host_if_drv *hif_drv)
        return result;
 }
 
-s32 host_int_disconnect(struct host_if_drv *hif_drv, u16 u16ReasonCode)
+s32 wilc_disconnect(struct wilc_vif *vif, u16 u16ReasonCode)
 {
        s32 result = 0;
        struct host_if_msg msg;
+       struct host_if_drv *hif_drv = vif->hif_drv;
 
        if (!hif_drv) {
                PRINT_ER("Driver is null\n");
@@ -3578,7 +3472,7 @@ s32 host_int_disconnect(struct host_if_drv *hif_drv, u16 u16ReasonCode)
        memset(&msg, 0, sizeof(struct host_if_msg));
 
        msg.id = HOST_IF_MSG_DISCONNECT;
-       msg.drv = hif_drv;
+       msg.vif = vif;
 
        result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
        if (result)
@@ -3589,39 +3483,14 @@ s32 host_int_disconnect(struct host_if_drv *hif_drv, u16 u16ReasonCode)
        return result;
 }
 
-s32 host_int_disconnect_station(struct host_if_drv *hif_drv, u8 assoc_id)
-{
-       struct wid wid;
-
-       wid.id = (u16)WID_DISCONNECT;
-       wid.type = WID_CHAR;
-       wid.val = (s8 *)&assoc_id;
-       wid.size = sizeof(char);
-
-       return 0;
-}
-
-s32 host_int_get_assoc_req_info(struct host_if_drv *hif_drv,
-                               u8 *pu8AssocReqInfo,
-                               u32 u32AssocReqInfoLen)
-{
-       struct wid wid;
-
-       wid.id = (u16)WID_ASSOC_REQ_INFO;
-       wid.type = WID_STR;
-       wid.val = pu8AssocReqInfo;
-       wid.size = u32AssocReqInfoLen;
-
-       return 0;
-}
-
-s32 host_int_get_assoc_res_info(struct host_if_drv *hif_drv,
-                               u8 *pu8AssocRespInfo,
-                               u32 u32MaxAssocRespInfoLen,
-                               u32 *pu32RcvdAssocRespInfoLen)
+static s32 host_int_get_assoc_res_info(struct wilc_vif *vif,
+                                      u8 *pu8AssocRespInfo,
+                                      u32 u32MaxAssocRespInfoLen,
+                                      u32 *pu32RcvdAssocRespInfoLen)
 {
        s32 result = 0;
        struct wid wid;
+       struct host_if_drv *hif_drv = vif->hif_drv;
 
        if (!hif_drv) {
                PRINT_ER("Driver is null\n");
@@ -3633,8 +3502,8 @@ s32 host_int_get_assoc_res_info(struct host_if_drv *hif_drv,
        wid.val = pu8AssocRespInfo;
        wid.size = u32MaxAssocRespInfoLen;
 
-       result = send_config_pkt(GET_CFG, &wid, 1,
-                                get_id_from_handler(hif_drv));
+       result = wilc_send_config_pkt(vif->wilc, GET_CFG, &wid, 1,
+                                wilc_get_vif_idx(vif));
        if (result) {
                *pu32RcvdAssocRespInfoLen = 0;
                PRINT_ER("Failed to send association response config packet\n");
@@ -3646,24 +3515,11 @@ s32 host_int_get_assoc_res_info(struct host_if_drv *hif_drv,
        return result;
 }
 
-s32 host_int_get_rx_power_level(struct host_if_drv *hif_drv,
-                               u8 *pu8RxPowerLevel,
-                               u32 u32RxPowerLevelLen)
-{
-       struct wid wid;
-
-       wid.id = (u16)WID_RX_POWER_LEVEL;
-       wid.type = WID_STR;
-       wid.val = pu8RxPowerLevel;
-       wid.size = u32RxPowerLevelLen;
-
-       return 0;
-}
-
-int host_int_set_mac_chnl_num(struct host_if_drv *hif_drv, u8 channel)
+int wilc_set_mac_chnl_num(struct wilc_vif *vif, u8 channel)
 {
        int result;
        struct host_if_msg msg;
+       struct host_if_drv *hif_drv = vif->hif_drv;
 
        if (!hif_drv) {
                PRINT_ER("driver is null\n");
@@ -3673,7 +3529,7 @@ int host_int_set_mac_chnl_num(struct host_if_drv *hif_drv, u8 channel)
        memset(&msg, 0, sizeof(struct host_if_msg));
        msg.id = HOST_IF_MSG_SET_CHANNEL;
        msg.body.channel_info.set_ch = channel;
-       msg.drv = hif_drv;
+       msg.vif = vif;
 
        result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
        if (result) {
@@ -3684,7 +3540,7 @@ int host_int_set_mac_chnl_num(struct host_if_drv *hif_drv, u8 channel)
        return 0;
 }
 
-int host_int_wait_msg_queue_idle(void)
+int wilc_wait_msg_queue_idle(void)
 {
        int result = 0;
        struct host_if_msg msg;
@@ -3702,15 +3558,15 @@ int host_int_wait_msg_queue_idle(void)
        return result;
 }
 
-int host_int_set_wfi_drv_handler(struct host_if_drv *hif_drv)
+int wilc_set_wfi_drv_handler(struct wilc_vif *vif, int index)
 {
        int result = 0;
        struct host_if_msg msg;
 
        memset(&msg, 0, sizeof(struct host_if_msg));
        msg.id = HOST_IF_MSG_SET_WFIDRV_HANDLER;
-       msg.body.drv.handler = get_id_from_handler(hif_drv);
-       msg.drv = hif_drv;
+       msg.body.drv.handler = index;
+       msg.vif = vif;
 
        result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
        if (result) {
@@ -3721,7 +3577,7 @@ int host_int_set_wfi_drv_handler(struct host_if_drv *hif_drv)
        return result;
 }
 
-int host_int_set_operation_mode(struct host_if_drv *hif_drv, u32 mode)
+int wilc_set_operation_mode(struct wilc_vif *vif, u32 mode)
 {
        int result = 0;
        struct host_if_msg msg;
@@ -3729,7 +3585,7 @@ int host_int_set_operation_mode(struct host_if_drv *hif_drv, u32 mode)
        memset(&msg, 0, sizeof(struct host_if_msg));
        msg.id = HOST_IF_MSG_SET_OPERATION_MODE;
        msg.body.mode.mode = mode;
-       msg.drv = hif_drv;
+       msg.vif = vif;
 
        result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
        if (result) {
@@ -3740,36 +3596,12 @@ int host_int_set_operation_mode(struct host_if_drv *hif_drv, u32 mode)
        return result;
 }
 
-s32 host_int_get_host_chnl_num(struct host_if_drv *hif_drv, u8 *pu8ChNo)
-{
-       s32 result = 0;
-       struct host_if_msg msg;
-
-       if (!hif_drv) {
-               PRINT_ER("driver is null\n");
-               return -EFAULT;
-       }
-
-       memset(&msg, 0, sizeof(struct host_if_msg));
-
-       msg.id = HOST_IF_MSG_GET_CHNL;
-       msg.drv = hif_drv;
-
-       result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
-       if (result)
-               PRINT_ER("wilc mq send fail\n");
-       down(&hif_drv->sem_get_chnl);
-
-       *pu8ChNo = ch_no;
-
-       return result;
-}
-
-s32 host_int_get_inactive_time(struct host_if_drv *hif_drv,
-                              const u8 *mac, u32 *pu32InactiveTime)
+s32 wilc_get_inactive_time(struct wilc_vif *vif, const u8 *mac,
+                          u32 *pu32InactiveTime)
 {
        s32 result = 0;
        struct host_if_msg msg;
+       struct host_if_drv *hif_drv = vif->hif_drv;
 
        if (!hif_drv) {
                PRINT_ER("driver is null\n");
@@ -3780,7 +3612,7 @@ s32 host_int_get_inactive_time(struct host_if_drv *hif_drv,
        memcpy(msg.body.mac_info.mac, mac, ETH_ALEN);
 
        msg.id = HOST_IF_MSG_GET_INACTIVETIME;
-       msg.drv = hif_drv;
+       msg.vif = vif;
 
        result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
        if (result)
@@ -3793,42 +3625,15 @@ s32 host_int_get_inactive_time(struct host_if_drv *hif_drv,
        return result;
 }
 
-s32 host_int_test_get_int_wid(struct host_if_drv *hif_drv, u32 *pu32TestMemAddr)
-{
-       s32 result = 0;
-       struct wid wid;
-
-       if (!hif_drv) {
-               PRINT_ER("driver is null\n");
-               return -EFAULT;
-       }
-
-       wid.id = (u16)WID_MEMORY_ADDRESS;
-       wid.type = WID_INT;
-       wid.val = (s8 *)pu32TestMemAddr;
-       wid.size = sizeof(u32);
-
-       result = send_config_pkt(GET_CFG, &wid, 1,
-                                get_id_from_handler(hif_drv));
-
-       if (result) {
-               PRINT_ER("Failed to get wid value\n");
-               return -EINVAL;
-       } else {
-               PRINT_D(HOSTINF_DBG, "Successfully got wid value\n");
-       }
-
-       return result;
-}
-
-s32 host_int_get_rssi(struct host_if_drv *hif_drv, s8 *ps8Rssi)
+s32 wilc_get_rssi(struct wilc_vif *vif, s8 *ps8Rssi)
 {
        s32 result = 0;
        struct host_if_msg msg;
+       struct host_if_drv *hif_drv = vif->hif_drv;
 
        memset(&msg, 0, sizeof(struct host_if_msg));
        msg.id = HOST_IF_MSG_GET_RSSI;
-       msg.drv = hif_drv;
+       msg.vif = vif;
 
        result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
        if (result) {
@@ -3848,34 +3653,7 @@ s32 host_int_get_rssi(struct host_if_drv *hif_drv, s8 *ps8Rssi)
        return result;
 }
 
-s32 host_int_get_link_speed(struct host_if_drv *hif_drv, s8 *ps8lnkspd)
-{
-       struct host_if_msg msg;
-       s32 result = 0;
-
-       memset(&msg, 0, sizeof(struct host_if_msg));
-       msg.id = HOST_IF_MSG_GET_LINKSPEED;
-       msg.drv = hif_drv;
-
-       result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
-       if (result) {
-               PRINT_ER("Failed to send GET_LINKSPEED to message queue ");
-               return -EFAULT;
-       }
-
-       down(&hif_drv->sem_get_link_speed);
-
-       if (!ps8lnkspd) {
-               PRINT_ER("LINKSPEED pointer value is null");
-               return -EFAULT;
-       }
-
-       *ps8lnkspd = link_speed;
-
-       return result;
-}
-
-s32 host_int_get_statistics(struct host_if_drv *hif_drv, struct rf_info *pstrStatistics)
+s32 wilc_get_statistics(struct wilc_vif *vif, struct rf_info *pstrStatistics)
 {
        s32 result = 0;
        struct host_if_msg msg;
@@ -3883,7 +3661,7 @@ s32 host_int_get_statistics(struct host_if_drv *hif_drv, struct rf_info *pstrSta
        memset(&msg, 0, sizeof(struct host_if_msg));
        msg.id = HOST_IF_MSG_GET_STATISTICS;
        msg.body.data = (char *)pstrStatistics;
-       msg.drv = hif_drv;
+       msg.vif = vif;
 
        result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
        if (result) {
@@ -3895,14 +3673,14 @@ s32 host_int_get_statistics(struct host_if_drv *hif_drv, struct rf_info *pstrSta
        return result;
 }
 
-s32 host_int_scan(struct host_if_drv *hif_drv, u8 u8ScanSource,
-                 u8 u8ScanType, u8 *pu8ChnlFreqList,
-                 u8 u8ChnlListLen, const u8 *pu8IEs,
-                 size_t IEsLen, wilc_scan_result ScanResult,
-                 void *pvUserArg, struct hidden_network *pstrHiddenNetwork)
+s32 wilc_scan(struct wilc_vif *vif, u8 u8ScanSource, u8 u8ScanType,
+             u8 *pu8ChnlFreqList, u8 u8ChnlListLen, const u8 *pu8IEs,
+             size_t IEsLen, wilc_scan_result ScanResult, void *pvUserArg,
+             struct hidden_network *pstrHiddenNetwork)
 {
        s32 result = 0;
        struct host_if_msg msg;
+       struct host_if_drv *hif_drv = vif->hif_drv;
 
        if (!hif_drv || !ScanResult) {
                PRINT_ER("hif_drv or ScanResult = NULL\n");
@@ -3920,7 +3698,7 @@ s32 host_int_scan(struct host_if_drv *hif_drv, u8 u8ScanSource,
        } else
                PRINT_D(HOSTINF_DBG, "pstrHiddenNetwork IS EQUAL TO NULL\n");
 
-       msg.drv = hif_drv;
+       msg.vif = vif;
        msg.body.scan_info.src = u8ScanSource;
        msg.body.scan_info.type = u8ScanType;
        msg.body.scan_info.result = ScanResult;
@@ -3941,18 +3719,19 @@ s32 host_int_scan(struct host_if_drv *hif_drv, u8 u8ScanSource,
        }
 
        PRINT_D(HOSTINF_DBG, ">> Starting the SCAN timer\n");
-       hif_drv->scan_timer.data = (unsigned long)hif_drv;
+       hif_drv->scan_timer.data = (unsigned long)vif;
        mod_timer(&hif_drv->scan_timer,
                  jiffies + msecs_to_jiffies(HOST_IF_SCAN_TIMEOUT));
 
        return result;
 }
 
-s32 hif_set_cfg(struct host_if_drv *hif_drv,
-               struct cfg_param_val *pstrCfgParamVal)
+s32 wilc_hif_set_cfg(struct wilc_vif *vif,
+                    struct cfg_param_val *pstrCfgParamVal)
 {
        s32 result = 0;
        struct host_if_msg msg;
+       struct host_if_drv *hif_drv = vif->hif_drv;
 
        if (!hif_drv) {
                PRINT_ER("hif_drv NULL\n");
@@ -3962,123 +3741,30 @@ s32 hif_set_cfg(struct host_if_drv *hif_drv,
        memset(&msg, 0, sizeof(struct host_if_msg));
        msg.id = HOST_IF_MSG_CFG_PARAMS;
        msg.body.cfg_info.cfg_attr_info = *pstrCfgParamVal;
-       msg.drv = hif_drv;
+       msg.vif = vif;
 
        result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
 
        return result;
 }
 
-s32 hif_get_cfg(struct host_if_drv *hif_drv, u16 u16WID, u16 *pu16WID_Value)
-{
-       s32 result = 0;
-
-       down(&hif_drv->sem_cfg_values);
-
-       if (!hif_drv) {
-               PRINT_ER("hif_drv NULL\n");
-               return -EFAULT;
-       }
-       PRINT_D(HOSTINF_DBG, "Getting configuration parameters\n");
-       switch (u16WID) {
-       case WID_BSS_TYPE:
-               *pu16WID_Value = (u16)hif_drv->cfg_values.bss_type;
-               break;
-
-       case WID_AUTH_TYPE:
-               *pu16WID_Value = (u16)hif_drv->cfg_values.auth_type;
-               break;
-
-       case WID_AUTH_TIMEOUT:
-               *pu16WID_Value = hif_drv->cfg_values.auth_timeout;
-               break;
-
-       case WID_POWER_MANAGEMENT:
-               *pu16WID_Value = (u16)hif_drv->cfg_values.power_mgmt_mode;
-               break;
-
-       case WID_SHORT_RETRY_LIMIT:
-               *pu16WID_Value = hif_drv->cfg_values.short_retry_limit;
-               break;
-
-       case WID_LONG_RETRY_LIMIT:
-               *pu16WID_Value = hif_drv->cfg_values.long_retry_limit;
-               break;
-
-       case WID_FRAG_THRESHOLD:
-               *pu16WID_Value = hif_drv->cfg_values.frag_threshold;
-               break;
-
-       case WID_RTS_THRESHOLD:
-               *pu16WID_Value = hif_drv->cfg_values.rts_threshold;
-               break;
-
-       case WID_PREAMBLE:
-               *pu16WID_Value = (u16)hif_drv->cfg_values.preamble_type;
-               break;
-
-       case WID_SHORT_SLOT_ALLOWED:
-               *pu16WID_Value = (u16)hif_drv->cfg_values.short_slot_allowed;
-               break;
-
-       case WID_11N_TXOP_PROT_DISABLE:
-               *pu16WID_Value = (u16)hif_drv->cfg_values.txop_prot_disabled;
-               break;
-
-       case WID_BEACON_INTERVAL:
-               *pu16WID_Value = hif_drv->cfg_values.beacon_interval;
-               break;
-
-       case WID_DTIM_PERIOD:
-               *pu16WID_Value = (u16)hif_drv->cfg_values.dtim_period;
-               break;
-
-       case WID_SITE_SURVEY:
-               *pu16WID_Value = (u16)hif_drv->cfg_values.site_survey_enabled;
-               break;
-
-       case WID_SITE_SURVEY_SCAN_TIME:
-               *pu16WID_Value = hif_drv->cfg_values.site_survey_scan_time;
-               break;
-
-       case WID_ACTIVE_SCAN_TIME:
-               *pu16WID_Value = hif_drv->cfg_values.active_scan_time;
-               break;
-
-       case WID_PASSIVE_SCAN_TIME:
-               *pu16WID_Value = hif_drv->cfg_values.passive_scan_time;
-               break;
-
-       case WID_CURRENT_TX_RATE:
-               *pu16WID_Value = hif_drv->cfg_values.curr_tx_rate;
-               break;
-
-       default:
-               break;
-       }
-
-       up(&hif_drv->sem_cfg_values);
-
-       return result;
-}
-
 static void GetPeriodicRSSI(unsigned long arg)
 {
-       struct host_if_drv *hif_drv = (struct host_if_drv *)arg;
+       struct wilc_vif *vif = (struct wilc_vif *)arg;
 
-       if (!hif_drv)   {
+       if (!vif->hif_drv) {
                PRINT_ER("Driver handler is NULL\n");
                return;
        }
 
-       if (hif_drv->hif_state == HOST_IF_CONNECTED) {
+       if (vif->hif_drv->hif_state == HOST_IF_CONNECTED) {
                s32 result = 0;
                struct host_if_msg msg;
 
                memset(&msg, 0, sizeof(struct host_if_msg));
 
                msg.id = HOST_IF_MSG_GET_RSSI;
-               msg.drv = hif_drv;
+               msg.vif = vif;
 
                result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
                if (result) {
@@ -4086,20 +3772,20 @@ static void GetPeriodicRSSI(unsigned long arg)
                        return;
                }
        }
-       periodic_rssi.data = (unsigned long)hif_drv;
+       periodic_rssi.data = (unsigned long)vif;
        mod_timer(&periodic_rssi, jiffies + msecs_to_jiffies(5000));
 }
 
-s32 host_int_init(struct net_device *dev, struct host_if_drv **hif_drv_handler)
+s32 wilc_init(struct net_device *dev, struct host_if_drv **hif_drv_handler)
 {
        s32 result = 0;
        struct host_if_drv *hif_drv;
-       int err;
-       perInterface_wlan_t *nic;
+       struct wilc_vif *vif;
        struct wilc *wilc;
+       int i;
 
-       nic = netdev_priv(dev);
-       wilc = nic->wilc;
+       vif = netdev_priv(dev);
+       wilc = vif->wilc;
 
        PRINT_D(HOSTINF_DBG, "Initializing host interface for client %d\n", clients_count + 1);
 
@@ -4113,13 +3799,13 @@ s32 host_int_init(struct net_device *dev, struct host_if_drv **hif_drv_handler)
                goto _fail_;
        }
        *hif_drv_handler = hif_drv;
-       err = add_handler_in_list(hif_drv);
-       if (err) {
-               result = -EFAULT;
-               goto _fail_timer_2;
-       }
+       for (i = 0; i < wilc->vif_num; i++)
+               if (dev == wilc->vif[i]->ndev) {
+                       wilc->vif[i]->hif_drv = hif_drv;
+                       break;
+               }
 
-       g_obtainingIP = false;
+       wilc_optaining_ip = false;
 
        PRINT_D(HOSTINF_DBG, "Global handle pointer value=%p\n", hif_drv);
        if (clients_count == 0) {
@@ -4154,7 +3840,7 @@ s32 host_int_init(struct net_device *dev, struct host_if_drv **hif_drv_handler)
                        goto _fail_mq_;
                }
                setup_timer(&periodic_rssi, GetPeriodicRSSI,
-                           (unsigned long)hif_drv);
+                           (unsigned long)vif);
                mod_timer(&periodic_rssi, jiffies + msecs_to_jiffies(5000));
        }
 
@@ -4187,22 +3873,17 @@ s32 host_int_init(struct net_device *dev, struct host_if_drv **hif_drv_handler)
 
        return result;
 
-_fail_timer_2:
-       up(&hif_drv->sem_cfg_values);
-       del_timer_sync(&hif_drv->connect_timer);
-       del_timer_sync(&hif_drv->scan_timer);
-       kthread_stop(hif_thread_handler);
 _fail_mq_:
        wilc_mq_destroy(&hif_msg_q);
 _fail_:
        return result;
 }
 
-s32 host_int_deinit(struct host_if_drv *hif_drv)
+s32 wilc_deinit(struct wilc_vif *vif)
 {
        s32 result = 0;
        struct host_if_msg msg;
-       int ret;
+       struct host_if_drv *hif_drv = vif->hif_drv;
 
        if (!hif_drv)   {
                PRINT_ER("hif_drv = NULL\n");
@@ -4225,7 +3906,7 @@ s32 host_int_deinit(struct host_if_drv *hif_drv)
 
        del_timer_sync(&hif_drv->remain_on_ch_timer);
 
-       host_int_set_wfi_drv_handler(NULL);
+       wilc_set_wfi_drv_handler(vif, 0);
        down(&hif_sema_driver);
 
        if (hif_drv->usr_scan_req.scan_result) {
@@ -4245,7 +3926,7 @@ s32 host_int_deinit(struct host_if_drv *hif_drv)
                        PRINT_D(HOSTINF_DBG, ">> Connect timer is active\n");
 
                msg.id = HOST_IF_MSG_EXIT;
-               msg.drv = hif_drv;
+               msg.vif = vif;
 
                result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
                if (result != 0)
@@ -4256,12 +3937,6 @@ s32 host_int_deinit(struct host_if_drv *hif_drv)
                wilc_mq_destroy(&hif_msg_q);
        }
 
-       down(&hif_drv->sem_cfg_values);
-
-       ret = remove_handler_in_list(hif_drv);
-       if (ret)
-               result = -ENOENT;
-
        kfree(hif_drv);
 
        clients_count--;
@@ -4270,15 +3945,20 @@ s32 host_int_deinit(struct host_if_drv *hif_drv)
        return result;
 }
 
-void NetworkInfoReceived(u8 *pu8Buffer, u32 u32Length)
+void wilc_network_info_received(struct wilc *wilc, u8 *pu8Buffer,
+                               u32 u32Length)
 {
        s32 result = 0;
        struct host_if_msg msg;
        int id;
        struct host_if_drv *hif_drv = NULL;
+       struct wilc_vif *vif;
 
        id = ((pu8Buffer[u32Length - 4]) | (pu8Buffer[u32Length - 3] << 8) | (pu8Buffer[u32Length - 2] << 16) | (pu8Buffer[u32Length - 1] << 24));
-       hif_drv = get_handler_from_id(id);
+       vif = wilc_get_vif_from_idx(wilc, id);
+       if (!vif)
+               return;
+       hif_drv = vif->hif_drv;
 
        if (!hif_drv || hif_drv == terminated_handle)   {
                PRINT_ER("NetworkInfo received but driver not init[%p]\n", hif_drv);
@@ -4288,7 +3968,7 @@ void NetworkInfoReceived(u8 *pu8Buffer, u32 u32Length)
        memset(&msg, 0, sizeof(struct host_if_msg));
 
        msg.id = HOST_IF_MSG_RCVD_NTWRK_INFO;
-       msg.drv = hif_drv;
+       msg.vif = vif;
 
        msg.body.net_info.len = u32Length;
        msg.body.net_info.buffer = kmalloc(u32Length, GFP_KERNEL);
@@ -4299,17 +3979,25 @@ void NetworkInfoReceived(u8 *pu8Buffer, u32 u32Length)
                PRINT_ER("Error in sending network info message queue message parameters: Error(%d)\n", result);
 }
 
-void GnrlAsyncInfoReceived(u8 *pu8Buffer, u32 u32Length)
+void wilc_gnrl_async_info_received(struct wilc *wilc, u8 *pu8Buffer,
+                                  u32 u32Length)
 {
        s32 result = 0;
        struct host_if_msg msg;
        int id;
        struct host_if_drv *hif_drv = NULL;
+       struct wilc_vif *vif;
 
        down(&hif_sema_deinit);
 
        id = ((pu8Buffer[u32Length - 4]) | (pu8Buffer[u32Length - 3] << 8) | (pu8Buffer[u32Length - 2] << 16) | (pu8Buffer[u32Length - 1] << 24));
-       hif_drv = get_handler_from_id(id);
+       vif = wilc_get_vif_from_idx(wilc, id);
+       if (!vif) {
+               up(&hif_sema_deinit);
+               return;
+       }
+
+       hif_drv = vif->hif_drv;
        PRINT_D(HOSTINF_DBG, "General asynchronous info packet received\n");
 
        if (!hif_drv || hif_drv == terminated_handle) {
@@ -4327,7 +4015,7 @@ void GnrlAsyncInfoReceived(u8 *pu8Buffer, u32 u32Length)
        memset(&msg, 0, sizeof(struct host_if_msg));
 
        msg.id = HOST_IF_MSG_RCVD_GNRL_ASYNC_INFO;
-       msg.drv = hif_drv;
+       msg.vif = vif;
 
        msg.body.async_info.len = u32Length;
        msg.body.async_info.buffer = kmalloc(u32Length, GFP_KERNEL);
@@ -4340,15 +4028,20 @@ void GnrlAsyncInfoReceived(u8 *pu8Buffer, u32 u32Length)
        up(&hif_sema_deinit);
 }
 
-void host_int_ScanCompleteReceived(u8 *pu8Buffer, u32 u32Length)
+void wilc_scan_complete_received(struct wilc *wilc, u8 *pu8Buffer,
+                                u32 u32Length)
 {
        s32 result = 0;
        struct host_if_msg msg;
        int id;
        struct host_if_drv *hif_drv = NULL;
+       struct wilc_vif *vif;
 
        id = ((pu8Buffer[u32Length - 4]) | (pu8Buffer[u32Length - 3] << 8) | (pu8Buffer[u32Length - 2] << 16) | (pu8Buffer[u32Length - 1] << 24));
-       hif_drv = get_handler_from_id(id);
+       vif = wilc_get_vif_from_idx(wilc, id);
+       if (!vif)
+               return;
+       hif_drv = vif->hif_drv;
 
        PRINT_D(GENERIC_DBG, "Scan notification received %p\n", hif_drv);
 
@@ -4359,7 +4052,7 @@ void host_int_ScanCompleteReceived(u8 *pu8Buffer, u32 u32Length)
                memset(&msg, 0, sizeof(struct host_if_msg));
 
                msg.id = HOST_IF_MSG_RCVD_SCAN_COMPLETE;
-               msg.drv = hif_drv;
+               msg.vif = vif;
 
                result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
                if (result)
@@ -4369,14 +4062,15 @@ void host_int_ScanCompleteReceived(u8 *pu8Buffer, u32 u32Length)
        return;
 }
 
-s32 host_int_remain_on_channel(struct host_if_drv *hif_drv, u32 u32SessionID,
-                              u32 u32duration, u16 chan,
-                              wilc_remain_on_chan_expired RemainOnChanExpired,
-                              wilc_remain_on_chan_ready RemainOnChanReady,
-                              void *pvUserArg)
+s32 wilc_remain_on_channel(struct wilc_vif *vif, u32 u32SessionID,
+                          u32 u32duration, u16 chan,
+                          wilc_remain_on_chan_expired RemainOnChanExpired,
+                          wilc_remain_on_chan_ready RemainOnChanReady,
+                          void *pvUserArg)
 {
        s32 result = 0;
        struct host_if_msg msg;
+       struct host_if_drv *hif_drv = vif->hif_drv;
 
        if (!hif_drv) {
                PRINT_ER("driver is null\n");
@@ -4392,7 +4086,7 @@ s32 host_int_remain_on_channel(struct host_if_drv *hif_drv, u32 u32SessionID,
        msg.body.remain_on_ch.arg = pvUserArg;
        msg.body.remain_on_ch.u32duration = u32duration;
        msg.body.remain_on_ch.id = u32SessionID;
-       msg.drv = hif_drv;
+       msg.vif = vif;
 
        result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
        if (result)
@@ -4401,10 +4095,11 @@ s32 host_int_remain_on_channel(struct host_if_drv *hif_drv, u32 u32SessionID,
        return result;
 }
 
-s32 host_int_ListenStateExpired(struct host_if_drv *hif_drv, u32 u32SessionID)
+s32 wilc_listen_state_expired(struct wilc_vif *vif, u32 u32SessionID)
 {
        s32 result = 0;
        struct host_if_msg msg;
+       struct host_if_drv *hif_drv = vif->hif_drv;
 
        if (!hif_drv) {
                PRINT_ER("driver is null\n");
@@ -4415,7 +4110,7 @@ s32 host_int_ListenStateExpired(struct host_if_drv *hif_drv, u32 u32SessionID)
 
        memset(&msg, 0, sizeof(struct host_if_msg));
        msg.id = HOST_IF_MSG_LISTEN_TIMER_FIRED;
-       msg.drv = hif_drv;
+       msg.vif = vif;
        msg.body.remain_on_ch.id = u32SessionID;
 
        result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
@@ -4425,10 +4120,11 @@ s32 host_int_ListenStateExpired(struct host_if_drv *hif_drv, u32 u32SessionID)
        return result;
 }
 
-s32 host_int_frame_register(struct host_if_drv *hif_drv, u16 u16FrameType, bool bReg)
+s32 wilc_frame_register(struct wilc_vif *vif, u16 u16FrameType, bool bReg)
 {
        s32 result = 0;
        struct host_if_msg msg;
+       struct host_if_drv *hif_drv = vif->hif_drv;
 
        if (!hif_drv) {
                PRINT_ER("driver is null\n");
@@ -4455,7 +4151,7 @@ s32 host_int_frame_register(struct host_if_drv *hif_drv, u16 u16FrameType, bool
        }
        msg.body.reg_frame.frame_type = u16FrameType;
        msg.body.reg_frame.reg = bReg;
-       msg.drv = hif_drv;
+       msg.vif = vif;
 
        result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
        if (result)
@@ -4464,13 +4160,13 @@ s32 host_int_frame_register(struct host_if_drv *hif_drv, u16 u16FrameType, bool
        return result;
 }
 
-s32 host_int_add_beacon(struct host_if_drv *hif_drv, u32 u32Interval,
-                       u32 u32DTIMPeriod, u32 u32HeadLen, u8 *pu8Head,
-                       u32 u32TailLen, u8 *pu8Tail)
+s32 wilc_add_beacon(struct wilc_vif *vif, u32 u32Interval, u32 u32DTIMPeriod,
+                   u32 u32HeadLen, u8 *pu8Head, u32 u32TailLen, u8 *pu8Tail)
 {
        s32 result = 0;
        struct host_if_msg msg;
        struct beacon_attr *pstrSetBeaconParam = &msg.body.beacon_info;
+       struct host_if_drv *hif_drv = vif->hif_drv;
 
        if (!hif_drv) {
                PRINT_ER("driver is null\n");
@@ -4482,7 +4178,7 @@ s32 host_int_add_beacon(struct host_if_drv *hif_drv, u32 u32Interval,
        PRINT_D(HOSTINF_DBG, "Setting adding beacon message queue params\n");
 
        msg.id = HOST_IF_MSG_ADD_BEACON;
-       msg.drv = hif_drv;
+       msg.vif = vif;
        pstrSetBeaconParam->interval = u32Interval;
        pstrSetBeaconParam->dtim_period = u32DTIMPeriod;
        pstrSetBeaconParam->head_len = u32HeadLen;
@@ -4518,10 +4214,11 @@ ERRORHANDLER:
        return result;
 }
 
-int host_int_del_beacon(struct host_if_drv *hif_drv)
+int wilc_del_beacon(struct wilc_vif *vif)
 {
        int result = 0;
        struct host_if_msg msg;
+       struct host_if_drv *hif_drv = vif->hif_drv;
 
        if (!hif_drv) {
                PRINT_ER("driver is null\n");
@@ -4529,7 +4226,7 @@ int host_int_del_beacon(struct host_if_drv *hif_drv)
        }
 
        msg.id = HOST_IF_MSG_DEL_BEACON;
-       msg.drv = hif_drv;
+       msg.vif = vif;
        PRINT_D(HOSTINF_DBG, "Setting deleting beacon message queue params\n");
 
        result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
@@ -4539,12 +4236,12 @@ int host_int_del_beacon(struct host_if_drv *hif_drv)
        return result;
 }
 
-int host_int_add_station(struct host_if_drv *hif_drv,
-                        struct add_sta_param *sta_param)
+int wilc_add_station(struct wilc_vif *vif, struct add_sta_param *sta_param)
 {
        int result = 0;
        struct host_if_msg msg;
        struct add_sta_param *add_sta_info = &msg.body.add_sta_info;
+       struct host_if_drv *hif_drv = vif->hif_drv;
 
        if (!hif_drv) {
                PRINT_ER("driver is null\n");
@@ -4556,7 +4253,7 @@ int host_int_add_station(struct host_if_drv *hif_drv,
        PRINT_D(HOSTINF_DBG, "Setting adding station message queue params\n");
 
        msg.id = HOST_IF_MSG_ADD_STATION;
-       msg.drv = hif_drv;
+       msg.vif = vif;
 
        memcpy(add_sta_info, sta_param, sizeof(struct add_sta_param));
        if (add_sta_info->rates_len > 0) {
@@ -4573,11 +4270,12 @@ int host_int_add_station(struct host_if_drv *hif_drv,
        return result;
 }
 
-int host_int_del_station(struct host_if_drv *hif_drv, const u8 *mac_addr)
+int wilc_del_station(struct wilc_vif *vif, const u8 *mac_addr)
 {
        int result = 0;
        struct host_if_msg msg;
        struct del_sta *del_sta_info = &msg.body.del_sta_info;
+       struct host_if_drv *hif_drv = vif->hif_drv;
 
        if (!hif_drv) {
                PRINT_ER("driver is null\n");
@@ -4589,7 +4287,7 @@ int host_int_del_station(struct host_if_drv *hif_drv, const u8 *mac_addr)
        PRINT_D(HOSTINF_DBG, "Setting deleting station message queue params\n");
 
        msg.id = HOST_IF_MSG_DEL_STATION;
-       msg.drv = hif_drv;
+       msg.vif = vif;
 
        if (!mac_addr)
                eth_broadcast_addr(del_sta_info->mac_addr);
@@ -4602,12 +4300,12 @@ int host_int_del_station(struct host_if_drv *hif_drv, const u8 *mac_addr)
        return result;
 }
 
-s32 host_int_del_allstation(struct host_if_drv *hif_drv,
-                           u8 pu8MacAddr[][ETH_ALEN])
+s32 wilc_del_allstation(struct wilc_vif *vif, u8 pu8MacAddr[][ETH_ALEN])
 {
        s32 result = 0;
        struct host_if_msg msg;
        struct del_all_sta *pstrDelAllStationMsg = &msg.body.del_all_sta_info;
+       struct host_if_drv *hif_drv = vif->hif_drv;
        u8 au8Zero_Buff[ETH_ALEN] = {0};
        u32 i;
        u8 u8AssocNumb = 0;
@@ -4622,7 +4320,7 @@ s32 host_int_del_allstation(struct host_if_drv *hif_drv,
        PRINT_D(HOSTINF_DBG, "Setting deauthenticating station message queue params\n");
 
        msg.id = HOST_IF_MSG_DEL_ALL_STA;
-       msg.drv = hif_drv;
+       msg.vif = vif;
 
        for (i = 0; i < MAX_NUM_STA; i++) {
                if (memcmp(pu8MacAddr[i], au8Zero_Buff, ETH_ALEN)) {
@@ -4653,12 +4351,13 @@ s32 host_int_del_allstation(struct host_if_drv *hif_drv,
        return result;
 }
 
-s32 host_int_edit_station(struct host_if_drv *hif_drv,
-                         struct add_sta_param *pstrStaParams)
+s32 wilc_edit_station(struct wilc_vif *vif,
+                     struct add_sta_param *pstrStaParams)
 {
        s32 result = 0;
        struct host_if_msg msg;
        struct add_sta_param *pstrAddStationMsg = &msg.body.add_sta_info;
+       struct host_if_drv *hif_drv = vif->hif_drv;
 
        if (!hif_drv) {
                PRINT_ER("driver is null\n");
@@ -4670,7 +4369,7 @@ s32 host_int_edit_station(struct host_if_drv *hif_drv,
        memset(&msg, 0, sizeof(struct host_if_msg));
 
        msg.id = HOST_IF_MSG_EDIT_STATION;
-       msg.drv = hif_drv;
+       msg.vif = vif;
 
        memcpy(pstrAddStationMsg, pstrStaParams, sizeof(struct add_sta_param));
        if (pstrAddStationMsg->rates_len > 0) {
@@ -4691,13 +4390,12 @@ s32 host_int_edit_station(struct host_if_drv *hif_drv,
        return result;
 }
 
-s32 host_int_set_power_mgmt(struct host_if_drv *hif_drv,
-                           bool bIsEnabled,
-                           u32 u32Timeout)
+s32 wilc_set_power_mgmt(struct wilc_vif *vif, bool bIsEnabled, u32 u32Timeout)
 {
        s32 result = 0;
        struct host_if_msg msg;
        struct power_mgmt_param *pstrPowerMgmtParam = &msg.body.pwr_mgmt_info;
+       struct host_if_drv *hif_drv = vif->hif_drv;
 
        PRINT_INFO(HOSTINF_DBG, "\n\n>> Setting PS to %d <<\n\n", bIsEnabled);
 
@@ -4711,7 +4409,7 @@ s32 host_int_set_power_mgmt(struct host_if_drv *hif_drv,
        memset(&msg, 0, sizeof(struct host_if_msg));
 
        msg.id = HOST_IF_MSG_POWER_MGMT;
-       msg.drv = hif_drv;
+       msg.vif = vif;
 
        pstrPowerMgmtParam->enabled = bIsEnabled;
        pstrPowerMgmtParam->timeout = u32Timeout;
@@ -4722,13 +4420,13 @@ s32 host_int_set_power_mgmt(struct host_if_drv *hif_drv,
        return result;
 }
 
-s32 host_int_setup_multicast_filter(struct host_if_drv *hif_drv,
-                                   bool bIsEnabled,
-                                   u32 u32count)
+s32 wilc_setup_multicast_filter(struct wilc_vif *vif, bool bIsEnabled,
+                               u32 u32count)
 {
        s32 result = 0;
        struct host_if_msg msg;
        struct set_multicast *pstrMulticastFilterParam = &msg.body.multicast_info;
+       struct host_if_drv *hif_drv = vif->hif_drv;
 
        if (!hif_drv) {
                PRINT_ER("driver is null\n");
@@ -4740,7 +4438,7 @@ s32 host_int_setup_multicast_filter(struct host_if_drv *hif_drv,
        memset(&msg, 0, sizeof(struct host_if_msg));
 
        msg.id = HOST_IF_MSG_SET_MULTICAST_FILTER;
-       msg.drv = hif_drv;
+       msg.vif = vif;
 
        pstrMulticastFilterParam->enabled = bIsEnabled;
        pstrMulticastFilterParam->cnt = u32count;
@@ -4908,7 +4606,7 @@ static void *host_int_ParseJoinBssParam(tstrNetworkInfo *ptstrNetworkInfo)
        return (void *)pNewJoinBssParam;
 }
 
-void host_int_freeJoinParams(void *pJoinParams)
+void wilc_free_join_params(void *pJoinParams)
 {
        if ((struct bss_param *)pJoinParams)
                kfree((struct bss_param *)pJoinParams);
@@ -4916,41 +4614,12 @@ void host_int_freeJoinParams(void *pJoinParams)
                PRINT_ER("Unable to FREE null pointer\n");
 }
 
-s32 host_int_delBASession(struct host_if_drv *hif_drv, char *pBSSID, char TID)
-{
-       s32 result = 0;
-       struct host_if_msg msg;
-       struct ba_session_info *pBASessionInfo = &msg.body.session_info;
-
-       if (!hif_drv) {
-               PRINT_ER("driver is null\n");
-               return -EFAULT;
-       }
-
-       memset(&msg, 0, sizeof(struct host_if_msg));
-
-       msg.id = HOST_IF_MSG_DEL_BA_SESSION;
-
-       memcpy(pBASessionInfo->bssid, pBSSID, ETH_ALEN);
-       pBASessionInfo->tid = TID;
-       msg.drv = hif_drv;
-
-       result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
-       if (result)
-               PRINT_ER("wilc_mq_send fail\n");
-
-       down(&hif_sema_wait_response);
-
-       return result;
-}
-
-s32 host_int_del_All_Rx_BASession(struct host_if_drv *hif_drv,
-                                 char *pBSSID,
-                                 char TID)
+s32 wilc_del_all_rx_ba_session(struct wilc_vif *vif, char *pBSSID, char TID)
 {
        s32 result = 0;
        struct host_if_msg msg;
        struct ba_session_info *pBASessionInfo = &msg.body.session_info;
+       struct host_if_drv *hif_drv = vif->hif_drv;
 
        if (!hif_drv) {
                PRINT_ER("driver is null\n");
@@ -4963,7 +4632,7 @@ s32 host_int_del_All_Rx_BASession(struct host_if_drv *hif_drv,
 
        memcpy(pBASessionInfo->bssid, pBSSID, ETH_ALEN);
        pBASessionInfo->tid = TID;
-       msg.drv = hif_drv;
+       msg.vif = vif;
 
        result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
        if (result)
@@ -4974,10 +4643,11 @@ s32 host_int_del_All_Rx_BASession(struct host_if_drv *hif_drv,
        return result;
 }
 
-s32 host_int_setup_ipaddress(struct host_if_drv *hif_drv, u8 *u16ipadd, u8 idx)
+s32 wilc_setup_ipaddress(struct wilc_vif *vif, u8 *u16ipadd, u8 idx)
 {
        s32 result = 0;
        struct host_if_msg msg;
+       struct host_if_drv *hif_drv = vif->hif_drv;
 
        return 0;
 
@@ -4991,7 +4661,7 @@ s32 host_int_setup_ipaddress(struct host_if_drv *hif_drv, u8 *u16ipadd, u8 idx)
        msg.id = HOST_IF_MSG_SET_IPADDRESS;
 
        msg.body.ip_info.ip_addr = u16ipadd;
-       msg.drv = hif_drv;
+       msg.vif = vif;
        msg.body.ip_info.idx = idx;
 
        result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
@@ -5001,7 +4671,9 @@ s32 host_int_setup_ipaddress(struct host_if_drv *hif_drv, u8 *u16ipadd, u8 idx)
        return result;
 }
 
-s32 host_int_get_ipaddress(struct host_if_drv *hif_drv, u8 *u16ipadd, u8 idx)
+static s32 host_int_get_ipaddress(struct wilc_vif *vif,
+                                 struct host_if_drv *hif_drv,
+                                 u8 *u16ipadd, u8 idx)
 {
        s32 result = 0;
        struct host_if_msg msg;
@@ -5016,7 +4688,7 @@ s32 host_int_get_ipaddress(struct host_if_drv *hif_drv, u8 *u16ipadd, u8 idx)
        msg.id = HOST_IF_MSG_GET_IPADDRESS;
 
        msg.body.ip_info.ip_addr = u16ipadd;
-       msg.drv = hif_drv;
+       msg.vif = vif;
        msg.body.ip_info.idx = idx;
 
        result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
index 57e1d424afdc4c53e9f4f7a7c97d31c2ee258d59..8faac27002e99947eba1e5689be73ed275c48b09 100644 (file)
@@ -259,6 +259,7 @@ enum p2p_listen_state {
        P2P_GRP_FORMATION
 };
 
+struct wilc;
 struct host_if_drv {
        struct user_scan_req usr_scan_req;
        struct user_conn_req usr_conn_req;
@@ -303,122 +304,83 @@ struct add_sta_param {
        u16 flags_set;
 };
 
-s32 host_int_remove_key(struct host_if_drv *hWFIDrv, const u8 *pu8StaAddress);
-int host_int_remove_wep_key(struct host_if_drv *wfi_drv, u8 index);
-int host_int_set_wep_default_key(struct host_if_drv *hif_drv, u8 index);
-int host_int_add_wep_key_bss_sta(struct host_if_drv *hif_drv,
-                                const u8 *key, u8 len, u8 index);
-int host_int_add_wep_key_bss_ap(struct host_if_drv *hif_drv,
-                               const u8 *key, u8 len, u8 index, u8 mode,
-                               enum AUTHTYPE auth_type);
-s32 host_int_add_ptk(struct host_if_drv *hWFIDrv, const u8 *pu8Ptk,
-                    u8 u8PtkKeylen, const u8 *mac_addr,
-                    const u8 *pu8RxMic, const u8 *pu8TxMic,
-                    u8 mode, u8 u8Ciphermode, u8 u8Idx);
-s32 host_int_get_inactive_time(struct host_if_drv *hWFIDrv, const u8 *mac,
-                              u32 *pu32InactiveTime);
-s32 host_int_add_rx_gtk(struct host_if_drv *hWFIDrv, const u8 *pu8RxGtk,
-                       u8 u8GtkKeylen, u8 u8KeyIdx,
-                       u32 u32KeyRSClen, const u8 *KeyRSC,
-                       const u8 *pu8RxMic, const u8 *pu8TxMic,
-                       u8 mode, u8 u8Ciphermode);
-s32 host_int_add_tx_gtk(struct host_if_drv *hWFIDrv, u8 u8KeyLen,
+struct wilc_vif;
+s32 wilc_remove_key(struct host_if_drv *hWFIDrv, const u8 *pu8StaAddress);
+int wilc_remove_wep_key(struct wilc_vif *vif, u8 index);
+int wilc_set_wep_default_keyid(struct wilc_vif *vif, u8 index);
+int wilc_add_wep_key_bss_sta(struct wilc_vif *vif, const u8 *key, u8 len,
+                            u8 index);
+int wilc_add_wep_key_bss_ap(struct wilc_vif *vif, const u8 *key, u8 len,
+                           u8 index, u8 mode, enum AUTHTYPE auth_type);
+s32 wilc_add_ptk(struct wilc_vif *vif, const u8 *pu8Ptk, u8 u8PtkKeylen,
+                const u8 *mac_addr, const u8 *pu8RxMic, const u8 *pu8TxMic,
+                u8 mode, u8 u8Ciphermode, u8 u8Idx);
+s32 wilc_get_inactive_time(struct wilc_vif *vif, const u8 *mac,
+                          u32 *pu32InactiveTime);
+s32 wilc_add_rx_gtk(struct wilc_vif *vif, const u8 *pu8RxGtk, u8 u8GtkKeylen,
+                   u8 u8KeyIdx, u32 u32KeyRSClen, const u8 *KeyRSC,
+                   const u8 *pu8RxMic, const u8 *pu8TxMic, u8 mode,
+                   u8 u8Ciphermode);
+s32 wilc_add_tx_gtk(struct host_if_drv *hWFIDrv, u8 u8KeyLen,
                        u8 *pu8TxGtk, u8 u8KeyIdx);
-s32 host_int_set_pmkid_info(struct host_if_drv *hWFIDrv,
-                           struct host_if_pmkid_attr *pu8PmkidInfoArray);
-s32 host_int_get_pmkid_info(struct host_if_drv *hWFIDrv, u8 *pu8PmkidInfoArray,
-                           u32 u32PmkidInfoLen);
-s32 host_int_set_RSNAConfigPSKPassPhrase(struct host_if_drv *hWFIDrv,
-                                        u8 *pu8PassPhrase,
-                                        u8 u8Psklength);
-s32 host_int_get_RSNAConfigPSKPassPhrase(struct host_if_drv *hWFIDrv,
-                                        u8 *pu8PassPhrase, u8 u8Psklength);
-s32 hif_get_mac_address(struct host_if_drv *hWFIDrv, u8 *pu8MacAddress);
-s32 host_int_set_MacAddress(struct host_if_drv *hWFIDrv, u8 *pu8MacAddress);
-int host_int_wait_msg_queue_idle(void);
-s32 host_int_set_start_scan_req(struct host_if_drv *hWFIDrv, u8 scanSource);
-s32 host_int_get_start_scan_req(struct host_if_drv *hWFIDrv, u8 *pu8ScanSource);
-s32 host_int_set_join_req(struct host_if_drv *hWFIDrv, u8 *pu8bssid,
-                         const u8 *pu8ssid, size_t ssidLen,
-                         const u8 *pu8IEs, size_t IEsLen,
-                         wilc_connect_result pfConnectResult, void *pvUserArg,
-                         u8 u8security, enum AUTHTYPE tenuAuth_type,
-                         u8 u8channel, void *pJoinParams);
-s32 host_int_flush_join_req(struct host_if_drv *hWFIDrv);
-s32 host_int_disconnect(struct host_if_drv *hWFIDrv, u16 u16ReasonCode);
-s32 host_int_disconnect_station(struct host_if_drv *hWFIDrv, u8 assoc_id);
-s32 host_int_get_assoc_req_info(struct host_if_drv *hWFIDrv,
-                               u8 *pu8AssocReqInfo,
-                               u32 u32AssocReqInfoLen);
-s32 host_int_get_assoc_res_info(struct host_if_drv *hWFIDrv,
-                               u8 *pu8AssocRespInfo,
-                               u32 u32MaxAssocRespInfoLen,
-                               u32 *pu32RcvdAssocRespInfoLen);
-s32 host_int_get_rx_power_level(struct host_if_drv *hWFIDrv,
-                               u8 *pu8RxPowerLevel,
-                               u32 u32RxPowerLevelLen);
-int host_int_set_mac_chnl_num(struct host_if_drv *wfi_drv, u8 channel);
-s32 host_int_get_host_chnl_num(struct host_if_drv *hWFIDrv, u8 *pu8ChNo);
-s32 host_int_get_rssi(struct host_if_drv *hWFIDrv, s8 *ps8Rssi);
-s32 host_int_get_link_speed(struct host_if_drv *hWFIDrv, s8 *ps8lnkspd);
-s32 host_int_scan(struct host_if_drv *hWFIDrv, u8 u8ScanSource,
-                 u8 u8ScanType, u8 *pu8ChnlFreqList,
-                 u8 u8ChnlListLen, const u8 *pu8IEs,
-                 size_t IEsLen, wilc_scan_result ScanResult,
-                 void *pvUserArg, struct hidden_network *pstrHiddenNetwork);
-s32 hif_set_cfg(struct host_if_drv *hWFIDrv,
-               struct cfg_param_val *pstrCfgParamVal);
-s32 hif_get_cfg(struct host_if_drv *hWFIDrv, u16 u16WID, u16 *pu16WID_Value);
-s32 host_int_init(struct net_device *dev, struct host_if_drv **phWFIDrv);
-s32 host_int_deinit(struct host_if_drv *hWFIDrv);
-s32 host_int_add_beacon(struct host_if_drv *hWFIDrv, u32 u32Interval,
-                       u32 u32DTIMPeriod,
-                       u32 u32HeadLen,
-                       u8 *pu8Head,
-                       u32 u32TailLen,
-                       u8 *pu8tail);
-int host_int_del_beacon(struct host_if_drv *hif_drv);
-int host_int_add_station(struct host_if_drv *hif_drv,
-                        struct add_sta_param *sta_param);
-s32 host_int_del_allstation(struct host_if_drv *hWFIDrv,
-                           u8 pu8MacAddr[][ETH_ALEN]);
-int host_int_del_station(struct host_if_drv *hif_drv, const u8 *mac_addr);
-s32 host_int_edit_station(struct host_if_drv *hWFIDrv,
-                         struct add_sta_param *pstrStaParams);
-s32 host_int_set_power_mgmt(struct host_if_drv *hWFIDrv,
-                           bool bIsEnabled,
-                           u32 u32Timeout);
-s32 host_int_setup_multicast_filter(struct host_if_drv *hWFIDrv,
-                                   bool bIsEnabled,
-                                   u32 u32count);
-s32 host_int_setup_ipaddress(struct host_if_drv *hWFIDrv,
-                            u8 *pu8IPAddr,
-                            u8 idx);
-s32 host_int_delBASession(struct host_if_drv *hWFIDrv, char *pBSSID, char TID);
-s32 host_int_del_All_Rx_BASession(struct host_if_drv *hWFIDrv,
-                                 char *pBSSID,
-                                 char TID);
-s32 host_int_get_ipaddress(struct host_if_drv *hWFIDrv, u8 *pu8IPAddr, u8 idx);
-s32 host_int_remain_on_channel(struct host_if_drv *hWFIDrv,
-                              u32 u32SessionID,
-                              u32 u32duration,
-                              u16 chan,
-                              wilc_remain_on_chan_expired RemainOnChanExpired,
-                              wilc_remain_on_chan_ready RemainOnChanReady,
-                              void *pvUserArg);
-s32 host_int_ListenStateExpired(struct host_if_drv *hWFIDrv, u32 u32SessionID);
-s32 host_int_frame_register(struct host_if_drv *hWFIDrv,
-                           u16 u16FrameType,
-                           bool bReg);
-int host_int_set_wfi_drv_handler(struct host_if_drv *address);
-int host_int_set_operation_mode(struct host_if_drv *wfi_drv, u32 mode);
-
-static s32 Handle_ScanDone(struct host_if_drv *drvHandler,
-                          enum scan_event enuEvent);
-
-void host_int_freeJoinParams(void *pJoinParams);
-
-s32 host_int_get_statistics(struct host_if_drv *hWFIDrv,
-                           struct rf_info *pstrStatistics);
-void resolve_disconnect_aberration(struct host_if_drv *hif_drv);
+s32 wilc_set_pmkid_info(struct wilc_vif *vif,
+                       struct host_if_pmkid_attr *pu8PmkidInfoArray);
+s32 wilc_get_mac_address(struct wilc_vif *vif, u8 *pu8MacAddress);
+s32 wilc_set_mac_address(struct wilc_vif *vif, u8 *pu8MacAddress);
+int wilc_wait_msg_queue_idle(void);
+s32 wilc_set_start_scan_req(struct host_if_drv *hWFIDrv, u8 scanSource);
+s32 wilc_set_join_req(struct wilc_vif *vif, u8 *pu8bssid, const u8 *pu8ssid,
+                     size_t ssidLen, const u8 *pu8IEs, size_t IEsLen,
+                     wilc_connect_result pfConnectResult, void *pvUserArg,
+                     u8 u8security, enum AUTHTYPE tenuAuth_type,
+                     u8 u8channel, void *pJoinParams);
+s32 wilc_flush_join_req(struct wilc_vif *vif);
+s32 wilc_disconnect(struct wilc_vif *vif, u16 u16ReasonCode);
+int wilc_set_mac_chnl_num(struct wilc_vif *vif, u8 channel);
+s32 wilc_get_rssi(struct wilc_vif *vif, s8 *ps8Rssi);
+s32 wilc_scan(struct wilc_vif *vif, u8 u8ScanSource, u8 u8ScanType,
+             u8 *pu8ChnlFreqList, u8 u8ChnlListLen, const u8 *pu8IEs,
+             size_t IEsLen, wilc_scan_result ScanResult, void *pvUserArg,
+             struct hidden_network *pstrHiddenNetwork);
+s32 wilc_hif_set_cfg(struct wilc_vif *vif,
+                    struct cfg_param_val *pstrCfgParamVal);
+s32 wilc_init(struct net_device *dev, struct host_if_drv **phWFIDrv);
+s32 wilc_deinit(struct wilc_vif *vif);
+s32 wilc_add_beacon(struct wilc_vif *vif, u32 u32Interval, u32 u32DTIMPeriod,
+                   u32 u32HeadLen, u8 *pu8Head, u32 u32TailLen, u8 *pu8Tail);
+int wilc_del_beacon(struct wilc_vif *vif);
+int wilc_add_station(struct wilc_vif *vif, struct add_sta_param *sta_param);
+s32 wilc_del_allstation(struct wilc_vif *vif, u8 pu8MacAddr[][ETH_ALEN]);
+int wilc_del_station(struct wilc_vif *vif, const u8 *mac_addr);
+s32 wilc_edit_station(struct wilc_vif *vif,
+                     struct add_sta_param *pstrStaParams);
+s32 wilc_set_power_mgmt(struct wilc_vif *vif, bool bIsEnabled, u32 u32Timeout);
+s32 wilc_setup_multicast_filter(struct wilc_vif *vif, bool bIsEnabled,
+                               u32 u32count);
+s32 wilc_setup_ipaddress(struct wilc_vif *vif, u8 *u16ipadd, u8 idx);
+s32 wilc_del_all_rx_ba_session(struct wilc_vif *vif, char *pBSSID, char TID);
+s32 wilc_remain_on_channel(struct wilc_vif *vif, u32 u32SessionID,
+                          u32 u32duration, u16 chan,
+                          wilc_remain_on_chan_expired RemainOnChanExpired,
+                          wilc_remain_on_chan_ready RemainOnChanReady,
+                          void *pvUserArg);
+s32 wilc_listen_state_expired(struct wilc_vif *vif, u32 u32SessionID);
+s32 wilc_frame_register(struct wilc_vif *vif, u16 u16FrameType, bool bReg);
+int wilc_set_wfi_drv_handler(struct wilc_vif *vif, int index);
+int wilc_set_operation_mode(struct wilc_vif *vif, u32 mode);
+
+void wilc_free_join_params(void *pJoinParams);
+
+s32 wilc_get_statistics(struct wilc_vif *vif, struct rf_info *pstrStatistics);
+void wilc_resolve_disconnect_aberration(struct wilc_vif *vif);
+int wilc_get_vif_idx(struct wilc_vif *vif);
+
+extern bool wilc_optaining_ip;
+extern u8 wilc_connected_ssid[6];
+extern u8 wilc_multicast_mac_addr_list[WILC_MULTICAST_TABLE_SIZE][ETH_ALEN];
+
+extern int wilc_connecting;
+extern u8 wilc_initialized;
+extern struct timer_list wilc_during_ip_timer;
+
 #endif
index 589a11fd977c3be0f2d32829b9d452253e1d6291..e550027645b79109b00993476882c353fdde68a4 100644 (file)
@@ -26,12 +26,9 @@ struct wilc_wfi_radiotap_cb_hdr {
 
 static struct net_device *wilc_wfi_mon; /* global monitor netdev */
 
-extern int  mac_xmit(struct sk_buff *skb, struct net_device *dev);
-
-
-u8 srcAdd[6];
-u8 bssid[6];
-u8 broadcast[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+static u8 srcAdd[6];
+static u8 bssid[6];
+static u8 broadcast[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
 /**
  *  @brief      WILC_WFI_monitor_rx
  *  @details
@@ -298,7 +295,7 @@ static netdev_tx_t WILC_WFI_mon_xmit(struct sk_buff *skb,
                mon_mgmt_tx(mon_priv->real_ndev, skb->data, skb->len);
                dev_kfree_skb(skb);
        } else
-               ret = mac_xmit(skb, mon_priv->real_ndev);
+               ret = wilc_mac_xmit(skb, mon_priv->real_ndev);
 
        return ret;
 }
index 086f1dbfb157d8e94a8e52ec4debaf898b903c22..54fe9d74b78082b57988d24fbf68e325fab67095 100644 (file)
 
 #include <linux/semaphore.h>
 
-#ifdef WILC_SDIO
-#include "linux_wlan_sdio.h"
-#else
-#include "linux_wlan_spi.h"
-#endif
-
- #define _linux_wlan_device_power_on()         {}
- #define _linux_wlan_device_power_off()                {}
-
- #define _linux_wlan_device_detection()                {}
- #define _linux_wlan_device_removal()          {}
-
-extern bool g_obtainingIP;
-extern u8 multicast_mac_addr_list[WILC_MULTICAST_TABLE_SIZE][ETH_ALEN];
-extern struct timer_list hDuringIpTimer;
-
-static int linux_wlan_device_power(int on_off)
-{
-       PRINT_D(INIT_DBG, "linux_wlan_device_power.. (%d)\n", on_off);
-
-       if (on_off) {
-               _linux_wlan_device_power_on();
-       } else {
-               _linux_wlan_device_power_off();
-       }
-
-       return 0;
-}
-
-static int linux_wlan_device_detection(int on_off)
-{
-       PRINT_D(INIT_DBG, "linux_wlan_device_detection.. (%d)\n", on_off);
-
-#ifdef WILC_SDIO
-       if (on_off) {
-               _linux_wlan_device_detection();
-       } else {
-               _linux_wlan_device_removal();
-       }
-#endif
-
-       return 0;
-}
-
 static int dev_state_ev_handler(struct notifier_block *this, unsigned long event, void *ptr);
 
 static struct notifier_block g_dev_notifier = {
@@ -81,25 +37,20 @@ static struct semaphore close_exit_sync;
 
 static int wlan_deinit_locks(struct net_device *dev);
 static void wlan_deinitialize_threads(struct net_device *dev);
-extern void WILC_WFI_monitor_rx(u8 *buff, u32 size);
-extern void WILC_WFI_p2p_rx(struct net_device *dev, u8 *buff, u32 size);
 
 static void linux_wlan_tx_complete(void *priv, int status);
 static int  mac_init_fn(struct net_device *ndev);
-int  mac_xmit(struct sk_buff *skb, struct net_device *dev);
-int  mac_open(struct net_device *ndev);
-int  mac_close(struct net_device *ndev);
 static struct net_device_stats *mac_stats(struct net_device *dev);
 static int  mac_ioctl(struct net_device *ndev, struct ifreq *req, int cmd);
 static void wilc_set_multicast_list(struct net_device *dev);
-struct wilc *g_linux_wlan;
-bool bEnablePS = true;
+
+bool wilc_enable_ps = true;
 
 static const struct net_device_ops wilc_netdev_ops = {
        .ndo_init = mac_init_fn,
-       .ndo_open = mac_open,
-       .ndo_stop = mac_close,
-       .ndo_start_xmit = mac_xmit,
+       .ndo_open = wilc_mac_open,
+       .ndo_stop = wilc_mac_close,
+       .ndo_start_xmit = wilc_mac_xmit,
        .ndo_do_ioctl = mac_ioctl,
        .ndo_get_stats = mac_stats,
        .ndo_set_rx_mode  = wilc_set_multicast_list,
@@ -113,7 +64,7 @@ static int dev_state_ev_handler(struct notifier_block *this, unsigned long event
        struct host_if_drv *hif_drv;
        struct net_device *dev;
        u8 *ip_addr_buf;
-       perInterface_wlan_t *nic;
+       struct wilc_vif *vif;
        u8 null_ip[4] = {0};
        char wlan_dev_name[5] = "wlan0";
 
@@ -139,8 +90,8 @@ static int dev_state_ev_handler(struct notifier_block *this, unsigned long event
                return NOTIFY_DONE;
        }
        hif_drv = (struct host_if_drv *)priv->hWILCWFIDrv;
-       nic = netdev_priv(dev);
-       if (!nic || !hif_drv) {
+       vif = netdev_priv(dev);
+       if (!vif || !hif_drv) {
                PRINT_D(GENERIC_DBG, "No Wireless Priv\n");
                return NOTIFY_DONE;
        }
@@ -153,15 +104,15 @@ static int dev_state_ev_handler(struct notifier_block *this, unsigned long event
 
                PRINT_INFO(GENERIC_DBG, "\n ============== IP Address Obtained ===============\n\n");
 
-               if (nic->iftype == STATION_MODE || nic->iftype == CLIENT_MODE) {
+               if (vif->iftype == STATION_MODE || vif->iftype == CLIENT_MODE) {
                        hif_drv->IFC_UP = 1;
-                       g_obtainingIP = false;
-                       del_timer(&hDuringIpTimer);
+                       wilc_optaining_ip = false;
+                       del_timer(&wilc_during_ip_timer);
                        PRINT_D(GENERIC_DBG, "IP obtained , enable scan\n");
                }
 
-               if (bEnablePS)
-                       host_int_set_power_mgmt(hif_drv, 1, 0);
+               if (wilc_enable_ps)
+                       wilc_set_power_mgmt(vif, 1, 0);
 
                PRINT_D(GENERIC_DBG, "[%s] Up IP\n", dev_iface->ifa_label);
 
@@ -169,7 +120,7 @@ static int dev_state_ev_handler(struct notifier_block *this, unsigned long event
                PRINT_D(GENERIC_DBG, "IP add=%d:%d:%d:%d\n",
                        ip_addr_buf[0], ip_addr_buf[1],
                        ip_addr_buf[2], ip_addr_buf[3]);
-               host_int_setup_ipaddress(hif_drv, ip_addr_buf, nic->u8IfIdx);
+               wilc_setup_ipaddress(vif, ip_addr_buf, vif->u8IfIdx);
 
                break;
 
@@ -177,15 +128,15 @@ static int dev_state_ev_handler(struct notifier_block *this, unsigned long event
                PRINT_D(GENERIC_DBG, "dev_state_ev_handler event=NETDEV_DOWN %p\n", dev);
 
                PRINT_INFO(GENERIC_DBG, "\n ============== IP Address Released ===============\n\n");
-               if (nic->iftype == STATION_MODE || nic->iftype == CLIENT_MODE) {
+               if (vif->iftype == STATION_MODE || vif->iftype == CLIENT_MODE) {
                        hif_drv->IFC_UP = 0;
-                       g_obtainingIP = false;
+                       wilc_optaining_ip = false;
                }
 
                if (memcmp(dev_iface->ifa_label, wlan_dev_name, 5) == 0)
-                       host_int_set_power_mgmt(hif_drv, 0, 0);
+                       wilc_set_power_mgmt(vif, 0, 0);
 
-               resolve_disconnect_aberration(hif_drv);
+               wilc_resolve_disconnect_aberration(vif);
 
                PRINT_D(GENERIC_DBG, "[%s] Down IP\n", dev_iface->ifa_label);
 
@@ -194,7 +145,7 @@ static int dev_state_ev_handler(struct notifier_block *this, unsigned long event
                        ip_addr_buf[0], ip_addr_buf[1],
                        ip_addr_buf[2], ip_addr_buf[3]);
 
-               host_int_setup_ipaddress(hif_drv, ip_addr_buf, nic->u8IfIdx);
+               wilc_setup_ipaddress(vif, ip_addr_buf, vif->u8IfIdx);
 
                break;
 
@@ -208,15 +159,14 @@ static int dev_state_ev_handler(struct notifier_block *this, unsigned long event
        return NOTIFY_DONE;
 }
 
-#if (defined WILC_SPI) || (defined WILC_SDIO_IRQ_GPIO)
 static irqreturn_t isr_uh_routine(int irq, void *user_data)
 {
-       perInterface_wlan_t *nic;
+       struct wilc_vif *vif;
        struct wilc *wilc;
        struct net_device *dev = (struct net_device *)user_data;
 
-       nic = netdev_priv(dev);
-       wilc = nic->wilc;
+       vif = netdev_priv(dev);
+       wilc = vif->wilc;
        PRINT_D(INT_DBG, "Interrupt received UH\n");
 
        if (wilc->close) {
@@ -225,15 +175,14 @@ static irqreturn_t isr_uh_routine(int irq, void *user_data)
        }
        return IRQ_WAKE_THREAD;
 }
-#endif
 
-irqreturn_t isr_bh_routine(int irq, void *userdata)
+static irqreturn_t isr_bh_routine(int irq, void *userdata)
 {
-       perInterface_wlan_t *nic;
+       struct wilc_vif *vif;
        struct wilc *wilc;
 
-       nic = netdev_priv(userdata);
-       wilc = nic->wilc;
+       vif = netdev_priv(userdata);
+       wilc = vif->wilc;
 
        if (wilc->close) {
                PRINT_ER("Driver is CLOSING: Can't handle BH interrupt\n");
@@ -246,19 +195,18 @@ irqreturn_t isr_bh_routine(int irq, void *userdata)
        return IRQ_HANDLED;
 }
 
-#if (defined WILC_SPI) || (defined WILC_SDIO_IRQ_GPIO)
 static int init_irq(struct net_device *dev)
 {
        int ret = 0;
-       perInterface_wlan_t *nic;
+       struct wilc_vif *vif;
        struct wilc *wl;
 
-       nic = netdev_priv(dev);
-       wl = nic->wilc;
+       vif = netdev_priv(dev);
+       wl = vif->wilc;
 
-       if ((gpio_request(GPIO_NUM, "WILC_INTR") == 0) &&
-           (gpio_direction_input(GPIO_NUM) == 0)) {
-               wl->dev_irq_num = gpio_to_irq(GPIO_NUM);
+       if ((gpio_request(wl->gpio, "WILC_INTR") == 0) &&
+           (gpio_direction_input(wl->gpio) == 0)) {
+               wl->dev_irq_num = gpio_to_irq(wl->gpio);
        } else {
                ret = -1;
                PRINT_ER("could not obtain gpio for WILC_INTR\n");
@@ -269,41 +217,40 @@ static int init_irq(struct net_device *dev)
                                              isr_bh_routine,
                                              IRQF_TRIGGER_LOW | IRQF_ONESHOT,
                                              "WILC_IRQ", dev) < 0) {
-               PRINT_ER("Failed to request IRQ for GPIO: %d\n", GPIO_NUM);
+               PRINT_ER("Failed to request IRQ for GPIO: %d\n", wl->gpio);
+               gpio_free(wl->gpio);
                ret = -1;
        } else {
                PRINT_D(INIT_DBG, "IRQ request succeeded IRQ-NUM= %d on GPIO: %d\n",
-                       wl->dev_irq_num, GPIO_NUM);
+                       wl->dev_irq_num, wl->gpio);
        }
 
        return ret;
 }
-#endif
 
 static void deinit_irq(struct net_device *dev)
 {
-       perInterface_wlan_t *nic;
+       struct wilc_vif *vif;
        struct wilc *wilc;
 
-       nic = netdev_priv(dev);
-       wilc = nic->wilc;
+       vif = netdev_priv(dev);
+       wilc = vif->wilc;
 
-#if (defined WILC_SPI) || (defined WILC_SDIO_IRQ_GPIO)
-       if (&wilc->dev_irq_num != 0) {
+       /* Deintialize IRQ */
+       if (wilc->dev_irq_num) {
                free_irq(wilc->dev_irq_num, wilc);
-
-               gpio_free(GPIO_NUM);
+               gpio_free(wilc->gpio);
        }
-#endif
 }
 
-void linux_wlan_dbg(u8 *buff)
+void wilc_dbg(u8 *buff)
 {
        PRINT_D(INIT_DBG, "%d\n", *buff);
 }
 
-int linux_wlan_lock_timeout(void *vp, u32 timeout)
+int wilc_lock_timeout(struct wilc *nic, void *vp, u32 timeout)
 {
+       /* FIXME: replace with mutex_lock or wait_for_completion */
        int error = -1;
 
        PRINT_D(LOCK_DBG, "Locking %p\n", vp);
@@ -315,7 +262,7 @@ int linux_wlan_lock_timeout(void *vp, u32 timeout)
        return error;
 }
 
-void linux_wlan_mac_indicate(struct wilc *wilc, int flag)
+void wilc_mac_indicate(struct wilc *wilc, int flag)
 {
        int status;
 
@@ -333,7 +280,7 @@ void linux_wlan_mac_indicate(struct wilc *wilc, int flag)
        }
 }
 
-struct net_device *get_if_handler(struct wilc *wilc, u8 *mac_header)
+static struct net_device *get_if_handler(struct wilc *wilc, u8 *mac_header)
 {
        u8 *bssid, *bssid1;
        int i = 0;
@@ -342,9 +289,9 @@ struct net_device *get_if_handler(struct wilc *wilc, u8 *mac_header)
        bssid1 = mac_header + 4;
 
        for (i = 0; i < wilc->vif_num; i++)
-               if (!memcmp(bssid1, wilc->vif[i].bssid, ETH_ALEN) ||
-                   !memcmp(bssid, wilc->vif[i].bssid, ETH_ALEN))
-                       return wilc->vif[i].ndev;
+               if (!memcmp(bssid1, wilc->vif[i]->bssid, ETH_ALEN) ||
+                   !memcmp(bssid, wilc->vif[i]->bssid, ETH_ALEN))
+                       return wilc->vif[i]->ndev;
 
        PRINT_INFO(INIT_DBG, "Invalide handle\n");
        for (i = 0; i < 25; i++)
@@ -352,27 +299,27 @@ struct net_device *get_if_handler(struct wilc *wilc, u8 *mac_header)
        bssid = mac_header + 18;
        bssid1 = mac_header + 12;
        for (i = 0; i < wilc->vif_num; i++)
-               if (!memcmp(bssid1, wilc->vif[i].bssid, ETH_ALEN) ||
-                   !memcmp(bssid, wilc->vif[i].bssid, ETH_ALEN))
-                       return wilc->vif[i].ndev;
+               if (!memcmp(bssid1, wilc->vif[i]->bssid, ETH_ALEN) ||
+                   !memcmp(bssid, wilc->vif[i]->bssid, ETH_ALEN))
+                       return wilc->vif[i]->ndev;
 
        PRINT_INFO(INIT_DBG, "\n");
        return NULL;
 }
 
-int linux_wlan_set_bssid(struct net_device *wilc_netdev, u8 *bssid)
+int wilc_wlan_set_bssid(struct net_device *wilc_netdev, u8 *bssid)
 {
        int i = 0;
        int ret = -1;
-       perInterface_wlan_t *nic;
+       struct wilc_vif *vif;
        struct wilc *wilc;
 
-       nic = netdev_priv(wilc_netdev);
-       wilc = nic->wilc;
+       vif = netdev_priv(wilc_netdev);
+       wilc = vif->wilc;
 
        for (i = 0; i < wilc->vif_num; i++)
-               if (wilc->vif[i].ndev == wilc_netdev) {
-                       memcpy(wilc->vif[i].bssid, bssid, 6);
+               if (wilc->vif[i]->ndev == wilc_netdev) {
+                       memcpy(wilc->vif[i]->bssid, bssid, 6);
                        ret = 0;
                        break;
                }
@@ -380,14 +327,14 @@ int linux_wlan_set_bssid(struct net_device *wilc_netdev, u8 *bssid)
        return ret;
 }
 
-int linux_wlan_get_num_conn_ifcs(void)
+int wilc_wlan_get_num_conn_ifcs(struct wilc *wilc)
 {
        u8 i = 0;
        u8 null_bssid[6] = {0};
        u8 ret_val = 0;
 
-       for (i = 0; i < g_linux_wlan->vif_num; i++)
-               if (memcmp(g_linux_wlan->vif[i].bssid, null_bssid, 6))
+       for (i = 0; i < wilc->vif_num; i++)
+               if (memcmp(wilc->vif[i]->bssid, null_bssid, 6))
                        ret_val++;
 
        return ret_val;
@@ -398,7 +345,7 @@ int linux_wlan_get_num_conn_ifcs(void)
 static int linux_wlan_txq_task(void *vp)
 {
        int ret, txq_count;
-       perInterface_wlan_t *nic;
+       struct wilc_vif *vif;
        struct wilc *wl;
        struct net_device *dev = vp;
 #if defined USE_TX_BACKOFF_DELAY_IF_NO_BUFFERS
@@ -410,8 +357,8 @@ static int linux_wlan_txq_task(void *vp)
        int backoff_weight = TX_BACKOFF_WEIGHT_MIN;
 #endif
 
-       nic = netdev_priv(dev);
-       wl = nic->wilc;
+       vif = netdev_priv(dev);
+       wl = vif->wilc;
 
        up(&wl->txq_thread_started);
        while (1) {
@@ -437,10 +384,10 @@ static int linux_wlan_txq_task(void *vp)
                        if (txq_count < FLOW_CONTROL_LOWER_THRESHOLD) {
                                PRINT_D(TX_DBG, "Waking up queue\n");
 
-                               if (netif_queue_stopped(wl->vif[0].ndev))
-                                       netif_wake_queue(wl->vif[0].ndev);
-                               if (netif_queue_stopped(wl->vif[1].ndev))
-                                       netif_wake_queue(wl->vif[1].ndev);
+                               if (netif_queue_stopped(wl->vif[0]->ndev))
+                                       netif_wake_queue(wl->vif[0]->ndev);
+                               if (netif_queue_stopped(wl->vif[1]->ndev))
+                                       netif_wake_queue(wl->vif[1]->ndev);
                        }
 
                        if (ret == WILC_TX_ERR_NO_BUF) {
@@ -463,54 +410,46 @@ static int linux_wlan_txq_task(void *vp)
        return 0;
 }
 
-void linux_wlan_rx_complete(void)
+void wilc_rx_complete(struct wilc *nic)
 {
        PRINT_D(RX_DBG, "RX completed\n");
 }
 
-int linux_wlan_get_firmware(struct net_device *dev)
+int wilc_wlan_get_firmware(struct net_device *dev)
 {
-       perInterface_wlan_t *nic;
+       struct wilc_vif *vif;
        struct wilc *wilc;
        int ret = 0;
        const struct firmware *wilc_firmware;
        char *firmware;
 
-       nic = netdev_priv(dev);
-       wilc = nic->wilc;
+       vif = netdev_priv(dev);
+       wilc = vif->wilc;
 
-       if (nic->iftype == AP_MODE) {
+       if (vif->iftype == AP_MODE) {
                firmware = AP_FIRMWARE;
-       } else if (nic->iftype == STATION_MODE) {
+       } else if (vif->iftype == STATION_MODE) {
                firmware = STA_FIRMWARE;
        } else {
                PRINT_D(INIT_DBG, "Get P2P_CONCURRENCY_FIRMWARE\n");
                firmware = P2P_CONCURRENCY_FIRMWARE;
        }
 
-       if (!nic) {
-               PRINT_ER("NIC is NULL\n");
+       if (!vif) {
+               PRINT_ER("vif is NULL\n");
                goto _fail_;
        }
 
-       if (!(&nic->wilc_netdev->dev)) {
-               PRINT_ER("&nic->wilc_netdev->dev  is NULL\n");
+       if (!(&vif->ndev->dev)) {
+               PRINT_ER("&vif->ndev->dev  is NULL\n");
                goto _fail_;
        }
 
-#ifdef WILC_SDIO
-       if (request_firmware(&wilc_firmware, firmware, &wilc->wilc_sdio_func->dev) != 0) {
+       if (request_firmware(&wilc_firmware, firmware, wilc->dev) != 0) {
                PRINT_ER("%s - firmare not available\n", firmware);
                ret = -1;
                goto _fail_;
        }
-#else
-       if (request_firmware(&wilc_firmware, firmware, &wilc->wilc_spidev->dev) != 0) {
-               PRINT_ER("%s - firmare not available\n", firmware);
-               ret = -1;
-               goto _fail_;
-       }
-#endif
        wilc->firmware = wilc_firmware;
 
 _fail_:
@@ -520,22 +459,22 @@ _fail_:
 
 static int linux_wlan_start_firmware(struct net_device *dev)
 {
-       perInterface_wlan_t *nic;
+       struct wilc_vif *vif;
        struct wilc *wilc;
        int ret = 0;
 
-       nic = netdev_priv(dev);
-       wilc = nic->wilc;
+       vif = netdev_priv(dev);
+       wilc = vif->wilc;
 
        PRINT_D(INIT_DBG, "Starting Firmware ...\n");
-       ret = wilc_wlan_start();
+       ret = wilc_wlan_start(wilc);
        if (ret < 0) {
                PRINT_ER("Failed to start Firmware\n");
                return ret;
        }
 
        PRINT_D(INIT_DBG, "Waiting for Firmware to get ready ...\n");
-       ret = linux_wlan_lock_timeout(&wilc->sync_event, 5000);
+       ret = wilc_lock_timeout(wilc, &wilc->sync_event, 5000);
        if (ret) {
                PRINT_D(INIT_DBG, "Firmware start timed out");
                return ret;
@@ -545,21 +484,21 @@ static int linux_wlan_start_firmware(struct net_device *dev)
        return 0;
 }
 
-static int linux_wlan_firmware_download(struct net_device *dev)
+static int wilc1000_firmware_download(struct net_device *dev)
 {
-       perInterface_wlan_t *nic;
+       struct wilc_vif *vif;
        struct wilc *wilc;
        int ret = 0;
 
-       nic = netdev_priv(dev);
-       wilc = nic->wilc;
+       vif = netdev_priv(dev);
+       wilc = vif->wilc;
 
        if (!wilc->firmware) {
                PRINT_ER("Firmware buffer is NULL\n");
                return -ENOBUFS;
        }
        PRINT_D(INIT_DBG, "Downloading Firmware ...\n");
-       ret = wilc_wlan_firmware_download(wilc->firmware->data,
+       ret = wilc_wlan_firmware_download(wilc, wilc->firmware->data,
                                          wilc->firmware->size);
        if (ret < 0)
                return ret;
@@ -567,13 +506,15 @@ static int linux_wlan_firmware_download(struct net_device *dev)
        PRINT_D(INIT_DBG, "Freeing FW buffer ...\n");
        PRINT_D(INIT_DBG, "Releasing firmware\n");
        release_firmware(wilc->firmware);
+       wilc->firmware = NULL;
 
        PRINT_D(INIT_DBG, "Download Succeeded\n");
 
        return 0;
 }
 
-static int linux_wlan_init_test_config(struct net_device *dev, struct wilc *p_nic)
+static int linux_wlan_init_test_config(struct net_device *dev,
+                                      struct wilc *wilc)
 {
        unsigned char c_val[64];
        unsigned char mac_add[] = {0x00, 0x80, 0xC2, 0x5E, 0xa2, 0xff};
@@ -591,183 +532,198 @@ static int linux_wlan_init_test_config(struct net_device *dev, struct wilc *p_ni
        PRINT_D(INIT_DBG, "MAC address is : %02x-%02x-%02x-%02x-%02x-%02x\n",
                mac_add[0], mac_add[1], mac_add[2],
                mac_add[3], mac_add[4], mac_add[5]);
-       wilc_get_chipid(0);
+       wilc_get_chipid(wilc, 0);
 
        *(int *)c_val = 1;
 
-       if (!wilc_wlan_cfg_set(1, WID_SET_DRV_HANDLER, c_val, 4, 0, 0))
+       if (!wilc_wlan_cfg_set(wilc, 1, WID_SET_DRV_HANDLER, c_val, 4, 0, 0))
                goto _fail_;
 
        c_val[0] = 0;
-       if (!wilc_wlan_cfg_set(0, WID_PC_TEST_MODE, c_val, 1, 0, 0))
+       if (!wilc_wlan_cfg_set(wilc, 0, WID_PC_TEST_MODE, c_val, 1, 0, 0))
                goto _fail_;
 
        c_val[0] = INFRASTRUCTURE;
-       if (!wilc_wlan_cfg_set(0, WID_BSS_TYPE, c_val, 1, 0, 0))
+       if (!wilc_wlan_cfg_set(wilc, 0, WID_BSS_TYPE, c_val, 1, 0, 0))
                goto _fail_;
 
        c_val[0] = RATE_AUTO;
-       if (!wilc_wlan_cfg_set(0, WID_CURRENT_TX_RATE, c_val, 1, 0, 0))
+       if (!wilc_wlan_cfg_set(wilc, 0, WID_CURRENT_TX_RATE, c_val, 1, 0, 0))
                goto _fail_;
 
        c_val[0] = G_MIXED_11B_2_MODE;
-       if (!wilc_wlan_cfg_set(0, WID_11G_OPERATING_MODE, c_val, 1, 0, 0))
+       if (!wilc_wlan_cfg_set(wilc, 0, WID_11G_OPERATING_MODE, c_val, 1, 0,
+                              0))
                goto _fail_;
 
        c_val[0] = 1;
-       if (!wilc_wlan_cfg_set(0, WID_CURRENT_CHANNEL, c_val, 1, 0, 0))
+       if (!wilc_wlan_cfg_set(wilc, 0, WID_CURRENT_CHANNEL, c_val, 1, 0, 0))
                goto _fail_;
 
        c_val[0] = G_SHORT_PREAMBLE;
-       if (!wilc_wlan_cfg_set(0, WID_PREAMBLE, c_val, 1, 0, 0))
+       if (!wilc_wlan_cfg_set(wilc, 0, WID_PREAMBLE, c_val, 1, 0, 0))
                goto _fail_;
 
        c_val[0] = AUTO_PROT;
-       if (!wilc_wlan_cfg_set(0, WID_11N_PROT_MECH, c_val, 1, 0, 0))
+       if (!wilc_wlan_cfg_set(wilc, 0, WID_11N_PROT_MECH, c_val, 1, 0, 0))
                goto _fail_;
 
        c_val[0] = ACTIVE_SCAN;
-       if (!wilc_wlan_cfg_set(0, WID_SCAN_TYPE, c_val, 1, 0, 0))
+       if (!wilc_wlan_cfg_set(wilc, 0, WID_SCAN_TYPE, c_val, 1, 0, 0))
                goto _fail_;
 
        c_val[0] = SITE_SURVEY_OFF;
-       if (!wilc_wlan_cfg_set(0, WID_SITE_SURVEY, c_val, 1, 0, 0))
+       if (!wilc_wlan_cfg_set(wilc, 0, WID_SITE_SURVEY, c_val, 1, 0, 0))
                goto _fail_;
 
        *((int *)c_val) = 0xffff;
-       if (!wilc_wlan_cfg_set(0, WID_RTS_THRESHOLD, c_val, 2, 0, 0))
+       if (!wilc_wlan_cfg_set(wilc, 0, WID_RTS_THRESHOLD, c_val, 2, 0, 0))
                goto _fail_;
 
        *((int *)c_val) = 2346;
-       if (!wilc_wlan_cfg_set(0, WID_FRAG_THRESHOLD, c_val, 2, 0, 0))
+       if (!wilc_wlan_cfg_set(wilc, 0, WID_FRAG_THRESHOLD, c_val, 2, 0, 0))
                goto _fail_;
 
        c_val[0] = 0;
-       if (!wilc_wlan_cfg_set(0, WID_BCAST_SSID, c_val, 1, 0, 0))
+       if (!wilc_wlan_cfg_set(wilc, 0, WID_BCAST_SSID, c_val, 1, 0, 0))
                goto _fail_;
 
        c_val[0] = 1;
-       if (!wilc_wlan_cfg_set(0, WID_QOS_ENABLE, c_val, 1, 0, 0))
+       if (!wilc_wlan_cfg_set(wilc, 0, WID_QOS_ENABLE, c_val, 1, 0, 0))
                goto _fail_;
 
        c_val[0] = NO_POWERSAVE;
-       if (!wilc_wlan_cfg_set(0, WID_POWER_MANAGEMENT, c_val, 1, 0, 0))
+       if (!wilc_wlan_cfg_set(wilc, 0, WID_POWER_MANAGEMENT, c_val, 1, 0, 0))
                goto _fail_;
 
-       c_val[0] = NO_ENCRYPT;
-       if (!wilc_wlan_cfg_set(0, WID_11I_MODE, c_val, 1, 0, 0))
+       c_val[0] = NO_SECURITY; /* NO_ENCRYPT, 0x79 */
+       if (!wilc_wlan_cfg_set(wilc, 0, WID_11I_MODE, c_val, 1, 0, 0))
                goto _fail_;
 
        c_val[0] = OPEN_SYSTEM;
-       if (!wilc_wlan_cfg_set(0, WID_AUTH_TYPE, c_val, 1, 0, 0))
+       if (!wilc_wlan_cfg_set(wilc, 0, WID_AUTH_TYPE, c_val, 1, 0, 0))
                goto _fail_;
 
        strcpy(c_val, "123456790abcdef1234567890");
-       if (!wilc_wlan_cfg_set(0, WID_WEP_KEY_VALUE, c_val, (strlen(c_val) + 1), 0, 0))
+       if (!wilc_wlan_cfg_set(wilc, 0, WID_WEP_KEY_VALUE, c_val,
+                              (strlen(c_val) + 1), 0, 0))
                goto _fail_;
 
        strcpy(c_val, "12345678");
-       if (!wilc_wlan_cfg_set(0, WID_11I_PSK, c_val, (strlen(c_val)), 0, 0))
+       if (!wilc_wlan_cfg_set(wilc, 0, WID_11I_PSK, c_val, (strlen(c_val)), 0,
+                              0))
                goto _fail_;
 
        strcpy(c_val, "password");
-       if (!wilc_wlan_cfg_set(0, WID_1X_KEY, c_val, (strlen(c_val) + 1), 0, 0))
+       if (!wilc_wlan_cfg_set(wilc, 0, WID_1X_KEY, c_val, (strlen(c_val) + 1),
+                              0, 0))
                goto _fail_;
 
        c_val[0] = 192;
        c_val[1] = 168;
        c_val[2] = 1;
        c_val[3] = 112;
-       if (!wilc_wlan_cfg_set(0, WID_1X_SERV_ADDR, c_val, 4, 0, 0))
+       if (!wilc_wlan_cfg_set(wilc, 0, WID_1X_SERV_ADDR, c_val, 4, 0, 0))
                goto _fail_;
 
        c_val[0] = 3;
-       if (!wilc_wlan_cfg_set(0, WID_LISTEN_INTERVAL, c_val, 1, 0, 0))
+       if (!wilc_wlan_cfg_set(wilc, 0, WID_LISTEN_INTERVAL, c_val, 1, 0, 0))
                goto _fail_;
 
        c_val[0] = 3;
-       if (!wilc_wlan_cfg_set(0, WID_DTIM_PERIOD, c_val, 1, 0, 0))
+       if (!wilc_wlan_cfg_set(wilc, 0, WID_DTIM_PERIOD, c_val, 1, 0, 0))
                goto _fail_;
 
        c_val[0] = NORMAL_ACK;
-       if (!wilc_wlan_cfg_set(0, WID_ACK_POLICY, c_val, 1, 0, 0))
+       if (!wilc_wlan_cfg_set(wilc, 0, WID_ACK_POLICY, c_val, 1, 0, 0))
                goto _fail_;
 
        c_val[0] = 0;
-       if (!wilc_wlan_cfg_set(0, WID_USER_CONTROL_ON_TX_POWER, c_val, 1, 0, 0))
+       if (!wilc_wlan_cfg_set(wilc, 0, WID_USER_CONTROL_ON_TX_POWER, c_val, 1,
+                              0, 0))
                goto _fail_;
 
        c_val[0] = 48;
-       if (!wilc_wlan_cfg_set(0, WID_TX_POWER_LEVEL_11A, c_val, 1, 0, 0))
+       if (!wilc_wlan_cfg_set(wilc, 0, WID_TX_POWER_LEVEL_11A, c_val, 1, 0,
+                              0))
                goto _fail_;
 
        c_val[0] = 28;
-       if (!wilc_wlan_cfg_set(0, WID_TX_POWER_LEVEL_11B, c_val, 1, 0, 0))
+       if (!wilc_wlan_cfg_set(wilc, 0, WID_TX_POWER_LEVEL_11B, c_val, 1, 0,
+                              0))
                goto _fail_;
 
        *((int *)c_val) = 100;
-       if (!wilc_wlan_cfg_set(0, WID_BEACON_INTERVAL, c_val, 2, 0, 0))
+       if (!wilc_wlan_cfg_set(wilc, 0, WID_BEACON_INTERVAL, c_val, 2, 0, 0))
                goto _fail_;
 
        c_val[0] = REKEY_DISABLE;
-       if (!wilc_wlan_cfg_set(0, WID_REKEY_POLICY, c_val, 1, 0, 0))
+       if (!wilc_wlan_cfg_set(wilc, 0, WID_REKEY_POLICY, c_val, 1, 0, 0))
                goto _fail_;
 
        *((int *)c_val) = 84600;
-       if (!wilc_wlan_cfg_set(0, WID_REKEY_PERIOD, c_val, 4, 0, 0))
+       if (!wilc_wlan_cfg_set(wilc, 0, WID_REKEY_PERIOD, c_val, 4, 0, 0))
                goto _fail_;
 
        *((int *)c_val) = 500;
-       if (!wilc_wlan_cfg_set(0, WID_REKEY_PACKET_COUNT, c_val, 4, 0, 0))
+       if (!wilc_wlan_cfg_set(wilc, 0, WID_REKEY_PACKET_COUNT, c_val, 4, 0,
+                              0))
                goto _fail_;
 
        c_val[0] = 1;
-       if (!wilc_wlan_cfg_set(0, WID_SHORT_SLOT_ALLOWED, c_val, 1, 0, 0))
+       if (!wilc_wlan_cfg_set(wilc, 0, WID_SHORT_SLOT_ALLOWED, c_val, 1, 0,
+                              0))
                goto _fail_;
 
        c_val[0] = G_SELF_CTS_PROT;
-       if (!wilc_wlan_cfg_set(0, WID_11N_ERP_PROT_TYPE, c_val, 1, 0, 0))
+       if (!wilc_wlan_cfg_set(wilc, 0, WID_11N_ERP_PROT_TYPE, c_val, 1, 0, 0))
                goto _fail_;
 
        c_val[0] = 1;
-       if (!wilc_wlan_cfg_set(0, WID_11N_ENABLE, c_val, 1, 0, 0))
+       if (!wilc_wlan_cfg_set(wilc, 0, WID_11N_ENABLE, c_val, 1, 0, 0))
                goto _fail_;
 
        c_val[0] = HT_MIXED_MODE;
-       if (!wilc_wlan_cfg_set(0, WID_11N_OPERATING_MODE, c_val, 1, 0, 0))
+       if (!wilc_wlan_cfg_set(wilc, 0, WID_11N_OPERATING_MODE, c_val, 1, 0,
+                              0))
                goto _fail_;
 
        c_val[0] = 1;
-       if (!wilc_wlan_cfg_set(0, WID_11N_TXOP_PROT_DISABLE, c_val, 1, 0, 0))
+       if (!wilc_wlan_cfg_set(wilc, 0, WID_11N_TXOP_PROT_DISABLE, c_val, 1, 0,
+                              0))
                goto _fail_;
 
        memcpy(c_val, mac_add, 6);
 
-       if (!wilc_wlan_cfg_set(0, WID_MAC_ADDR, c_val, 6, 0, 0))
+       if (!wilc_wlan_cfg_set(wilc, 0, WID_MAC_ADDR, c_val, 6, 0, 0))
                goto _fail_;
 
        c_val[0] = DETECT_PROTECT_REPORT;
-       if (!wilc_wlan_cfg_set(0, WID_11N_OBSS_NONHT_DETECTION, c_val, 1, 0, 0))
+       if (!wilc_wlan_cfg_set(wilc, 0, WID_11N_OBSS_NONHT_DETECTION, c_val, 1,
+                              0, 0))
                goto _fail_;
 
        c_val[0] = RTS_CTS_NONHT_PROT;
-       if (!wilc_wlan_cfg_set(0, WID_11N_HT_PROT_TYPE, c_val, 1, 0, 0))
+       if (!wilc_wlan_cfg_set(wilc, 0, WID_11N_HT_PROT_TYPE, c_val, 1, 0, 0))
                goto _fail_;
 
        c_val[0] = 0;
-       if (!wilc_wlan_cfg_set(0, WID_11N_RIFS_PROT_ENABLE, c_val, 1, 0, 0))
+       if (!wilc_wlan_cfg_set(wilc, 0, WID_11N_RIFS_PROT_ENABLE, c_val, 1, 0,
+                              0))
                goto _fail_;
 
        c_val[0] = MIMO_MODE;
-       if (!wilc_wlan_cfg_set(0, WID_11N_SMPS_MODE, c_val, 1, 0, 0))
+       if (!wilc_wlan_cfg_set(wilc, 0, WID_11N_SMPS_MODE, c_val, 1, 0, 0))
                goto _fail_;
 
        c_val[0] = 7;
-       if (!wilc_wlan_cfg_set(0, WID_11N_CURRENT_TX_MCS, c_val, 1, 0, 0))
+       if (!wilc_wlan_cfg_set(wilc, 0, WID_11N_CURRENT_TX_MCS, c_val, 1, 0,
+                              0))
                goto _fail_;
 
        c_val[0] = 1;
-       if (!wilc_wlan_cfg_set(0, WID_11N_IMMEDIATE_BA_ENABLED, c_val, 1, 1, 1))
+       if (!wilc_wlan_cfg_set(wilc, 0, WID_11N_IMMEDIATE_BA_ENABLED, c_val, 1,
+                              1, 1))
                goto _fail_;
 
        return 0;
@@ -778,11 +734,11 @@ _fail_:
 
 void wilc1000_wlan_deinit(struct net_device *dev)
 {
-       perInterface_wlan_t *nic;
+       struct wilc_vif *vif;
        struct wilc *wl;
 
-       nic = netdev_priv(dev);
-       wl = nic->wilc;
+       vif = netdev_priv(dev);
+       wl = vif->wilc;
 
        if (!wl) {
                netdev_err(dev, "wl is NULL\n");
@@ -792,18 +748,13 @@ void wilc1000_wlan_deinit(struct net_device *dev)
        if (wl->initialized)    {
                netdev_info(dev, "Deinitializing wilc1000...\n");
 
-#if defined(PLAT_ALLWINNER_A20) || defined(PLAT_ALLWINNER_A23) || defined(PLAT_ALLWINNER_A31)
-               PRINT_D(INIT_DBG, "skip wilc_bus_set_default_speed\n");
-#else
-               wilc_bus_set_default_speed();
-#endif
-
                PRINT_D(INIT_DBG, "Disabling IRQ\n");
-#ifdef WILC_SDIO
-               mutex_lock(&wl->hif_cs);
-               disable_sdio_interrupt();
-               mutex_unlock(&wl->hif_cs);
-#endif
+               if (!wl->dev_irq_num &&
+                   wl->hif_func->disable_interrupt) {
+                       mutex_lock(&wl->hif_cs);
+                       wl->hif_func->disable_interrupt(wl);
+                       mutex_unlock(&wl->hif_cs);
+               }
                if (&wl->txq_event)
                        up(&wl->txq_event);
 
@@ -813,18 +764,20 @@ void wilc1000_wlan_deinit(struct net_device *dev)
                PRINT_D(INIT_DBG, "Deinitializing IRQ\n");
                deinit_irq(dev);
 
-               wilc_wlan_stop();
+               wilc_wlan_stop(wl);
 
                PRINT_D(INIT_DBG, "Deinitializing WILC Wlan\n");
                wilc_wlan_cleanup(dev);
-#if (defined WILC_SDIO) && (!defined WILC_SDIO_IRQ_GPIO)
-  #if defined(PLAT_ALLWINNER_A20) || defined(PLAT_ALLWINNER_A23) || defined(PLAT_ALLWINNER_A31)
-               PRINT_D(INIT_DBG, "Disabling IRQ 2\n");
-
-               mutex_lock(&wl->hif_cs);
-               disable_sdio_interrupt();
-               mutex_unlock(&wl->hif_cs);
-  #endif
+#if defined(PLAT_ALLWINNER_A20) || defined(PLAT_ALLWINNER_A23) || defined(PLAT_ALLWINNER_A31)
+               if (!wl->dev_irq_num &&
+                   wl->hif_func->disable_interrupt) {
+
+                       PRINT_D(INIT_DBG, "Disabling IRQ 2\n");
+
+                       mutex_lock(&wl->hif_cs);
+                       wl->hif_func->disable_interrupt(wl);
+                       mutex_unlock(&wl->hif_cs);
+               }
 #endif
 
                PRINT_D(INIT_DBG, "Deinitializing Locks\n");
@@ -839,13 +792,13 @@ void wilc1000_wlan_deinit(struct net_device *dev)
        }
 }
 
-int wlan_init_locks(struct net_device *dev)
+static int wlan_init_locks(struct net_device *dev)
 {
-       perInterface_wlan_t *nic;
+       struct wilc_vif *vif;
        struct wilc *wl;
 
-       nic = netdev_priv(dev);
-       wl = nic->wilc;
+       vif = netdev_priv(dev);
+       wl = vif->wilc;
 
        PRINT_D(INIT_DBG, "Initializing Locks ...\n");
 
@@ -867,11 +820,11 @@ int wlan_init_locks(struct net_device *dev)
 
 static int wlan_deinit_locks(struct net_device *dev)
 {
-       perInterface_wlan_t *nic;
+       struct wilc_vif *vif;
        struct wilc *wilc;
 
-       nic = netdev_priv(dev);
-       wilc = nic->wilc;
+       vif = netdev_priv(dev);
+       wilc = vif->wilc;
 
        PRINT_D(INIT_DBG, "De-Initializing Locks\n");
 
@@ -884,24 +837,13 @@ static int wlan_deinit_locks(struct net_device *dev)
        return 0;
 }
 
-void linux_to_wlan(wilc_wlan_inp_t *nwi, struct wilc *nic)
+static int wlan_initialize_threads(struct net_device *dev)
 {
-       PRINT_D(INIT_DBG, "Linux to Wlan services ...\n");
-
-#ifdef WILC_SDIO
-       nwi->io_func.io_type = HIF_SDIO;
-#else
-       nwi->io_func.io_type = HIF_SPI;
-#endif
-}
-
-int wlan_initialize_threads(struct net_device *dev)
-{
-       perInterface_wlan_t *nic;
+       struct wilc_vif *vif;
        struct wilc *wilc;
 
-       nic = netdev_priv(dev);
-       wilc = nic->wilc;
+       vif = netdev_priv(dev);
+       wilc = vif->wilc;
 
        PRINT_D(INIT_DBG, "Initializing Threads ...\n");
        PRINT_D(INIT_DBG, "Creating kthread for transmission\n");
@@ -919,11 +861,10 @@ int wlan_initialize_threads(struct net_device *dev)
 
 static void wlan_deinitialize_threads(struct net_device *dev)
 {
-       perInterface_wlan_t *nic;
+       struct wilc_vif *vif;
        struct wilc *wl;
-
-       nic = netdev_priv(dev);
-       wl = nic->wilc;
+       vif = netdev_priv(dev);
+       wl = vif->wilc;
 
        wl->close = 1;
        PRINT_D(INIT_DBG, "Deinitializing Threads\n");
@@ -937,12 +878,10 @@ static void wlan_deinitialize_threads(struct net_device *dev)
        }
 }
 
-int wilc1000_wlan_init(struct net_device *dev, perInterface_wlan_t *p_nic)
+int wilc1000_wlan_init(struct net_device *dev, struct wilc_vif *vif)
 {
-       wilc_wlan_inp_t nwi;
-       perInterface_wlan_t *nic = p_nic;
        int ret = 0;
-       struct wilc *wl = nic->wilc;
+       struct wilc *wl = vif->wilc;
 
        if (!wl->initialized) {
                wl->mac_status = WILC_MAC_STATUS_INIT;
@@ -950,22 +889,18 @@ int wilc1000_wlan_init(struct net_device *dev, perInterface_wlan_t *p_nic)
 
                wlan_init_locks(dev);
 
-               linux_to_wlan(&nwi, wl);
-
-               ret = wilc_wlan_init(dev, &nwi);
+               ret = wilc_wlan_init(dev);
                if (ret < 0) {
                        PRINT_ER("Initializing WILC_Wlan FAILED\n");
                        ret = -EIO;
                        goto _fail_locks_;
                }
 
-#if (!defined WILC_SDIO) || (defined WILC_SDIO_IRQ_GPIO)
-               if (init_irq(dev)) {
+               if (wl->gpio >= 0 && init_irq(dev)) {
                        PRINT_ER("couldn't initialize IRQ\n");
                        ret = -EIO;
                        goto _fail_locks_;
                }
-#endif
 
                ret = wlan_initialize_threads(dev);
                if (ret < 0) {
@@ -974,21 +909,21 @@ int wilc1000_wlan_init(struct net_device *dev, perInterface_wlan_t *p_nic)
                        goto _fail_wilc_wlan_;
                }
 
-#if (defined WILC_SDIO) && (!defined WILC_SDIO_IRQ_GPIO)
-               if (enable_sdio_interrupt()) {
+               if (!wl->dev_irq_num &&
+                   wl->hif_func->enable_interrupt &&
+                   wl->hif_func->enable_interrupt(wl)) {
                        PRINT_ER("couldn't initialize IRQ\n");
                        ret = -EIO;
                        goto _fail_irq_init_;
                }
-#endif
 
-               if (linux_wlan_get_firmware(dev)) {
+               if (wilc_wlan_get_firmware(dev)) {
                        PRINT_ER("Can't get firmware\n");
                        ret = -EIO;
                        goto _fail_irq_enable_;
                }
 
-               ret = linux_wlan_firmware_download(dev);
+               ret = wilc1000_firmware_download(dev);
                if (ret < 0) {
                        PRINT_ER("Failed to download firmware\n");
                        ret = -EIO;
@@ -1002,9 +937,7 @@ int wilc1000_wlan_init(struct net_device *dev, perInterface_wlan_t *p_nic)
                        goto _fail_irq_enable_;
                }
 
-               wilc_bus_set_max_speed();
-
-               if (wilc_wlan_cfg_get(1, WID_FIRMWARE_VERSION, 1, 0)) {
+               if (wilc_wlan_cfg_get(wl, 1, WID_FIRMWARE_VERSION, 1, 0)) {
                        int size;
                        char Firmware_ver[20];
 
@@ -1026,17 +959,16 @@ int wilc1000_wlan_init(struct net_device *dev, perInterface_wlan_t *p_nic)
                return 0;
 
 _fail_fw_start_:
-               wilc_wlan_stop();
+               wilc_wlan_stop(wl);
 
 _fail_irq_enable_:
-#if (defined WILC_SDIO) && (!defined WILC_SDIO_IRQ_GPIO)
-               disable_sdio_interrupt();
+               if (!wl->dev_irq_num &&
+                   wl->hif_func->disable_interrupt)
+                       wl->hif_func->disable_interrupt(wl);
 _fail_irq_init_:
-#endif
-#if (!defined WILC_SDIO) || (defined WILC_SDIO_IRQ_GPIO)
-               deinit_irq(dev);
+               if (wl->dev_irq_num)
+                       deinit_irq(dev);
 
-#endif
                wlan_deinitialize_threads(dev);
 _fail_wilc_wlan_:
                wilc_wlan_cleanup(dev);
@@ -1049,7 +981,7 @@ _fail_locks_:
        return ret;
 }
 
-int mac_init_fn(struct net_device *ndev)
+static int mac_init_fn(struct net_device *ndev)
 {
        netif_start_queue(ndev);
        netif_stop_queue(ndev);
@@ -1057,9 +989,10 @@ int mac_init_fn(struct net_device *ndev)
        return 0;
 }
 
-int mac_open(struct net_device *ndev)
+int wilc_mac_open(struct net_device *ndev)
 {
-       perInterface_wlan_t *nic;
+       struct wilc_vif *vif;
+       struct wilc *wilc;
 
        unsigned char mac_add[ETH_ALEN] = {0};
        int ret = 0;
@@ -1067,17 +1000,17 @@ int mac_open(struct net_device *ndev)
        struct wilc_priv *priv;
        struct wilc *wl;
 
-       nic = netdev_priv(ndev);
-       wl = nic->wilc;
+       vif = netdev_priv(ndev);
+       wl = vif->wilc;
 
-#ifdef WILC_SPI
-       if (!wl || !wl->wilc_spidev) {
+       if (!wl|| !wl->dev) {
                netdev_err(ndev, "wilc1000: SPI device not ready\n");
                return -ENODEV;
        }
-#endif
-       nic = netdev_priv(ndev);
-       priv = wiphy_priv(nic->wilc_netdev->ieee80211_ptr->wiphy);
+
+       vif = netdev_priv(ndev);
+       wilc = vif->wilc;
+       priv = wiphy_priv(vif->ndev->ieee80211_ptr->wiphy);
        PRINT_D(INIT_DBG, "MAC OPEN[%p]\n", ndev);
 
        ret = wilc_init_host_int(ndev);
@@ -1088,27 +1021,26 @@ int mac_open(struct net_device *ndev)
        }
 
        PRINT_D(INIT_DBG, "*** re-init ***\n");
-       ret = wilc1000_wlan_init(ndev, nic);
+       ret = wilc1000_wlan_init(ndev, vif);
        if (ret < 0) {
                PRINT_ER("Failed to initialize wilc1000\n");
                wilc_deinit_host_int(ndev);
                return ret;
        }
 
-       set_machw_change_vir_if(ndev, false);
+       wilc_set_machw_change_vir_if(ndev, false);
 
-       hif_get_mac_address(priv->hWILCWFIDrv, mac_add);
+       wilc_get_mac_address(vif, mac_add);
        PRINT_D(INIT_DBG, "Mac address: %pM\n", mac_add);
 
        for (i = 0; i < wl->vif_num; i++) {
-               if (ndev == wl->vif[i].ndev) {
-                       memcpy(wl->vif[i].src_addr, mac_add, ETH_ALEN);
-                       wl->vif[i].hif_drv = priv->hWILCWFIDrv;
+               if (ndev == wl->vif[i]->ndev) {
+                       memcpy(wl->vif[i]->src_addr, mac_add, ETH_ALEN);
                        break;
                }
        }
 
-       memcpy(ndev->dev_addr, wl->vif[i].src_addr, ETH_ALEN);
+       memcpy(ndev->dev_addr, wl->vif[i]->src_addr, ETH_ALEN);
 
        if (!is_valid_ether_addr(ndev->dev_addr)) {
                PRINT_ER("Error: Wrong MAC address\n");
@@ -1117,25 +1049,25 @@ int mac_open(struct net_device *ndev)
                return -EINVAL;
        }
 
-       wilc_mgmt_frame_register(nic->wilc_netdev->ieee80211_ptr->wiphy,
-                                nic->wilc_netdev->ieee80211_ptr,
-                                nic->g_struct_frame_reg[0].frame_type,
-                                nic->g_struct_frame_reg[0].reg);
-       wilc_mgmt_frame_register(nic->wilc_netdev->ieee80211_ptr->wiphy,
-                                nic->wilc_netdev->ieee80211_ptr,
-                                nic->g_struct_frame_reg[1].frame_type,
-                                nic->g_struct_frame_reg[1].reg);
+       wilc_mgmt_frame_register(vif->ndev->ieee80211_ptr->wiphy,
+                                vif->ndev->ieee80211_ptr,
+                                vif->g_struct_frame_reg[0].frame_type,
+                                vif->g_struct_frame_reg[0].reg);
+       wilc_mgmt_frame_register(vif->ndev->ieee80211_ptr->wiphy,
+                                vif->ndev->ieee80211_ptr,
+                                vif->g_struct_frame_reg[1].frame_type,
+                                vif->g_struct_frame_reg[1].reg);
        netif_wake_queue(ndev);
        wl->open_ifcs++;
-       nic->mac_opened = 1;
+       vif->mac_opened = 1;
        return 0;
 }
 
-struct net_device_stats *mac_stats(struct net_device *dev)
+static struct net_device_stats *mac_stats(struct net_device *dev)
 {
-       perInterface_wlan_t *nic = netdev_priv(dev);
+       struct wilc_vif *vif= netdev_priv(dev);
 
-       return &nic->netstats;
+       return &vif->netstats;
 }
 
 static void wilc_set_multicast_list(struct net_device *dev)
@@ -1143,9 +1075,11 @@ static void wilc_set_multicast_list(struct net_device *dev)
        struct netdev_hw_addr *ha;
        struct wilc_priv *priv;
        struct host_if_drv *hif_drv;
+       struct wilc_vif *vif;
        int i = 0;
 
        priv = wiphy_priv(dev->ieee80211_ptr->wiphy);
+       vif = netdev_priv(dev);
        hif_drv = (struct host_if_drv *)priv->hWILCWFIDrv;
 
        if (!dev)
@@ -1162,29 +1096,29 @@ static void wilc_set_multicast_list(struct net_device *dev)
        if ((dev->flags & IFF_ALLMULTI) ||
            (dev->mc.count) > WILC_MULTICAST_TABLE_SIZE) {
                PRINT_D(INIT_DBG, "Disable multicast filter, retrive all multicast packets\n");
-               host_int_setup_multicast_filter(hif_drv, false, 0);
+               wilc_setup_multicast_filter(vif, false, 0);
                return;
        }
 
        if ((dev->mc.count) == 0) {
                PRINT_D(INIT_DBG, "Enable multicast filter, retrive directed packets only.\n");
-               host_int_setup_multicast_filter(hif_drv, true, 0);
+               wilc_setup_multicast_filter(vif, true, 0);
                return;
        }
 
        netdev_for_each_mc_addr(ha, dev) {
-               memcpy(multicast_mac_addr_list[i], ha->addr, ETH_ALEN);
+               memcpy(wilc_multicast_mac_addr_list[i], ha->addr, ETH_ALEN);
                PRINT_D(INIT_DBG, "Entry[%d]: %x:%x:%x:%x:%x:%x\n", i,
-                       multicast_mac_addr_list[i][0],
-                       multicast_mac_addr_list[i][1],
-                       multicast_mac_addr_list[i][2],
-                       multicast_mac_addr_list[i][3],
-                       multicast_mac_addr_list[i][4],
-                       multicast_mac_addr_list[i][5]);
+                       wilc_multicast_mac_addr_list[i][0],
+                       wilc_multicast_mac_addr_list[i][1],
+                       wilc_multicast_mac_addr_list[i][2],
+                       wilc_multicast_mac_addr_list[i][3],
+                       wilc_multicast_mac_addr_list[i][4],
+                       wilc_multicast_mac_addr_list[i][5]);
                i++;
        }
 
-       host_int_setup_multicast_filter(hif_drv, true, (dev->mc.count));
+       wilc_setup_multicast_filter(vif, true, (dev->mc.count));
 
        return;
 }
@@ -1201,9 +1135,9 @@ static void linux_wlan_tx_complete(void *priv, int status)
        kfree(pv_data);
 }
 
-int mac_xmit(struct sk_buff *skb, struct net_device *ndev)
+int wilc_mac_xmit(struct sk_buff *skb, struct net_device *ndev)
 {
-       perInterface_wlan_t *nic;
+       struct wilc_vif *vif;
        struct tx_complete_data *tx_data = NULL;
        int queue_count;
        char *udp_buf;
@@ -1211,8 +1145,8 @@ int mac_xmit(struct sk_buff *skb, struct net_device *ndev)
        struct ethhdr *eth_h;
        struct wilc *wilc;
 
-       nic = netdev_priv(ndev);
-       wilc = nic->wilc;
+       vif = netdev_priv(ndev);
+       wilc = vif->wilc;
 
        PRINT_D(TX_DBG, "Sending packet just received from TCP/IP\n");
 
@@ -1247,38 +1181,38 @@ int mac_xmit(struct sk_buff *skb, struct net_device *ndev)
 
        PRINT_D(TX_DBG, "Sending packet - Size = %d - Address = %p - SKB = %p\n", tx_data->size, tx_data->buff, tx_data->skb);
        PRINT_D(TX_DBG, "Adding tx packet to TX Queue\n");
-       nic->netstats.tx_packets++;
-       nic->netstats.tx_bytes += tx_data->size;
-       tx_data->pBssid = wilc->vif[nic->u8IfIdx].bssid;
+       vif->netstats.tx_packets++;
+       vif->netstats.tx_bytes += tx_data->size;
+       tx_data->pBssid = wilc->vif[vif->u8IfIdx]->bssid;
        queue_count = wilc_wlan_txq_add_net_pkt(ndev, (void *)tx_data,
                                                tx_data->buff, tx_data->size,
                                                linux_wlan_tx_complete);
 
        if (queue_count > FLOW_CONTROL_UPPER_THRESHOLD) {
-               netif_stop_queue(wilc->vif[0].ndev);
-               netif_stop_queue(wilc->vif[1].ndev);
+               netif_stop_queue(wilc->vif[0]->ndev);
+               netif_stop_queue(wilc->vif[1]->ndev);
        }
 
        return 0;
 }
 
-int mac_close(struct net_device *ndev)
+int wilc_mac_close(struct net_device *ndev)
 {
        struct wilc_priv *priv;
-       perInterface_wlan_t *nic;
+       struct wilc_vif *vif;
        struct host_if_drv *hif_drv;
        struct wilc *wl;
 
-       nic = netdev_priv(ndev);
+       vif = netdev_priv(ndev);
 
-       if (!nic || !nic->wilc_netdev || !nic->wilc_netdev->ieee80211_ptr ||
-           !nic->wilc_netdev->ieee80211_ptr->wiphy) {
-               PRINT_ER("nic = NULL\n");
+       if (!vif || !vif->ndev || !vif->ndev->ieee80211_ptr ||
+           !vif->ndev->ieee80211_ptr->wiphy) {
+               PRINT_ER("vif = NULL\n");
                return 0;
        }
 
-       priv = wiphy_priv(nic->wilc_netdev->ieee80211_ptr->wiphy);
-       wl = nic->wilc;
+       priv = wiphy_priv(vif->ndev->ieee80211_ptr->wiphy);
+       wl = vif->wilc;
 
        if (!priv) {
                PRINT_ER("priv = NULL\n");
@@ -1306,10 +1240,10 @@ int mac_close(struct net_device *ndev)
                return 0;
        }
 
-       if (nic->wilc_netdev) {
-               netif_stop_queue(nic->wilc_netdev);
+       if (vif->ndev) {
+               netif_stop_queue(vif->ndev);
 
-               wilc_deinit_host_int(nic->wilc_netdev);
+               wilc_deinit_host_int(vif->ndev);
        }
 
        if (wl->open_ifcs == 0) {
@@ -1320,23 +1254,23 @@ int mac_close(struct net_device *ndev)
        }
 
        up(&close_exit_sync);
-       nic->mac_opened = 0;
+       vif->mac_opened = 0;
 
        return 0;
 }
 
-int mac_ioctl(struct net_device *ndev, struct ifreq *req, int cmd)
+static int mac_ioctl(struct net_device *ndev, struct ifreq *req, int cmd)
 {
        u8 *buff = NULL;
        s8 rssi;
        u32 size = 0, length = 0;
-       perInterface_wlan_t *nic;
+       struct wilc_vif *vif;
        struct wilc_priv *priv;
        s32 ret = 0;
        struct wilc *wilc;
 
-       nic = netdev_priv(ndev);
-       wilc = nic->wilc;
+       vif = netdev_priv(ndev);
+       wilc = vif->wilc;
 
        if (!wilc->initialized)
                return 0;
@@ -1355,9 +1289,8 @@ int mac_ioctl(struct net_device *ndev, struct ifreq *req, int cmd)
                                return PTR_ERR(buff);
 
                        if (strncasecmp(buff, "RSSI", length) == 0) {
-                               priv = wiphy_priv(nic->wilc_netdev->ieee80211_ptr->wiphy);
-                               ret = host_int_get_rssi(priv->hWILCWFIDrv,
-                                                       &rssi);
+                               priv = wiphy_priv(vif->ndev->ieee80211_ptr->wiphy);
+                               ret = wilc_get_rssi(vif, &rssi);
                                if (ret)
                                        PRINT_ER("Failed to send get rssi param's message queue ");
                                PRINT_INFO(GENERIC_DBG, "RSSI :%d\n", rssi);
@@ -1391,21 +1324,21 @@ done:
        return ret;
 }
 
-void frmw_to_linux(struct wilc *wilc, u8 *buff, u32 size, u32 pkt_offset)
+void wilc_frmw_to_linux(struct wilc *wilc, u8 *buff, u32 size, u32 pkt_offset)
 {
        unsigned int frame_len = 0;
        int stats;
        unsigned char *buff_to_send = NULL;
        struct sk_buff *skb;
        struct net_device *wilc_netdev;
-       perInterface_wlan_t *nic;
+       struct wilc_vif *vif;
 
        wilc_netdev = get_if_handler(wilc, buff);
        if (!wilc_netdev)
                return;
 
        buff += pkt_offset;
-       nic = netdev_priv(wilc_netdev);
+       vif = netdev_priv(wilc_netdev);
 
        if (size > 0) {
                frame_len = size;
@@ -1427,8 +1360,8 @@ void frmw_to_linux(struct wilc *wilc, u8 *buff, u32 size, u32 pkt_offset)
                memcpy(skb_put(skb, frame_len), buff_to_send, frame_len);
 
                skb->protocol = eth_type_trans(skb, wilc_netdev);
-               nic->netstats.rx_packets++;
-               nic->netstats.rx_bytes += frame_len;
+               vif->netstats.rx_packets++;
+               vif->netstats.rx_bytes += frame_len;
                skb->ip_summed = CHECKSUM_UNNECESSARY;
                stats = netif_rx(skb);
                PRINT_D(RX_DBG, "netif_rx ret value is: %d\n", stats);
@@ -1438,119 +1371,118 @@ void frmw_to_linux(struct wilc *wilc, u8 *buff, u32 size, u32 pkt_offset)
 void WILC_WFI_mgmt_rx(struct wilc *wilc, u8 *buff, u32 size)
 {
        int i = 0;
-       perInterface_wlan_t *nic;
+       struct wilc_vif *vif;
 
        for (i = 0; i < wilc->vif_num; i++) {
-               nic = netdev_priv(wilc->vif[i].ndev);
-               if (nic->monitor_flag) {
+               vif = netdev_priv(wilc->vif[i]->ndev);
+               if (vif->monitor_flag) {
                        WILC_WFI_monitor_rx(buff, size);
                        return;
                }
        }
 
-       nic = netdev_priv(wilc->vif[1].ndev);
-       if ((buff[0] == nic->g_struct_frame_reg[0].frame_type && nic->g_struct_frame_reg[0].reg) ||
-           (buff[0] == nic->g_struct_frame_reg[1].frame_type && nic->g_struct_frame_reg[1].reg))
-               WILC_WFI_p2p_rx(wilc->vif[1].ndev, buff, size);
+       vif = netdev_priv(wilc->vif[1]->ndev);
+       if ((buff[0] == vif->g_struct_frame_reg[0].frame_type && vif->g_struct_frame_reg[0].reg) ||
+           (buff[0] == vif->g_struct_frame_reg[1].frame_type && vif->g_struct_frame_reg[1].reg))
+               WILC_WFI_p2p_rx(wilc->vif[1]->ndev, buff, size);
 }
 
-void wl_wlan_cleanup(struct wilc *wilc)
+void wilc_netdev_cleanup(struct wilc *wilc)
 {
        int i = 0;
-       perInterface_wlan_t *nic[NUM_CONCURRENT_IFC];
+       struct wilc_vif *vif[NUM_CONCURRENT_IFC];
 
-       if (wilc && (wilc->vif[0].ndev || wilc->vif[1].ndev)) {
+       if (wilc && (wilc->vif[0]->ndev || wilc->vif[1]->ndev)) {
                unregister_inetaddr_notifier(&g_dev_notifier);
 
                for (i = 0; i < NUM_CONCURRENT_IFC; i++)
-                       nic[i] = netdev_priv(wilc->vif[i].ndev);
+                       vif[i] = netdev_priv(wilc->vif[i]->ndev);
        }
 
        if (wilc && wilc->firmware)
                release_firmware(wilc->firmware);
 
-       if (wilc && (wilc->vif[0].ndev || wilc->vif[1].ndev)) {
-               linux_wlan_lock_timeout(&close_exit_sync, 12 * 1000);
+       if (wilc && (wilc->vif[0]->ndev || wilc->vif[1]->ndev)) {
+               wilc_lock_timeout(wilc, &close_exit_sync, 12 * 1000);
 
                for (i = 0; i < NUM_CONCURRENT_IFC; i++)
-                       if (wilc->vif[i].ndev)
-                               if (nic[i]->mac_opened)
-                                       mac_close(wilc->vif[i].ndev);
+                       if (wilc->vif[i]->ndev)
+                               if (vif[i]->mac_opened)
+                                       wilc_mac_close(wilc->vif[i]->ndev);
 
                for (i = 0; i < NUM_CONCURRENT_IFC; i++) {
-                       unregister_netdev(wilc->vif[i].ndev);
-                       wilc_free_wiphy(wilc->vif[i].ndev);
-                       free_netdev(wilc->vif[i].ndev);
+                       unregister_netdev(wilc->vif[i]->ndev);
+                       wilc_free_wiphy(wilc->vif[i]->ndev);
+                       free_netdev(wilc->vif[i]->ndev);
                }
        }
 
        kfree(wilc);
-
-#if defined(WILC_DEBUGFS)
-       wilc_debugfs_remove();
-#endif
-       linux_wlan_device_detection(0);
-       linux_wlan_device_power(0);
 }
+EXPORT_SYMBOL_GPL(wilc_netdev_cleanup);
 
-int wilc_netdev_init(struct wilc **wilc)
+int wilc_netdev_init(struct wilc **wilc, struct device *dev, int io_type,
+                    int gpio, const struct wilc_hif_func *ops)
 {
        int i;
-       perInterface_wlan_t *nic;
+       struct wilc_vif *vif;
        struct net_device *ndev;
+       struct wilc *wl;
 
        sema_init(&close_exit_sync, 0);
 
-       g_linux_wlan = kzalloc(sizeof(*g_linux_wlan), GFP_KERNEL);
-       if (!g_linux_wlan)
+       wl = kzalloc(sizeof(*wl), GFP_KERNEL);
+       if (!wl)
                return -ENOMEM;
 
-       *wilc = g_linux_wlan;
+       *wilc = wl;
+       wl->io_type = io_type;
+       wl->gpio = gpio;
+       wl->hif_func = ops;
 
        register_inetaddr_notifier(&g_dev_notifier);
 
        for (i = 0; i < NUM_CONCURRENT_IFC; i++) {
-               ndev = alloc_etherdev(sizeof(perInterface_wlan_t));
+               ndev = alloc_etherdev(sizeof(struct wilc_vif));
                if (!ndev) {
                        PRINT_ER("Failed to allocate ethernet dev\n");
                        return -1;
                }
 
-               nic = netdev_priv(ndev);
-               memset(nic, 0, sizeof(perInterface_wlan_t));
+               vif = netdev_priv(ndev);
+               memset(vif, 0, sizeof(struct wilc_vif));
 
                if (i == 0)
                        strcpy(ndev->name, "wlan%d");
                else
                        strcpy(ndev->name, "p2p%d");
 
-               nic->u8IfIdx = g_linux_wlan->vif_num;
-               nic->wilc_netdev = ndev;
-               nic->wilc = *wilc;
-               g_linux_wlan->vif[g_linux_wlan->vif_num].ndev = ndev;
-               g_linux_wlan->vif_num++;
+               vif->u8IfIdx = wl->vif_num;
+               vif->wilc = *wilc;
+               wl->vif[i] = vif;
+               wl->vif[wl->vif_num]->ndev = ndev;
+               wl->vif_num++;
                ndev->netdev_ops = &wilc_netdev_ops;
 
                {
                        struct wireless_dev *wdev;
-                       wdev = wilc_create_wiphy(ndev);
+                       wdev = wilc_create_wiphy(ndev, dev);
 
-                       #ifdef WILC_SDIO
-                       SET_NETDEV_DEV(ndev, &local_sdio_func->dev);
-                       #endif
+                       if (dev)
+                               SET_NETDEV_DEV(ndev, dev);
 
                        if (!wdev) {
                                PRINT_ER("Can't register WILC Wiphy\n");
                                return -1;
                        }
 
-                       nic->wilc_netdev->ieee80211_ptr = wdev;
-                       nic->wilc_netdev->ml_priv = nic;
-                       wdev->netdev = nic->wilc_netdev;
-                       nic->netstats.rx_packets = 0;
-                       nic->netstats.tx_packets = 0;
-                       nic->netstats.rx_bytes = 0;
-                       nic->netstats.tx_bytes = 0;
+                       vif->ndev->ieee80211_ptr = wdev;
+                       vif->ndev->ml_priv = vif;
+                       wdev->netdev = vif->ndev;
+                       vif->netstats.rx_packets = 0;
+                       vif->netstats.tx_packets = 0;
+                       vif->netstats.rx_bytes = 0;
+                       vif->netstats.tx_bytes = 0;
                }
 
                if (register_netdev(ndev)) {
@@ -1559,72 +1491,12 @@ int wilc_netdev_init(struct wilc **wilc)
                        return -1;
                }
 
-               nic->iftype = STATION_MODE;
-               nic->mac_opened = 0;
-       }
-
-       #ifndef WILC_SDIO
-       if (!linux_spi_init()) {
-               PRINT_ER("Can't initialize SPI\n");
-               return -1;
+               vif->iftype = STATION_MODE;
+               vif->mac_opened = 0;
        }
-       g_linux_wlan->wilc_spidev = wilc_spi_dev;
-       #else
-       g_linux_wlan->wilc_sdio_func = local_sdio_func;
-       #endif
 
        return 0;
 }
-
-static int __init init_wilc_driver(void)
-{
-#ifdef WILC_SPI
-       struct wilc *wilc;
-#endif
-
-#if defined(WILC_DEBUGFS)
-       if (wilc_debugfs_init() < 0) {
-               PRINT_D(GENERIC_DBG, "fail to create debugfs for wilc driver\n");
-               return -1;
-       }
-#endif
-
-       printk("IN INIT FUNCTION\n");
-       printk("*** WILC1000 driver VERSION=[10.2] FW_VER=[10.2] ***\n");
-
-       linux_wlan_device_power(1);
-       msleep(100);
-       linux_wlan_device_detection(1);
-
-#ifdef WILC_SDIO
-       {
-               int ret;
-
-               ret = sdio_register_driver(&wilc_bus);
-               if (ret < 0)
-                       PRINT_D(INIT_DBG, "init_wilc_driver: Failed register sdio driver\n");
-
-               return ret;
-       }
-#else
-       PRINT_D(INIT_DBG, "Initializing netdev\n");
-       if (wilc_netdev_init(&wilc))
-               PRINT_ER("Couldn't initialize netdev\n");
-       return 0;
-#endif
-}
-late_initcall(init_wilc_driver);
-
-static void __exit exit_wilc_driver(void)
-{
-#ifndef WILC_SDIO
-       PRINT_D(INIT_DBG, "SPI unregister...\n");
-       spi_unregister_driver(&wilc_bus);
-#else
-       PRINT_D(INIT_DBG, "SDIO unregister...\n");
-       sdio_unregister_driver(&wilc_bus);
-#endif
-}
-module_exit(exit_wilc_driver);
+EXPORT_SYMBOL_GPL(wilc_netdev_init);
 
 MODULE_LICENSE("GPL");
index 2b76e41ebd4d506ec0fc85002b51acaa6a98b5ed..5d40f05124c1cdecbdf76a05d926529ce5e32ad4 100644 (file)
@@ -38,11 +38,8 @@ enum debug_region {
 #define FIRM_DBG                (1 << Firmware_debug)
 
 #if defined (WILC_DEBUGFS)
-int wilc_debugfs_init(void);
-void wilc_debugfs_remove(void);
-
-extern atomic_t REGION;
-extern atomic_t DEBUG_LEVEL;
+extern atomic_t WILC_REGION;
+extern atomic_t WILC_DEBUG_LEVEL;
 
 #define DEBUG           BIT(0)
 #define INFO            BIT(1)
@@ -51,8 +48,8 @@ extern atomic_t DEBUG_LEVEL;
 
 #define PRINT_D(region, ...)                                           \
        do {                                                            \
-               if ((atomic_read(&DEBUG_LEVEL) & DEBUG) &&              \
-                  ((atomic_read(&REGION)) & (region))) {               \
+               if ((atomic_read(&WILC_DEBUG_LEVEL) & DEBUG) && \
+                  ((atomic_read(&WILC_REGION)) & (region))) {  \
                        printk("DBG [%s: %d]", __func__, __LINE__);     \
                        printk(__VA_ARGS__);                            \
                }                                                       \
@@ -60,8 +57,8 @@ extern atomic_t DEBUG_LEVEL;
 
 #define PRINT_INFO(region, ...)                                                \
        do {                                                            \
-               if ((atomic_read(&DEBUG_LEVEL) & INFO) &&               \
-                  ((atomic_read(&REGION)) & (region))) {               \
+               if ((atomic_read(&WILC_DEBUG_LEVEL) & INFO) &&  \
+                  ((atomic_read(&WILC_REGION)) & (region))) {  \
                        printk("INFO [%s]", __func__);                  \
                        printk(__VA_ARGS__);                            \
                }                                                       \
@@ -69,8 +66,8 @@ extern atomic_t DEBUG_LEVEL;
 
 #define PRINT_WRN(region, ...)                                         \
        do {                                                            \
-               if ((atomic_read(&DEBUG_LEVEL) & WRN) &&                \
-                  ((atomic_read(&REGION)) & (region))) {               \
+               if ((atomic_read(&WILC_DEBUG_LEVEL) & WRN) &&   \
+                  ((atomic_read(&WILC_REGION)) & (region))) {  \
                        printk("WRN [%s: %d]", __func__, __LINE__);     \
                        printk(__VA_ARGS__);                            \
                }                                                       \
@@ -78,7 +75,7 @@ extern atomic_t DEBUG_LEVEL;
 
 #define PRINT_ER(...)                                                  \
        do {                                                            \
-               if ((atomic_read(&DEBUG_LEVEL) & ERR)) {                \
+               if ((atomic_read(&WILC_DEBUG_LEVEL) & ERR)) {   \
                        printk("ERR [%s: %d]", __func__, __LINE__);     \
                        printk(__VA_ARGS__);                            \
                }                                                       \
@@ -121,14 +118,13 @@ extern atomic_t DEBUG_LEVEL;
                printk("ERR [%s: %d]", __func__, __LINE__);             \
                printk(__VA_ARGS__);                                    \
        } while (0)
+
 #endif
 
 #define FN_IN   /* PRINT_D(">>> \n") */
 #define FN_OUT  /* PRINT_D("<<<\n") */
 
-#ifdef MEMORY_STATIC
 #define LINUX_RX_SIZE  (96 * 1024)
-#endif
 #define LINUX_TX_SIZE  (64 * 1024)
 
 
diff --git a/drivers/staging/wilc1000/linux_wlan_sdio.c b/drivers/staging/wilc1000/linux_wlan_sdio.c
deleted file mode 100644 (file)
index e854d37..0000000
+++ /dev/null
@@ -1,251 +0,0 @@
-#include "wilc_wfi_netdevice.h"
-
-#include <linux/mmc/sdio_func.h>
-#include <linux/mmc/card.h>
-#include <linux/mmc/sdio_ids.h>
-#include <linux/mmc/sdio.h>
-#include <linux/mmc/host.h>
-
-
-
-#define SDIO_MODALIAS "wilc1000_sdio"
-
-#if defined(CUSTOMER_PLATFORM)
-/* TODO : User have to stable bus clock as user's environment. */
- #ifdef MAX_BUS_SPEED
- #define MAX_SPEED MAX_BUS_SPEED
- #else
- #define MAX_SPEED 50000000
- #endif
-#else
- #define MAX_SPEED (6 * 1000000) /* Max 50M */
-#endif
-
-struct wilc_sdio {
-       struct sdio_func *func;
-       struct wilc *wilc;
-};
-
-struct sdio_func *local_sdio_func;
-
-static unsigned int sdio_default_speed;
-
-#define SDIO_VENDOR_ID_WILC 0x0296
-#define SDIO_DEVICE_ID_WILC 0x5347
-
-static const struct sdio_device_id wilc_sdio_ids[] = {
-       { SDIO_DEVICE(SDIO_VENDOR_ID_WILC, SDIO_DEVICE_ID_WILC) },
-       { },
-};
-
-
-static void wilc_sdio_interrupt(struct sdio_func *func)
-{
-       struct wilc_sdio *wl_sdio;
-
-       wl_sdio = sdio_get_drvdata(func);
-
-#ifndef WILC_SDIO_IRQ_GPIO
-       sdio_release_host(func);
-       wilc_handle_isr(wl_sdio->wilc);
-       sdio_claim_host(func);
-#endif
-}
-
-
-int linux_sdio_cmd52(sdio_cmd52_t *cmd)
-{
-       struct sdio_func *func = g_linux_wlan->wilc_sdio_func;
-       int ret;
-       u8 data;
-
-       sdio_claim_host(func);
-
-       func->num = cmd->function;
-       if (cmd->read_write) {  /* write */
-               if (cmd->raw) {
-                       sdio_writeb(func, cmd->data, cmd->address, &ret);
-                       data = sdio_readb(func, cmd->address, &ret);
-                       cmd->data = data;
-               } else {
-                       sdio_writeb(func, cmd->data, cmd->address, &ret);
-               }
-       } else {        /* read */
-               data = sdio_readb(func, cmd->address, &ret);
-               cmd->data = data;
-       }
-
-       sdio_release_host(func);
-
-       if (ret < 0) {
-               PRINT_ER("wilc_sdio_cmd52..failed, err(%d)\n", ret);
-               return 0;
-       }
-       return 1;
-}
-
-
-int linux_sdio_cmd53(sdio_cmd53_t *cmd)
-{
-       struct sdio_func *func = g_linux_wlan->wilc_sdio_func;
-       int size, ret;
-
-       sdio_claim_host(func);
-
-       func->num = cmd->function;
-       func->cur_blksize = cmd->block_size;
-       if (cmd->block_mode)
-               size = cmd->count * cmd->block_size;
-       else
-               size = cmd->count;
-
-       if (cmd->read_write) {  /* write */
-               ret = sdio_memcpy_toio(func, cmd->address, (void *)cmd->buffer, size);
-       } else {        /* read */
-               ret = sdio_memcpy_fromio(func, (void *)cmd->buffer, cmd->address,  size);
-       }
-
-       sdio_release_host(func);
-
-
-       if (ret < 0) {
-               PRINT_ER("wilc_sdio_cmd53..failed, err(%d)\n", ret);
-               return 0;
-       }
-
-       return 1;
-}
-
-static int linux_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id)
-{
-       struct wilc_sdio *wl_sdio;
-       struct wilc *wilc;
-
-       PRINT_D(INIT_DBG, "probe function\n");
-       wl_sdio = kzalloc(sizeof(struct wilc_sdio), GFP_KERNEL);
-       if (!wl_sdio)
-               return -ENOMEM;
-
-       PRINT_D(INIT_DBG, "Initializing netdev\n");
-       local_sdio_func = func;
-       if (wilc_netdev_init(&wilc)) {
-               PRINT_ER("Couldn't initialize netdev\n");
-               kfree(wl_sdio);
-               return -1;
-       }
-       wl_sdio->func = func;
-       wl_sdio->wilc = wilc;
-       sdio_set_drvdata(func, wl_sdio);
-
-       printk("Driver Initializing success\n");
-       return 0;
-}
-
-static void linux_sdio_remove(struct sdio_func *func)
-{
-       struct wilc_sdio *wl_sdio;
-
-       wl_sdio = sdio_get_drvdata(func);
-       wl_wlan_cleanup(wl_sdio->wilc);
-       kfree(wl_sdio);
-}
-
-struct sdio_driver wilc_bus = {
-       .name           = SDIO_MODALIAS,
-       .id_table       = wilc_sdio_ids,
-       .probe          = linux_sdio_probe,
-       .remove         = linux_sdio_remove,
-};
-
-int enable_sdio_interrupt(void)
-{
-       int ret = 0;
-#ifndef WILC_SDIO_IRQ_GPIO
-
-       sdio_claim_host(local_sdio_func);
-       ret = sdio_claim_irq(local_sdio_func, wilc_sdio_interrupt);
-       sdio_release_host(local_sdio_func);
-
-       if (ret < 0) {
-               PRINT_ER("can't claim sdio_irq, err(%d)\n", ret);
-               ret = -EIO;
-       }
-#endif
-       return ret;
-}
-
-void disable_sdio_interrupt(void)
-{
-
-#ifndef WILC_SDIO_IRQ_GPIO
-       int ret;
-
-       PRINT_D(INIT_DBG, "disable_sdio_interrupt IN\n");
-
-       sdio_claim_host(local_sdio_func);
-       ret = sdio_release_irq(local_sdio_func);
-       if (ret < 0) {
-               PRINT_ER("can't release sdio_irq, err(%d)\n", ret);
-       }
-       sdio_release_host(local_sdio_func);
-
-       PRINT_D(INIT_DBG, "disable_sdio_interrupt OUT\n");
-#endif
-}
-
-static int linux_sdio_set_speed(int speed)
-{
-       struct mmc_ios ios;
-
-       sdio_claim_host(local_sdio_func);
-
-       memcpy((void *)&ios, (void *)&local_sdio_func->card->host->ios, sizeof(struct mmc_ios));
-       local_sdio_func->card->host->ios.clock = speed;
-       ios.clock = speed;
-       local_sdio_func->card->host->ops->set_ios(local_sdio_func->card->host, &ios);
-       sdio_release_host(local_sdio_func);
-       PRINT_INFO(INIT_DBG, "@@@@@@@@@@@@ change SDIO speed to %d @@@@@@@@@\n", speed);
-
-       return 1;
-}
-
-static int linux_sdio_get_speed(void)
-{
-       return local_sdio_func->card->host->ios.clock;
-}
-
-int linux_sdio_init(void)
-{
-
-       /**
-        *      TODO :
-        **/
-
-
-       sdio_default_speed = linux_sdio_get_speed();
-       return 1;
-}
-
-void linux_sdio_deinit(void *pv)
-{
-
-       /**
-        *      TODO :
-        **/
-
-
-       sdio_unregister_driver(&wilc_bus);
-}
-
-int linux_sdio_set_max_speed(void)
-{
-       return linux_sdio_set_speed(MAX_SPEED);
-}
-
-int linux_sdio_set_default_speed(void)
-{
-       return linux_sdio_set_speed(sdio_default_speed);
-}
-
-
-
diff --git a/drivers/staging/wilc1000/linux_wlan_sdio.h b/drivers/staging/wilc1000/linux_wlan_sdio.h
deleted file mode 100644 (file)
index 6f42bc7..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-extern struct sdio_func *local_sdio_func;
-extern struct sdio_driver wilc_bus;
-
-#include <linux/mmc/sdio_func.h>
-
-int linux_sdio_init(void);
-void linux_sdio_deinit(void *);
-int linux_sdio_cmd52(sdio_cmd52_t *cmd);
-int linux_sdio_cmd53(sdio_cmd53_t *cmd);
-int enable_sdio_interrupt(void);
-void disable_sdio_interrupt(void);
-int linux_sdio_set_max_speed(void);
-int linux_sdio_set_default_speed(void);
-
diff --git a/drivers/staging/wilc1000/linux_wlan_spi.c b/drivers/staging/wilc1000/linux_wlan_spi.c
deleted file mode 100644 (file)
index 73c788f..0000000
+++ /dev/null
@@ -1,409 +0,0 @@
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/fs.h>
-#include <linux/slab.h>
-#include <linux/types.h>
-#include <linux/cdev.h>
-#include <linux/uaccess.h>
-#include <linux/device.h>
-#include <linux/spi/spi.h>
-
-#include "linux_wlan_common.h"
-#include "linux_wlan_spi.h"
-
-#define USE_SPI_DMA     0       /* johnny add */
-
-#ifdef WILC_ASIC_A0
- #if defined(PLAT_PANDA_ES_OMAP4460)
-  #define MIN_SPEED 12000000
-  #define MAX_SPEED 24000000
- #elif defined(PLAT_WMS8304)
-  #define MIN_SPEED 12000000
-  #define MAX_SPEED 24000000 /* 4000000 */
- #elif defined(CUSTOMER_PLATFORM)
-/*
-  TODO : define Clock speed under 48M.
- *
- * ex)
- * #define MIN_SPEED 24000000
- * #define MAX_SPEED 48000000
- */
- #else
-  #define MIN_SPEED 24000000
-  #define MAX_SPEED 48000000
- #endif
-#else /* WILC_ASIC_A0 */
-/* Limit clk to 6MHz on FPGA. */
- #define MIN_SPEED 6000000
- #define MAX_SPEED 6000000
-#endif /* WILC_ASIC_A0 */
-
-static u32 SPEED = MIN_SPEED;
-
-struct spi_device *wilc_spi_dev;
-void linux_spi_deinit(void *vp);
-
-static int __init wilc_bus_probe(struct spi_device *spi)
-{
-
-       PRINT_D(BUS_DBG, "spiModalias: %s\n", spi->modalias);
-       PRINT_D(BUS_DBG, "spiMax-Speed: %d\n", spi->max_speed_hz);
-       wilc_spi_dev = spi;
-
-       printk("Driver Initializing success\n");
-       return 0;
-}
-
-static int __exit wilc_bus_remove(struct spi_device *spi)
-{
-
-       return 0;
-}
-
-#ifdef CONFIG_OF
-static const struct of_device_id wilc1000_of_match[] = {
-       { .compatible = "atmel,wilc_spi", },
-       {}
-};
-MODULE_DEVICE_TABLE(of, wilc1000_of_match);
-#endif
-
-struct spi_driver wilc_bus __refdata = {
-       .driver = {
-               .name = MODALIAS,
-#ifdef CONFIG_OF
-               .of_match_table = wilc1000_of_match,
-#endif
-       },
-       .probe =  wilc_bus_probe,
-       .remove = __exit_p(wilc_bus_remove),
-};
-
-
-void linux_spi_deinit(void *vp)
-{
-
-       spi_unregister_driver(&wilc_bus);
-
-       SPEED = MIN_SPEED;
-       PRINT_ER("@@@@@@@@@@@@ restore SPI speed to %d @@@@@@@@@\n", SPEED);
-
-}
-
-
-
-int linux_spi_init(void)
-{
-       int ret = 1;
-       static int called;
-
-
-       if (called == 0) {
-               called++;
-               ret = spi_register_driver(&wilc_bus);
-       }
-
-       /* change return value to match WILC interface */
-       (ret < 0) ? (ret = 0) : (ret = 1);
-
-       return ret;
-}
-
-#if defined(PLAT_WMS8304)
-#define TXRX_PHASE_SIZE (4096)
-#endif
-
-#if defined(TXRX_PHASE_SIZE)
-
-int linux_spi_write(u8 *b, u32 len)
-{
-       int ret;
-
-       if (len > 0 && b != NULL) {
-               int i = 0;
-               int blk = len / TXRX_PHASE_SIZE;
-               int remainder = len % TXRX_PHASE_SIZE;
-
-               char *r_buffer = kzalloc(TXRX_PHASE_SIZE, GFP_KERNEL);
-               if (!r_buffer)
-                       return -ENOMEM;
-
-               if (blk) {
-                       while (i < blk) {
-                               struct spi_message msg;
-                               struct spi_transfer tr = {
-                                       .tx_buf = b + (i * TXRX_PHASE_SIZE),
-                                       .len = TXRX_PHASE_SIZE,
-                                       .speed_hz = SPEED,
-                                       .bits_per_word = 8,
-                                       .delay_usecs = 0,
-                               };
-
-                               tr.rx_buf = r_buffer;
-
-                               memset(&msg, 0, sizeof(msg));
-                               spi_message_init(&msg);
-                               msg.spi = wilc_spi_dev;
-                               msg.is_dma_mapped = USE_SPI_DMA;
-
-                               spi_message_add_tail(&tr, &msg);
-                               ret = spi_sync(wilc_spi_dev, &msg);
-                               if (ret < 0) {
-                                       PRINT_ER("SPI transaction failed\n");
-                               }
-                               i++;
-
-                       }
-               }
-               if (remainder) {
-                       struct spi_message msg;
-                       struct spi_transfer tr = {
-                               .tx_buf = b + (blk * TXRX_PHASE_SIZE),
-                               .len = remainder,
-                               .speed_hz = SPEED,
-                               .bits_per_word = 8,
-                               .delay_usecs = 0,
-                       };
-                       tr.rx_buf = r_buffer;
-
-                       memset(&msg, 0, sizeof(msg));
-                       spi_message_init(&msg);
-                       msg.spi = wilc_spi_dev;
-                       msg.is_dma_mapped = USE_SPI_DMA;                                /* rachel */
-
-                       spi_message_add_tail(&tr, &msg);
-                       ret = spi_sync(wilc_spi_dev, &msg);
-                       if (ret < 0) {
-                               PRINT_ER("SPI transaction failed\n");
-                       }
-               }
-               kfree(r_buffer);
-       } else {
-               PRINT_ER("can't write data with the following length: %d\n", len);
-               PRINT_ER("FAILED due to NULL buffer or ZERO length check the following length: %d\n", len);
-               ret = -1;
-       }
-
-       /* change return value to match WILC interface */
-       (ret < 0) ? (ret = 0) : (ret = 1);
-
-       return ret;
-
-}
-
-#else
-int linux_spi_write(u8 *b, u32 len)
-{
-
-       int ret;
-       struct spi_message msg;
-
-       if (len > 0 && b != NULL) {
-               struct spi_transfer tr = {
-                       .tx_buf = b,
-                       .len = len,
-                       .speed_hz = SPEED,
-                       .delay_usecs = 0,
-               };
-               char *r_buffer = kzalloc(len, GFP_KERNEL);
-               if (!r_buffer)
-                       return -ENOMEM;
-
-               tr.rx_buf = r_buffer;
-               PRINT_D(BUS_DBG, "Request writing %d bytes\n", len);
-
-               memset(&msg, 0, sizeof(msg));
-               spi_message_init(&msg);
-/* [[johnny add */
-               msg.spi = wilc_spi_dev;
-               msg.is_dma_mapped = USE_SPI_DMA;
-/* ]] */
-               spi_message_add_tail(&tr, &msg);
-
-               ret = spi_sync(wilc_spi_dev, &msg);
-               if (ret < 0) {
-                       PRINT_ER("SPI transaction failed\n");
-               }
-
-               kfree(r_buffer);
-       } else {
-               PRINT_ER("can't write data with the following length: %d\n", len);
-               PRINT_ER("FAILED due to NULL buffer or ZERO length check the following length: %d\n", len);
-               ret = -1;
-       }
-
-       /* change return value to match WILC interface */
-       (ret < 0) ? (ret = 0) : (ret = 1);
-
-
-       return ret;
-}
-
-#endif
-
-#if defined(TXRX_PHASE_SIZE)
-
-int linux_spi_read(u8 *rb, u32 rlen)
-{
-       int ret;
-
-       if (rlen > 0) {
-               int i = 0;
-
-               int blk = rlen / TXRX_PHASE_SIZE;
-               int remainder = rlen % TXRX_PHASE_SIZE;
-
-               char *t_buffer = kzalloc(TXRX_PHASE_SIZE, GFP_KERNEL);
-               if (!t_buffer)
-                       return -ENOMEM;
-
-               if (blk) {
-                       while (i < blk) {
-                               struct spi_message msg;
-                               struct spi_transfer tr = {
-                                       .rx_buf = rb + (i * TXRX_PHASE_SIZE),
-                                       .len = TXRX_PHASE_SIZE,
-                                       .speed_hz = SPEED,
-                                       .bits_per_word = 8,
-                                       .delay_usecs = 0,
-                               };
-                               tr.tx_buf = t_buffer;
-
-                               memset(&msg, 0, sizeof(msg));
-                               spi_message_init(&msg);
-                               msg.spi = wilc_spi_dev;
-                               msg.is_dma_mapped = USE_SPI_DMA;
-
-                               spi_message_add_tail(&tr, &msg);
-                               ret = spi_sync(wilc_spi_dev, &msg);
-                               if (ret < 0) {
-                                       PRINT_ER("SPI transaction failed\n");
-                               }
-                               i++;
-                       }
-               }
-               if (remainder) {
-                       struct spi_message msg;
-                       struct spi_transfer tr = {
-                               .rx_buf = rb + (blk * TXRX_PHASE_SIZE),
-                               .len = remainder,
-                               .speed_hz = SPEED,
-                               .bits_per_word = 8,
-                               .delay_usecs = 0,
-                       };
-                       tr.tx_buf = t_buffer;
-
-                       memset(&msg, 0, sizeof(msg));
-                       spi_message_init(&msg);
-                       msg.spi = wilc_spi_dev;
-                       msg.is_dma_mapped = USE_SPI_DMA;                                /* rachel */
-
-                       spi_message_add_tail(&tr, &msg);
-                       ret = spi_sync(wilc_spi_dev, &msg);
-                       if (ret < 0) {
-                               PRINT_ER("SPI transaction failed\n");
-                       }
-               }
-
-               kfree(t_buffer);
-       } else {
-               PRINT_ER("can't read data with the following length: %u\n", rlen);
-               ret = -1;
-       }
-       /* change return value to match WILC interface */
-       (ret < 0) ? (ret = 0) : (ret = 1);
-
-       return ret;
-}
-
-#else
-int linux_spi_read(u8 *rb, u32 rlen)
-{
-
-       int ret;
-
-       if (rlen > 0) {
-               struct spi_message msg;
-               struct spi_transfer tr = {
-                       .rx_buf = rb,
-                       .len = rlen,
-                       .speed_hz = SPEED,
-                       .delay_usecs = 0,
-
-               };
-               char *t_buffer = kzalloc(rlen, GFP_KERNEL);
-               if (!t_buffer)
-                       return -ENOMEM;
-
-               tr.tx_buf = t_buffer;
-
-               memset(&msg, 0, sizeof(msg));
-               spi_message_init(&msg);
-/* [[ johnny add */
-               msg.spi = wilc_spi_dev;
-               msg.is_dma_mapped = USE_SPI_DMA;
-/* ]] */
-               spi_message_add_tail(&tr, &msg);
-
-               ret = spi_sync(wilc_spi_dev, &msg);
-               if (ret < 0) {
-                       PRINT_ER("SPI transaction failed\n");
-               }
-               kfree(t_buffer);
-       } else {
-               PRINT_ER("can't read data with the following length: %u\n", rlen);
-               ret = -1;
-       }
-       /* change return value to match WILC interface */
-       (ret < 0) ? (ret = 0) : (ret = 1);
-
-       return ret;
-}
-
-#endif
-
-int linux_spi_write_read(u8 *wb, u8 *rb, u32 rlen)
-{
-
-       int ret;
-
-       if (rlen > 0) {
-               struct spi_message msg;
-               struct spi_transfer tr = {
-                       .rx_buf = rb,
-                       .tx_buf = wb,
-                       .len = rlen,
-                       .speed_hz = SPEED,
-                       .bits_per_word = 8,
-                       .delay_usecs = 0,
-
-               };
-
-               memset(&msg, 0, sizeof(msg));
-               spi_message_init(&msg);
-               msg.spi = wilc_spi_dev;
-               msg.is_dma_mapped = USE_SPI_DMA;
-
-               spi_message_add_tail(&tr, &msg);
-               ret = spi_sync(wilc_spi_dev, &msg);
-               if (ret < 0) {
-                       PRINT_ER("SPI transaction failed\n");
-               }
-       } else {
-               PRINT_ER("can't read data with the following length: %u\n", rlen);
-               ret = -1;
-       }
-       /* change return value to match WILC interface */
-       (ret < 0) ? (ret = 0) : (ret = 1);
-
-       return ret;
-}
-
-int linux_spi_set_max_speed(void)
-{
-       SPEED = MAX_SPEED;
-
-       PRINT_INFO(BUS_DBG, "@@@@@@@@@@@@ change SPI speed to %d @@@@@@@@@\n", SPEED);
-       return 1;
-}
diff --git a/drivers/staging/wilc1000/linux_wlan_spi.h b/drivers/staging/wilc1000/linux_wlan_spi.h
deleted file mode 100644 (file)
index b956100..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-#ifndef LINUX_WLAN_SPI_H
-#define LINUX_WLAN_SPI_H
-
-#include <linux/spi/spi.h>
-extern struct spi_device *wilc_spi_dev;
-extern struct spi_driver wilc_bus;
-
-int linux_spi_init(void);
-void linux_spi_deinit(void *vp);
-int linux_spi_write(u8 *b, u32 len);
-int linux_spi_read(u8 *rb, u32 rlen);
-int linux_spi_write_read(u8 *wb, u8 *rb, u32 rlen);
-int linux_spi_set_max_speed(void);
-#endif
index ae111862e7a967a98ddaafcc901b9014a7c8264c..27c653a0cdf9444d0722de87f613bf3a940dae94 100644 (file)
@@ -26,8 +26,10 @@ static struct dentry *wilc_dir;
 
 #define DBG_REGION_ALL (GENERIC_DBG | HOSTAPD_DBG | HOSTINF_DBG | CORECONFIG_DBG | CFG80211_DBG | INT_DBG | TX_DBG | RX_DBG | LOCK_DBG | INIT_DBG | BUS_DBG | MEM_DBG)
 #define DBG_LEVEL_ALL  (DEBUG | INFO | WRN | ERR)
-atomic_t REGION = ATOMIC_INIT(INIT_DBG | GENERIC_DBG | CFG80211_DBG | FIRM_DBG | HOSTAPD_DBG);
-atomic_t DEBUG_LEVEL = ATOMIC_INIT(ERR);
+atomic_t WILC_REGION = ATOMIC_INIT(INIT_DBG | GENERIC_DBG | CFG80211_DBG | FIRM_DBG | HOSTAPD_DBG);
+EXPORT_SYMBOL_GPL(WILC_REGION);
+atomic_t WILC_DEBUG_LEVEL = ATOMIC_INIT(ERR);
+EXPORT_SYMBOL_GPL(WILC_DEBUG_LEVEL);
 
 /*
  * --------------------------------------------------------------------------------
@@ -43,7 +45,7 @@ static ssize_t wilc_debug_level_read(struct file *file, char __user *userbuf, si
        if (*ppos > 0)
                return 0;
 
-       res = scnprintf(buf, sizeof(buf), "Debug Level: %x\n", atomic_read(&DEBUG_LEVEL));
+       res = scnprintf(buf, sizeof(buf), "Debug Level: %x\n", atomic_read(&WILC_DEBUG_LEVEL));
 
        return simple_read_from_buffer(userbuf, count, ppos, buf, res);
 }
@@ -59,11 +61,11 @@ static ssize_t wilc_debug_level_write(struct file *filp, const char __user *buf,
                return ret;
 
        if (flag > DBG_LEVEL_ALL) {
-               printk("%s, value (0x%08x) is out of range, stay previous flag (0x%08x)\n", __func__, flag, atomic_read(&DEBUG_LEVEL));
+               printk("%s, value (0x%08x) is out of range, stay previous flag (0x%08x)\n", __func__, flag, atomic_read(&WILC_DEBUG_LEVEL));
                return -EINVAL;
        }
 
-       atomic_set(&DEBUG_LEVEL, (int)flag);
+       atomic_set(&WILC_DEBUG_LEVEL, (int)flag);
 
        if (flag == 0)
                printk("Debug-level disabled\n");
@@ -82,7 +84,7 @@ static ssize_t wilc_debug_region_read(struct file *file, char __user *userbuf, s
        if (*ppos > 0)
                return 0;
 
-       res = scnprintf(buf, sizeof(buf), "Debug region: %x\n", atomic_read(&REGION));
+       res = scnprintf(buf, sizeof(buf), "Debug region: %x\n", atomic_read(&WILC_REGION));
 
        return simple_read_from_buffer(userbuf, count, ppos, buf, res);
 }
@@ -102,12 +104,12 @@ static ssize_t wilc_debug_region_write(struct file *filp, const char *buf, size_
        flag = buffer[0] - '0';
 
        if (flag > DBG_REGION_ALL) {
-               printk("%s, value (0x%08x) is out of range, stay previous flag (0x%08x)\n", __func__, flag, atomic_read(&REGION));
+               printk("%s, value (0x%08x) is out of range, stay previous flag (0x%08x)\n", __func__, flag, atomic_read(&WILC_REGION));
                return -EFAULT;
        }
 
-       atomic_set(&REGION, (int)flag);
-       printk("new debug-region is %x\n", atomic_read(&REGION));
+       atomic_set(&WILC_REGION, (int)flag);
+       printk("new debug-region is %x\n", atomic_read(&WILC_REGION));
 
        return count;
 }
@@ -136,7 +138,7 @@ static struct wilc_debugfs_info_t debugfs_info[] = {
        { "wilc_debug_region",  0666,   (INIT_DBG | GENERIC_DBG | CFG80211_DBG), FOPS(NULL, wilc_debug_region_read, wilc_debug_region_write, NULL), },
 };
 
-int wilc_debugfs_init(void)
+static int __init wilc_debugfs_init(void)
 {
        int i;
 
@@ -171,11 +173,13 @@ int wilc_debugfs_init(void)
        }
        return 0;
 }
+module_init(wilc_debugfs_init);
 
-void wilc_debugfs_remove(void)
+static void __exit wilc_debugfs_remove(void)
 {
        debugfs_remove_recursive(wilc_dir);
 }
+module_exit(wilc_debugfs_remove);
 
 #endif
 
index 0eff121b8291eeefaa7773eb8970d39d959880f3..098390cdf31995a0bfcc8c74b0af746a0196c1fa 100644 (file)
@@ -115,7 +115,6 @@ int wilc_mq_recv(WILC_MsgQueueHandle *pHandle,
                             u32 *pu32ReceivedLength)
 {
        Message *pstrMessage;
-       int result = 0;
        unsigned long flags;
 
        if ((!pHandle) || (u32RecvBufferSize == 0)
@@ -135,12 +134,6 @@ int wilc_mq_recv(WILC_MsgQueueHandle *pHandle,
 
        down(&pHandle->hSem);
 
-       /* other non-timeout scenarios */
-       if (result) {
-               PRINT_ER("Non-timeout\n");
-               return result;
-       }
-
        if (pHandle->bExiting) {
                PRINT_ER("pHandle fail\n");
                return -EFAULT;
@@ -174,5 +167,5 @@ int wilc_mq_recv(WILC_MsgQueueHandle *pHandle,
 
        spin_unlock_irqrestore(&pHandle->strCriticalSection, flags);
 
-       return result;
+       return 0;
 }
index d231c334ed93316063cdecb86c3720545e798505..d7e0328baceef9b6f3f94fc6647c63cb614f2273 100644 (file)
@@ -35,7 +35,7 @@ typedef struct __MessageQueue_struct {
  *                              any other message queue having the same name in the system
  *  @param[in,out]     pHandle handle to the message queue object
  *  @param[in] pstrAttrs Optional attributes, NULL for default
- *  @return            Error code indicating sucess/failure
+ *  @return            Error code indicating success/failure
  *  @author            syounan
  *  @date              30 Aug 2010
  *  @version           1.0
@@ -44,7 +44,7 @@ int wilc_mq_create(WILC_MsgQueueHandle *pHandle);
 
 /*!
  *  @brief             Sends a message
- *  @details           Sends a message, this API will block unil the message is
+ *  @details           Sends a message, this API will block until the message is
  *                              actually sent or until it is timedout (as long as the feature
  *                              CONFIG_WILC_MSG_QUEUE_TIMEOUT is enabled and pstrAttrs->u32Timeout
  *                              is not set to WILC_OS_INFINITY), zero timeout is a valid value
@@ -52,7 +52,7 @@ int wilc_mq_create(WILC_MsgQueueHandle *pHandle);
  *  @param[in] pvSendBuffer pointer to the data to send
  *  @param[in] u32SendBufferSize the size of the data to send
  *  @param[in] pstrAttrs Optional attributes, NULL for default
- *  @return            Error code indicating sucess/failure
+ *  @return            Error code indicating success/failure
  *  @author            syounan
  *  @date              30 Aug 2010
  *  @version           1.0
@@ -62,7 +62,7 @@ int wilc_mq_send(WILC_MsgQueueHandle *pHandle,
 
 /*!
  *  @brief             Receives a message
- *  @details           Receives a message, this API will block unil a message is
+ *  @details           Receives a message, this API will block until a message is
  *                              received or until it is timedout (as long as the feature
  *                              CONFIG_WILC_MSG_QUEUE_TIMEOUT is enabled and pstrAttrs->u32Timeout
  *                              is not set to WILC_OS_INFINITY), zero timeout is a valid value
@@ -71,7 +71,7 @@ int wilc_mq_send(WILC_MsgQueueHandle *pHandle,
  *  @param[in] u32RecvBufferSize the size of the receive buffer
  *  @param[out]        pu32ReceivedLength the length of received data
  *  @param[in] pstrAttrs Optional attributes, NULL for default
- *  @return            Error code indicating sucess/failure
+ *  @return            Error code indicating success/failure
  *  @author            syounan
  *  @date              30 Aug 2010
  *  @version           1.0
@@ -84,7 +84,7 @@ int wilc_mq_recv(WILC_MsgQueueHandle *pHandle,
  *  @brief             Destroys an existing  Message queue
  *  @param[in] pHandle handle to the message queue object
  *  @param[in] pstrAttrs Optional attributes, NULL for default
- *  @return            Error code indicating sucess/failure
+ *  @return            Error code indicating success/failure
  *  @author            syounan
  *  @date              30 Aug 2010
  *  @version           1.0
index 8aacf55e5eb80bece8db4f2952d7e44aabd52c48..e961b500490283acb9d7599ea93111e9959372bb 100644 (file)
 #include <linux/string.h>
 #include "wilc_wlan_if.h"
 #include "wilc_wlan.h"
-#include "linux_wlan_sdio.h"
 #include "wilc_wfi_netdevice.h"
+#include <linux/mmc/sdio_func.h>
+#include <linux/mmc/card.h>
+#include <linux/mmc/sdio_ids.h>
+#include <linux/mmc/sdio.h>
+#include <linux/mmc/host.h>
+#include <linux/of_gpio.h>
+
+#define SDIO_MODALIAS "wilc1000_sdio"
+
+#define SDIO_VENDOR_ID_WILC 0x0296
+#define SDIO_DEVICE_ID_WILC 0x5347
+
+static const struct sdio_device_id wilc_sdio_ids[] = {
+       { SDIO_DEVICE(SDIO_VENDOR_ID_WILC, SDIO_DEVICE_ID_WILC) },
+       { },
+};
 
 #define WILC_SDIO_BLOCK_SIZE 512
 
 typedef struct {
+       bool irq_gpio;
        u32 block_size;
-       wilc_debug_func dPrint;
        int nint;
 #define MAX_NUN_INT_THRPT_ENH2 (5) /* Max num interrupts allowed in registers 0xf7, 0xf8 */
        int has_thrpt_enh3;
@@ -25,10 +40,155 @@ typedef struct {
 
 static wilc_sdio_t g_sdio;
 
-#ifdef WILC_SDIO_IRQ_GPIO
-static int sdio_write_reg(u32 addr, u32 data);
-static int sdio_read_reg(u32 addr, u32 *data);
-#endif
+static int sdio_write_reg(struct wilc *wilc, u32 addr, u32 data);
+static int sdio_read_reg(struct wilc *wilc, u32 addr, u32 *data);
+
+static void wilc_sdio_interrupt(struct sdio_func *func)
+{
+       sdio_release_host(func);
+       wilc_handle_isr(sdio_get_drvdata(func));
+       sdio_claim_host(func);
+}
+
+static int wilc_sdio_cmd52(struct wilc *wilc, sdio_cmd52_t *cmd)
+{
+       struct sdio_func *func = container_of(wilc->dev, struct sdio_func, dev);
+       int ret;
+       u8 data;
+
+       sdio_claim_host(func);
+
+       func->num = cmd->function;
+       if (cmd->read_write) {  /* write */
+               if (cmd->raw) {
+                       sdio_writeb(func, cmd->data, cmd->address, &ret);
+                       data = sdio_readb(func, cmd->address, &ret);
+                       cmd->data = data;
+               } else {
+                       sdio_writeb(func, cmd->data, cmd->address, &ret);
+               }
+       } else {        /* read */
+               data = sdio_readb(func, cmd->address, &ret);
+               cmd->data = data;
+       }
+
+       sdio_release_host(func);
+
+       if (ret)
+               dev_err(&func->dev, "wilc_sdio_cmd52..failed, err(%d)\n", ret);
+       return ret;
+}
+
+
+static int wilc_sdio_cmd53(struct wilc *wilc, sdio_cmd53_t *cmd)
+{
+       struct sdio_func *func = container_of(wilc->dev, struct sdio_func, dev);
+       int size, ret;
+
+       sdio_claim_host(func);
+
+       func->num = cmd->function;
+       func->cur_blksize = cmd->block_size;
+       if (cmd->block_mode)
+               size = cmd->count * cmd->block_size;
+       else
+               size = cmd->count;
+
+       if (cmd->read_write) {  /* write */
+               ret = sdio_memcpy_toio(func, cmd->address,
+                                      (void *)cmd->buffer, size);
+       } else {        /* read */
+               ret = sdio_memcpy_fromio(func, (void *)cmd->buffer,
+                                        cmd->address,  size);
+       }
+
+       sdio_release_host(func);
+
+       if (ret)
+               dev_err(&func->dev, "wilc_sdio_cmd53..failed, err(%d)\n", ret);
+
+       return ret;
+}
+
+static int linux_sdio_probe(struct sdio_func *func,
+                           const struct sdio_device_id *id)
+{
+       struct wilc *wilc;
+       int gpio, ret;
+
+       gpio = -1;
+       if (IS_ENABLED(CONFIG_WILC1000_HW_OOB_INTR)) {
+               gpio = of_get_gpio(func->dev.of_node, 0);
+               if (gpio < 0)
+                       gpio = GPIO_NUM;
+       }
+
+       dev_dbg(&func->dev, "Initializing netdev\n");
+       ret = wilc_netdev_init(&wilc, &func->dev, HIF_SDIO, gpio,
+                            &wilc_hif_sdio);
+       if (ret) {
+               dev_err(&func->dev, "Couldn't initialize netdev\n");
+               return ret;
+       }
+       sdio_set_drvdata(func, wilc);
+       wilc->dev = &func->dev;
+
+       dev_info(&func->dev, "Driver Initializing success\n");
+       return 0;
+}
+
+static void linux_sdio_remove(struct sdio_func *func)
+{
+       wilc_netdev_cleanup(sdio_get_drvdata(func));
+}
+
+static struct sdio_driver wilc1000_sdio_driver = {
+       .name           = SDIO_MODALIAS,
+       .id_table       = wilc_sdio_ids,
+       .probe          = linux_sdio_probe,
+       .remove         = linux_sdio_remove,
+};
+module_driver(wilc1000_sdio_driver,
+             sdio_register_driver,
+             sdio_unregister_driver);
+MODULE_LICENSE("GPL");
+
+static int wilc_sdio_enable_interrupt(struct wilc *dev)
+{
+       struct sdio_func *func = container_of(dev->dev, struct sdio_func, dev);
+       int ret = 0;
+
+       sdio_claim_host(func);
+       ret = sdio_claim_irq(func, wilc_sdio_interrupt);
+       sdio_release_host(func);
+
+       if (ret < 0) {
+               dev_err(&func->dev, "can't claim sdio_irq, err(%d)\n", ret);
+               ret = -EIO;
+       }
+       return ret;
+}
+
+static void wilc_sdio_disable_interrupt(struct wilc *dev)
+{
+       struct sdio_func *func = container_of(dev->dev, struct sdio_func, dev);
+       int ret;
+
+       dev_dbg(&func->dev, "wilc_sdio_disable_interrupt IN\n");
+
+       sdio_claim_host(func);
+       ret = sdio_release_irq(func);
+       if (ret < 0)
+               dev_err(&func->dev, "can't release sdio_irq, err(%d)\n", ret);
+       sdio_release_host(func);
+
+       dev_info(&func->dev, "wilc_sdio_disable_interrupt OUT\n");
+}
+
+static int wilc_sdio_init(void)
+{
+       return 1;
+}
 
 /********************************************
  *
@@ -36,9 +196,11 @@ static int sdio_read_reg(u32 addr, u32 *data);
  *
  ********************************************/
 
-static int sdio_set_func0_csa_address(u32 adr)
+static int sdio_set_func0_csa_address(struct wilc *wilc, u32 adr)
 {
+       struct sdio_func *func = dev_to_sdio_func(wilc->dev);
        sdio_cmd52_t cmd;
+       int ret;
 
        /**
         *      Review: BIG ENDIAN
@@ -48,22 +210,25 @@ static int sdio_set_func0_csa_address(u32 adr)
        cmd.raw = 0;
        cmd.address = 0x10c;
        cmd.data = (u8)adr;
-       if (!linux_sdio_cmd52(&cmd)) {
-               g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0x10c data...\n");
+       ret = wilc_sdio_cmd52(wilc, &cmd);
+       if (ret) {
+               dev_err(&func->dev, "Failed cmd52, set 0x10c data...\n");
                goto _fail_;
        }
 
        cmd.address = 0x10d;
        cmd.data = (u8)(adr >> 8);
-       if (!linux_sdio_cmd52(&cmd)) {
-               g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0x10d data...\n");
+       ret = wilc_sdio_cmd52(wilc, &cmd);
+       if (ret) {
+               dev_err(&func->dev, "Failed cmd52, set 0x10d data...\n");
                goto _fail_;
        }
 
        cmd.address = 0x10e;
        cmd.data = (u8)(adr >> 16);
-       if (!linux_sdio_cmd52(&cmd)) {
-               g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0x10e data...\n");
+       ret = wilc_sdio_cmd52(wilc, &cmd);
+       if (ret) {
+               dev_err(&func->dev, "Failed cmd52, set 0x10e data...\n");
                goto _fail_;
        }
 
@@ -72,24 +237,28 @@ _fail_:
        return 0;
 }
 
-static int sdio_set_func0_block_size(u32 block_size)
+static int sdio_set_func0_block_size(struct wilc *wilc, u32 block_size)
 {
+       struct sdio_func *func = dev_to_sdio_func(wilc->dev);
        sdio_cmd52_t cmd;
+       int ret;
 
        cmd.read_write = 1;
        cmd.function = 0;
        cmd.raw = 0;
        cmd.address = 0x10;
        cmd.data = (u8)block_size;
-       if (!linux_sdio_cmd52(&cmd)) {
-               g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0x10 data...\n");
+       ret = wilc_sdio_cmd52(wilc, &cmd);
+       if (ret) {
+               dev_err(&func->dev, "Failed cmd52, set 0x10 data...\n");
                goto _fail_;
        }
 
        cmd.address = 0x11;
        cmd.data = (u8)(block_size >> 8);
-       if (!linux_sdio_cmd52(&cmd)) {
-               g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0x11 data...\n");
+       ret = wilc_sdio_cmd52(wilc, &cmd);
+       if (ret) {
+               dev_err(&func->dev, "Failed cmd52, set 0x11 data...\n");
                goto _fail_;
        }
 
@@ -104,23 +273,27 @@ _fail_:
  *
  ********************************************/
 
-static int sdio_set_func1_block_size(u32 block_size)
+static int sdio_set_func1_block_size(struct wilc *wilc, u32 block_size)
 {
+       struct sdio_func *func = dev_to_sdio_func(wilc->dev);
        sdio_cmd52_t cmd;
+       int ret;
 
        cmd.read_write = 1;
        cmd.function = 0;
        cmd.raw = 0;
        cmd.address = 0x110;
        cmd.data = (u8)block_size;
-       if (!linux_sdio_cmd52(&cmd)) {
-               g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0x110 data...\n");
+       ret = wilc_sdio_cmd52(wilc, &cmd);
+       if (ret) {
+               dev_err(&func->dev, "Failed cmd52, set 0x110 data...\n");
                goto _fail_;
        }
        cmd.address = 0x111;
        cmd.data = (u8)(block_size >> 8);
-       if (!linux_sdio_cmd52(&cmd)) {
-               g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0x111 data...\n");
+       ret = wilc_sdio_cmd52(wilc, &cmd);
+       if (ret) {
+               dev_err(&func->dev, "Failed cmd52, set 0x111 data...\n");
                goto _fail_;
        }
 
@@ -129,100 +302,17 @@ _fail_:
        return 0;
 }
 
-static int sdio_clear_int(void)
-{
-#ifndef WILC_SDIO_IRQ_GPIO
-       /* u32 sts; */
-       sdio_cmd52_t cmd;
-
-       cmd.read_write = 0;
-       cmd.function = 1;
-       cmd.raw = 0;
-       cmd.address = 0x4;
-       cmd.data = 0;
-       linux_sdio_cmd52(&cmd);
-
-       return cmd.data;
-#else
-       u32 reg;
-
-       if (!sdio_read_reg(WILC_HOST_RX_CTRL_0, &reg)) {
-               g_sdio.dPrint(N_ERR, "[wilc spi]: Failed read reg (%08x)...\n", WILC_HOST_RX_CTRL_0);
-               return 0;
-       }
-       reg &= ~0x1;
-       sdio_write_reg(WILC_HOST_RX_CTRL_0, reg);
-       return 1;
-#endif
-
-}
-
-u32 sdio_xfer_cnt(void)
-{
-       u32 cnt = 0;
-       sdio_cmd52_t cmd;
-
-       cmd.read_write = 0;
-       cmd.function = 1;
-       cmd.raw = 0;
-       cmd.address = 0x1C;
-       cmd.data = 0;
-       linux_sdio_cmd52(&cmd);
-       cnt = cmd.data;
-
-       cmd.read_write = 0;
-       cmd.function = 1;
-       cmd.raw = 0;
-       cmd.address = 0x1D;
-       cmd.data = 0;
-       linux_sdio_cmd52(&cmd);
-       cnt |= (cmd.data << 8);
-
-       cmd.read_write = 0;
-       cmd.function = 1;
-       cmd.raw = 0;
-       cmd.address = 0x1E;
-       cmd.data = 0;
-       linux_sdio_cmd52(&cmd);
-       cnt |= (cmd.data << 16);
-
-       return cnt;
-}
-
 /********************************************
  *
  *      Sdio interfaces
  *
  ********************************************/
-int sdio_check_bs(void)
+static int sdio_write_reg(struct wilc *wilc, u32 addr, u32 data)
 {
-       sdio_cmd52_t cmd;
-
-       /**
-        *      poll until BS is 0
-        **/
-       cmd.read_write = 0;
-       cmd.function = 0;
-       cmd.raw = 0;
-       cmd.address = 0xc;
-       cmd.data = 0;
-       if (!linux_sdio_cmd52(&cmd)) {
-               g_sdio.dPrint(N_ERR, "[wilc sdio]: Fail cmd 52, get BS register...\n");
-               goto _fail_;
-       }
-
-       return 1;
-
-_fail_:
-
-       return 0;
-}
+       struct sdio_func *func = dev_to_sdio_func(wilc->dev);
+       int ret;
 
-static int sdio_write_reg(u32 addr, u32 data)
-{
-#ifdef BIG_ENDIAN
-       data = BYTE_SWAP(data);
-#endif
+       data = cpu_to_le32(data);
 
        if ((addr >= 0xf0) && (addr <= 0xff)) {
                sdio_cmd52_t cmd;
@@ -232,8 +322,10 @@ static int sdio_write_reg(u32 addr, u32 data)
                cmd.raw = 0;
                cmd.address = addr;
                cmd.data = data;
-               if (!linux_sdio_cmd52(&cmd)) {
-                       g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd 52, read reg (%08x) ...\n", addr);
+               ret = wilc_sdio_cmd52(wilc, &cmd);
+               if (ret) {
+                       dev_err(&func->dev,
+                               "Failed cmd 52, read reg (%08x) ...\n", addr);
                        goto _fail_;
                }
        } else {
@@ -242,7 +334,7 @@ static int sdio_write_reg(u32 addr, u32 data)
                /**
                 *      set the AHB address
                 **/
-               if (!sdio_set_func0_csa_address(addr))
+               if (!sdio_set_func0_csa_address(wilc, addr))
                        goto _fail_;
 
                cmd.read_write = 1;
@@ -253,9 +345,10 @@ static int sdio_write_reg(u32 addr, u32 data)
                cmd.count = 4;
                cmd.buffer = (u8 *)&data;
                cmd.block_size = g_sdio.block_size; /* johnny : prevent it from setting unexpected value */
-
-               if (!linux_sdio_cmd53(&cmd)) {
-                       g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd53, write reg (%08x)...\n", addr);
+               ret = wilc_sdio_cmd53(wilc, &cmd);
+               if (ret) {
+                       dev_err(&func->dev,
+                               "Failed cmd53, write reg (%08x)...\n", addr);
                        goto _fail_;
                }
        }
@@ -267,11 +360,12 @@ _fail_:
        return 0;
 }
 
-static int sdio_write(u32 addr, u8 *buf, u32 size)
+static int sdio_write(struct wilc *wilc, u32 addr, u8 *buf, u32 size)
 {
+       struct sdio_func *func = dev_to_sdio_func(wilc->dev);
        u32 block_size = g_sdio.block_size;
        sdio_cmd53_t cmd;
-       int nblk, nleft;
+       int nblk, nleft, ret;
 
        cmd.read_write = 1;
        if (addr > 0) {
@@ -314,11 +408,13 @@ static int sdio_write(u32 addr, u8 *buf, u32 size)
                cmd.buffer = buf;
                cmd.block_size = block_size;
                if (addr > 0) {
-                       if (!sdio_set_func0_csa_address(addr))
+                       if (!sdio_set_func0_csa_address(wilc, addr))
                                goto _fail_;
                }
-               if (!linux_sdio_cmd53(&cmd)) {
-                       g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd53 [%x], block send...\n", addr);
+               ret = wilc_sdio_cmd53(wilc, &cmd);
+               if (ret) {
+                       dev_err(&func->dev,
+                               "Failed cmd53 [%x], block send...\n", addr);
                        goto _fail_;
                }
                if (addr > 0)
@@ -335,11 +431,13 @@ static int sdio_write(u32 addr, u8 *buf, u32 size)
                cmd.block_size = block_size; /* johnny : prevent it from setting unexpected value */
 
                if (addr > 0) {
-                       if (!sdio_set_func0_csa_address(addr))
+                       if (!sdio_set_func0_csa_address(wilc, addr))
                                goto _fail_;
                }
-               if (!linux_sdio_cmd53(&cmd)) {
-                       g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd53 [%x], bytes send...\n", addr);
+               ret = wilc_sdio_cmd53(wilc, &cmd);
+               if (ret) {
+                       dev_err(&func->dev,
+                               "Failed cmd53 [%x], bytes send...\n", addr);
                        goto _fail_;
                }
        }
@@ -351,8 +449,11 @@ _fail_:
        return 0;
 }
 
-static int sdio_read_reg(u32 addr, u32 *data)
+static int sdio_read_reg(struct wilc *wilc, u32 addr, u32 *data)
 {
+       struct sdio_func *func = dev_to_sdio_func(wilc->dev);
+       int ret;
+
        if ((addr >= 0xf0) && (addr <= 0xff)) {
                sdio_cmd52_t cmd;
 
@@ -360,15 +461,17 @@ static int sdio_read_reg(u32 addr, u32 *data)
                cmd.function = 0;
                cmd.raw = 0;
                cmd.address = addr;
-               if (!linux_sdio_cmd52(&cmd)) {
-                       g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd 52, read reg (%08x) ...\n", addr);
+               ret = wilc_sdio_cmd52(wilc, &cmd);
+               if (ret) {
+                       dev_err(&func->dev,
+                               "Failed cmd 52, read reg (%08x) ...\n", addr);
                        goto _fail_;
                }
                *data = cmd.data;
        } else {
                sdio_cmd53_t cmd;
 
-               if (!sdio_set_func0_csa_address(addr))
+               if (!sdio_set_func0_csa_address(wilc, addr))
                        goto _fail_;
 
                cmd.read_write = 0;
@@ -380,16 +483,15 @@ static int sdio_read_reg(u32 addr, u32 *data)
                cmd.buffer = (u8 *)data;
 
                cmd.block_size = g_sdio.block_size; /* johnny : prevent it from setting unexpected value */
-
-               if (!linux_sdio_cmd53(&cmd)) {
-                       g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd53, read reg (%08x)...\n", addr);
+               ret = wilc_sdio_cmd53(wilc, &cmd);
+               if (ret) {
+                       dev_err(&func->dev,
+                               "Failed cmd53, read reg (%08x)...\n", addr);
                        goto _fail_;
                }
        }
 
-#ifdef BIG_ENDIAN
-       *data = BYTE_SWAP(*data);
-#endif
+       *data = cpu_to_le32(*data);
 
        return 1;
 
@@ -398,11 +500,12 @@ _fail_:
        return 0;
 }
 
-static int sdio_read(u32 addr, u8 *buf, u32 size)
+static int sdio_read(struct wilc *wilc, u32 addr, u8 *buf, u32 size)
 {
+       struct sdio_func *func = dev_to_sdio_func(wilc->dev);
        u32 block_size = g_sdio.block_size;
        sdio_cmd53_t cmd;
-       int nblk, nleft;
+       int nblk, nleft, ret;
 
        cmd.read_write = 0;
        if (addr > 0) {
@@ -445,11 +548,13 @@ static int sdio_read(u32 addr, u8 *buf, u32 size)
                cmd.buffer = buf;
                cmd.block_size = block_size;
                if (addr > 0) {
-                       if (!sdio_set_func0_csa_address(addr))
+                       if (!sdio_set_func0_csa_address(wilc, addr))
                                goto _fail_;
                }
-               if (!linux_sdio_cmd53(&cmd)) {
-                       g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd53 [%x], block read...\n", addr);
+               ret = wilc_sdio_cmd53(wilc, &cmd);
+               if (ret) {
+                       dev_err(&func->dev,
+                               "Failed cmd53 [%x], block read...\n", addr);
                        goto _fail_;
                }
                if (addr > 0)
@@ -466,11 +571,13 @@ static int sdio_read(u32 addr, u8 *buf, u32 size)
                cmd.block_size = block_size; /* johnny : prevent it from setting unexpected value */
 
                if (addr > 0) {
-                       if (!sdio_set_func0_csa_address(addr))
+                       if (!sdio_set_func0_csa_address(wilc, addr))
                                goto _fail_;
                }
-               if (!linux_sdio_cmd53(&cmd)) {
-                       g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd53 [%x], bytes read...\n", addr);
+               ret = wilc_sdio_cmd53(wilc, &cmd);
+               if (ret) {
+                       dev_err(&func->dev,
+                               "Failed cmd53 [%x], bytes read...\n", addr);
                        goto _fail_;
                }
        }
@@ -488,81 +595,24 @@ _fail_:
  *
  ********************************************/
 
-static int sdio_deinit(void *pv)
-{
-       return 1;
-}
-
-static int sdio_sync(void)
+static int sdio_deinit(struct wilc *wilc)
 {
-       u32 reg;
-
-       /**
-        *      Disable power sequencer
-        **/
-       if (!sdio_read_reg(WILC_MISC, &reg)) {
-               g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed read misc reg...\n");
-               return 0;
-       }
-
-       reg &= ~BIT(8);
-       if (!sdio_write_reg(WILC_MISC, reg)) {
-               g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed write misc reg...\n");
-               return 0;
-       }
-
-#ifdef WILC_SDIO_IRQ_GPIO
-       {
-               u32 reg;
-               int ret;
-
-               /**
-                *      interrupt pin mux select
-                **/
-               ret = sdio_read_reg(WILC_PIN_MUX_0, &reg);
-               if (!ret) {
-                       g_sdio.dPrint(N_ERR, "[wilc spi]: Failed read reg (%08x)...\n", WILC_PIN_MUX_0);
-                       return 0;
-               }
-               reg |= BIT(8);
-               ret = sdio_write_reg(WILC_PIN_MUX_0, reg);
-               if (!ret) {
-                       g_sdio.dPrint(N_ERR, "[wilc spi]: Failed write reg (%08x)...\n", WILC_PIN_MUX_0);
-                       return 0;
-               }
-
-               /**
-                *      interrupt enable
-                **/
-               ret = sdio_read_reg(WILC_INTR_ENABLE, &reg);
-               if (!ret) {
-                       g_sdio.dPrint(N_ERR, "[wilc spi]: Failed read reg (%08x)...\n", WILC_INTR_ENABLE);
-                       return 0;
-               }
-               reg |= BIT(16);
-               ret = sdio_write_reg(WILC_INTR_ENABLE, reg);
-               if (!ret) {
-                       g_sdio.dPrint(N_ERR, "[wilc spi]: Failed write reg (%08x)...\n", WILC_INTR_ENABLE);
-                       return 0;
-               }
-       }
-#endif
-
        return 1;
 }
 
-static int sdio_init(struct wilc *wilc, wilc_debug_func func)
+static int sdio_init(struct wilc *wilc)
 {
+       struct sdio_func *func = dev_to_sdio_func(wilc->dev);
        sdio_cmd52_t cmd;
-       int loop;
+       int loop, ret;
        u32 chipid;
 
        memset(&g_sdio, 0, sizeof(wilc_sdio_t));
 
-       g_sdio.dPrint = func;
+       g_sdio.irq_gpio = (wilc->dev_irq_num);
 
-       if (!linux_sdio_init()) {
-               g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed io init bus...\n");
+       if (!wilc_sdio_init()) {
+               dev_err(&func->dev, "Failed io init bus...\n");
                return 0;
        } else {
                return 0;
@@ -576,16 +626,17 @@ static int sdio_init(struct wilc *wilc, wilc_debug_func func)
        cmd.raw = 1;
        cmd.address = 0x100;
        cmd.data = 0x80;
-       if (!linux_sdio_cmd52(&cmd)) {
-               g_sdio.dPrint(N_ERR, "[wilc sdio]: Fail cmd 52, enable csa...\n");
+       ret = wilc_sdio_cmd52(wilc, &cmd);
+       if (ret) {
+               dev_err(&func->dev, "Fail cmd 52, enable csa...\n");
                goto _fail_;
        }
 
        /**
         *      function 0 block size
         **/
-       if (!sdio_set_func0_block_size(WILC_SDIO_BLOCK_SIZE)) {
-               g_sdio.dPrint(N_ERR, "[wilc sdio]: Fail cmd 52, set func 0 block size...\n");
+       if (!sdio_set_func0_block_size(wilc, WILC_SDIO_BLOCK_SIZE)) {
+               dev_err(&func->dev, "Fail cmd 52, set func 0 block size...\n");
                goto _fail_;
        }
        g_sdio.block_size = WILC_SDIO_BLOCK_SIZE;
@@ -598,8 +649,10 @@ static int sdio_init(struct wilc *wilc, wilc_debug_func func)
        cmd.raw = 1;
        cmd.address = 0x2;
        cmd.data = 0x2;
-       if (!linux_sdio_cmd52(&cmd)) {
-               g_sdio.dPrint(N_ERR, "[wilc sdio] Fail cmd 52, set IOE register...\n");
+       ret = wilc_sdio_cmd52(wilc, &cmd);
+       if (ret) {
+               dev_err(&func->dev,
+                       "Fail cmd 52, set IOE register...\n");
                goto _fail_;
        }
 
@@ -613,8 +666,10 @@ static int sdio_init(struct wilc *wilc, wilc_debug_func func)
        loop = 3;
        do {
                cmd.data = 0;
-               if (!linux_sdio_cmd52(&cmd)) {
-                       g_sdio.dPrint(N_ERR, "[wilc sdio]: Fail cmd 52, get IOR register...\n");
+               ret = wilc_sdio_cmd52(wilc, &cmd);
+               if (ret) {
+                       dev_err(&func->dev,
+                               "Fail cmd 52, get IOR register...\n");
                        goto _fail_;
                }
                if (cmd.data == 0x2)
@@ -622,15 +677,15 @@ static int sdio_init(struct wilc *wilc, wilc_debug_func func)
        } while (loop--);
 
        if (loop <= 0) {
-               g_sdio.dPrint(N_ERR, "[wilc sdio]: Fail func 1 is not ready...\n");
+               dev_err(&func->dev, "Fail func 1 is not ready...\n");
                goto _fail_;
        }
 
        /**
         *      func 1 is ready, set func 1 block size
         **/
-       if (!sdio_set_func1_block_size(WILC_SDIO_BLOCK_SIZE)) {
-               g_sdio.dPrint(N_ERR, "[wilc sdio]: Fail set func 1 block size...\n");
+       if (!sdio_set_func1_block_size(wilc, WILC_SDIO_BLOCK_SIZE)) {
+               dev_err(&func->dev, "Fail set func 1 block size...\n");
                goto _fail_;
        }
 
@@ -642,24 +697,25 @@ static int sdio_init(struct wilc *wilc, wilc_debug_func func)
        cmd.raw = 1;
        cmd.address = 0x4;
        cmd.data = 0x3;
-       if (!linux_sdio_cmd52(&cmd)) {
-               g_sdio.dPrint(N_ERR, "[wilc sdio]: Fail cmd 52, set IEN register...\n");
+       ret = wilc_sdio_cmd52(wilc, &cmd);
+       if (ret) {
+               dev_err(&func->dev, "Fail cmd 52, set IEN register...\n");
                goto _fail_;
        }
 
        /**
         *      make sure can read back chip id correctly
         **/
-       if (!sdio_read_reg(0x1000, &chipid)) {
-               g_sdio.dPrint(N_ERR, "[wilc sdio]: Fail cmd read chip id...\n");
+       if (!sdio_read_reg(wilc, 0x1000, &chipid)) {
+               dev_err(&func->dev, "Fail cmd read chip id...\n");
                goto _fail_;
        }
-       g_sdio.dPrint(N_ERR, "[wilc sdio]: chipid (%08x)\n", chipid);
+       dev_err(&func->dev, "chipid (%08x)\n", chipid);
        if ((chipid & 0xfff) > 0x2a0)
                g_sdio.has_thrpt_enh3 = 1;
        else
                g_sdio.has_thrpt_enh3 = 0;
-       g_sdio.dPrint(N_ERR, "[wilc sdio]: has_thrpt_enh3 = %d...\n", g_sdio.has_thrpt_enh3);
+       dev_info(&func->dev, "has_thrpt_enh3 = %d...\n", g_sdio.has_thrpt_enh3);
 
        return 1;
 
@@ -668,19 +724,8 @@ _fail_:
        return 0;
 }
 
-static void sdio_set_max_speed(void)
+static int sdio_read_size(struct wilc *wilc, u32 *size)
 {
-       linux_sdio_set_max_speed();
-}
-
-static void sdio_set_default_speed(void)
-{
-       linux_sdio_set_default_speed();
-}
-
-static int sdio_read_size(u32 *size)
-{
-
        u32 tmp;
        sdio_cmd52_t cmd;
 
@@ -692,7 +737,7 @@ static int sdio_read_size(u32 *size)
        cmd.raw = 0;
        cmd.address = 0xf2;
        cmd.data = 0;
-       linux_sdio_cmd52(&cmd);
+       wilc_sdio_cmd52(wilc, &cmd);
        tmp = cmd.data;
 
        /* cmd.read_write = 0; */
@@ -700,54 +745,53 @@ static int sdio_read_size(u32 *size)
        /* cmd.raw = 0; */
        cmd.address = 0xf3;
        cmd.data = 0;
-       linux_sdio_cmd52(&cmd);
+       wilc_sdio_cmd52(wilc, &cmd);
        tmp |= (cmd.data << 8);
 
        *size = tmp;
        return 1;
 }
 
-static int sdio_read_int(u32 *int_status)
+static int sdio_read_int(struct wilc *wilc, u32 *int_status)
 {
-
+       struct sdio_func *func = dev_to_sdio_func(wilc->dev);
        u32 tmp;
        sdio_cmd52_t cmd;
 
-       sdio_read_size(&tmp);
+       sdio_read_size(wilc, &tmp);
 
        /**
         *      Read IRQ flags
         **/
-#ifndef WILC_SDIO_IRQ_GPIO
-       cmd.function = 1;
-       cmd.address = 0x04;
-       cmd.data = 0;
-       linux_sdio_cmd52(&cmd);
-
-       if (cmd.data & BIT(0))
-               tmp |= INT_0;
-       if (cmd.data & BIT(2))
-               tmp |= INT_1;
-       if (cmd.data & BIT(3))
-               tmp |= INT_2;
-       if (cmd.data & BIT(4))
-               tmp |= INT_3;
-       if (cmd.data & BIT(5))
-               tmp |= INT_4;
-       if (cmd.data & BIT(6))
-               tmp |= INT_5;
-       {
+       if (!g_sdio.irq_gpio) {
                int i;
 
+               cmd.function = 1;
+               cmd.address = 0x04;
+               cmd.data = 0;
+               wilc_sdio_cmd52(wilc, &cmd);
+
+               if (cmd.data & BIT(0))
+                       tmp |= INT_0;
+               if (cmd.data & BIT(2))
+                       tmp |= INT_1;
+               if (cmd.data & BIT(3))
+                       tmp |= INT_2;
+               if (cmd.data & BIT(4))
+                       tmp |= INT_3;
+               if (cmd.data & BIT(5))
+                       tmp |= INT_4;
+               if (cmd.data & BIT(6))
+                       tmp |= INT_5;
                for (i = g_sdio.nint; i < MAX_NUM_INT; i++) {
                        if ((tmp >> (IRG_FLAGS_OFFSET + i)) & 0x1) {
-                               g_sdio.dPrint(N_ERR, "[wilc sdio]: Unexpected interrupt (1) : tmp=%x, data=%x\n", tmp, cmd.data);
+                               dev_err(&func->dev,
+                                       "Unexpected interrupt (1) : tmp=%x, data=%x\n",
+                                       tmp, cmd.data);
                                break;
                        }
                }
-       }
-#else
-       {
+       } else {
                u32 irq_flags;
 
                cmd.read_write = 0;
@@ -755,35 +799,32 @@ static int sdio_read_int(u32 *int_status)
                cmd.raw = 0;
                cmd.address = 0xf7;
                cmd.data = 0;
-               linux_sdio_cmd52(&cmd);
+               wilc_sdio_cmd52(wilc, &cmd);
                irq_flags = cmd.data & 0x1f;
                tmp |= ((irq_flags >> 0) << IRG_FLAGS_OFFSET);
        }
 
-#endif
-
        *int_status = tmp;
 
        return 1;
 }
 
-static int sdio_clear_int_ext(u32 val)
+static int sdio_clear_int_ext(struct wilc *wilc, u32 val)
 {
+       struct sdio_func *func = dev_to_sdio_func(wilc->dev);
        int ret;
 
        if (g_sdio.has_thrpt_enh3) {
                u32 reg;
 
-#ifdef WILC_SDIO_IRQ_GPIO
-               {
+               if (g_sdio.irq_gpio) {
                        u32 flags;
 
                        flags = val & (BIT(MAX_NUN_INT_THRPT_ENH2) - 1);
                        reg = flags;
+               } else {
+                       reg = 0;
                }
-#else
-               reg = 0;
-#endif
                /* select VMM table 0 */
                if ((val & SEL_VMM_TBL0) == SEL_VMM_TBL0)
                        reg |= BIT(5);
@@ -802,16 +843,17 @@ static int sdio_clear_int_ext(u32 val)
                        cmd.address = 0xf8;
                        cmd.data = reg;
 
-                       ret = linux_sdio_cmd52(&cmd);
-                       if (!ret) {
-                               g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0xf8 data (%d) ...\n", __LINE__);
+                       ret = wilc_sdio_cmd52(wilc, &cmd);
+                       if (ret) {
+                               dev_err(&func->dev,
+                                       "Failed cmd52, set 0xf8 data (%d) ...\n",
+                                       __LINE__);
                                goto _fail_;
                        }
 
                }
        } else {
-#ifdef WILC_SDIO_IRQ_GPIO
-               {
+               if (g_sdio.irq_gpio) {
                        /* see below. has_thrpt_enh2 uses register 0xf8 to clear interrupts. */
                        /* Cannot clear multiple interrupts. Must clear each interrupt individually */
                        u32 flags;
@@ -831,9 +873,11 @@ static int sdio_clear_int_ext(u32 val)
                                                cmd.address = 0xf8;
                                                cmd.data = BIT(i);
 
-                                               ret = linux_sdio_cmd52(&cmd);
-                                               if (!ret) {
-                                                       g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0xf8 data (%d) ...\n", __LINE__);
+                                               ret = wilc_sdio_cmd52(wilc, &cmd);
+                                               if (ret) {
+                                                       dev_err(&func->dev,
+                                                               "Failed cmd52, set 0xf8 data (%d) ...\n",
+                                                               __LINE__);
                                                        goto _fail_;
                                                }
 
@@ -846,12 +890,13 @@ static int sdio_clear_int_ext(u32 val)
                                        goto _fail_;
                                for (i = g_sdio.nint; i < MAX_NUM_INT; i++) {
                                        if (flags & 1)
-                                               g_sdio.dPrint(N_ERR, "[wilc sdio]: Unexpected interrupt cleared %d...\n", i);
+                                               dev_err(&func->dev,
+                                                       "Unexpected interrupt cleared %d...\n",
+                                                       i);
                                        flags >>= 1;
                                }
                        }
                }
-#endif /* WILC_SDIO_IRQ_GPIO */
 
                {
                        u32 vmm_ctl;
@@ -875,9 +920,11 @@ static int sdio_clear_int_ext(u32 val)
                                cmd.raw = 0;
                                cmd.address = 0xf6;
                                cmd.data = vmm_ctl;
-                               ret = linux_sdio_cmd52(&cmd);
-                               if (!ret) {
-                                       g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0xf6 data (%d) ...\n", __LINE__);
+                               ret = wilc_sdio_cmd52(wilc, &cmd);
+                               if (ret) {
+                                       dev_err(&func->dev,
+                                               "Failed cmd52, set 0xf6 data (%d) ...\n",
+                                               __LINE__);
                                        goto _fail_;
                                }
                        }
@@ -889,16 +936,18 @@ _fail_:
        return 0;
 }
 
-static int sdio_sync_ext(int nint /*  how mant interrupts to enable. */)
+static int sdio_sync_ext(struct wilc *wilc, int nint)
 {
+       struct sdio_func *func = dev_to_sdio_func(wilc->dev);
        u32 reg;
 
        if (nint > MAX_NUM_INT) {
-               g_sdio.dPrint(N_ERR, "[wilc sdio]: Too many interupts (%d)...\n", nint);
+               dev_err(&func->dev, "Too many interupts (%d)...\n", nint);
                return 0;
        }
        if (nint > MAX_NUN_INT_THRPT_ENH2) {
-               g_sdio.dPrint(N_ERR, "[wilc sdio]: Error: Cannot support more than 5 interrupts when has_thrpt_enh2=1.\n");
+               dev_err(&func->dev,
+                       "Cannot support more than 5 interrupts when has_thrpt_enh2=1.\n");
                return 0;
        }
 
@@ -907,71 +956,77 @@ static int sdio_sync_ext(int nint /*  how mant interrupts to enable. */)
        /**
         *      Disable power sequencer
         **/
-       if (!sdio_read_reg(WILC_MISC, &reg)) {
-               g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed read misc reg...\n");
+       if (!sdio_read_reg(wilc, WILC_MISC, &reg)) {
+               dev_err(&func->dev, "Failed read misc reg...\n");
                return 0;
        }
 
        reg &= ~BIT(8);
-       if (!sdio_write_reg(WILC_MISC, reg)) {
-               g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed write misc reg...\n");
+       if (!sdio_write_reg(wilc, WILC_MISC, reg)) {
+               dev_err(&func->dev, "Failed write misc reg...\n");
                return 0;
        }
 
-#ifdef WILC_SDIO_IRQ_GPIO
-       {
+       if (g_sdio.irq_gpio) {
                u32 reg;
                int ret, i;
 
                /**
                 *      interrupt pin mux select
                 **/
-               ret = sdio_read_reg(WILC_PIN_MUX_0, &reg);
+               ret = sdio_read_reg(wilc, WILC_PIN_MUX_0, &reg);
                if (!ret) {
-                       g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed read reg (%08x)...\n", WILC_PIN_MUX_0);
+                       dev_err(&func->dev, "Failed read reg (%08x)...\n",
+                               WILC_PIN_MUX_0);
                        return 0;
                }
                reg |= BIT(8);
-               ret = sdio_write_reg(WILC_PIN_MUX_0, reg);
+               ret = sdio_write_reg(wilc, WILC_PIN_MUX_0, reg);
                if (!ret) {
-                       g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed write reg (%08x)...\n", WILC_PIN_MUX_0);
+                       dev_err(&func->dev, "Failed write reg (%08x)...\n",
+                               WILC_PIN_MUX_0);
                        return 0;
                }
 
                /**
                 *      interrupt enable
                 **/
-               ret = sdio_read_reg(WILC_INTR_ENABLE, &reg);
+               ret = sdio_read_reg(wilc, WILC_INTR_ENABLE, &reg);
                if (!ret) {
-                       g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed read reg (%08x)...\n", WILC_INTR_ENABLE);
+                       dev_err(&func->dev, "Failed read reg (%08x)...\n",
+                               WILC_INTR_ENABLE);
                        return 0;
                }
 
                for (i = 0; (i < 5) && (nint > 0); i++, nint--)
                        reg |= BIT((27 + i));
-               ret = sdio_write_reg(WILC_INTR_ENABLE, reg);
+               ret = sdio_write_reg(wilc, WILC_INTR_ENABLE, reg);
                if (!ret) {
-                       g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed write reg (%08x)...\n", WILC_INTR_ENABLE);
+                       dev_err(&func->dev, "Failed write reg (%08x)...\n",
+                               WILC_INTR_ENABLE);
                        return 0;
                }
                if (nint) {
-                       ret = sdio_read_reg(WILC_INTR2_ENABLE, &reg);
+                       ret = sdio_read_reg(wilc, WILC_INTR2_ENABLE, &reg);
                        if (!ret) {
-                               g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed read reg (%08x)...\n", WILC_INTR2_ENABLE);
+                               dev_err(&func->dev,
+                                       "Failed read reg (%08x)...\n",
+                                       WILC_INTR2_ENABLE);
                                return 0;
                        }
 
                        for (i = 0; (i < 3) && (nint > 0); i++, nint--)
                                reg |= BIT(i);
 
-                       ret = sdio_read_reg(WILC_INTR2_ENABLE, &reg);
+                       ret = sdio_read_reg(wilc, WILC_INTR2_ENABLE, &reg);
                        if (!ret) {
-                               g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed write reg (%08x)...\n", WILC_INTR2_ENABLE);
+                               dev_err(&func->dev,
+                                       "Failed write reg (%08x)...\n",
+                                       WILC_INTR2_ENABLE);
                                return 0;
                        }
                }
        }
-#endif /* WILC_SDIO_IRQ_GPIO */
        return 1;
 }
 
@@ -981,23 +1036,20 @@ static int sdio_sync_ext(int nint /*  how mant interrupts to enable. */)
  *
  ********************************************/
 
-struct wilc_hif_func hif_sdio = {
-       sdio_init,
-       sdio_deinit,
-       sdio_read_reg,
-       sdio_write_reg,
-       sdio_read,
-       sdio_write,
-       sdio_sync,
-       sdio_clear_int,
-       sdio_read_int,
-       sdio_clear_int_ext,
-       sdio_read_size,
-       sdio_write,
-       sdio_read,
-       sdio_sync_ext,
-
-       sdio_set_max_speed,
-       sdio_set_default_speed,
+const struct wilc_hif_func wilc_hif_sdio = {
+       .hif_init = sdio_init,
+       .hif_deinit = sdio_deinit,
+       .hif_read_reg = sdio_read_reg,
+       .hif_write_reg = sdio_write_reg,
+       .hif_block_rx = sdio_read,
+       .hif_block_tx = sdio_write,
+       .hif_read_int = sdio_read_int,
+       .hif_clear_int_ext = sdio_clear_int_ext,
+       .hif_read_size = sdio_read_size,
+       .hif_block_tx_ext = sdio_write,
+       .hif_block_rx_ext = sdio_read,
+       .hif_sync_ext = sdio_sync_ext,
+       .enable_interrupt = wilc_sdio_enable_interrupt,
+       .disable_interrupt = wilc_sdio_disable_interrupt,
 };
 
index 3741836dad4198c6e819abcd11bd6b57ed88db34..86de50c9f7f5ff4faa9f4bcdc2c81b1068b5a8b9 100644 (file)
@@ -6,15 +6,25 @@
 /*  */
 /*  */
 /* //////////////////////////////////////////////////////////////////////////// */
-
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+#include <linux/cdev.h>
+#include <linux/uaccess.h>
+#include <linux/device.h>
+#include <linux/spi/spi.h>
+#include <linux/of_gpio.h>
+
+#include "linux_wlan_common.h"
 #include <linux/string.h>
 #include "wilc_wlan_if.h"
 #include "wilc_wlan.h"
-#include "linux_wlan_spi.h"
 #include "wilc_wfi_netdevice.h"
 
 typedef struct {
-       wilc_debug_func dPrint;
        int crc_off;
        int nint;
        int has_thrpt_enh;
@@ -22,8 +32,8 @@ typedef struct {
 
 static wilc_spi_t g_spi;
 
-static int wilc_spi_read(u32, u8 *, u32);
-static int wilc_spi_write(u32, u8 *, u32);
+static int wilc_spi_read(struct wilc *wilc, u32, u8 *, u32);
+static int wilc_spi_write(struct wilc *wilc, u32, u8 *, u32);
 
 /********************************************
  *
@@ -108,165 +118,175 @@ static u8 crc7(u8 crc, const u8 *buffer, u32 len)
 #define DATA_PKT_SZ_8K                         (8 * 1024)
 #define DATA_PKT_SZ                                    DATA_PKT_SZ_8K
 
-static int spi_cmd(u8 cmd, u32 adr, u32 data, u32 sz, u8 clockless)
+#define USE_SPI_DMA     0
+
+static const struct wilc1000_ops wilc1000_spi_ops;
+
+static int wilc_bus_probe(struct spi_device *spi)
 {
-       u8 bc[9];
-       int len = 5;
-       int result = N_OK;
+       int ret, gpio;
+       struct wilc *wilc;
 
-       bc[0] = cmd;
-       switch (cmd) {
-       case CMD_SINGLE_READ:                           /* single word (4 bytes) read */
-               bc[1] = (u8)(adr >> 16);
-               bc[2] = (u8)(adr >> 8);
-               bc[3] = (u8)adr;
-               len = 5;
-               break;
+       gpio = of_get_gpio(spi->dev.of_node, 0);
+       if (gpio < 0)
+               gpio = GPIO_NUM;
 
-       case CMD_INTERNAL_READ:                 /* internal register read */
-               bc[1] = (u8)(adr >> 8);
-               if (clockless)
-                       bc[1] |= BIT(7);
-               bc[2] = (u8)adr;
-               bc[3] = 0x00;
-               len = 5;
-               break;
+       ret = wilc_netdev_init(&wilc, NULL, HIF_SPI, GPIO_NUM, &wilc_hif_spi);
+       if (ret)
+               return ret;
 
-       case CMD_TERMINATE:                                     /* termination */
-               bc[1] = 0x00;
-               bc[2] = 0x00;
-               bc[3] = 0x00;
-               len = 5;
-               break;
+       spi_set_drvdata(spi, wilc);
+       wilc->dev = &spi->dev;
 
-       case CMD_REPEAT:                                                /* repeat */
-               bc[1] = 0x00;
-               bc[2] = 0x00;
-               bc[3] = 0x00;
-               len = 5;
-               break;
+       return 0;
+}
 
-       case CMD_RESET:                                                 /* reset */
-               bc[1] = 0xff;
-               bc[2] = 0xff;
-               bc[3] = 0xff;
-               len = 5;
-               break;
+static int wilc_bus_remove(struct spi_device *spi)
+{
+       wilc_netdev_cleanup(spi_get_drvdata(spi));
+       return 0;
+}
 
-       case CMD_DMA_WRITE:                                     /* dma write */
-       case CMD_DMA_READ:                                      /* dma read */
-               bc[1] = (u8)(adr >> 16);
-               bc[2] = (u8)(adr >> 8);
-               bc[3] = (u8)adr;
-               bc[4] = (u8)(sz >> 8);
-               bc[5] = (u8)(sz);
-               len = 7;
-               break;
+static const struct of_device_id wilc1000_of_match[] = {
+       { .compatible = "atmel,wilc_spi", },
+       {}
+};
+MODULE_DEVICE_TABLE(of, wilc1000_of_match);
+
+struct spi_driver wilc1000_spi_driver = {
+       .driver = {
+               .name = MODALIAS,
+               .of_match_table = wilc1000_of_match,
+       },
+       .probe =  wilc_bus_probe,
+       .remove = wilc_bus_remove,
+};
+module_spi_driver(wilc1000_spi_driver);
+MODULE_LICENSE("GPL");
 
-       case CMD_DMA_EXT_WRITE:         /* dma extended write */
-       case CMD_DMA_EXT_READ:                  /* dma extended read */
-               bc[1] = (u8)(adr >> 16);
-               bc[2] = (u8)(adr >> 8);
-               bc[3] = (u8)adr;
-               bc[4] = (u8)(sz >> 16);
-               bc[5] = (u8)(sz >> 8);
-               bc[6] = (u8)(sz);
-               len = 8;
-               break;
+static int wilc_spi_tx(struct wilc *wilc, u8 *b, u32 len)
+{
+       struct spi_device *spi = to_spi_device(wilc->dev);
+       int ret;
+       struct spi_message msg;
 
-       case CMD_INTERNAL_WRITE:                /* internal register write */
-               bc[1] = (u8)(adr >> 8);
-               if (clockless)
-                       bc[1] |= BIT(7);
-               bc[2] = (u8)(adr);
-               bc[3] = (u8)(data >> 24);
-               bc[4] = (u8)(data >> 16);
-               bc[5] = (u8)(data >> 8);
-               bc[6] = (u8)(data);
-               len = 8;
-               break;
+       if (len > 0 && b) {
+               struct spi_transfer tr = {
+                       .tx_buf = b,
+                       .len = len,
+                       .delay_usecs = 0,
+               };
+               char *r_buffer = kzalloc(len, GFP_KERNEL);
 
-       case CMD_SINGLE_WRITE:                  /* single word write */
-               bc[1] = (u8)(adr >> 16);
-               bc[2] = (u8)(adr >> 8);
-               bc[3] = (u8)(adr);
-               bc[4] = (u8)(data >> 24);
-               bc[5] = (u8)(data >> 16);
-               bc[6] = (u8)(data >> 8);
-               bc[7] = (u8)(data);
-               len = 9;
-               break;
+               if (!r_buffer)
+                       return -ENOMEM;
 
-       default:
-               result = N_FAIL;
-               break;
-       }
+               tr.rx_buf = r_buffer;
+               dev_dbg(&spi->dev, "Request writing %d bytes\n", len);
 
-       if (result) {
-               if (!g_spi.crc_off)
-                       bc[len - 1] = (crc7(0x7f, (const u8 *)&bc[0], len - 1)) << 1;
-               else
-                       len -= 1;
+               memset(&msg, 0, sizeof(msg));
+               spi_message_init(&msg);
+               msg.spi = spi;
+               msg.is_dma_mapped = USE_SPI_DMA;
+               spi_message_add_tail(&tr, &msg);
 
-               if (!linux_spi_write(bc, len)) {
-                       PRINT_ER("[wilc spi]: Failed cmd write, bus error...\n");
-                       result = N_FAIL;
-               }
+               ret = spi_sync(spi, &msg);
+               if (ret < 0)
+                       dev_err(&spi->dev, "SPI transaction failed\n");
+
+               kfree(r_buffer);
+       } else {
+               dev_err(&spi->dev,
+                       "can't write data with the following length: %d\n",
+                       len);
+               dev_err(&spi->dev,
+                       "FAILED due to NULL buffer or ZERO length check the following length: %d\n",
+                       len);
+               ret = -EINVAL;
        }
 
-       return result;
+       return ret;
 }
 
-static int spi_cmd_rsp(u8 cmd)
+static int wilc_spi_rx(struct wilc *wilc, u8 *rb, u32 rlen)
 {
-       u8 rsp;
-       int result = N_OK;
+       struct spi_device *spi = to_spi_device(wilc->dev);
+       int ret;
 
-       /**
-        *      Command/Control response
-        **/
-       if ((cmd == CMD_RESET) ||
-           (cmd == CMD_TERMINATE) ||
-           (cmd == CMD_REPEAT)) {
-               if (!linux_spi_read(&rsp, 1)) {
-                       result = N_FAIL;
-                       goto _fail_;
-               }
-       }
+       if (rlen > 0) {
+               struct spi_message msg;
+               struct spi_transfer tr = {
+                       .rx_buf = rb,
+                       .len = rlen,
+                       .delay_usecs = 0,
 
-       if (!linux_spi_read(&rsp, 1)) {
-               PRINT_ER("[wilc spi]: Failed cmd response read, bus error...\n");
-               result = N_FAIL;
-               goto _fail_;
-       }
+               };
+               char *t_buffer = kzalloc(rlen, GFP_KERNEL);
 
-       if (rsp != cmd) {
-               PRINT_ER("[wilc spi]: Failed cmd response, cmd (%02x), resp (%02x)\n", cmd, rsp);
-               result = N_FAIL;
-               goto _fail_;
-       }
+               if (!t_buffer)
+                       return -ENOMEM;
 
-       /**
-        *      State response
-        **/
-       if (!linux_spi_read(&rsp, 1)) {
-               PRINT_ER("[wilc spi]: Failed cmd state read, bus error...\n");
-               result = N_FAIL;
-               goto _fail_;
-       }
+               tr.tx_buf = t_buffer;
 
-       if (rsp != 0x00) {
-               PRINT_ER("[wilc spi]: Failed cmd state response state (%02x)\n", rsp);
-               result = N_FAIL;
+               memset(&msg, 0, sizeof(msg));
+               spi_message_init(&msg);
+               msg.spi = spi;
+               msg.is_dma_mapped = USE_SPI_DMA;
+               spi_message_add_tail(&tr, &msg);
+
+               ret = spi_sync(spi, &msg);
+               if (ret < 0)
+                       dev_err(&spi->dev, "SPI transaction failed\n");
+               kfree(t_buffer);
+       } else {
+               dev_err(&spi->dev,
+                       "can't read data with the following length: %u\n",
+                       rlen);
+               ret = -EINVAL;
        }
 
-_fail_:
+       return ret;
+}
 
-       return result;
+static int wilc_spi_tx_rx(struct wilc *wilc, u8 *wb, u8 *rb, u32 rlen)
+{
+       struct spi_device *spi = to_spi_device(wilc->dev);
+       int ret;
+
+       if (rlen > 0) {
+               struct spi_message msg;
+               struct spi_transfer tr = {
+                       .rx_buf = rb,
+                       .tx_buf = wb,
+                       .len = rlen,
+                       .bits_per_word = 8,
+                       .delay_usecs = 0,
+
+               };
+
+               memset(&msg, 0, sizeof(msg));
+               spi_message_init(&msg);
+               msg.spi = spi;
+               msg.is_dma_mapped = USE_SPI_DMA;
+
+               spi_message_add_tail(&tr, &msg);
+               ret = spi_sync(spi, &msg);
+               if (ret < 0)
+                       dev_err(&spi->dev, "SPI transaction failed\n");
+       } else {
+               dev_err(&spi->dev,
+                       "can't read data with the following length: %u\n",
+                       rlen);
+               ret = -EINVAL;
+       }
+
+       return ret;
 }
 
-static int spi_cmd_complete(u8 cmd, u32 adr, u8 *b, u32 sz, u8 clockless)
+static int spi_cmd_complete(struct wilc *wilc, u8 cmd, u32 adr, u8 *b, u32 sz,
+                           u8 clockless)
 {
+       struct spi_device *spi = to_spi_device(wilc->dev);
        u8 wb[32], rb[32];
        u8 wix, rix;
        u32 len2;
@@ -395,7 +415,7 @@ static int spi_cmd_complete(u8 cmd, u32 adr, u8 *b, u32 sz, u8 clockless)
 #undef NUM_DUMMY_BYTES
 
        if (len2 > ARRAY_SIZE(wb)) {
-               PRINT_ER("[wilc spi]: spi buffer size too small (%d) (%zu)\n",
+               dev_err(&spi->dev, "spi buffer size too small (%d) (%zu)\n",
                         len2, ARRAY_SIZE(wb));
                result = N_FAIL;
                return result;
@@ -406,8 +426,8 @@ static int spi_cmd_complete(u8 cmd, u32 adr, u8 *b, u32 sz, u8 clockless)
        }
        rix = len;
 
-       if (!linux_spi_write_read(wb, rb, len2)) {
-               PRINT_ER("[wilc spi]: Failed cmd write, bus error...\n");
+       if (wilc_spi_tx_rx(wilc, wb, rb, len2)) {
+               dev_err(&spi->dev, "Failed cmd write, bus error...\n");
                result = N_FAIL;
                return result;
        }
@@ -427,7 +447,7 @@ static int spi_cmd_complete(u8 cmd, u32 adr, u8 *b, u32 sz, u8 clockless)
        /* } while(&rptr[1] <= &rb[len2]); */
 
        if (rsp != cmd) {
-               PRINT_ER("[wilc spi]: Failed cmd response, cmd (%02x)"
+               dev_err(&spi->dev, "Failed cmd response, cmd (%02x)"
                         ", resp (%02x)\n", cmd, rsp);
                result = N_FAIL;
                return result;
@@ -438,8 +458,8 @@ static int spi_cmd_complete(u8 cmd, u32 adr, u8 *b, u32 sz, u8 clockless)
         **/
        rsp = rb[rix++];
        if (rsp != 0x00) {
-               PRINT_ER("[wilc spi]: Failed cmd state response "
-                        "state (%02x)\n", rsp);
+               dev_err(&spi->dev, "Failed cmd state response state (%02x)\n",
+                       rsp);
                result = N_FAIL;
                return result;
        }
@@ -466,8 +486,8 @@ static int spi_cmd_complete(u8 cmd, u32 adr, u8 *b, u32 sz, u8 clockless)
                } while (retry--);
 
                if (retry <= 0) {
-                       PRINT_ER("[wilc spi]: Error, data read "
-                                "response (%02x)\n", rsp);
+                       dev_err(&spi->dev,
+                               "Error, data read response (%02x)\n", rsp);
                        result = N_RESET;
                        return result;
                }
@@ -482,7 +502,8 @@ static int spi_cmd_complete(u8 cmd, u32 adr, u8 *b, u32 sz, u8 clockless)
                                b[2] = rb[rix++];
                                b[3] = rb[rix++];
                        } else {
-                               PRINT_ER("[wilc spi]: buffer overrun when reading data.\n");
+                               dev_err(&spi->dev,
+                                       "buffer overrun when reading data.\n");
                                result = N_FAIL;
                                return result;
                        }
@@ -495,7 +516,7 @@ static int spi_cmd_complete(u8 cmd, u32 adr, u8 *b, u32 sz, u8 clockless)
                                        crc[0] = rb[rix++];
                                        crc[1] = rb[rix++];
                                } else {
-                                       PRINT_ER("[wilc spi]: buffer overrun when reading crc.\n");
+                                       dev_err(&spi->dev,"buffer overrun when reading crc.\n");
                                        result = N_FAIL;
                                        return result;
                                }
@@ -521,8 +542,8 @@ static int spi_cmd_complete(u8 cmd, u32 adr, u8 *b, u32 sz, u8 clockless)
                                /**
                                 * Read bytes
                                 **/
-                               if (!linux_spi_read(&b[ix], nbytes)) {
-                                       PRINT_ER("[wilc spi]: Failed data block read, bus error...\n");
+                               if (wilc_spi_rx(wilc, &b[ix], nbytes)) {
+                                       dev_err(&spi->dev, "Failed data block read, bus error...\n");
                                        result = N_FAIL;
                                        goto _error_;
                                }
@@ -531,8 +552,8 @@ static int spi_cmd_complete(u8 cmd, u32 adr, u8 *b, u32 sz, u8 clockless)
                                 * Read Crc
                                 **/
                                if (!g_spi.crc_off) {
-                                       if (!linux_spi_read(crc, 2)) {
-                                               PRINT_ER("[wilc spi]: Failed data block crc read, bus error...\n");
+                                       if (wilc_spi_rx(wilc, crc, 2)) {
+                                               dev_err(&spi->dev, "Failed data block crc read, bus error...\n");
                                                result = N_FAIL;
                                                goto _error_;
                                        }
@@ -562,8 +583,8 @@ static int spi_cmd_complete(u8 cmd, u32 adr, u8 *b, u32 sz, u8 clockless)
                                 **/
                                retry = 10;
                                do {
-                                       if (!linux_spi_read(&rsp, 1)) {
-                                               PRINT_ER("[wilc spi]: Failed data response read, bus error...\n");
+                                       if (wilc_spi_rx(wilc, &rsp, 1)) {
+                                               dev_err(&spi->dev, "Failed data response read, bus error...\n");
                                                result = N_FAIL;
                                                break;
                                        }
@@ -578,8 +599,8 @@ static int spi_cmd_complete(u8 cmd, u32 adr, u8 *b, u32 sz, u8 clockless)
                                /**
                                 * Read bytes
                                 **/
-                               if (!linux_spi_read(&b[ix], nbytes)) {
-                                       PRINT_ER("[wilc spi]: Failed data block read, bus error...\n");
+                               if (wilc_spi_rx(wilc, &b[ix], nbytes)) {
+                                       dev_err(&spi->dev, "Failed data block read, bus error...\n");
                                        result = N_FAIL;
                                        break;
                                }
@@ -588,8 +609,8 @@ static int spi_cmd_complete(u8 cmd, u32 adr, u8 *b, u32 sz, u8 clockless)
                                 * Read Crc
                                 **/
                                if (!g_spi.crc_off) {
-                                       if (!linux_spi_read(crc, 2)) {
-                                               PRINT_ER("[wilc spi]: Failed data block crc read, bus error...\n");
+                                       if (wilc_spi_rx(wilc, crc, 2)) {
+                                               dev_err(&spi->dev, "Failed data block crc read, bus error...\n");
                                                result = N_FAIL;
                                                break;
                                        }
@@ -604,76 +625,9 @@ _error_:
        return result;
 }
 
-static int spi_data_read(u8 *b, u32 sz)
-{
-       int retry, ix, nbytes;
-       int result = N_OK;
-       u8 crc[2];
-       u8 rsp;
-
-       /**
-        *      Data
-        **/
-       ix = 0;
-       do {
-               if (sz <= DATA_PKT_SZ)
-                       nbytes = sz;
-               else
-                       nbytes = DATA_PKT_SZ;
-
-               /**
-                *      Data Respnose header
-                **/
-               retry = 10;
-               do {
-                       if (!linux_spi_read(&rsp, 1)) {
-                               PRINT_ER("[wilc spi]: Failed data response read, bus error...\n");
-                               result = N_FAIL;
-                               break;
-                       }
-                       if (((rsp >> 4) & 0xf) == 0xf)
-                               break;
-               } while (retry--);
-
-               if (result == N_FAIL)
-                       break;
-
-               if (retry <= 0) {
-                       PRINT_ER("[wilc spi]: Failed data response read...(%02x)\n", rsp);
-                       result = N_FAIL;
-                       break;
-               }
-
-               /**
-                *      Read bytes
-                **/
-               if (!linux_spi_read(&b[ix], nbytes)) {
-                       PRINT_ER("[wilc spi]: Failed data block read, bus error...\n");
-                       result = N_FAIL;
-                       break;
-               }
-
-               /**
-                *      Read Crc
-                **/
-               if (!g_spi.crc_off) {
-                       if (!linux_spi_read(crc, 2)) {
-                               PRINT_ER("[wilc spi]: Failed data block crc read, bus error...\n");
-                               result = N_FAIL;
-                               break;
-                       }
-               }
-
-               ix += nbytes;
-               sz -= nbytes;
-
-       } while (sz);
-
-       return result;
-}
-
-static int spi_data_write(u8 *b, u32 sz)
+static int spi_data_write(struct wilc *wilc, u8 *b, u32 sz)
 {
+       struct spi_device *spi = to_spi_device(wilc->dev);
        int ix, nbytes;
        int result = 1;
        u8 cmd, order, crc[2] = {0};
@@ -706,8 +660,9 @@ static int spi_data_write(u8 *b, u32 sz)
                                order = 0x2;
                }
                cmd |= order;
-               if (!linux_spi_write(&cmd, 1)) {
-                       PRINT_ER("[wilc spi]: Failed data block cmd write, bus error...\n");
+               if (wilc_spi_tx(wilc, &cmd, 1)) {
+                       dev_err(&spi->dev,
+                               "Failed data block cmd write, bus error...\n");
                        result = N_FAIL;
                        break;
                }
@@ -715,8 +670,9 @@ static int spi_data_write(u8 *b, u32 sz)
                /**
                 *      Write data
                 **/
-               if (!linux_spi_write(&b[ix], nbytes)) {
-                       PRINT_ER("[wilc spi]: Failed data block write, bus error...\n");
+               if (wilc_spi_tx(wilc, &b[ix], nbytes)) {
+                       dev_err(&spi->dev,
+                               "Failed data block write, bus error...\n");
                        result = N_FAIL;
                        break;
                }
@@ -725,8 +681,8 @@ static int spi_data_write(u8 *b, u32 sz)
                 *      Write Crc
                 **/
                if (!g_spi.crc_off) {
-                       if (!linux_spi_write(crc, 2)) {
-                               PRINT_ER("[wilc spi]: Failed data block crc write, bus error...\n");
+                       if (wilc_spi_tx(wilc, crc, 2)) {
+                               dev_err(&spi->dev,"Failed data block crc write, bus error...\n");
                                result = N_FAIL;
                                break;
                        }
@@ -749,34 +705,34 @@ static int spi_data_write(u8 *b, u32 sz)
  *
  ********************************************/
 
-static int spi_internal_write(u32 adr, u32 dat)
+static int spi_internal_write(struct wilc *wilc, u32 adr, u32 dat)
 {
+       struct spi_device *spi = to_spi_device(wilc->dev);
        int result;
 
-#ifdef BIG_ENDIAN
-       dat = BYTE_SWAP(dat);
-#endif
-       result = spi_cmd_complete(CMD_INTERNAL_WRITE, adr, (u8 *)&dat, 4, 0);
+       dat = cpu_to_le32(dat);
+       result = spi_cmd_complete(wilc, CMD_INTERNAL_WRITE, adr, (u8 *)&dat, 4,
+                                 0);
        if (result != N_OK) {
-               PRINT_ER("[wilc spi]: Failed internal write cmd...\n");
+               dev_err(&spi->dev, "Failed internal write cmd...\n");
        }
 
        return result;
 }
 
-static int spi_internal_read(u32 adr, u32 *data)
+static int spi_internal_read(struct wilc *wilc, u32 adr, u32 *data)
 {
+       struct spi_device *spi = to_spi_device(wilc->dev);
        int result;
 
-       result = spi_cmd_complete(CMD_INTERNAL_READ, adr, (u8 *)data, 4, 0);
+       result = spi_cmd_complete(wilc, CMD_INTERNAL_READ, adr, (u8 *)data, 4,
+                                 0);
        if (result != N_OK) {
-               PRINT_ER("[wilc spi]: Failed internal read cmd...\n");
+               dev_err(&spi->dev, "Failed internal read cmd...\n");
                return 0;
        }
 
-#ifdef BIG_ENDIAN
-       *data = BYTE_SWAP(*data);
-#endif
+       *data = cpu_to_le32(*data);
 
        return 1;
 }
@@ -787,31 +743,31 @@ static int spi_internal_read(u32 adr, u32 *data)
  *
  ********************************************/
 
-static int wilc_spi_write_reg(u32 addr, u32 data)
+static int wilc_spi_write_reg(struct wilc *wilc, u32 addr, u32 data)
 {
+       struct spi_device *spi = to_spi_device(wilc->dev);
        int result = N_OK;
        u8 cmd = CMD_SINGLE_WRITE;
        u8 clockless = 0;
 
-#ifdef BIG_ENDIAN
-       data = BYTE_SWAP(data);
-#endif
+       data = cpu_to_le32(data);
        if (addr < 0x30) {
                /* Clockless register*/
                cmd = CMD_INTERNAL_WRITE;
                clockless = 1;
        }
 
-       result = spi_cmd_complete(cmd, addr, (u8 *)&data, 4, clockless);
+       result = spi_cmd_complete(wilc, cmd, addr, (u8 *)&data, 4, clockless);
        if (result != N_OK) {
-               PRINT_ER("[wilc spi]: Failed cmd, write reg (%08x)...\n", addr);
+               dev_err(&spi->dev, "Failed cmd, write reg (%08x)...\n", addr);
        }
 
        return result;
 }
 
-static int wilc_spi_write(u32 addr, u8 *buf, u32 size)
+static int wilc_spi_write(struct wilc *wilc, u32 addr, u8 *buf, u32 size)
 {
+       struct spi_device *spi = to_spi_device(wilc->dev);
        int result;
        u8 cmd = CMD_DMA_EXT_WRITE;
 
@@ -821,60 +777,61 @@ static int wilc_spi_write(u32 addr, u8 *buf, u32 size)
        if (size <= 4)
                return 0;
 
-       result = spi_cmd_complete(cmd, addr, NULL, size, 0);
+       result = spi_cmd_complete(wilc, cmd, addr, NULL, size, 0);
        if (result != N_OK) {
-               PRINT_ER("[wilc spi]: Failed cmd, write block (%08x)...\n", addr);
+               dev_err(&spi->dev,
+                       "Failed cmd, write block (%08x)...\n", addr);
                return 0;
        }
 
        /**
         *      Data
         **/
-       result = spi_data_write(buf, size);
+       result = spi_data_write(wilc, buf, size);
        if (result != N_OK) {
-               PRINT_ER("[wilc spi]: Failed block data write...\n");
+               dev_err(&spi->dev, "Failed block data write...\n");
        }
 
        return 1;
 }
 
-static int wilc_spi_read_reg(u32 addr, u32 *data)
+static int wilc_spi_read_reg(struct wilc *wilc, u32 addr, u32 *data)
 {
+       struct spi_device *spi = to_spi_device(wilc->dev);
        int result = N_OK;
        u8 cmd = CMD_SINGLE_READ;
        u8 clockless = 0;
 
        if (addr < 0x30) {
-               /* PRINT_ER("***** read addr %d\n\n", addr); */
+               /* dev_err(&spi->dev, "***** read addr %d\n\n", addr); */
                /* Clockless register*/
                cmd = CMD_INTERNAL_READ;
                clockless = 1;
        }
 
-       result = spi_cmd_complete(cmd, addr, (u8 *)data, 4, clockless);
+       result = spi_cmd_complete(wilc, cmd, addr, (u8 *)data, 4, clockless);
        if (result != N_OK) {
-               PRINT_ER("[wilc spi]: Failed cmd, read reg (%08x)...\n", addr);
+               dev_err(&spi->dev, "Failed cmd, read reg (%08x)...\n", addr);
                return 0;
        }
 
-#ifdef BIG_ENDIAN
-       *data = BYTE_SWAP(*data);
-#endif
+       *data = cpu_to_le32(*data);
 
        return 1;
 }
 
-static int wilc_spi_read(u32 addr, u8 *buf, u32 size)
+static int wilc_spi_read(struct wilc *wilc, u32 addr, u8 *buf, u32 size)
 {
+       struct spi_device *spi = to_spi_device(wilc->dev);
        u8 cmd = CMD_DMA_EXT_READ;
        int result;
 
        if (size <= 4)
                return 0;
 
-       result = spi_cmd_complete(cmd, addr, buf, size, 0);
+       result = spi_cmd_complete(wilc, cmd, addr, buf, size, 0);
        if (result != N_OK) {
-               PRINT_ER("[wilc spi]: Failed cmd, read block (%08x)...\n", addr);
+               dev_err(&spi->dev, "Failed cmd, read block (%08x)...\n", addr);
                return 0;
        }
 
@@ -887,20 +844,7 @@ static int wilc_spi_read(u32 addr, u8 *buf, u32 size)
  *
  ********************************************/
 
-static int wilc_spi_clear_int(void)
-{
-       u32 reg;
-
-       if (!wilc_spi_read_reg(WILC_HOST_RX_CTRL_0, &reg)) {
-               PRINT_ER("[wilc spi]: Failed read reg (%08x)...\n", WILC_HOST_RX_CTRL_0);
-               return 0;
-       }
-       reg &= ~0x1;
-       wilc_spi_write_reg(WILC_HOST_RX_CTRL_0, reg);
-       return 1;
-}
-
-static int wilc_spi_deinit(void *pv)
+static int _wilc_spi_deinit(struct wilc *wilc)
 {
        /**
         *      TODO:
@@ -908,46 +852,9 @@ static int wilc_spi_deinit(void *pv)
        return 1;
 }
 
-static int wilc_spi_sync(void)
-{
-       u32 reg;
-       int ret;
-
-       /**
-        *      interrupt pin mux select
-        **/
-       ret = wilc_spi_read_reg(WILC_PIN_MUX_0, &reg);
-       if (!ret) {
-               PRINT_ER("[wilc spi]: Failed read reg (%08x)...\n", WILC_PIN_MUX_0);
-               return 0;
-       }
-       reg |= BIT(8);
-       ret = wilc_spi_write_reg(WILC_PIN_MUX_0, reg);
-       if (!ret) {
-               PRINT_ER("[wilc spi]: Failed write reg (%08x)...\n", WILC_PIN_MUX_0);
-               return 0;
-       }
-
-       /**
-        *      interrupt enable
-        **/
-       ret = wilc_spi_read_reg(WILC_INTR_ENABLE, &reg);
-       if (!ret) {
-               PRINT_ER("[wilc spi]: Failed read reg (%08x)...\n", WILC_INTR_ENABLE);
-               return 0;
-       }
-       reg |= BIT(16);
-       ret = wilc_spi_write_reg(WILC_INTR_ENABLE, reg);
-       if (!ret) {
-               PRINT_ER("[wilc spi]: Failed write reg (%08x)...\n", WILC_INTR_ENABLE);
-               return 0;
-       }
-
-       return 1;
-}
-
-static int wilc_spi_init(struct wilc *wilc, wilc_debug_func func)
+static int wilc_spi_init(struct wilc *wilc)
 {
+       struct spi_device *spi = to_spi_device(wilc->dev);
        u32 reg;
        u32 chipid;
 
@@ -955,8 +862,8 @@ static int wilc_spi_init(struct wilc *wilc, wilc_debug_func func)
 
        if (isinit) {
 
-               if (!wilc_spi_read_reg(0x1000, &chipid)) {
-                       PRINT_ER("[wilc spi]: Fail cmd read chip id...\n");
+               if (!wilc_spi_read_reg(wilc, 0x1000, &chipid)) {
+                       dev_err(&spi->dev, "Fail cmd read chip id...\n");
                        return 0;
                }
                return 1;
@@ -964,14 +871,6 @@ static int wilc_spi_init(struct wilc *wilc, wilc_debug_func func)
 
        memset(&g_spi, 0, sizeof(wilc_spi_t));
 
-       g_spi.dPrint = func;
-       if (!linux_spi_init()) {
-               PRINT_ER("[wilc spi]: Failed io init bus...\n");
-               return 0;
-       } else {
-               return 0;
-       }
-
        /**
         *      configure protocol
         **/
@@ -979,14 +878,15 @@ static int wilc_spi_init(struct wilc *wilc, wilc_debug_func func)
 
        /* TODO: We can remove the CRC trials if there is a definite way to reset */
        /* the SPI to it's initial value. */
-       if (!spi_internal_read(WILC_SPI_PROTOCOL_OFFSET, &reg)) {
+       if (!spi_internal_read(wilc, WILC_SPI_PROTOCOL_OFFSET, &reg)) {
                /* Read failed. Try with CRC off. This might happen when module
                 * is removed but chip isn't reset*/
                g_spi.crc_off = 1;
-               PRINT_ER("[wilc spi]: Failed internal read protocol with CRC on, retyring with CRC off...\n");
-               if (!spi_internal_read(WILC_SPI_PROTOCOL_OFFSET, &reg)) {
+               dev_err(&spi->dev, "Failed internal read protocol with CRC on, retyring with CRC off...\n");
+               if (!spi_internal_read(wilc, WILC_SPI_PROTOCOL_OFFSET, &reg)) {
                        /* Reaad failed with both CRC on and off, something went bad */
-                       PRINT_ER("[wilc spi]: Failed internal read protocol...\n");
+                       dev_err(&spi->dev,
+                               "Failed internal read protocol...\n");
                        return 0;
                }
        }
@@ -994,8 +894,8 @@ static int wilc_spi_init(struct wilc *wilc, wilc_debug_func func)
                reg &= ~0xc;    /* disable crc checking */
                reg &= ~0x70;
                reg |= (0x5 << 4);
-               if (!spi_internal_write(WILC_SPI_PROTOCOL_OFFSET, reg)) {
-                       PRINT_ER("[wilc spi %d]: Failed internal write protocol reg...\n", __LINE__);
+               if (!spi_internal_write(wilc, WILC_SPI_PROTOCOL_OFFSET, reg)) {
+                       dev_err(&spi->dev, "[wilc spi %d]: Failed internal write protocol reg...\n", __LINE__);
                        return 0;
                }
                g_spi.crc_off = 1;
@@ -1005,11 +905,11 @@ static int wilc_spi_init(struct wilc *wilc, wilc_debug_func func)
        /**
         *      make sure can read back chip id correctly
         **/
-       if (!wilc_spi_read_reg(0x1000, &chipid)) {
-               PRINT_ER("[wilc spi]: Fail cmd read chip id...\n");
+       if (!wilc_spi_read_reg(wilc, 0x1000, &chipid)) {
+               dev_err(&spi->dev, "Fail cmd read chip id...\n");
                return 0;
        }
-       /* PRINT_ER("[wilc spi]: chipid (%08x)\n", chipid); */
+       /* dev_err(&spi->dev, "chipid (%08x)\n", chipid); */
 
        g_spi.has_thrpt_enh = 1;
 
@@ -1018,29 +918,24 @@ static int wilc_spi_init(struct wilc *wilc, wilc_debug_func func)
        return 1;
 }
 
-static void wilc_spi_max_bus_speed(void)
-{
-       linux_spi_set_max_speed();
-}
-
-static void wilc_spi_default_bus_speed(void)
-{
-}
-
-static int wilc_spi_read_size(u32 *size)
+static int wilc_spi_read_size(struct wilc *wilc, u32 *size)
 {
+       struct spi_device *spi = to_spi_device(wilc->dev);
        int ret;
 
        if (g_spi.has_thrpt_enh) {
-               ret = spi_internal_read(0xe840 - WILC_SPI_REG_BASE, size);
+               ret = spi_internal_read(wilc, 0xe840 - WILC_SPI_REG_BASE,
+                                       size);
                *size = *size  & IRQ_DMA_WD_CNT_MASK;
        } else {
                u32 tmp;
                u32 byte_cnt;
 
-               ret = wilc_spi_read_reg(WILC_VMM_TO_HOST_SIZE, &byte_cnt);
+               ret = wilc_spi_read_reg(wilc, WILC_VMM_TO_HOST_SIZE,
+                                       &byte_cnt);
                if (!ret) {
-                       PRINT_ER("[wilc spi]: Failed read WILC_VMM_TO_HOST_SIZE ...\n");
+                       dev_err(&spi->dev,
+                               "Failed read WILC_VMM_TO_HOST_SIZE ...\n");
                        goto _fail_;
                }
                tmp = (byte_cnt >> 2) & IRQ_DMA_WD_CNT_MASK;
@@ -1055,19 +950,23 @@ _fail_:
 
 
 
-static int wilc_spi_read_int(u32 *int_status)
+static int wilc_spi_read_int(struct wilc *wilc, u32 *int_status)
 {
+       struct spi_device *spi = to_spi_device(wilc->dev);
        int ret;
 
        if (g_spi.has_thrpt_enh) {
-               ret = spi_internal_read(0xe840 - WILC_SPI_REG_BASE, int_status);
+               ret = spi_internal_read(wilc, 0xe840 - WILC_SPI_REG_BASE,
+                                       int_status);
        } else {
                u32 tmp;
                u32 byte_cnt;
 
-               ret = wilc_spi_read_reg(WILC_VMM_TO_HOST_SIZE, &byte_cnt);
+               ret = wilc_spi_read_reg(wilc, WILC_VMM_TO_HOST_SIZE,
+                                       &byte_cnt);
                if (!ret) {
-                       PRINT_ER("[wilc spi]: Failed read WILC_VMM_TO_HOST_SIZE ...\n");
+                       dev_err(&spi->dev,
+                               "Failed read WILC_VMM_TO_HOST_SIZE ...\n");
                        goto _fail_;
                }
                tmp = (byte_cnt >> 2) & IRQ_DMA_WD_CNT_MASK;
@@ -1081,11 +980,12 @@ static int wilc_spi_read_int(u32 *int_status)
 
                                happended = 0;
 
-                               wilc_spi_read_reg(0x1a90, &irq_flags);
+                               wilc_spi_read_reg(wilc, 0x1a90, &irq_flags);
                                tmp |= ((irq_flags >> 27) << IRG_FLAGS_OFFSET);
 
                                if (g_spi.nint > 5) {
-                                       wilc_spi_read_reg(0x1a94, &irq_flags);
+                                       wilc_spi_read_reg(wilc, 0x1a94,
+                                                         &irq_flags);
                                        tmp |= (((irq_flags >> 0) & 0x7) << (IRG_FLAGS_OFFSET + 5));
                                }
 
@@ -1095,7 +995,7 @@ static int wilc_spi_read_int(u32 *int_status)
                                        unkmown_mask = ~((1ul << g_spi.nint) - 1);
 
                                        if ((tmp >> IRG_FLAGS_OFFSET) & unkmown_mask) {
-                                               PRINT_ER("[wilc spi]: Unexpected interrupt (2): j=%d, tmp=%x, mask=%x\n", j, tmp, unkmown_mask);
+                                               dev_err(&spi->dev, "Unexpected interrupt (2): j=%d, tmp=%x, mask=%x\n", j, tmp, unkmown_mask);
                                                happended = 1;
                                        }
                                }
@@ -1111,12 +1011,14 @@ _fail_:
        return ret;
 }
 
-static int wilc_spi_clear_int_ext(u32 val)
+static int wilc_spi_clear_int_ext(struct wilc *wilc, u32 val)
 {
+       struct spi_device *spi = to_spi_device(wilc->dev);
        int ret;
 
        if (g_spi.has_thrpt_enh) {
-               ret = spi_internal_write(0xe844 - WILC_SPI_REG_BASE, val);
+               ret = spi_internal_write(wilc, 0xe844 - WILC_SPI_REG_BASE,
+                                        val);
        } else {
                u32 flags;
 
@@ -1128,18 +1030,22 @@ static int wilc_spi_clear_int_ext(u32 val)
                        for (i = 0; i < g_spi.nint; i++) {
                                /* No matter what you write 1 or 0, it will clear interrupt. */
                                if (flags & 1)
-                                       ret = wilc_spi_write_reg(0x10c8 + i * 4, 1);
+                                       ret = wilc_spi_write_reg(wilc, 0x10c8 + i * 4, 1);
                                if (!ret)
                                        break;
                                flags >>= 1;
                        }
                        if (!ret) {
-                               PRINT_ER("[wilc spi]: Failed wilc_spi_write_reg, set reg %x ...\n", 0x10c8 + i * 4);
+                               dev_err(&spi->dev,
+                                       "Failed wilc_spi_write_reg, set reg %x ...\n",
+                                       0x10c8 + i * 4);
                                goto _fail_;
                        }
                        for (i = g_spi.nint; i < MAX_NUM_INT; i++) {
                                if (flags & 1)
-                                       PRINT_ER("[wilc spi]: Unexpected interrupt cleared %d...\n", i);
+                                       dev_err(&spi->dev,
+                                               "Unexpected interrupt cleared %d...\n",
+                                               i);
                                flags >>= 1;
                        }
                }
@@ -1155,9 +1061,11 @@ static int wilc_spi_clear_int_ext(u32 val)
                        if ((val & SEL_VMM_TBL1) == SEL_VMM_TBL1)
                                tbl_ctl |= BIT(1);
 
-                       ret = wilc_spi_write_reg(WILC_VMM_TBL_CTL, tbl_ctl);
+                       ret = wilc_spi_write_reg(wilc, WILC_VMM_TBL_CTL,
+                                                tbl_ctl);
                        if (!ret) {
-                               PRINT_ER("[wilc spi]: fail write reg vmm_tbl_ctl...\n");
+                               dev_err(&spi->dev,
+                                       "fail write reg vmm_tbl_ctl...\n");
                                goto _fail_;
                        }
 
@@ -1165,9 +1073,10 @@ static int wilc_spi_clear_int_ext(u32 val)
                                /**
                                 *      enable vmm transfer.
                                 **/
-                               ret = wilc_spi_write_reg(WILC_VMM_CORE_CTL, 1);
+                               ret = wilc_spi_write_reg(wilc,
+                                                        WILC_VMM_CORE_CTL, 1);
                                if (!ret) {
-                                       PRINT_ER("[wilc spi]: fail write reg vmm_core_ctl...\n");
+                                       dev_err(&spi->dev,"fail write reg vmm_core_ctl...\n");
                                        goto _fail_;
                                }
                        }
@@ -1177,13 +1086,14 @@ _fail_:
        return ret;
 }
 
-static int wilc_spi_sync_ext(int nint /*  how mant interrupts to enable. */)
+static int wilc_spi_sync_ext(struct wilc *wilc, int nint)
 {
+       struct spi_device *spi = to_spi_device(wilc->dev);
        u32 reg;
        int ret, i;
 
        if (nint > MAX_NUM_INT) {
-               PRINT_ER("[wilc spi]: Too many interupts (%d)...\n", nint);
+               dev_err(&spi->dev, "Too many interupts (%d)...\n", nint);
                return 0;
        }
 
@@ -1192,39 +1102,44 @@ static int wilc_spi_sync_ext(int nint /*  how mant interrupts to enable. */)
        /**
         *      interrupt pin mux select
         **/
-       ret = wilc_spi_read_reg(WILC_PIN_MUX_0, &reg);
+       ret = wilc_spi_read_reg(wilc, WILC_PIN_MUX_0, &reg);
        if (!ret) {
-               PRINT_ER("[wilc spi]: Failed read reg (%08x)...\n", WILC_PIN_MUX_0);
+               dev_err(&spi->dev, "Failed read reg (%08x)...\n",
+                       WILC_PIN_MUX_0);
                return 0;
        }
        reg |= BIT(8);
-       ret = wilc_spi_write_reg(WILC_PIN_MUX_0, reg);
+       ret = wilc_spi_write_reg(wilc, WILC_PIN_MUX_0, reg);
        if (!ret) {
-               PRINT_ER("[wilc spi]: Failed write reg (%08x)...\n", WILC_PIN_MUX_0);
+               dev_err(&spi->dev, "Failed write reg (%08x)...\n",
+                       WILC_PIN_MUX_0);
                return 0;
        }
 
        /**
         *      interrupt enable
         **/
-       ret = wilc_spi_read_reg(WILC_INTR_ENABLE, &reg);
+       ret = wilc_spi_read_reg(wilc, WILC_INTR_ENABLE, &reg);
        if (!ret) {
-               PRINT_ER("[wilc spi]: Failed read reg (%08x)...\n", WILC_INTR_ENABLE);
+               dev_err(&spi->dev, "Failed read reg (%08x)...\n",
+                       WILC_INTR_ENABLE);
                return 0;
        }
 
        for (i = 0; (i < 5) && (nint > 0); i++, nint--) {
                reg |= (BIT((27 + i)));
        }
-       ret = wilc_spi_write_reg(WILC_INTR_ENABLE, reg);
+       ret = wilc_spi_write_reg(wilc, WILC_INTR_ENABLE, reg);
        if (!ret) {
-               PRINT_ER("[wilc spi]: Failed write reg (%08x)...\n", WILC_INTR_ENABLE);
+               dev_err(&spi->dev, "Failed write reg (%08x)...\n",
+                       WILC_INTR_ENABLE);
                return 0;
        }
        if (nint) {
-               ret = wilc_spi_read_reg(WILC_INTR2_ENABLE, &reg);
+               ret = wilc_spi_read_reg(wilc, WILC_INTR2_ENABLE, &reg);
                if (!ret) {
-                       PRINT_ER("[wilc spi]: Failed read reg (%08x)...\n", WILC_INTR2_ENABLE);
+                       dev_err(&spi->dev, "Failed read reg (%08x)...\n",
+                               WILC_INTR2_ENABLE);
                        return 0;
                }
 
@@ -1232,9 +1147,10 @@ static int wilc_spi_sync_ext(int nint /*  how mant interrupts to enable. */)
                        reg |= BIT(i);
                }
 
-               ret = wilc_spi_read_reg(WILC_INTR2_ENABLE, &reg);
+               ret = wilc_spi_read_reg(wilc, WILC_INTR2_ENABLE, &reg);
                if (!ret) {
-                       PRINT_ER("[wilc spi]: Failed write reg (%08x)...\n", WILC_INTR2_ENABLE);
+                       dev_err(&spi->dev, "Failed write reg (%08x)...\n",
+                               WILC_INTR2_ENABLE);
                        return 0;
                }
        }
@@ -1246,21 +1162,17 @@ static int wilc_spi_sync_ext(int nint /*  how mant interrupts to enable. */)
  *      Global spi HIF function table
  *
  ********************************************/
-struct wilc_hif_func hif_spi = {
-       wilc_spi_init,
-       wilc_spi_deinit,
-       wilc_spi_read_reg,
-       wilc_spi_write_reg,
-       wilc_spi_read,
-       wilc_spi_write,
-       wilc_spi_sync,
-       wilc_spi_clear_int,
-       wilc_spi_read_int,
-       wilc_spi_clear_int_ext,
-       wilc_spi_read_size,
-       wilc_spi_write,
-       wilc_spi_read,
-       wilc_spi_sync_ext,
-       wilc_spi_max_bus_speed,
-       wilc_spi_default_bus_speed,
+const struct wilc_hif_func wilc_hif_spi = {
+       .hif_init = wilc_spi_init,
+       .hif_deinit = _wilc_spi_deinit,
+       .hif_read_reg = wilc_spi_read_reg,
+       .hif_write_reg = wilc_spi_write_reg,
+       .hif_block_rx = wilc_spi_read,
+       .hif_block_tx = wilc_spi_write,
+       .hif_read_int = wilc_spi_read_int,
+       .hif_clear_int_ext = wilc_spi_clear_int_ext,
+       .hif_read_size = wilc_spi_read_size,
+       .hif_block_tx_ext = wilc_spi_write,
+       .hif_block_rx_ext = wilc_spi_read,
+       .hif_sync_ext = wilc_spi_sync_ext,
 };
index 6f405221030cb7376a0d85a8858f1741c72cd8d7..53fb2d4bb0bd11c9038b2b05c42979dee3bd722a 100644 (file)
-/*!
- *  @file      wilc_wfi_cfgopertaions.c
- *  @brief     CFG80211 Function Implementation functionality
- *  @author    aabouzaeid
- *                      mabubakr
- *                      mdaftedar
- *                      zsalah
- *  @sa                wilc_wfi_cfgopertaions.h top level OS wrapper file
- *  @date      31 Aug 2010
- *  @version   1.0
- */
-
 #include "wilc_wfi_cfgoperations.h"
-#ifdef WILC_SDIO
-#include "linux_wlan_sdio.h"
-#endif
+#include "host_interface.h"
 #include <linux/errno.h>
 
+#define NO_ENCRYPT             0
+#define ENCRYPT_ENABLED                BIT(0)
+#define WEP                    BIT(1)
+#define WEP_EXTENDED           BIT(2)
+#define WPA                    BIT(3)
+#define WPA2                   BIT(4)
+#define AES                    BIT(5)
+#define TKIP                   BIT(6)
+
+#define FRAME_TYPE_ID                  0
+#define ACTION_CAT_ID                  24
+#define ACTION_SUBTYPE_ID              25
+#define P2P_PUB_ACTION_SUBTYPE         30
+
+#define ACTION_FRAME                   0xd0
+#define GO_INTENT_ATTR_ID              0x04
+#define CHANLIST_ATTR_ID               0x0b
+#define OPERCHAN_ATTR_ID               0x11
+#define PUB_ACTION_ATTR_ID             0x04
+#define P2PELEM_ATTR_ID                        0xdd
+
+#define GO_NEG_REQ                     0x00
+#define GO_NEG_RSP                     0x01
+#define GO_NEG_CONF                    0x02
+#define P2P_INV_REQ                    0x03
+#define P2P_INV_RSP                    0x04
+#define PUBLIC_ACT_VENDORSPEC          0x09
+#define GAS_INTIAL_REQ                 0x0a
+#define GAS_INTIAL_RSP                 0x0b
+
+#define INVALID_CHANNEL                        0
+
+#define nl80211_SCAN_RESULT_EXPIRE     (3 * HZ)
+#define SCAN_RESULT_EXPIRE             (40 * HZ)
+
+static const u32 cipher_suites[] = {
+       WLAN_CIPHER_SUITE_WEP40,
+       WLAN_CIPHER_SUITE_WEP104,
+       WLAN_CIPHER_SUITE_TKIP,
+       WLAN_CIPHER_SUITE_CCMP,
+       WLAN_CIPHER_SUITE_AES_CMAC,
+};
+
+static const struct ieee80211_txrx_stypes
+       wilc_wfi_cfg80211_mgmt_types[NUM_NL80211_IFTYPES] = {
+       [NL80211_IFTYPE_STATION] = {
+               .tx = 0xffff,
+               .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
+                       BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
+       },
+       [NL80211_IFTYPE_AP] = {
+               .tx = 0xffff,
+               .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
+                       BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
+                       BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
+                       BIT(IEEE80211_STYPE_DISASSOC >> 4) |
+                       BIT(IEEE80211_STYPE_AUTH >> 4) |
+                       BIT(IEEE80211_STYPE_DEAUTH >> 4) |
+                       BIT(IEEE80211_STYPE_ACTION >> 4)
+       },
+       [NL80211_IFTYPE_P2P_CLIENT] = {
+               .tx = 0xffff,
+               .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
+                       BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
+                       BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
+                       BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
+                       BIT(IEEE80211_STYPE_DISASSOC >> 4) |
+                       BIT(IEEE80211_STYPE_AUTH >> 4) |
+                       BIT(IEEE80211_STYPE_DEAUTH >> 4)
+       }
+};
+
+#define WILC_WFI_DWELL_PASSIVE 100
+#define WILC_WFI_DWELL_ACTIVE  40
+
+#define TCP_ACK_FILTER_LINK_SPEED_THRESH       54
+#define DEFAULT_LINK_SPEED                     72
+
+
 #define IS_MANAGMEMENT                         0x100
 #define IS_MANAGMEMENT_CALLBACK                        0x080
 #define IS_MGMT_STATUS_SUCCES                  0x040
 #define GET_PKT_OFFSET(a) (((a) >> 22) & 0x1ff)
 
-extern int mac_open(struct net_device *ndev);
-extern int mac_close(struct net_device *ndev);
+extern int wilc_mac_open(struct net_device *ndev);
+extern int wilc_mac_close(struct net_device *ndev);
 
-tstrNetworkInfo astrLastScannedNtwrksShadow[MAX_NUM_SCANNED_NETWORKS_SHADOW];
-u32 u32LastScannedNtwrksCountShadow;
-struct timer_list hDuringIpTimer;
-struct timer_list hAgingTimer;
+static tstrNetworkInfo last_scanned_shadow[MAX_NUM_SCANNED_NETWORKS_SHADOW];
+static u32 last_scanned_cnt;
+struct timer_list wilc_during_ip_timer;
+static struct timer_list hAgingTimer;
 static u8 op_ifcs;
-extern u8 u8ConnectedSSID[6];
 
-u8 g_wilc_initialized = 1;
-extern bool g_obtainingIP;
+u8 wilc_initialized = 1;
 
 #define CHAN2G(_channel, _freq, _flags) {       \
                .band             = IEEE80211_BAND_2GHZ, \
@@ -43,8 +106,7 @@ extern bool g_obtainingIP;
                .max_power        = 30,                  \
 }
 
-/*Frequency range for channels*/
-static struct ieee80211_channel WILC_WFI_2ghz_channels[] = {
+static struct ieee80211_channel ieee80211_2ghz_channels[] = {
        CHAN2G(1,  2412, 0),
        CHAN2G(2,  2417, 0),
        CHAN2G(3,  2422, 0),
@@ -67,9 +129,7 @@ static struct ieee80211_channel WILC_WFI_2ghz_channels[] = {
                .flags    = (_flags),                   \
 }
 
-
-/* Table 6 in section 3.2.1.1 */
-static struct ieee80211_rate WILC_WFI_rates[] = {
+static struct ieee80211_rate ieee80211_bitrates[] = {
        RATETAB_ENT(10,  0,  0),
        RATETAB_ENT(20,  1,  0),
        RATETAB_ENT(55,  2,  0),
@@ -89,22 +149,19 @@ struct p2p_mgmt_data {
        u8 *buff;
 };
 
-/*Global variable used to state the current  connected STA channel*/
-u8 u8WLANChannel = INVALID_CHANNEL;
-
-u8 curr_channel;
-
-u8 u8P2P_oui[] = {0x50, 0x6f, 0x9A, 0x09};
-u8 u8P2Plocalrandom = 0x01;
-u8 u8P2Precvrandom = 0x00;
-u8 u8P2P_vendorspec[] = {0xdd, 0x05, 0x00, 0x08, 0x40, 0x03};
-bool bWilc_ie;
+static u8 wlan_channel = INVALID_CHANNEL;
+static u8 curr_channel;
+static u8 p2p_oui[] = {0x50, 0x6f, 0x9A, 0x09};
+static u8 p2p_local_random = 0x01;
+static u8 p2p_recv_random = 0x00;
+static u8 p2p_vendor_spec[] = {0xdd, 0x05, 0x00, 0x08, 0x40, 0x03};
+static bool wilc_ie;
 
 static struct ieee80211_supported_band WILC_WFI_band_2ghz = {
-       .channels = WILC_WFI_2ghz_channels,
-       .n_channels = ARRAY_SIZE(WILC_WFI_2ghz_channels),
-       .bitrates = WILC_WFI_rates,
-       .n_bitrates = ARRAY_SIZE(WILC_WFI_rates),
+       .channels = ieee80211_2ghz_channels,
+       .n_channels = ARRAY_SIZE(ieee80211_2ghz_channels),
+       .bitrates = ieee80211_bitrates,
+       .n_bitrates = ARRAY_SIZE(ieee80211_bitrates),
 };
 
 
@@ -113,19 +170,19 @@ struct add_key_params {
        bool pairwise;
        u8 *mac_addr;
 };
-struct add_key_params g_add_gtk_key_params;
-struct wilc_wfi_key g_key_gtk_params;
-struct add_key_params g_add_ptk_key_params;
-struct wilc_wfi_key g_key_ptk_params;
-struct wilc_wfi_wep_key g_key_wep_params;
-bool g_ptk_keys_saved;
-bool g_gtk_keys_saved;
-bool g_wep_keys_saved;
+static struct add_key_params g_add_gtk_key_params;
+static struct wilc_wfi_key g_key_gtk_params;
+static struct add_key_params g_add_ptk_key_params;
+static struct wilc_wfi_key g_key_ptk_params;
+static struct wilc_wfi_wep_key g_key_wep_params;
+static bool g_ptk_keys_saved;
+static bool g_gtk_keys_saved;
+static bool g_wep_keys_saved;
 
 #define AGING_TIME     (9 * 1000)
-#define duringIP_TIME 15000
+#define during_ip_time 15000
 
-void clear_shadow_scan(void *pUserVoid)
+static void clear_shadow_scan(void)
 {
        int i;
 
@@ -133,34 +190,33 @@ void clear_shadow_scan(void *pUserVoid)
                del_timer_sync(&hAgingTimer);
                PRINT_INFO(CORECONFIG_DBG, "destroy aging timer\n");
 
-               for (i = 0; i < u32LastScannedNtwrksCountShadow; i++) {
-                       if (astrLastScannedNtwrksShadow[u32LastScannedNtwrksCountShadow].pu8IEs != NULL) {
-                               kfree(astrLastScannedNtwrksShadow[i].pu8IEs);
-                               astrLastScannedNtwrksShadow[u32LastScannedNtwrksCountShadow].pu8IEs = NULL;
+               for (i = 0; i < last_scanned_cnt; i++) {
+                       if (last_scanned_shadow[last_scanned_cnt].pu8IEs) {
+                               kfree(last_scanned_shadow[i].pu8IEs);
+                               last_scanned_shadow[last_scanned_cnt].pu8IEs = NULL;
                        }
 
-                       host_int_freeJoinParams(astrLastScannedNtwrksShadow[i].pJoinParams);
-                       astrLastScannedNtwrksShadow[i].pJoinParams = NULL;
+                       wilc_free_join_params(last_scanned_shadow[i].pJoinParams);
+                       last_scanned_shadow[i].pJoinParams = NULL;
                }
-               u32LastScannedNtwrksCountShadow = 0;
+               last_scanned_cnt = 0;
        }
-
 }
 
-u32 get_rssi_avg(tstrNetworkInfo *pstrNetworkInfo)
+static u32 get_rssi_avg(tstrNetworkInfo *network_info)
 {
        u8 i;
        int rssi_v = 0;
-       u8 num_rssi = (pstrNetworkInfo->strRssi.u8Full) ? NUM_RSSI : (pstrNetworkInfo->strRssi.u8Index);
+       u8 num_rssi = (network_info->strRssi.u8Full) ? NUM_RSSI : (network_info->strRssi.u8Index);
 
        for (i = 0; i < num_rssi; i++)
-               rssi_v += pstrNetworkInfo->strRssi.as8RSSI[i];
+               rssi_v += network_info->strRssi.as8RSSI[i];
 
        rssi_v /= num_rssi;
        return rssi_v;
 }
 
-void refresh_scan(void *pUserVoid, u8 all, bool bDirectScan)
+static void refresh_scan(void *user_void, u8 all, bool direct_scan)
 {
        struct wilc_priv *priv;
        struct wiphy *wiphy;
@@ -168,55 +224,49 @@ void refresh_scan(void *pUserVoid, u8 all, bool bDirectScan)
        int i;
        int rssi = 0;
 
-       priv = (struct wilc_priv *)pUserVoid;
+       priv = (struct wilc_priv *)user_void;
        wiphy = priv->dev->ieee80211_ptr->wiphy;
 
-       for (i = 0; i < u32LastScannedNtwrksCountShadow; i++) {
-               tstrNetworkInfo *pstrNetworkInfo;
+       for (i = 0; i < last_scanned_cnt; i++) {
+               tstrNetworkInfo *network_info;
 
-               pstrNetworkInfo = &(astrLastScannedNtwrksShadow[i]);
+               network_info = &last_scanned_shadow[i];
 
-
-               if ((!pstrNetworkInfo->u8Found) || all) {
-                       s32 s32Freq;
+               if (!network_info->u8Found || all) {
+                       s32 freq;
                        struct ieee80211_channel *channel;
 
-                       if (pstrNetworkInfo != NULL) {
-
-                               s32Freq = ieee80211_channel_to_frequency((s32)pstrNetworkInfo->u8channel, IEEE80211_BAND_2GHZ);
-                               channel = ieee80211_get_channel(wiphy, s32Freq);
+                       if (network_info) {
+                               freq = ieee80211_channel_to_frequency((s32)network_info->u8channel, IEEE80211_BAND_2GHZ);
+                               channel = ieee80211_get_channel(wiphy, freq);
 
-                               rssi = get_rssi_avg(pstrNetworkInfo);
-                               if (memcmp("DIRECT-", pstrNetworkInfo->au8ssid, 7) || bDirectScan)      {
-                                       bss = cfg80211_inform_bss(wiphy, channel, CFG80211_BSS_FTYPE_UNKNOWN, pstrNetworkInfo->au8bssid, pstrNetworkInfo->u64Tsf, pstrNetworkInfo->u16CapInfo,
-                                                                 pstrNetworkInfo->u16BeaconPeriod, (const u8 *)pstrNetworkInfo->pu8IEs,
-                                                                 (size_t)pstrNetworkInfo->u16IEsLen, (((s32)rssi) * 100), GFP_KERNEL);
+                               rssi = get_rssi_avg(network_info);
+                               if (memcmp("DIRECT-", network_info->au8ssid, 7) ||
+                                   direct_scan) {
+                                       bss = cfg80211_inform_bss(wiphy, channel, CFG80211_BSS_FTYPE_UNKNOWN, network_info->au8bssid, network_info->u64Tsf, network_info->u16CapInfo,
+                                                                 network_info->u16BeaconPeriod, (const u8 *)network_info->pu8IEs,
+                                                                 (size_t)network_info->u16IEsLen, (((s32)rssi) * 100), GFP_KERNEL);
                                        cfg80211_put_bss(wiphy, bss);
                                }
                        }
-
                }
        }
-
 }
 
-void reset_shadow_found(void *pUserVoid)
+static void reset_shadow_found(void)
 {
        int i;
 
-       for (i = 0; i < u32LastScannedNtwrksCountShadow; i++) {
-               astrLastScannedNtwrksShadow[i].u8Found = 0;
-
-       }
+       for (i = 0; i < last_scanned_cnt; i++)
+               last_scanned_shadow[i].u8Found = 0;
 }
 
-void update_scan_time(void *pUserVoid)
+static void update_scan_time(void)
 {
        int i;
 
-       for (i = 0; i < u32LastScannedNtwrksCountShadow; i++) {
-               astrLastScannedNtwrksShadow[i].u32TimeRcvdInScan = jiffies;
-       }
+       for (i = 0; i < last_scanned_cnt; i++)
+               last_scanned_shadow[i].u32TimeRcvdInScan = jiffies;
 }
 
 static void remove_network_from_shadow(unsigned long arg)
@@ -225,24 +275,25 @@ static void remove_network_from_shadow(unsigned long arg)
        int i, j;
 
 
-       for (i = 0; i < u32LastScannedNtwrksCountShadow; i++) {
-               if (time_after(now, astrLastScannedNtwrksShadow[i].u32TimeRcvdInScan + (unsigned long)(SCAN_RESULT_EXPIRE))) {
-                       PRINT_D(CFG80211_DBG, "Network expired in ScanShadow: %s\n", astrLastScannedNtwrksShadow[i].au8ssid);
+       for (i = 0; i < last_scanned_cnt; i++) {
+               if (time_after(now, last_scanned_shadow[i].u32TimeRcvdInScan + (unsigned long)(SCAN_RESULT_EXPIRE))) {
+                       PRINT_D(CFG80211_DBG, "Network expired in ScanShadow: %s\n", last_scanned_shadow[i].au8ssid);
 
-                       kfree(astrLastScannedNtwrksShadow[i].pu8IEs);
-                       astrLastScannedNtwrksShadow[i].pu8IEs = NULL;
+                       kfree(last_scanned_shadow[i].pu8IEs);
+                       last_scanned_shadow[i].pu8IEs = NULL;
 
-                       host_int_freeJoinParams(astrLastScannedNtwrksShadow[i].pJoinParams);
+                       wilc_free_join_params(last_scanned_shadow[i].pJoinParams);
 
-                       for (j = i; (j < u32LastScannedNtwrksCountShadow - 1); j++) {
-                               astrLastScannedNtwrksShadow[j] = astrLastScannedNtwrksShadow[j + 1];
-                       }
-                       u32LastScannedNtwrksCountShadow--;
+                       for (j = i; (j < last_scanned_cnt - 1); j++)
+                               last_scanned_shadow[j] = last_scanned_shadow[j + 1];
+
+                       last_scanned_cnt--;
                }
        }
 
-       PRINT_D(CFG80211_DBG, "Number of cached networks: %d\n", u32LastScannedNtwrksCountShadow);
-       if (u32LastScannedNtwrksCountShadow != 0) {
+       PRINT_D(CFG80211_DBG, "Number of cached networks: %d\n",
+               last_scanned_cnt);
+       if (last_scanned_cnt != 0) {
                hAgingTimer.data = arg;
                mod_timer(&hAgingTimer, jiffies + msecs_to_jiffies(AGING_TIME));
        } else {
@@ -253,24 +304,24 @@ static void remove_network_from_shadow(unsigned long arg)
 static void clear_duringIP(unsigned long arg)
 {
        PRINT_D(GENERIC_DBG, "GO:IP Obtained , enable scan\n");
-       g_obtainingIP = false;
+       wilc_optaining_ip = false;
 }
 
-int is_network_in_shadow(tstrNetworkInfo *pstrNetworkInfo, void *pUserVoid)
+static int is_network_in_shadow(tstrNetworkInfo *pstrNetworkInfo,
+                               void *user_void)
 {
        int state = -1;
        int i;
 
-       if (u32LastScannedNtwrksCountShadow == 0) {
+       if (last_scanned_cnt == 0) {
                PRINT_D(CFG80211_DBG, "Starting Aging timer\n");
-               hAgingTimer.data = (unsigned long)pUserVoid;
+               hAgingTimer.data = (unsigned long)user_void;
                mod_timer(&hAgingTimer, jiffies + msecs_to_jiffies(AGING_TIME));
                state = -1;
        } else {
-               /* Linear search for now */
-               for (i = 0; i < u32LastScannedNtwrksCountShadow; i++) {
-                       if (memcmp(astrLastScannedNtwrksShadow[i].au8bssid,
-                                       pstrNetworkInfo->au8bssid, 6) == 0) {
+               for (i = 0; i < last_scanned_cnt; i++) {
+                       if (memcmp(last_scanned_shadow[i].au8bssid,
+                                  pstrNetworkInfo->au8bssid, 6) == 0) {
                                state = i;
                                break;
                        }
@@ -279,78 +330,60 @@ int is_network_in_shadow(tstrNetworkInfo *pstrNetworkInfo, void *pUserVoid)
        return state;
 }
 
-void add_network_to_shadow(tstrNetworkInfo *pstrNetworkInfo, void *pUserVoid, void *pJoinParams)
+static void add_network_to_shadow(tstrNetworkInfo *pstrNetworkInfo,
+                                 void *user_void, void *pJoinParams)
 {
-       int ap_found = is_network_in_shadow(pstrNetworkInfo, pUserVoid);
+       int ap_found = is_network_in_shadow(pstrNetworkInfo, user_void);
        u32 ap_index = 0;
        u8 rssi_index = 0;
 
-       if (u32LastScannedNtwrksCountShadow >= MAX_NUM_SCANNED_NETWORKS_SHADOW) {
+       if (last_scanned_cnt >= MAX_NUM_SCANNED_NETWORKS_SHADOW) {
                PRINT_D(CFG80211_DBG, "Shadow network reached its maximum limit\n");
                return;
        }
        if (ap_found == -1) {
-               ap_index = u32LastScannedNtwrksCountShadow;
-               u32LastScannedNtwrksCountShadow++;
-
+               ap_index = last_scanned_cnt;
+               last_scanned_cnt++;
        } else {
                ap_index = ap_found;
        }
-       rssi_index = astrLastScannedNtwrksShadow[ap_index].strRssi.u8Index;
-       astrLastScannedNtwrksShadow[ap_index].strRssi.as8RSSI[rssi_index++] = pstrNetworkInfo->s8rssi;
+       rssi_index = last_scanned_shadow[ap_index].strRssi.u8Index;
+       last_scanned_shadow[ap_index].strRssi.as8RSSI[rssi_index++] = pstrNetworkInfo->s8rssi;
        if (rssi_index == NUM_RSSI) {
                rssi_index = 0;
-               astrLastScannedNtwrksShadow[ap_index].strRssi.u8Full = 1;
-       }
-       astrLastScannedNtwrksShadow[ap_index].strRssi.u8Index = rssi_index;
-
-       astrLastScannedNtwrksShadow[ap_index].s8rssi = pstrNetworkInfo->s8rssi;
-       astrLastScannedNtwrksShadow[ap_index].u16CapInfo = pstrNetworkInfo->u16CapInfo;
-
-       astrLastScannedNtwrksShadow[ap_index].u8SsidLen = pstrNetworkInfo->u8SsidLen;
-       memcpy(astrLastScannedNtwrksShadow[ap_index].au8ssid,
-                   pstrNetworkInfo->au8ssid, pstrNetworkInfo->u8SsidLen);
-
-       memcpy(astrLastScannedNtwrksShadow[ap_index].au8bssid,
-                   pstrNetworkInfo->au8bssid, ETH_ALEN);
-
-       astrLastScannedNtwrksShadow[ap_index].u16BeaconPeriod = pstrNetworkInfo->u16BeaconPeriod;
-       astrLastScannedNtwrksShadow[ap_index].u8DtimPeriod = pstrNetworkInfo->u8DtimPeriod;
-       astrLastScannedNtwrksShadow[ap_index].u8channel = pstrNetworkInfo->u8channel;
-
-       astrLastScannedNtwrksShadow[ap_index].u16IEsLen = pstrNetworkInfo->u16IEsLen;
-       astrLastScannedNtwrksShadow[ap_index].u64Tsf = pstrNetworkInfo->u64Tsf;
+               last_scanned_shadow[ap_index].strRssi.u8Full = 1;
+       }
+       last_scanned_shadow[ap_index].strRssi.u8Index = rssi_index;
+       last_scanned_shadow[ap_index].s8rssi = pstrNetworkInfo->s8rssi;
+       last_scanned_shadow[ap_index].u16CapInfo = pstrNetworkInfo->u16CapInfo;
+       last_scanned_shadow[ap_index].u8SsidLen = pstrNetworkInfo->u8SsidLen;
+       memcpy(last_scanned_shadow[ap_index].au8ssid,
+              pstrNetworkInfo->au8ssid, pstrNetworkInfo->u8SsidLen);
+       memcpy(last_scanned_shadow[ap_index].au8bssid,
+              pstrNetworkInfo->au8bssid, ETH_ALEN);
+       last_scanned_shadow[ap_index].u16BeaconPeriod = pstrNetworkInfo->u16BeaconPeriod;
+       last_scanned_shadow[ap_index].u8DtimPeriod = pstrNetworkInfo->u8DtimPeriod;
+       last_scanned_shadow[ap_index].u8channel = pstrNetworkInfo->u8channel;
+       last_scanned_shadow[ap_index].u16IEsLen = pstrNetworkInfo->u16IEsLen;
+       last_scanned_shadow[ap_index].u64Tsf = pstrNetworkInfo->u64Tsf;
        if (ap_found != -1)
-               kfree(astrLastScannedNtwrksShadow[ap_index].pu8IEs);
-       astrLastScannedNtwrksShadow[ap_index].pu8IEs =
-               kmalloc(pstrNetworkInfo->u16IEsLen, GFP_KERNEL);        /* will be deallocated by the WILC_WFI_CfgScan() function */
-       memcpy(astrLastScannedNtwrksShadow[ap_index].pu8IEs,
-                   pstrNetworkInfo->pu8IEs, pstrNetworkInfo->u16IEsLen);
-
-       astrLastScannedNtwrksShadow[ap_index].u32TimeRcvdInScan = jiffies;
-       astrLastScannedNtwrksShadow[ap_index].u32TimeRcvdInScanCached = jiffies;
-       astrLastScannedNtwrksShadow[ap_index].u8Found = 1;
+               kfree(last_scanned_shadow[ap_index].pu8IEs);
+       last_scanned_shadow[ap_index].pu8IEs =
+               kmalloc(pstrNetworkInfo->u16IEsLen, GFP_KERNEL);
+       memcpy(last_scanned_shadow[ap_index].pu8IEs,
+              pstrNetworkInfo->pu8IEs, pstrNetworkInfo->u16IEsLen);
+       last_scanned_shadow[ap_index].u32TimeRcvdInScan = jiffies;
+       last_scanned_shadow[ap_index].u32TimeRcvdInScanCached = jiffies;
+       last_scanned_shadow[ap_index].u8Found = 1;
        if (ap_found != -1)
-               host_int_freeJoinParams(astrLastScannedNtwrksShadow[ap_index].pJoinParams);
-       astrLastScannedNtwrksShadow[ap_index].pJoinParams = pJoinParams;
-
+               wilc_free_join_params(last_scanned_shadow[ap_index].pJoinParams);
+       last_scanned_shadow[ap_index].pJoinParams = pJoinParams;
 }
 
-
-/**
- *  @brief      CfgScanResult
- *  @details  Callback function which returns the scan results found
- *
- *  @param[in] tenuScanEvent enuScanEvent: enum, indicating the scan event triggered, whether that is
- *                        SCAN_EVENT_NETWORK_FOUND or SCAN_EVENT_DONE
- *                        tstrNetworkInfo* pstrNetworkInfo: structure holding the scan results information
- *                        void* pUserVoid: Private structure associated with the wireless interface
- *  @return     NONE
- *  @author    mabubakr
- *  @date
- *  @version   1.0
- */
-static void CfgScanResult(enum scan_event enuScanEvent, tstrNetworkInfo *pstrNetworkInfo, void *pUserVoid, void *pJoinParams)
+static void CfgScanResult(enum scan_event scan_event,
+                         tstrNetworkInfo *network_info,
+                         void *user_void,
+                         void *join_params)
 {
        struct wilc_priv *priv;
        struct wiphy *wiphy;
@@ -358,56 +391,45 @@ static void CfgScanResult(enum scan_event enuScanEvent, tstrNetworkInfo *pstrNet
        struct ieee80211_channel *channel;
        struct cfg80211_bss *bss = NULL;
 
-       priv = (struct wilc_priv *)pUserVoid;
+       priv = (struct wilc_priv *)user_void;
        if (priv->bCfgScanning) {
-               if (enuScanEvent == SCAN_EVENT_NETWORK_FOUND) {
+               if (scan_event == SCAN_EVENT_NETWORK_FOUND) {
                        wiphy = priv->dev->ieee80211_ptr->wiphy;
 
                        if (!wiphy)
                                return;
 
-                       if (wiphy->signal_type == CFG80211_SIGNAL_TYPE_UNSPEC
-                           &&
-                           ((((s32)pstrNetworkInfo->s8rssi) * 100) < 0
-                            ||
-                            (((s32)pstrNetworkInfo->s8rssi) * 100) > 100)
-                           ) {
+                       if (wiphy->signal_type == CFG80211_SIGNAL_TYPE_UNSPEC &&
+                           (((s32)network_info->s8rssi * 100) < 0 ||
+                           ((s32)network_info->s8rssi * 100) > 100)) {
                                PRINT_ER("wiphy signal type fial\n");
                                return;
                        }
 
-                       if (pstrNetworkInfo != NULL) {
-                               s32Freq = ieee80211_channel_to_frequency((s32)pstrNetworkInfo->u8channel, IEEE80211_BAND_2GHZ);
+                       if (network_info) {
+                               s32Freq = ieee80211_channel_to_frequency((s32)network_info->u8channel, IEEE80211_BAND_2GHZ);
                                channel = ieee80211_get_channel(wiphy, s32Freq);
 
                                if (!channel)
                                        return;
 
                                PRINT_INFO(CFG80211_DBG, "Network Info:: CHANNEL Frequency: %d, RSSI: %d, CapabilityInfo: %d,"
-                                          "BeaconPeriod: %d\n", channel->center_freq, (((s32)pstrNetworkInfo->s8rssi) * 100),
-                                          pstrNetworkInfo->u16CapInfo, pstrNetworkInfo->u16BeaconPeriod);
-
-                               if (pstrNetworkInfo->bNewNetwork) {
-                                       if (priv->u32RcvdChCount < MAX_NUM_SCANNED_NETWORKS) { /* TODO: mostafa: to be replaced by */
-                                               /*               max_scan_ssids */
-                                               PRINT_D(CFG80211_DBG, "Network %s found\n", pstrNetworkInfo->au8ssid);
-
+                                          "BeaconPeriod: %d\n", channel->center_freq, (((s32)network_info->s8rssi) * 100),
+                                          network_info->u16CapInfo, network_info->u16BeaconPeriod);
 
+                               if (network_info->bNewNetwork) {
+                                       if (priv->u32RcvdChCount < MAX_NUM_SCANNED_NETWORKS) {
+                                               PRINT_D(CFG80211_DBG, "Network %s found\n", network_info->au8ssid);
                                                priv->u32RcvdChCount++;
 
-
-
-                                               if (pJoinParams == NULL) {
+                                               if (!join_params)
                                                        PRINT_INFO(CORECONFIG_DBG, ">> Something really bad happened\n");
-                                               }
-                                               add_network_to_shadow(pstrNetworkInfo, priv, pJoinParams);
+                                               add_network_to_shadow(network_info, priv, join_params);
 
-                                               /*P2P peers are sent to WPA supplicant and added to shadow table*/
-
-                                               if (!(memcmp("DIRECT-", pstrNetworkInfo->au8ssid, 7))) {
-                                                       bss = cfg80211_inform_bss(wiphy, channel, CFG80211_BSS_FTYPE_UNKNOWN,  pstrNetworkInfo->au8bssid, pstrNetworkInfo->u64Tsf, pstrNetworkInfo->u16CapInfo,
-                                                                                 pstrNetworkInfo->u16BeaconPeriod, (const u8 *)pstrNetworkInfo->pu8IEs,
-                                                                                 (size_t)pstrNetworkInfo->u16IEsLen, (((s32)pstrNetworkInfo->s8rssi) * 100), GFP_KERNEL);
+                                               if (!(memcmp("DIRECT-", network_info->au8ssid, 7))) {
+                                                       bss = cfg80211_inform_bss(wiphy, channel, CFG80211_BSS_FTYPE_UNKNOWN,  network_info->au8bssid, network_info->u64Tsf, network_info->u16CapInfo,
+                                                                                 network_info->u16BeaconPeriod, (const u8 *)network_info->pu8IEs,
+                                                                                 (size_t)network_info->u16IEsLen, (((s32)network_info->s8rssi) * 100), GFP_KERNEL);
                                                        cfg80211_put_bss(wiphy, bss);
                                                }
 
@@ -417,19 +439,19 @@ static void CfgScanResult(enum scan_event enuScanEvent, tstrNetworkInfo *pstrNet
                                        }
                                } else {
                                        u32 i;
-                                       /* So this network is discovered before, we'll just update its RSSI */
+
                                        for (i = 0; i < priv->u32RcvdChCount; i++) {
-                                               if (memcmp(astrLastScannedNtwrksShadow[i].au8bssid, pstrNetworkInfo->au8bssid, 6) == 0) {
-                                                       PRINT_D(CFG80211_DBG, "Update RSSI of %s\n", astrLastScannedNtwrksShadow[i].au8ssid);
+                                               if (memcmp(last_scanned_shadow[i].au8bssid, network_info->au8bssid, 6) == 0) {
+                                                       PRINT_D(CFG80211_DBG, "Update RSSI of %s\n", last_scanned_shadow[i].au8ssid);
 
-                                                       astrLastScannedNtwrksShadow[i].s8rssi = pstrNetworkInfo->s8rssi;
-                                                       astrLastScannedNtwrksShadow[i].u32TimeRcvdInScan = jiffies;
+                                                       last_scanned_shadow[i].s8rssi = network_info->s8rssi;
+                                                       last_scanned_shadow[i].u32TimeRcvdInScan = jiffies;
                                                        break;
                                                }
                                        }
                                }
                        }
-               } else if (enuScanEvent == SCAN_EVENT_DONE)    {
+               } else if (scan_event == SCAN_EVENT_DONE) {
                        PRINT_D(CFG80211_DBG, "Scan Done[%p]\n", priv->dev);
                        PRINT_D(CFG80211_DBG, "Refreshing Scan ...\n");
                        refresh_scan(priv, 1, false);
@@ -441,23 +463,19 @@ static void CfgScanResult(enum scan_event enuScanEvent, tstrNetworkInfo *pstrNet
 
                        down(&(priv->hSemScanReq));
 
-                       if (priv->pstrScanReq != NULL) {
+                       if (priv->pstrScanReq) {
                                cfg80211_scan_done(priv->pstrScanReq, false);
                                priv->u32RcvdChCount = 0;
                                priv->bCfgScanning = false;
                                priv->pstrScanReq = NULL;
                        }
                        up(&(priv->hSemScanReq));
-
-               }
-               /*Aborting any scan operation during mac close*/
-               else if (enuScanEvent == SCAN_EVENT_ABORTED) {
+               } else if (scan_event == SCAN_EVENT_ABORTED) {
                        down(&(priv->hSemScanReq));
 
                        PRINT_D(CFG80211_DBG, "Scan Aborted\n");
-                       if (priv->pstrScanReq != NULL) {
-
-                               update_scan_time(priv);
+                       if (priv->pstrScanReq) {
+                               update_scan_time();
                                refresh_scan(priv, 1, false);
 
                                cfg80211_scan_done(priv->pstrScanReq, false);
@@ -469,58 +487,7 @@ static void CfgScanResult(enum scan_event enuScanEvent, tstrNetworkInfo *pstrNet
        }
 }
 
-
-/**
- *  @brief      WILC_WFI_Set_PMKSA
- *  @details  Check if pmksa is cached and set it.
- *  @param[in]
- *  @return     int : Return 0 on Success
- *  @author    mdaftedar
- *  @date      01 MAR 2012
- *  @version   1.0
- */
-int WILC_WFI_Set_PMKSA(u8 *bssid, struct wilc_priv *priv)
-{
-       u32 i;
-       s32 s32Error = 0;
-
-
-       for (i = 0; i < priv->pmkid_list.numpmkid; i++) {
-
-               if (!memcmp(bssid, priv->pmkid_list.pmkidlist[i].bssid,
-                                ETH_ALEN)) {
-                       PRINT_D(CFG80211_DBG, "PMKID successful comparison");
-
-                       /*If bssid is found, set the values*/
-                       s32Error = host_int_set_pmkid_info(priv->hWILCWFIDrv, &priv->pmkid_list);
-
-                       if (s32Error != 0)
-                               PRINT_ER("Error in pmkid\n");
-
-                       break;
-               }
-       }
-
-       return s32Error;
-
-
-}
-
-/**
- *  @brief      CfgConnectResult
- *  @details
- *  @param[in] tenuConnDisconnEvent enuConnDisconnEvent: Type of connection response either
- *                        connection response or disconnection notification.
- *                        tstrConnectInfo* pstrConnectInfo: COnnection information.
- *                        u8 u8MacStatus: Mac Status from firmware
- *                        tstrDisconnectNotifInfo* pstrDisconnectNotifInfo: Disconnection Notification
- *                        void* pUserVoid: Private data associated with wireless interface
- *  @return     NONE
- *  @author    mabubakr
- *  @date      01 MAR 2012
- *  @version   1.0
- */
-int connecting;
+int wilc_connecting;
 
 static void CfgConnectResult(enum conn_event enuConnDisconnEvent,
                             tstrConnectInfo *pstrConnectInfo,
@@ -533,18 +500,17 @@ static void CfgConnectResult(enum conn_event enuConnDisconnEvent,
        struct host_if_drv *pstrWFIDrv;
        u8 NullBssid[ETH_ALEN] = {0};
        struct wilc *wl;
-       perInterface_wlan_t *nic;
+       struct wilc_vif *vif;
 
-       connecting = 0;
+       wilc_connecting = 0;
 
        priv = (struct wilc_priv *)pUserVoid;
        dev = priv->dev;
-       nic = netdev_priv(dev);
-       wl = nic->wilc;
+       vif = netdev_priv(dev);
+       wl = vif->wilc;
        pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
 
        if (enuConnDisconnEvent == CONN_DISCONN_EVENT_CONN_RESP) {
-               /*Initialization*/
                u16 u16ConnectStatus;
 
                u16ConnectStatus = pstrConnectInfo->u16ConnectStatus;
@@ -553,15 +519,12 @@ static void CfgConnectResult(enum conn_event enuConnDisconnEvent,
 
                if ((u8MacStatus == MAC_DISCONNECTED) &&
                    (pstrConnectInfo->u16ConnectStatus == SUCCESSFUL_STATUSCODE)) {
-                       /* The case here is that our station was waiting for association response frame and has just received it containing status code
-                        *  = SUCCESSFUL_STATUSCODE, while mac status is MAC_DISCONNECTED (which means something wrong happened) */
                        u16ConnectStatus = WLAN_STATUS_UNSPECIFIED_FAILURE;
-                       linux_wlan_set_bssid(priv->dev, NullBssid);
-                       eth_zero_addr(u8ConnectedSSID);
+                       wilc_wlan_set_bssid(priv->dev, NullBssid);
+                       eth_zero_addr(wilc_connected_ssid);
 
-                       /*Invalidate u8WLANChannel value on wlan0 disconnect*/
                        if (!pstrWFIDrv->p2p_connect)
-                               u8WLANChannel = INVALID_CHANNEL;
+                               wlan_channel = INVALID_CHANNEL;
 
                        PRINT_ER("Unspecified failure: Connection status %d : MAC status = %d\n", u16ConnectStatus, u8MacStatus);
                }
@@ -575,13 +538,13 @@ static void CfgConnectResult(enum conn_event enuConnDisconnEvent,
                        memcpy(priv->au8AssociatedBss, pstrConnectInfo->au8bssid, ETH_ALEN);
 
 
-                       for (i = 0; i < u32LastScannedNtwrksCountShadow; i++) {
-                               if (memcmp(astrLastScannedNtwrksShadow[i].au8bssid,
-                                               pstrConnectInfo->au8bssid, ETH_ALEN) == 0) {
+                       for (i = 0; i < last_scanned_cnt; i++) {
+                               if (memcmp(last_scanned_shadow[i].au8bssid,
+                                          pstrConnectInfo->au8bssid, ETH_ALEN) == 0) {
                                        unsigned long now = jiffies;
 
                                        if (time_after(now,
-                                                      astrLastScannedNtwrksShadow[i].u32TimeRcvdInScanCached + (unsigned long)(nl80211_SCAN_RESULT_EXPIRE - (1 * HZ)))) {
+                                                      last_scanned_shadow[i].u32TimeRcvdInScanCached + (unsigned long)(nl80211_SCAN_RESULT_EXPIRE - (1 * HZ)))) {
                                                bNeedScanRefresh = true;
                                        }
 
@@ -589,12 +552,8 @@ static void CfgConnectResult(enum conn_event enuConnDisconnEvent,
                                }
                        }
 
-                       if (bNeedScanRefresh) {
-                               /*Also, refrsh DIRECT- results if */
+                       if (bNeedScanRefresh)
                                refresh_scan(priv, 1, true);
-
-                       }
-
                }
 
 
@@ -605,68 +564,47 @@ static void CfgConnectResult(enum conn_event enuConnDisconnEvent,
                cfg80211_connect_result(dev, pstrConnectInfo->au8bssid,
                                        pstrConnectInfo->pu8ReqIEs, pstrConnectInfo->ReqIEsLen,
                                        pstrConnectInfo->pu8RespIEs, pstrConnectInfo->u16RespIEsLen,
-                                       u16ConnectStatus, GFP_KERNEL);                         /* TODO: mostafa: u16ConnectStatus to */
-               /* be replaced by pstrConnectInfo->u16ConnectStatus */
+                                       u16ConnectStatus, GFP_KERNEL);
        } else if (enuConnDisconnEvent == CONN_DISCONN_EVENT_DISCONN_NOTIF)    {
-               g_obtainingIP = false;
+               wilc_optaining_ip = false;
                PRINT_ER("Received MAC_DISCONNECTED from firmware with reason %d on dev [%p]\n",
                         pstrDisconnectNotifInfo->u16reason, priv->dev);
-               u8P2Plocalrandom = 0x01;
-               u8P2Precvrandom = 0x00;
-               bWilc_ie = false;
+               p2p_local_random = 0x01;
+               p2p_recv_random = 0x00;
+               wilc_ie = false;
                eth_zero_addr(priv->au8AssociatedBss);
-               linux_wlan_set_bssid(priv->dev, NullBssid);
-               eth_zero_addr(u8ConnectedSSID);
+               wilc_wlan_set_bssid(priv->dev, NullBssid);
+               eth_zero_addr(wilc_connected_ssid);
 
-               /*Invalidate u8WLANChannel value on wlan0 disconnect*/
                if (!pstrWFIDrv->p2p_connect)
-                       u8WLANChannel = INVALID_CHANNEL;
-               /*Incase "P2P CLIENT Connected" send deauthentication reason by 3 to force the WPA_SUPPLICANT to directly change
-                *      virtual interface to station*/
-               if ((pstrWFIDrv->IFC_UP) && (dev == wl->vif[1].ndev)) {
+                       wlan_channel = INVALID_CHANNEL;
+               if ((pstrWFIDrv->IFC_UP) && (dev == wl->vif[1]->ndev)) {
                        pstrDisconnectNotifInfo->u16reason = 3;
-               }
-               /*Incase "P2P CLIENT during connection(not connected)" send deauthentication reason by 1 to force the WPA_SUPPLICANT
-                *      to scan again and retry the connection*/
-               else if ((!pstrWFIDrv->IFC_UP) && (dev == wl->vif[1].ndev)) {
+               } else if ((!pstrWFIDrv->IFC_UP) && (dev == wl->vif[1]->ndev)) {
                        pstrDisconnectNotifInfo->u16reason = 1;
                }
                cfg80211_disconnected(dev, pstrDisconnectNotifInfo->u16reason, pstrDisconnectNotifInfo->ie,
                                      pstrDisconnectNotifInfo->ie_len, false,
                                      GFP_KERNEL);
-
        }
-
 }
 
-
-/**
- *  @brief      set_channel
- *  @details    Set channel for a given wireless interface. Some devices
- *                      may support multi-channel operation (by channel hopping) so cfg80211
- *                      doesn't verify much. Note, however, that the passed netdev may be
- *                      %NULL as well if the user requested changing the channel for the
- *                      device itself, or for a monitor interface.
- *  @param[in]
- *  @return     int : Return 0 on Success
- *  @author    mdaftedar
- *  @date      01 MAR 2012
- *  @version   1.0
- */
 static int set_channel(struct wiphy *wiphy,
                       struct cfg80211_chan_def *chandef)
 {
        u32 channelnum = 0;
        struct wilc_priv *priv;
        int result = 0;
+       struct wilc_vif *vif;
 
        priv = wiphy_priv(wiphy);
+       vif = netdev_priv(priv->dev);
 
        channelnum = ieee80211_frequency_to_channel(chandef->chan->center_freq);
        PRINT_D(CFG80211_DBG, "Setting channel %d with frequency %d\n", channelnum, chandef->chan->center_freq);
 
        curr_channel = channelnum;
-       result = host_int_set_mac_chnl_num(priv->hWILCWFIDrv, channelnum);
+       result = wilc_set_mac_chnl_num(vif, channelnum);
 
        if (result != 0)
                PRINT_ER("Error in setting channel %d\n", channelnum);
@@ -674,19 +612,6 @@ static int set_channel(struct wiphy *wiphy,
        return result;
 }
 
-/**
- *  @brief      scan
- *  @details    Request to do a scan. If returning zero, the scan request is given
- *                      the driver, and will be valid until passed to cfg80211_scan_done().
- *                      For scan results, call cfg80211_inform_bss(); you can call this outside
- *                      the scan/scan_done bracket too.
- *  @param[in]
- *  @return     int : Return 0 on Success
- *  @author    mabubakr
- *  @date      01 MAR 2012
- *  @version   1.0
- */
-
 static int scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
 {
        struct wilc_priv *priv;
@@ -694,21 +619,20 @@ static int scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
        s32 s32Error = 0;
        u8 au8ScanChanList[MAX_NUM_SCANNED_NETWORKS];
        struct hidden_network strHiddenNetwork;
+       struct wilc_vif *vif;
 
        priv = wiphy_priv(wiphy);
+       vif = netdev_priv(priv->dev);
 
        priv->pstrScanReq = request;
 
        priv->u32RcvdChCount = 0;
 
-       host_int_set_wfi_drv_handler(priv->hWILCWFIDrv);
-
-
-       reset_shadow_found(priv);
+       wilc_set_wfi_drv_handler(vif, wilc_get_vif_idx(vif));
+       reset_shadow_found();
 
        priv->bCfgScanning = true;
-       if (request->n_channels <= MAX_NUM_SCANNED_NETWORKS) { /* TODO: mostafa: to be replaced by */
-               /*               max_scan_ssids */
+       if (request->n_channels <= MAX_NUM_SCANNED_NETWORKS) {
                for (i = 0; i < request->n_channels; i++) {
                        au8ScanChanList[i] = (u8)ieee80211_frequency_to_channel(request->channels[i]->center_freq);
                        PRINT_INFO(CFG80211_DBG, "ScanChannel List[%d] = %d,", i, au8ScanChanList[i]);
@@ -720,15 +644,13 @@ static int scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
                PRINT_D(CFG80211_DBG, "Number of SSIDs %d\n", request->n_ssids);
 
                if (request->n_ssids >= 1) {
-
-
                        strHiddenNetwork.pstrHiddenNetworkInfo = kmalloc(request->n_ssids * sizeof(struct hidden_network), GFP_KERNEL);
                        strHiddenNetwork.u8ssidnum = request->n_ssids;
 
 
                        for (i = 0; i < request->n_ssids; i++) {
-
-                               if (request->ssids[i].ssid != NULL && request->ssids[i].ssid_len != 0) {
+                               if (request->ssids[i].ssid &&
+                                   request->ssids[i].ssid_len != 0) {
                                        strHiddenNetwork.pstrHiddenNetworkInfo[i].pu8ssid = kmalloc(request->ssids[i].ssid_len, GFP_KERNEL);
                                        memcpy(strHiddenNetwork.pstrHiddenNetworkInfo[i].pu8ssid, request->ssids[i].ssid, request->ssids[i].ssid_len);
                                        strHiddenNetwork.pstrHiddenNetworkInfo[i].u8ssidlen = request->ssids[i].ssid_len;
@@ -738,18 +660,21 @@ static int scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
                                }
                        }
                        PRINT_D(CFG80211_DBG, "Trigger Scan Request\n");
-                       s32Error = host_int_scan(priv->hWILCWFIDrv, USER_SCAN, ACTIVE_SCAN,
-                                                au8ScanChanList, request->n_channels,
-                                                (const u8 *)request->ie, request->ie_len,
-                                                CfgScanResult, (void *)priv, &strHiddenNetwork);
+                       s32Error = wilc_scan(vif, USER_SCAN, ACTIVE_SCAN,
+                                            au8ScanChanList,
+                                            request->n_channels,
+                                            (const u8 *)request->ie,
+                                            request->ie_len, CfgScanResult,
+                                            (void *)priv, &strHiddenNetwork);
                } else {
                        PRINT_D(CFG80211_DBG, "Trigger Scan Request\n");
-                       s32Error = host_int_scan(priv->hWILCWFIDrv, USER_SCAN, ACTIVE_SCAN,
-                                                au8ScanChanList, request->n_channels,
-                                                (const u8 *)request->ie, request->ie_len,
-                                                CfgScanResult, (void *)priv, NULL);
+                       s32Error = wilc_scan(vif, USER_SCAN, ACTIVE_SCAN,
+                                            au8ScanChanList,
+                                            request->n_channels,
+                                            (const u8 *)request->ie,
+                                            request->ie_len, CfgScanResult,
+                                            (void *)priv, NULL);
                }
-
        } else {
                PRINT_ER("Requested num of scanned channels is greater than the max, supported"
                         " channels\n");
@@ -763,18 +688,6 @@ static int scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
        return s32Error;
 }
 
-/**
- *  @brief      connect
- *  @details    Connect to the ESS with the specified parameters. When connected,
- *                      call cfg80211_connect_result() with status code %WLAN_STATUS_SUCCESS.
- *                      If the connection fails for some reason, call cfg80211_connect_result()
- *                      with the status from the AP.
- *  @param[in]
- *  @return     int : Return 0 on Success
- *  @author    mabubakr
- *  @date      01 MAR 2012
- *  @version   1.0
- */
 static int connect(struct wiphy *wiphy, struct net_device *dev,
                   struct cfg80211_connect_params *sme)
 {
@@ -789,13 +702,14 @@ static int connect(struct wiphy *wiphy, struct net_device *dev,
        struct wilc_priv *priv;
        struct host_if_drv *pstrWFIDrv;
        tstrNetworkInfo *pstrNetworkInfo = NULL;
+       struct wilc_vif *vif;
 
-
-       connecting = 1;
+       wilc_connecting = 1;
        priv = wiphy_priv(wiphy);
+       vif = netdev_priv(priv->dev);
        pstrWFIDrv = (struct host_if_drv *)(priv->hWILCWFIDrv);
 
-       host_int_set_wfi_drv_handler(priv->hWILCWFIDrv);
+       wilc_set_wfi_drv_handler(vif, wilc_get_vif_idx(vif));
 
        PRINT_D(CFG80211_DBG, "Connecting to SSID [%s] on netdev [%p] host if [%p]\n", sme->ssid, dev, priv->hWILCWFIDrv);
        if (!(strncmp(sme->ssid, "DIRECT-", 7))) {
@@ -806,23 +720,19 @@ static int connect(struct wiphy *wiphy, struct net_device *dev,
        }
        PRINT_INFO(CFG80211_DBG, "Required SSID = %s\n , AuthType = %d\n", sme->ssid, sme->auth_type);
 
-       for (i = 0; i < u32LastScannedNtwrksCountShadow; i++) {
-               if ((sme->ssid_len == astrLastScannedNtwrksShadow[i].u8SsidLen) &&
-                   memcmp(astrLastScannedNtwrksShadow[i].au8ssid,
-                               sme->ssid,
-                               sme->ssid_len) == 0) {
+       for (i = 0; i < last_scanned_cnt; i++) {
+               if ((sme->ssid_len == last_scanned_shadow[i].u8SsidLen) &&
+                   memcmp(last_scanned_shadow[i].au8ssid,
+                          sme->ssid,
+                          sme->ssid_len) == 0) {
                        PRINT_INFO(CFG80211_DBG, "Network with required SSID is found %s\n", sme->ssid);
-                       if (sme->bssid == NULL) {
-                               /* BSSID is not passed from the user, so decision of matching
-                                * is done by SSID only */
+                       if (!sme->bssid) {
                                PRINT_INFO(CFG80211_DBG, "BSSID is not passed from the user\n");
                                break;
                        } else {
-                               /* BSSID is also passed from the user, so decision of matching
-                                * should consider also this passed BSSID */
-                               if (memcmp(astrLastScannedNtwrksShadow[i].au8bssid,
-                                               sme->bssid,
-                                               ETH_ALEN) == 0) {
+                               if (memcmp(last_scanned_shadow[i].au8bssid,
+                                          sme->bssid,
+                                          ETH_ALEN) == 0) {
                                        PRINT_INFO(CFG80211_DBG, "BSSID is passed from the user and matched\n");
                                        break;
                                }
@@ -830,10 +740,10 @@ static int connect(struct wiphy *wiphy, struct net_device *dev,
                }
        }
 
-       if (i < u32LastScannedNtwrksCountShadow) {
+       if (i < last_scanned_cnt) {
                PRINT_D(CFG80211_DBG, "Required bss is in scan results\n");
 
-               pstrNetworkInfo = &(astrLastScannedNtwrksShadow[i]);
+               pstrNetworkInfo = &last_scanned_shadow[i];
 
                PRINT_INFO(CFG80211_DBG, "network BSSID to be associated: %x%x%x%x%x%x\n",
                           pstrNetworkInfo->au8bssid[0], pstrNetworkInfo->au8bssid[1],
@@ -841,7 +751,7 @@ static int connect(struct wiphy *wiphy, struct net_device *dev,
                           pstrNetworkInfo->au8bssid[4], pstrNetworkInfo->au8bssid[5]);
        } else {
                s32Error = -ENOENT;
-               if (u32LastScannedNtwrksCountShadow == 0)
+               if (last_scanned_cnt == 0)
                        PRINT_D(CFG80211_DBG, "No Scan results yet\n");
                else
                        PRINT_D(CFG80211_DBG, "Required bss not in scan results: Error(%d)\n", s32Error);
@@ -864,8 +774,6 @@ static int connect(struct wiphy *wiphy, struct net_device *dev,
        }
 
        if (sme->crypto.cipher_group != NO_ENCRYPT) {
-               /* To determine the u8security value, first we check the group cipher suite then {in case of WPA or WPA2}
-                *  we will add to it the pairwise cipher suite(s) */
                pcwpa_version = "Default";
                PRINT_D(CORECONFIG_DBG, ">> sme->crypto.wpa_versions: %x\n", sme->crypto.wpa_versions);
                if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP40) {
@@ -888,8 +796,9 @@ static int connect(struct wiphy *wiphy, struct net_device *dev,
                        g_key_wep_params.key_idx = sme->key_idx;
                        g_wep_keys_saved = true;
 
-                       host_int_set_wep_default_key(priv->hWILCWFIDrv, sme->key_idx);
-                       host_int_add_wep_key_bss_sta(priv->hWILCWFIDrv, sme->key, sme->key_len, sme->key_idx);
+                       wilc_set_wep_default_keyid(vif, sme->key_idx);
+                       wilc_add_wep_key_bss_sta(vif, sme->key, sme->key_len,
+                                                sme->key_idx);
                } else if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP104)   {
                        u8security = ENCRYPT_ENABLED | WEP | WEP_EXTENDED;
                        pcgroup_encrypt_val = "WEP104";
@@ -905,15 +814,15 @@ static int connect(struct wiphy *wiphy, struct net_device *dev,
                        g_key_wep_params.key_idx = sme->key_idx;
                        g_wep_keys_saved = true;
 
-                       host_int_set_wep_default_key(priv->hWILCWFIDrv, sme->key_idx);
-                       host_int_add_wep_key_bss_sta(priv->hWILCWFIDrv, sme->key, sme->key_len, sme->key_idx);
+                       wilc_set_wep_default_keyid(vif, sme->key_idx);
+                       wilc_add_wep_key_bss_sta(vif, sme->key, sme->key_len,
+                                                sme->key_idx);
                } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)   {
                        if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_TKIP) {
                                u8security = ENCRYPT_ENABLED | WPA2 | TKIP;
                                pcgroup_encrypt_val = "WPA2_TKIP";
                                pccipher_group = "TKIP";
-                       } else {     /* TODO: mostafa: here we assume that any other encryption type is AES */
-                                    /* tenuSecurity_t = WPA2_AES; */
+                       } else {
                                u8security = ENCRYPT_ENABLED | WPA2 | AES;
                                pcgroup_encrypt_val = "WPA2_AES";
                                pccipher_group = "AES";
@@ -924,12 +833,10 @@ static int connect(struct wiphy *wiphy, struct net_device *dev,
                                u8security = ENCRYPT_ENABLED | WPA | TKIP;
                                pcgroup_encrypt_val = "WPA_TKIP";
                                pccipher_group = "TKIP";
-                       } else {     /* TODO: mostafa: here we assume that any other encryption type is AES */
-                                    /* tenuSecurity_t = WPA_AES; */
+                       } else {
                                u8security = ENCRYPT_ENABLED | WPA | AES;
                                pcgroup_encrypt_val = "WPA_AES";
                                pccipher_group = "AES";
-
                        }
                        pcwpa_version = "WPA_VERSION_1";
 
@@ -939,17 +846,14 @@ static int connect(struct wiphy *wiphy, struct net_device *dev,
 
                        goto done;
                }
-
        }
 
-       /* After we set the u8security value from checking the group cipher suite, {in case of WPA or WPA2} we will
-        *   add to it the pairwise cipher suite(s) */
        if ((sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
            || (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)) {
                for (i = 0; i < sme->crypto.n_ciphers_pairwise; i++) {
                        if (sme->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP) {
                                u8security = u8security | TKIP;
-                       } else {     /* TODO: mostafa: here we assume that any other encryption type is AES */
+                       } else {
                                u8security = u8security | AES;
                        }
                }
@@ -973,8 +877,6 @@ static int connect(struct wiphy *wiphy, struct net_device *dev,
                PRINT_D(CFG80211_DBG, "Automatic Authentation type = %d\n", sme->auth_type);
        }
 
-
-       /* ai: key_mgmt: enterprise case */
        if (sme->crypto.n_akm_suites) {
                switch (sme->crypto.akm_suites[0]) {
                case WLAN_AKM_SUITE_8021X:
@@ -995,17 +897,18 @@ static int connect(struct wiphy *wiphy, struct net_device *dev,
        curr_channel = pstrNetworkInfo->u8channel;
 
        if (!pstrWFIDrv->p2p_connect)
-               u8WLANChannel = pstrNetworkInfo->u8channel;
+               wlan_channel = pstrNetworkInfo->u8channel;
 
-       linux_wlan_set_bssid(dev, pstrNetworkInfo->au8bssid);
+       wilc_wlan_set_bssid(dev, pstrNetworkInfo->au8bssid);
 
-       s32Error = host_int_set_join_req(priv->hWILCWFIDrv, pstrNetworkInfo->au8bssid, sme->ssid,
-                                        sme->ssid_len, sme->ie, sme->ie_len,
-                                        CfgConnectResult, (void *)priv, u8security,
-                                        tenuAuth_type, pstrNetworkInfo->u8channel,
-                                        pstrNetworkInfo->pJoinParams);
+       s32Error = wilc_set_join_req(vif, pstrNetworkInfo->au8bssid, sme->ssid,
+                                    sme->ssid_len, sme->ie, sme->ie_len,
+                                    CfgConnectResult, (void *)priv,
+                                    u8security, tenuAuth_type,
+                                    pstrNetworkInfo->u8channel,
+                                    pstrNetworkInfo->pJoinParams);
        if (s32Error != 0) {
-               PRINT_ER("host_int_set_join_req(): Error(%d)\n", s32Error);
+               PRINT_ER("wilc_set_join_req(): Error(%d)\n", s32Error);
                s32Error = -ENOENT;
                goto done;
        }
@@ -1015,40 +918,31 @@ done:
        return s32Error;
 }
 
-
-/**
- *  @brief      disconnect
- *  @details    Disconnect from the BSS/ESS.
- *  @param[in]
- *  @return     int : Return 0 on Success
- *  @author    mdaftedar
- *  @date      01 MAR 2012
- *  @version   1.0
- */
 static int disconnect(struct wiphy *wiphy, struct net_device *dev, u16 reason_code)
 {
        s32 s32Error = 0;
        struct wilc_priv *priv;
        struct host_if_drv *pstrWFIDrv;
+       struct wilc_vif *vif;
        u8 NullBssid[ETH_ALEN] = {0};
 
-       connecting = 0;
+       wilc_connecting = 0;
        priv = wiphy_priv(wiphy);
+       vif = netdev_priv(priv->dev);
 
-       /*Invalidate u8WLANChannel value on wlan0 disconnect*/
        pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
        if (!pstrWFIDrv->p2p_connect)
-               u8WLANChannel = INVALID_CHANNEL;
-       linux_wlan_set_bssid(priv->dev, NullBssid);
+               wlan_channel = INVALID_CHANNEL;
+       wilc_wlan_set_bssid(priv->dev, NullBssid);
 
        PRINT_D(CFG80211_DBG, "Disconnecting with reason code(%d)\n", reason_code);
 
-       u8P2Plocalrandom = 0x01;
-       u8P2Precvrandom = 0x00;
-       bWilc_ie = false;
+       p2p_local_random = 0x01;
+       p2p_recv_random = 0x00;
+       wilc_ie = false;
        pstrWFIDrv->p2p_timeout = 0;
 
-       s32Error = host_int_disconnect(priv->hWILCWFIDrv, reason_code);
+       s32Error = wilc_disconnect(vif, reason_code);
        if (s32Error != 0) {
                PRINT_ER("Error in disconnecting: Error(%d)\n", s32Error);
                s32Error = -EINVAL;
@@ -1057,16 +951,6 @@ static int disconnect(struct wiphy *wiphy, struct net_device *dev, u16 reason_co
        return s32Error;
 }
 
-/**
- *  @brief      add_key
- *  @details    Add a key with the given parameters. @mac_addr will be %NULL
- *                      when adding a group key.
- *  @param[in] key : key buffer; TKIP: 16-byte temporal key, 8-byte Tx Mic key, 8-byte Rx Mic Key
- *  @return     int : Return 0 on Success
- *  @author    mdaftedar
- *  @date      01 MAR 2012
- *  @version   1.0
- */
 static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
                   bool pairwise,
                   const u8 *mac_addr, struct key_params *params)
@@ -1082,11 +966,11 @@ static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
        u8 u8pmode = NO_ENCRYPT;
        enum AUTHTYPE tenuAuth_type = ANY;
        struct wilc *wl;
-       perInterface_wlan_t *nic;
+       struct wilc_vif *vif;
 
        priv = wiphy_priv(wiphy);
-       nic = netdev_priv(netdev);
-       wl = nic->wilc;
+       vif = netdev_priv(netdev);
+       wl = vif->wilc;
 
        PRINT_D(CFG80211_DBG, "Adding key with cipher suite = %x\n", params->cipher);
 
@@ -1101,7 +985,6 @@ static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
        case WLAN_CIPHER_SUITE_WEP40:
        case WLAN_CIPHER_SUITE_WEP104:
                if (priv->wdev->iftype == NL80211_IFTYPE_AP) {
-
                        priv->WILC_WFI_wep_default = key_index;
                        priv->WILC_WFI_wep_key_len[key_index] = params->key_len;
                        memcpy(priv->WILC_WFI_wep_key[key_index], params->key, params->key_len);
@@ -1119,7 +1002,9 @@ static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
                        else
                                u8mode = ENCRYPT_ENABLED | WEP | WEP_EXTENDED;
 
-                       host_int_add_wep_key_bss_ap(priv->hWILCWFIDrv, params->key, params->key_len, key_index, u8mode, tenuAuth_type);
+                       wilc_add_wep_key_bss_ap(vif, params->key,
+                                               params->key_len, key_index,
+                                               u8mode, tenuAuth_type);
                        break;
                }
                if (memcmp(params->key, priv->WILC_WFI_wep_key[key_index], params->key_len)) {
@@ -1133,7 +1018,8 @@ static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
                                for (i = 0; i < params->key_len; i++)
                                        PRINT_INFO(CFG80211_DBG, "WEP key value[%d] = %d\n", i, params->key[i]);
                        }
-                       host_int_add_wep_key_bss_sta(priv->hWILCWFIDrv, params->key, params->key_len, key_index);
+                       wilc_add_wep_key_bss_sta(vif, params->key,
+                                                params->key_len, key_index);
                }
 
                break;
@@ -1141,14 +1027,12 @@ static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
        case WLAN_CIPHER_SUITE_TKIP:
        case WLAN_CIPHER_SUITE_CCMP:
                if (priv->wdev->iftype == NL80211_IFTYPE_AP || priv->wdev->iftype == NL80211_IFTYPE_P2P_GO) {
-
-                       if (priv->wilc_gtk[key_index] == NULL) {
+                       if (!priv->wilc_gtk[key_index]) {
                                priv->wilc_gtk[key_index] = kmalloc(sizeof(struct wilc_wfi_key), GFP_KERNEL);
                                priv->wilc_gtk[key_index]->key = NULL;
                                priv->wilc_gtk[key_index]->seq = NULL;
-
                        }
-                       if (priv->wilc_ptk[key_index] == NULL) {
+                       if (!priv->wilc_ptk[key_index]) {
                                priv->wilc_ptk[key_index] = kmalloc(sizeof(struct wilc_wfi_key), GFP_KERNEL);
                                priv->wilc_ptk[key_index]->key = NULL;
                                priv->wilc_ptk[key_index]->seq = NULL;
@@ -1165,18 +1049,14 @@ static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
                                priv->wilc_groupkey = u8gmode;
 
                                if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
-
                                        pu8TxMic = params->key + 24;
                                        pu8RxMic = params->key + 16;
                                        KeyLen = params->key_len - 16;
                                }
-                               /* if there has been previous allocation for the same index through its key, free that memory and allocate again*/
                                kfree(priv->wilc_gtk[key_index]->key);
 
                                priv->wilc_gtk[key_index]->key = kmalloc(params->key_len, GFP_KERNEL);
                                memcpy(priv->wilc_gtk[key_index]->key, params->key, params->key_len);
-
-                               /* if there has been previous allocation for the same index through its seq, free that memory and allocate again*/
                                kfree(priv->wilc_gtk[key_index]->seq);
 
                                if ((params->seq_len) > 0) {
@@ -1196,8 +1076,10 @@ static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
                                }
 
 
-                               host_int_add_rx_gtk(priv->hWILCWFIDrv, params->key, KeyLen,
-                                                   key_index, params->seq_len, params->seq, pu8RxMic, pu8TxMic, AP_MODE, u8gmode);
+                               wilc_add_rx_gtk(vif, params->key, KeyLen,
+                                               key_index, params->seq_len,
+                                               params->seq, pu8RxMic,
+                                               pu8TxMic, AP_MODE, u8gmode);
 
                        } else {
                                PRINT_INFO(CFG80211_DBG, "STA Address: %x%x%x%x%x\n", mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4]);
@@ -1209,7 +1091,6 @@ static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
 
 
                                if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
-
                                        pu8TxMic = params->key + 24;
                                        pu8RxMic = params->key + 16;
                                        KeyLen = params->key_len - 16;
@@ -1241,8 +1122,9 @@ static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
                                priv->wilc_ptk[key_index]->key_len = params->key_len;
                                priv->wilc_ptk[key_index]->seq_len = params->seq_len;
 
-                               host_int_add_ptk(priv->hWILCWFIDrv, params->key, KeyLen, mac_addr,
-                                                pu8RxMic, pu8TxMic, AP_MODE, u8pmode, key_index);
+                               wilc_add_ptk(vif, params->key, KeyLen,
+                                            mac_addr, pu8RxMic, pu8TxMic,
+                                            AP_MODE, u8pmode, key_index);
                        }
                        break;
                }
@@ -1251,14 +1133,12 @@ static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
                        u8mode = 0;
                        if (!pairwise) {
                                if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
-                                       /* swap the tx mic by rx mic */
                                        pu8RxMic = params->key + 24;
                                        pu8TxMic = params->key + 16;
                                        KeyLen = params->key_len - 16;
                                }
 
-                               /*save keys only on interface 0 (wifi interface)*/
-                               if (!g_gtk_keys_saved && netdev == wl->vif[0].ndev) {
+                               if (!g_gtk_keys_saved && netdev == wl->vif[0]->ndev) {
                                        g_add_gtk_key_params.key_idx = key_index;
                                        g_add_gtk_key_params.pairwise = pairwise;
                                        if (!mac_addr) {
@@ -1283,18 +1163,19 @@ static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
                                        g_gtk_keys_saved = true;
                                }
 
-                               host_int_add_rx_gtk(priv->hWILCWFIDrv, params->key, KeyLen,
-                                                   key_index, params->seq_len, params->seq, pu8RxMic, pu8TxMic, STATION_MODE, u8mode);
+                               wilc_add_rx_gtk(vif, params->key, KeyLen,
+                                               key_index, params->seq_len,
+                                               params->seq, pu8RxMic,
+                                               pu8TxMic, STATION_MODE,
+                                               u8mode);
                        } else {
                                if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
-                                       /* swap the tx mic by rx mic */
                                        pu8RxMic = params->key + 24;
                                        pu8TxMic = params->key + 16;
                                        KeyLen = params->key_len - 16;
                                }
 
-                               /*save keys only on interface 0 (wifi interface)*/
-                               if (!g_ptk_keys_saved && netdev == wl->vif[0].ndev) {
+                               if (!g_ptk_keys_saved && netdev == wl->vif[0]->ndev) {
                                        g_add_ptk_key_params.key_idx = key_index;
                                        g_add_ptk_key_params.pairwise = pairwise;
                                        if (!mac_addr) {
@@ -1319,8 +1200,9 @@ static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
                                        g_ptk_keys_saved = true;
                                }
 
-                               host_int_add_ptk(priv->hWILCWFIDrv, params->key, KeyLen, mac_addr,
-                                                pu8RxMic, pu8TxMic, STATION_MODE, u8mode, key_index);
+                               wilc_add_ptk(vif, params->key, KeyLen,
+                                            mac_addr, pu8RxMic, pu8TxMic,
+                                            STATION_MODE, u8mode, key_index);
                                PRINT_D(CFG80211_DBG, "Adding pairwise key\n");
                                if (INFO) {
                                        for (i = 0; i < params->key_len; i++)
@@ -1333,22 +1215,11 @@ static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
        default:
                PRINT_ER("Not supported cipher: Error(%d)\n", s32Error);
                s32Error = -ENOTSUPP;
-
        }
 
        return s32Error;
 }
 
-/**
- *  @brief      del_key
- *  @details    Remove a key given the @mac_addr (%NULL for a group key)
- *                      and @key_index, return -ENOENT if the key doesn't exist.
- *  @param[in]
- *  @return     int : Return 0 on Success
- *  @author    mdaftedar
- *  @date      01 MAR 2012
- *  @version   1.0
- */
 static int del_key(struct wiphy *wiphy, struct net_device *netdev,
                   u8 key_index,
                   bool pairwise,
@@ -1356,26 +1227,21 @@ static int del_key(struct wiphy *wiphy, struct net_device *netdev,
 {
        struct wilc_priv *priv;
        struct wilc *wl;
-       perInterface_wlan_t *nic;
+       struct wilc_vif *vif;
 
        priv = wiphy_priv(wiphy);
-       nic = netdev_priv(netdev);
-       wl = nic->wilc;
+       vif = netdev_priv(netdev);
+       wl = vif->wilc;
 
-       /*delete saved keys, if any*/
-       if (netdev == wl->vif[0].ndev) {
+       if (netdev == wl->vif[0]->ndev) {
                g_ptk_keys_saved = false;
                g_gtk_keys_saved = false;
                g_wep_keys_saved = false;
 
-               /*Delete saved WEP keys params, if any*/
                kfree(g_key_wep_params.key);
                g_key_wep_params.key = NULL;
 
-               /*freeing memory allocated by "wilc_gtk" and "wilc_ptk" in "WILC_WIFI_ADD_KEY"*/
-
                if ((priv->wilc_gtk[key_index]) != NULL) {
-
                        kfree(priv->wilc_gtk[key_index]->key);
                        priv->wilc_gtk[key_index]->key = NULL;
                        kfree(priv->wilc_gtk[key_index]->seq);
@@ -1383,11 +1249,9 @@ static int del_key(struct wiphy *wiphy, struct net_device *netdev,
 
                        kfree(priv->wilc_gtk[key_index]);
                        priv->wilc_gtk[key_index] = NULL;
-
                }
 
                if ((priv->wilc_ptk[key_index]) != NULL) {
-
                        kfree(priv->wilc_ptk[key_index]->key);
                        priv->wilc_ptk[key_index]->key = NULL;
                        kfree(priv->wilc_ptk[key_index]->seq);
@@ -1396,7 +1260,6 @@ static int del_key(struct wiphy *wiphy, struct net_device *netdev,
                        priv->wilc_ptk[key_index] = NULL;
                }
 
-               /*Delete saved PTK and GTK keys params, if any*/
                kfree(g_key_ptk_params.key);
                g_key_ptk_params.key = NULL;
                kfree(g_key_ptk_params.seq);
@@ -1407,8 +1270,7 @@ static int del_key(struct wiphy *wiphy, struct net_device *netdev,
                kfree(g_key_gtk_params.seq);
                g_key_gtk_params.seq = NULL;
 
-               /*Reset WILC_CHANGING_VIR_IF register to allow adding futrue keys to CE H/W*/
-               set_machw_change_vir_if(netdev, false);
+               wilc_set_machw_change_vir_if(netdev, false);
        }
 
        if (key_index >= 0 && key_index <= 3) {
@@ -1416,28 +1278,15 @@ static int del_key(struct wiphy *wiphy, struct net_device *netdev,
                priv->WILC_WFI_wep_key_len[key_index] = 0;
 
                PRINT_D(CFG80211_DBG, "Removing WEP key with index = %d\n", key_index);
-               host_int_remove_wep_key(priv->hWILCWFIDrv, key_index);
+               wilc_remove_wep_key(vif, key_index);
        } else {
                PRINT_D(CFG80211_DBG, "Removing all installed keys\n");
-               host_int_remove_key(priv->hWILCWFIDrv, mac_addr);
+               wilc_remove_key(priv->hWILCWFIDrv, mac_addr);
        }
 
        return 0;
 }
 
-/**
- *  @brief      get_key
- *  @details    Get information about the key with the given parameters.
- *                      @mac_addr will be %NULL when requesting information for a group
- *                      key. All pointers given to the @callback function need not be valid
- *                      after it returns. This function should return an error if it is
- *                      not possible to retrieve the key, -ENOENT if it doesn't exist.
- *  @param[in]
- *  @return     int : Return 0 on Success
- *  @author    mdaftedar
- *  @date      01 MAR 2012
- *  @version   1.0
- */
 static int get_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
                   bool pairwise,
                   const u8 *mac_addr, void *cookie, void (*callback)(void *cookie, struct key_params *))
@@ -1473,69 +1322,48 @@ static int get_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
 
        callback(cookie, &key_params);
 
-       return 0;        /* priv->wilc_gtk->key_len ?0 : -ENOENT; */
+       return 0;
 }
 
-/**
- *  @brief      set_default_key
- *  @details    Set the default management frame key on an interface
- *  @param[in]
- *  @return     int : Return 0 on Success.
- *  @author    mdaftedar
- *  @date      01 MAR 2012
- *  @version   1.0
- */
 static int set_default_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
                           bool unicast, bool multicast)
 {
        struct wilc_priv *priv;
-
+       struct wilc_vif *vif;
 
        priv = wiphy_priv(wiphy);
+       vif = netdev_priv(priv->dev);
 
        PRINT_D(CFG80211_DBG, "Setting default key with idx = %d\n", key_index);
 
        if (key_index != priv->WILC_WFI_wep_default) {
-
-               host_int_set_wep_default_key(priv->hWILCWFIDrv, key_index);
+               wilc_set_wep_default_keyid(vif, key_index);
        }
 
        return 0;
 }
 
-/**
- *  @brief      get_station
- *  @details    Get station information for the station identified by @mac
- *  @param[in]   NONE
- *  @return     int : Return 0 on Success.
- *  @author    mdaftedar
- *  @date      01 MAR 2012
- *  @version   1.0
- */
-
 static int get_station(struct wiphy *wiphy, struct net_device *dev,
                       const u8 *mac, struct station_info *sinfo)
 {
        struct wilc_priv *priv;
-       perInterface_wlan_t *nic;
+       struct wilc_vif *vif;
        u32 i = 0;
        u32 associatedsta = 0;
        u32 inactive_time = 0;
        priv = wiphy_priv(wiphy);
-       nic = netdev_priv(dev);
+       vif = netdev_priv(dev);
 
-       if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) {
+       if (vif->iftype == AP_MODE || vif->iftype == GO_MODE) {
                PRINT_D(HOSTAPD_DBG, "Getting station parameters\n");
 
                PRINT_INFO(HOSTAPD_DBG, ": %x%x%x%x%x\n", mac[0], mac[1], mac[2], mac[3], mac[4]);
 
                for (i = 0; i < NUM_STA_ASSOCIATED; i++) {
-
                        if (!(memcmp(mac, priv->assoc_stainfo.au8Sta_AssociatedBss[i], ETH_ALEN))) {
                                associatedsta = i;
                                break;
                        }
-
                }
 
                if (associatedsta == -1) {
@@ -1545,16 +1373,15 @@ static int get_station(struct wiphy *wiphy, struct net_device *dev,
 
                sinfo->filled |= BIT(NL80211_STA_INFO_INACTIVE_TIME);
 
-               host_int_get_inactive_time(priv->hWILCWFIDrv, mac, &(inactive_time));
+               wilc_get_inactive_time(vif, mac, &inactive_time);
                sinfo->inactive_time = 1000 * inactive_time;
                PRINT_D(CFG80211_DBG, "Inactive time %d\n", sinfo->inactive_time);
-
        }
 
-       if (nic->iftype == STATION_MODE) {
+       if (vif->iftype == STATION_MODE) {
                struct rf_info strStatistics;
 
-               host_int_get_statistics(priv->hWILCWFIDrv, &strStatistics);
+               wilc_get_statistics(vif, &strStatistics);
 
                sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL) |
                                                BIT(NL80211_STA_INFO_RX_PACKETS) |
@@ -1570,9 +1397,9 @@ static int get_station(struct wiphy *wiphy, struct net_device *dev,
 
                if ((strStatistics.link_speed > TCP_ACK_FILTER_LINK_SPEED_THRESH) &&
                    (strStatistics.link_speed != DEFAULT_LINK_SPEED))
-                       enable_tcp_ack_filter(true);
+                       wilc_enable_tcp_ack_filter(true);
                else if (strStatistics.link_speed != DEFAULT_LINK_SPEED)
-                       enable_tcp_ack_filter(false);
+                       wilc_enable_tcp_ack_filter(false);
 
                PRINT_D(CORECONFIG_DBG, "*** stats[%d][%d][%d][%d][%d]\n", sinfo->signal, sinfo->rx_packets, sinfo->tx_packets,
                        sinfo->tx_failed, sinfo->txrate.legacy);
@@ -1580,28 +1407,6 @@ static int get_station(struct wiphy *wiphy, struct net_device *dev,
        return 0;
 }
 
-
-/**
- *  @brief      change_bss
- *  @details    Modify parameters for a given BSS.
- *  @param[in]
- *   -use_cts_prot: Whether to use CTS protection
- *         (0 = no, 1 = yes, -1 = do not change)
- *  -use_short_preamble: Whether the use of short preambles is allowed
- *         (0 = no, 1 = yes, -1 = do not change)
- *  -use_short_slot_time: Whether the use of short slot time is allowed
- *         (0 = no, 1 = yes, -1 = do not change)
- *  -basic_rates: basic rates in IEEE 802.11 format
- *         (or NULL for no change)
- *  -basic_rates_len: number of basic rates
- *  -ap_isolate: do not forward packets between connected stations
- *  -ht_opmode: HT Operation mode
- *         (u16 = opmode, -1 = do not change)
- *  @return     int : Return 0 on Success.
- *  @author    mdaftedar
- *  @date      01 MAR 2012
- *  @version   1.0
- */
 static int change_bss(struct wiphy *wiphy, struct net_device *dev,
                      struct bss_parameters *params)
 {
@@ -1609,23 +1414,15 @@ static int change_bss(struct wiphy *wiphy, struct net_device *dev,
        return 0;
 }
 
-/**
- *  @brief      set_wiphy_params
- *  @details    Notify that wiphy parameters have changed;
- *  @param[in]   Changed bitfield (see &enum wiphy_params_flags) describes which values
- *                      have changed.
- *  @return     int : Return 0 on Success
- *  @author    mdaftedar
- *  @date      01 MAR 2012
- *  @version   1.0
- */
 static int set_wiphy_params(struct wiphy *wiphy, u32 changed)
 {
        s32 s32Error = 0;
        struct cfg_param_val pstrCfgParamVal;
        struct wilc_priv *priv;
+       struct wilc_vif *vif;
 
        priv = wiphy_priv(wiphy);
+       vif = netdev_priv(priv->dev);
 
        pstrCfgParamVal.flag = 0;
        PRINT_D(CFG80211_DBG, "Setting Wiphy params\n");
@@ -1637,17 +1434,14 @@ static int set_wiphy_params(struct wiphy *wiphy, u32 changed)
                pstrCfgParamVal.short_retry_limit = priv->dev->ieee80211_ptr->wiphy->retry_short;
        }
        if (changed & WIPHY_PARAM_RETRY_LONG) {
-
                PRINT_D(CFG80211_DBG, "Setting WIPHY_PARAM_RETRY_LONG %d\n", priv->dev->ieee80211_ptr->wiphy->retry_long);
                pstrCfgParamVal.flag |= RETRY_LONG;
                pstrCfgParamVal.long_retry_limit = priv->dev->ieee80211_ptr->wiphy->retry_long;
-
        }
        if (changed & WIPHY_PARAM_FRAG_THRESHOLD) {
                PRINT_D(CFG80211_DBG, "Setting WIPHY_PARAM_FRAG_THRESHOLD %d\n", priv->dev->ieee80211_ptr->wiphy->frag_threshold);
                pstrCfgParamVal.flag |= FRAG_THRESHOLD;
                pstrCfgParamVal.frag_threshold = priv->dev->ieee80211_ptr->wiphy->frag_threshold;
-
        }
 
        if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
@@ -1655,11 +1449,10 @@ static int set_wiphy_params(struct wiphy *wiphy, u32 changed)
 
                pstrCfgParamVal.flag |= RTS_THRESHOLD;
                pstrCfgParamVal.rts_threshold = priv->dev->ieee80211_ptr->wiphy->rts_threshold;
-
        }
 
        PRINT_D(CFG80211_DBG, "Setting CFG params in the host interface\n");
-       s32Error = hif_set_cfg(priv->hWILCWFIDrv, &pstrCfgParamVal);
+       s32Error = wilc_hif_set_cfg(vif, &pstrCfgParamVal);
        if (s32Error)
                PRINT_ER("Error in setting WIPHY PARAMS\n");
 
@@ -1667,33 +1460,22 @@ static int set_wiphy_params(struct wiphy *wiphy, u32 changed)
        return s32Error;
 }
 
-/**
- *  @brief      set_pmksa
- *  @details    Cache a PMKID for a BSSID. This is mostly useful for fullmac
- *                      devices running firmwares capable of generating the (re) association
- *                      RSN IE. It allows for faster roaming between WPA2 BSSIDs.
- *  @param[in]
- *  @return     int : Return 0 on Success
- *  @author    mdaftedar
- *  @date      01 MAR 2012
- *  @version   1.0
- */
 static int set_pmksa(struct wiphy *wiphy, struct net_device *netdev,
                     struct cfg80211_pmksa *pmksa)
 {
        u32 i;
        s32 s32Error = 0;
        u8 flag = 0;
-
+       struct wilc_vif *vif;
        struct wilc_priv *priv = wiphy_priv(wiphy);
 
+       vif = netdev_priv(priv->dev);
        PRINT_D(CFG80211_DBG, "Setting PMKSA\n");
 
 
        for (i = 0; i < priv->pmkid_list.numpmkid; i++) {
                if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
                                 ETH_ALEN)) {
-                       /*If bssid already exists and pmkid value needs to reset*/
                        flag = PMKID_FOUND;
                        PRINT_D(CFG80211_DBG, "PMKID already exists\n");
                        break;
@@ -1714,24 +1496,14 @@ static int set_pmksa(struct wiphy *wiphy, struct net_device *netdev,
 
        if (!s32Error) {
                PRINT_D(CFG80211_DBG, "Setting pmkid in the host interface\n");
-               s32Error = host_int_set_pmkid_info(priv->hWILCWFIDrv, &priv->pmkid_list);
+               s32Error = wilc_set_pmkid_info(vif, &priv->pmkid_list);
        }
        return s32Error;
 }
 
-/**
- *  @brief      del_pmksa
- *  @details    Delete a cached PMKID.
- *  @param[in]
- *  @return     int : Return 0 on Success
- *  @author    mdaftedar
- *  @date      01 MAR 2012
- *  @version   1.0
- */
 static int del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
                     struct cfg80211_pmksa *pmksa)
 {
-
        u32 i;
        s32 s32Error = 0;
 
@@ -1742,7 +1514,6 @@ static int del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
        for (i = 0; i < priv->pmkid_list.numpmkid; i++) {
                if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
                                 ETH_ALEN)) {
-                       /*If bssid is found, reset the values*/
                        PRINT_D(CFG80211_DBG, "Reseting PMKID values\n");
                        memset(&priv->pmkid_list.pmkidlist[i], 0, sizeof(struct host_if_pmkid));
                        break;
@@ -1766,43 +1537,18 @@ static int del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
        return s32Error;
 }
 
-/**
- *  @brief      flush_pmksa
- *  @details    Flush all cached PMKIDs.
- *  @param[in]
- *  @return     int : Return 0 on Success
- *  @author    mdaftedar
- *  @date      01 MAR 2012
- *  @version   1.0
- */
 static int flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
 {
        struct wilc_priv *priv = wiphy_priv(wiphy);
 
        PRINT_D(CFG80211_DBG,  "Flushing  PMKID key values\n");
 
-       /*Get cashed Pmkids and set all with zeros*/
        memset(&priv->pmkid_list, 0, sizeof(struct host_if_pmkid_attr));
 
        return 0;
 }
 
-
-/**
- *  @brief      WILC_WFI_CfgParseRxAction
- *  @details Function parses the received  frames and modifies the following attributes:
- *                -GO Intent
- *                 -Channel list
- *                 -Operating Channel
- *
- *  @param[in] u8* Buffer, u32 length
- *  @return     NONE.
- *  @author    mdaftedar
- *  @date      12 DEC 2012
- *  @version
- */
-
-void WILC_WFI_CfgParseRxAction(u8 *buf, u32 len)
+static void WILC_WFI_CfgParseRxAction(u8 *buf, u32 len)
 {
        u32 index = 0;
        u32 i = 0, j = 0;
@@ -1819,42 +1565,30 @@ void WILC_WFI_CfgParseRxAction(u8 *buf, u32 len)
                        channel_list_attr_index = index;
                else if (buf[index] ==  OPERCHAN_ATTR_ID)
                        op_channel_attr_index = index;
-               index += buf[index + 1] + 3; /* ID,Length byte */
+               index += buf[index + 1] + 3;
        }
-       if (u8WLANChannel != INVALID_CHANNEL) {
-
-               /*Modify channel list attribute*/
+       if (wlan_channel != INVALID_CHANNEL) {
                if (channel_list_attr_index) {
                        PRINT_D(GENERIC_DBG, "Modify channel list attribute\n");
                        for (i = channel_list_attr_index + 3; i < ((channel_list_attr_index + 3) + buf[channel_list_attr_index + 1]); i++) {
                                if (buf[i] == 0x51) {
                                        for (j = i + 2; j < ((i + 2) + buf[i + 1]); j++) {
-                                               buf[j] = u8WLANChannel;
+                                               buf[j] = wlan_channel;
                                        }
                                        break;
                                }
                        }
                }
-               /*Modify operating channel attribute*/
+
                if (op_channel_attr_index) {
                        PRINT_D(GENERIC_DBG, "Modify operating channel attribute\n");
                        buf[op_channel_attr_index + 6] = 0x51;
-                       buf[op_channel_attr_index + 7] = u8WLANChannel;
+                       buf[op_channel_attr_index + 7] = wlan_channel;
                }
        }
 }
 
-/**
- *  @brief      WILC_WFI_CfgParseTxAction
- *  @details Function parses the transmitted  action frames and modifies the
- *               GO Intent attribute
- *  @param[in] u8* Buffer, u32 length, bool bOperChan, u8 iftype
- *  @return     NONE.
- *  @author    mdaftedar
- *  @date      12 DEC 2012
- *  @version
- */
-void WILC_WFI_CfgParseTxAction(u8 *buf, u32 len, bool bOperChan, u8 iftype)
+static void WILC_WFI_CfgParseTxAction(u8 *buf, u32 len, bool bOperChan, u8 iftype)
 {
        u32 index = 0;
        u32 i = 0, j = 0;
@@ -1873,44 +1607,31 @@ void WILC_WFI_CfgParseTxAction(u8 *buf, u32 len, bool bOperChan, u8 iftype)
                        channel_list_attr_index = index;
                else if (buf[index] ==  OPERCHAN_ATTR_ID)
                        op_channel_attr_index = index;
-               index += buf[index + 1] + 3; /* ID,Length byte */
+               index += buf[index + 1] + 3;
        }
-       if (u8WLANChannel != INVALID_CHANNEL && bOperChan) {
-
-               /*Modify channel list attribute*/
+       if (wlan_channel != INVALID_CHANNEL && bOperChan) {
                if (channel_list_attr_index) {
                        PRINT_D(GENERIC_DBG, "Modify channel list attribute\n");
                        for (i = channel_list_attr_index + 3; i < ((channel_list_attr_index + 3) + buf[channel_list_attr_index + 1]); i++) {
                                if (buf[i] == 0x51) {
                                        for (j = i + 2; j < ((i + 2) + buf[i + 1]); j++) {
-                                               buf[j] = u8WLANChannel;
+                                               buf[j] = wlan_channel;
                                        }
                                        break;
                                }
                        }
                }
-               /*Modify operating channel attribute*/
+
                if (op_channel_attr_index) {
                        PRINT_D(GENERIC_DBG, "Modify operating channel attribute\n");
                        buf[op_channel_attr_index + 6] = 0x51;
-                       buf[op_channel_attr_index + 7] = u8WLANChannel;
+                       buf[op_channel_attr_index + 7] = wlan_channel;
                }
        }
 }
 
-/*  @brief                       WILC_WFI_p2p_rx
- *  @details
- *  @param[in]
- *
- *  @return             None
- *  @author            Mai Daftedar
- *  @date                      2 JUN 2013
- *  @version           1.0
- */
-
 void WILC_WFI_p2p_rx (struct net_device *dev, u8 *buff, u32 size)
 {
-
        struct wilc_priv *priv;
        u32 header, pkt_offset;
        struct host_if_drv *pstrWFIDrv;
@@ -1920,11 +1641,8 @@ void WILC_WFI_p2p_rx (struct net_device *dev, u8 *buff, u32 size)
        priv = wiphy_priv(dev->ieee80211_ptr->wiphy);
        pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
 
-       /* Get WILC header */
        memcpy(&header, (buff - HOST_HDR_OFFSET), HOST_HDR_OFFSET);
 
-       /* The packet offset field conain info about what type of managment frame */
-       /* we are dealing with and ack status */
        pkt_offset = GET_PKT_OFFSET(header);
 
        if (pkt_offset & IS_MANAGMEMENT_CALLBACK) {
@@ -1945,10 +1663,8 @@ void WILC_WFI_p2p_rx (struct net_device *dev, u8 *buff, u32 size)
                        return;
                }
        } else {
-
                PRINT_D(GENERIC_DBG, "Rx Frame Type:%x\n", buff[FRAME_TYPE_ID]);
 
-               /*Upper layer is informed that the frame is received on this freq*/
                s32Freq = ieee80211_channel_to_frequency(curr_channel, IEEE80211_BAND_2GHZ);
 
                if (ieee80211_is_action(buff[FRAME_TYPE_ID])) {
@@ -1959,7 +1675,6 @@ void WILC_WFI_p2p_rx (struct net_device *dev, u8 *buff, u32 size)
                                return;
                        }
                        if (buff[ACTION_CAT_ID] == PUB_ACTION_ATTR_ID) {
-
                                switch (buff[ACTION_SUBTYPE_ID]) {
                                case GAS_INTIAL_REQ:
                                        PRINT_D(GENERIC_DBG, "GAS INITIAL REQ %x\n", buff[ACTION_SUBTYPE_ID]);
@@ -1970,39 +1685,37 @@ void WILC_WFI_p2p_rx (struct net_device *dev, u8 *buff, u32 size)
                                        break;
 
                                case PUBLIC_ACT_VENDORSPEC:
-                                       /*Now we have a public action vendor specific action frame, check if its a p2p public action frame
-                                        * based on the standard its should have the p2p_oui attribute with the following values 50 6f 9A 09*/
-                                       if (!memcmp(u8P2P_oui, &buff[ACTION_SUBTYPE_ID + 1], 4)) {
+                                       if (!memcmp(p2p_oui, &buff[ACTION_SUBTYPE_ID + 1], 4)) {
                                                if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP)) {
-                                                       if (!bWilc_ie) {
+                                                       if (!wilc_ie) {
                                                                for (i = P2P_PUB_ACTION_SUBTYPE; i < size; i++) {
-                                                                       if (!memcmp(u8P2P_vendorspec, &buff[i], 6)) {
-                                                                               u8P2Precvrandom = buff[i + 6];
-                                                                               bWilc_ie = true;
-                                                                               PRINT_D(GENERIC_DBG, "WILC Vendor specific IE:%02x\n", u8P2Precvrandom);
+                                                                       if (!memcmp(p2p_vendor_spec, &buff[i], 6)) {
+                                                                               p2p_recv_random = buff[i + 6];
+                                                                               wilc_ie = true;
+                                                                               PRINT_D(GENERIC_DBG, "WILC Vendor specific IE:%02x\n", p2p_recv_random);
                                                                                break;
                                                                        }
                                                                }
                                                        }
                                                }
-                                               if (u8P2Plocalrandom > u8P2Precvrandom) {
+                                               if (p2p_local_random > p2p_recv_random) {
                                                        if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP
                                                              || buff[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)) {
                                                                for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < size; i++) {
-                                                                       if (buff[i] == P2PELEM_ATTR_ID && !(memcmp(u8P2P_oui, &buff[i + 2], 4))) {
+                                                                       if (buff[i] == P2PELEM_ATTR_ID && !(memcmp(p2p_oui, &buff[i + 2], 4))) {
                                                                                WILC_WFI_CfgParseRxAction(&buff[i + 6], size - (i + 6));
                                                                                break;
                                                                        }
                                                                }
                                                        }
-                                               } else
-                                                       PRINT_D(GENERIC_DBG, "PEER WILL BE GO LocaRand=%02x RecvRand %02x\n", u8P2Plocalrandom, u8P2Precvrandom);
+                                               } else {
+                                                       PRINT_D(GENERIC_DBG, "PEER WILL BE GO LocaRand=%02x RecvRand %02x\n", p2p_local_random, p2p_recv_random);
+                                               }
                                        }
 
 
-                                       if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP) && (bWilc_ie))   {
+                                       if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP) && (wilc_ie))    {
                                                PRINT_D(GENERIC_DBG, "Sending P2P to host without extra elemnt\n");
-                                               /* extra attribute for sig_dbm: signal strength in mBm, or 0 if unknown */
                                                cfg80211_rx_mgmt(priv->wdev, s32Freq, 0, buff, size - 7, 0);
                                                return;
                                        }
@@ -2019,16 +1732,6 @@ void WILC_WFI_p2p_rx (struct net_device *dev, u8 *buff, u32 size)
        }
 }
 
-/**
- *  @brief                      WILC_WFI_mgmt_tx_complete
- *  @details            Returns result of writing mgmt frame to VMM (Tx buffers are freed here)
- *  @param[in]          priv
- *                              transmitting status
- *  @return             None
- *  @author            Amr Abdelmoghny
- *  @date                      20 MAY 2013
- *  @version           1.0
- */
 static void WILC_WFI_mgmt_tx_complete(void *priv, int status)
 {
        struct p2p_mgmt_data *pv_data = (struct p2p_mgmt_data *)priv;
@@ -2038,16 +1741,6 @@ static void WILC_WFI_mgmt_tx_complete(void *priv, int status)
        kfree(pv_data);
 }
 
-/**
- * @brief               WILC_WFI_RemainOnChannelReady
- *  @details    Callback function, called from handle_remain_on_channel on being ready on channel
- *  @param
- *  @return     none
- *  @author    Amr abdelmoghny
- *  @date              9 JUNE 2013
- *  @version
- */
-
 static void WILC_WFI_RemainOnChannelReady(void *pUserVoid)
 {
        struct wilc_priv *priv;
@@ -2065,16 +1758,6 @@ static void WILC_WFI_RemainOnChannelReady(void *pUserVoid)
                                  GFP_KERNEL);
 }
 
-/**
- * @brief               WILC_WFI_RemainOnChannelExpired
- *  @details    Callback function, called on expiration of remain-on-channel duration
- *  @param
- *  @return     none
- *  @author    Amr abdelmoghny
- *  @date              15 MAY 2013
- *  @version
- */
-
 static void WILC_WFI_RemainOnChannelExpired(void *pUserVoid, u32 u32SessionID)
 {
        struct wilc_priv *priv;
@@ -2086,7 +1769,6 @@ static void WILC_WFI_RemainOnChannelExpired(void *pUserVoid, u32 u32SessionID)
 
                priv->bInP2PlistenState = false;
 
-               /*Inform wpas of remain-on-channel expiration*/
                cfg80211_remain_on_channel_expired(priv->wdev,
                                                   priv->strRemainOnChanParams.u64ListenCookie,
                                                   priv->strRemainOnChanParams.pstrListenChan,
@@ -2097,20 +1779,6 @@ static void WILC_WFI_RemainOnChannelExpired(void *pUserVoid, u32 u32SessionID)
        }
 }
 
-
-/**
- *  @brief      remain_on_channel
- *  @details    Request the driver to remain awake on the specified
- *                      channel for the specified duration to complete an off-channel
- *                      operation (e.g., public action frame exchange). When the driver is
- *                      ready on the requested channel, it must indicate this with an event
- *                      notification by calling cfg80211_ready_on_channel().
- *  @param[in]
- *  @return     int : Return 0 on Success
- *  @author    mdaftedar
- *  @date      01 MAR 2012
- *  @version   1.0
- */
 static int remain_on_channel(struct wiphy *wiphy,
                             struct wireless_dev *wdev,
                             struct ieee80211_channel *chan,
@@ -2118,8 +1786,10 @@ static int remain_on_channel(struct wiphy *wiphy,
 {
        s32 s32Error = 0;
        struct wilc_priv *priv;
+       struct wilc_vif *vif;
 
        priv = wiphy_priv(wiphy);
+       vif = netdev_priv(priv->dev);
 
        PRINT_D(GENERIC_DBG, "Remaining on channel %d\n", chan->hw_value);
 
@@ -2131,61 +1801,37 @@ static int remain_on_channel(struct wiphy *wiphy,
 
        curr_channel = chan->hw_value;
 
-       /*Setting params needed by WILC_WFI_RemainOnChannelExpired()*/
        priv->strRemainOnChanParams.pstrListenChan = chan;
        priv->strRemainOnChanParams.u64ListenCookie = *cookie;
        priv->strRemainOnChanParams.u32ListenDuration = duration;
        priv->strRemainOnChanParams.u32ListenSessionID++;
 
-       s32Error = host_int_remain_on_channel(priv->hWILCWFIDrv
-                                             , priv->strRemainOnChanParams.u32ListenSessionID
-                                             , duration
-                                             , chan->hw_value
-                                             , WILC_WFI_RemainOnChannelExpired
-                                             , WILC_WFI_RemainOnChannelReady
-                                             , (void *)priv);
+       s32Error = wilc_remain_on_channel(vif,
+                               priv->strRemainOnChanParams.u32ListenSessionID,
+                               duration, chan->hw_value,
+                               WILC_WFI_RemainOnChannelExpired,
+                               WILC_WFI_RemainOnChannelReady, (void *)priv);
 
        return s32Error;
 }
 
-/**
- *  @brief      cancel_remain_on_channel
- *  @details    Cancel an on-going remain-on-channel operation.
- *                      This allows the operation to be terminated prior to timeout based on
- *                      the duration value.
- *  @param[in]   struct wiphy *wiphy,
- *  @param[in]  struct net_device *dev
- *  @param[in]  u64 cookie,
- *  @return     int : Return 0 on Success
- *  @author    mdaftedar
- *  @date      01 MAR 2012
- *  @version   1.0
- */
 static int cancel_remain_on_channel(struct wiphy *wiphy,
                                    struct wireless_dev *wdev,
                                    u64 cookie)
 {
        s32 s32Error = 0;
        struct wilc_priv *priv;
+       struct wilc_vif *vif;
 
        priv = wiphy_priv(wiphy);
+       vif = netdev_priv(priv->dev);
 
        PRINT_D(CFG80211_DBG, "Cancel remain on channel\n");
 
-       s32Error = host_int_ListenStateExpired(priv->hWILCWFIDrv, priv->strRemainOnChanParams.u32ListenSessionID);
+       s32Error = wilc_listen_state_expired(vif, priv->strRemainOnChanParams.u32ListenSessionID);
        return s32Error;
 }
-/**
- *  @brief      WILC_WFI_mgmt_tx_frame
- *  @details
- *
- *  @param[in]
- *  @return     NONE.
- *  @author    mdaftedar
- *  @date      01 JUL 2012
- *  @version
- */
-extern bool bEnablePS;
+
 static int mgmt_tx(struct wiphy *wiphy,
                   struct wireless_dev *wdev,
                   struct cfg80211_mgmt_tx_params *params,
@@ -2200,10 +1846,10 @@ static int mgmt_tx(struct wiphy *wiphy,
        struct wilc_priv *priv;
        struct host_if_drv *pstrWFIDrv;
        u32 i;
-       perInterface_wlan_t *nic;
-       u32 buf_len = len + sizeof(u8P2P_vendorspec) + sizeof(u8P2Plocalrandom);
+       struct wilc_vif *vif;
+       u32 buf_len = len + sizeof(p2p_vendor_spec) + sizeof(p2p_local_random);
 
-       nic = netdev_priv(wdev->netdev);
+       vif = netdev_priv(wdev->netdev);
        priv = wiphy_priv(wiphy);
        pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
 
@@ -2212,15 +1858,13 @@ static int mgmt_tx(struct wiphy *wiphy,
        mgmt = (const struct ieee80211_mgmt *) buf;
 
        if (ieee80211_is_mgmt(mgmt->frame_control)) {
-
-               /*mgmt frame allocation*/
                mgmt_tx = kmalloc(sizeof(struct p2p_mgmt_data), GFP_KERNEL);
-               if (mgmt_tx == NULL) {
+               if (!mgmt_tx) {
                        PRINT_ER("Failed to allocate memory for mgmt_tx structure\n");
                        return -EFAULT;
                }
                mgmt_tx->buff = kmalloc(buf_len, GFP_KERNEL);
-               if (mgmt_tx->buff == NULL) {
+               if (!mgmt_tx->buff) {
                        PRINT_ER("Failed to allocate memory for mgmt_tx buff\n");
                        kfree(mgmt_tx);
                        return -EFAULT;
@@ -2232,23 +1876,18 @@ static int mgmt_tx(struct wiphy *wiphy,
                if (ieee80211_is_probe_resp(mgmt->frame_control)) {
                        PRINT_D(GENERIC_DBG, "TX: Probe Response\n");
                        PRINT_D(GENERIC_DBG, "Setting channel: %d\n", chan->hw_value);
-                       host_int_set_mac_chnl_num(priv->hWILCWFIDrv, chan->hw_value);
-                       /*Save the current channel after we tune to it*/
+                       wilc_set_mac_chnl_num(vif, chan->hw_value);
                        curr_channel = chan->hw_value;
                } else if (ieee80211_is_action(mgmt->frame_control))   {
                        PRINT_D(GENERIC_DBG, "ACTION FRAME:%x\n", (u16)mgmt->frame_control);
 
 
                        if (buf[ACTION_CAT_ID] == PUB_ACTION_ATTR_ID) {
-                               /*Only set the channel, if not a negotiation confirmation frame
-                                * (If Negotiation confirmation frame, force it
-                                * to be transmitted on the same negotiation channel)*/
-
                                if (buf[ACTION_SUBTYPE_ID] != PUBLIC_ACT_VENDORSPEC ||
                                    buf[P2P_PUB_ACTION_SUBTYPE] != GO_NEG_CONF) {
                                        PRINT_D(GENERIC_DBG, "Setting channel: %d\n", chan->hw_value);
-                                       host_int_set_mac_chnl_num(priv->hWILCWFIDrv, chan->hw_value);
-                                       /*Save the current channel after we tune to it*/
+                                       wilc_set_mac_chnl_num(vif,
+                                                             chan->hw_value);
                                        curr_channel = chan->hw_value;
                                }
                                switch (buf[ACTION_SUBTYPE_ID]) {
@@ -2266,48 +1905,37 @@ static int mgmt_tx(struct wiphy *wiphy,
 
                                case PUBLIC_ACT_VENDORSPEC:
                                {
-                                       /*Now we have a public action vendor specific action frame, check if its a p2p public action frame
-                                        * based on the standard its should have the p2p_oui attribute with the following values 50 6f 9A 09*/
-                                       if (!memcmp(u8P2P_oui, &buf[ACTION_SUBTYPE_ID + 1], 4)) {
-                                               /*For the connection of two WILC's connection generate a rand number to determine who will be a GO*/
+                                       if (!memcmp(p2p_oui, &buf[ACTION_SUBTYPE_ID + 1], 4)) {
                                                if ((buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP)) {
-                                                       if (u8P2Plocalrandom == 1 && u8P2Precvrandom < u8P2Plocalrandom) {
-                                                               get_random_bytes(&u8P2Plocalrandom, 1);
-                                                               /*Increment the number to prevent if its 0*/
-                                                               u8P2Plocalrandom++;
+                                                       if (p2p_local_random == 1 && p2p_recv_random < p2p_local_random) {
+                                                               get_random_bytes(&p2p_local_random, 1);
+                                                               p2p_local_random++;
                                                        }
                                                }
 
                                                if ((buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP
                                                      || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)) {
-                                                       if (u8P2Plocalrandom > u8P2Precvrandom) {
-                                                               PRINT_D(GENERIC_DBG, "LOCAL WILL BE GO LocaRand=%02x RecvRand %02x\n", u8P2Plocalrandom, u8P2Precvrandom);
+                                                       if (p2p_local_random > p2p_recv_random) {
+                                                               PRINT_D(GENERIC_DBG, "LOCAL WILL BE GO LocaRand=%02x RecvRand %02x\n", p2p_local_random, p2p_recv_random);
 
-                                                               /*Search for the p2p information information element , after the Public action subtype theres a byte for teh dialog token, skip that*/
                                                                for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < len; i++) {
-                                                                       if (buf[i] == P2PELEM_ATTR_ID && !(memcmp(u8P2P_oui, &buf[i + 2], 4))) {
+                                                                       if (buf[i] == P2PELEM_ATTR_ID && !(memcmp(p2p_oui, &buf[i + 2], 4))) {
                                                                                if (buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)
-                                                                                       WILC_WFI_CfgParseTxAction(&mgmt_tx->buff[i + 6], len - (i + 6), true, nic->iftype);
-
-                                                                               /*If using supplicant go intent, no need at all*/
-                                                                               /*to parse transmitted negotiation frames*/
+                                                                                       WILC_WFI_CfgParseTxAction(&mgmt_tx->buff[i + 6], len - (i + 6), true, vif->iftype);
                                                                                else
-                                                                                       WILC_WFI_CfgParseTxAction(&mgmt_tx->buff[i + 6], len - (i + 6), false, nic->iftype);
+                                                                                       WILC_WFI_CfgParseTxAction(&mgmt_tx->buff[i + 6], len - (i + 6), false, vif->iftype);
                                                                                break;
                                                                        }
                                                                }
 
                                                                if (buf[P2P_PUB_ACTION_SUBTYPE] != P2P_INV_REQ && buf[P2P_PUB_ACTION_SUBTYPE] != P2P_INV_RSP) {
-                                                                       /*
-                                                                        * Adding WILC information element to allow two WILC devices to
-                                                                        * identify each other and connect
-                                                                        */
-                                                                       memcpy(&mgmt_tx->buff[len], u8P2P_vendorspec, sizeof(u8P2P_vendorspec));
-                                                                       mgmt_tx->buff[len + sizeof(u8P2P_vendorspec)] = u8P2Plocalrandom;
+                                                                       memcpy(&mgmt_tx->buff[len], p2p_vendor_spec, sizeof(p2p_vendor_spec));
+                                                                       mgmt_tx->buff[len + sizeof(p2p_vendor_spec)] = p2p_local_random;
                                                                        mgmt_tx->size = buf_len;
                                                                }
-                                                       } else
-                                                               PRINT_D(GENERIC_DBG, "PEER WILL BE GO LocaRand=%02x RecvRand %02x\n", u8P2Plocalrandom, u8P2Precvrandom);
+                                                       } else {
+                                                               PRINT_D(GENERIC_DBG, "PEER WILL BE GO LocaRand=%02x RecvRand %02x\n", p2p_local_random, p2p_recv_random);
+                                                       }
                                                }
 
                                        } else {
@@ -2323,7 +1951,6 @@ static int mgmt_tx(struct wiphy *wiphy,
                                        break;
                                }
                                }
-
                        }
 
                        PRINT_D(GENERIC_DBG, "TX: ACTION FRAME Type:%x : Chan:%d\n", buf[ACTION_SUBTYPE_ID], chan->hw_value);
@@ -2366,28 +1993,16 @@ static int mgmt_tx_cancel_wait(struct wiphy *wiphy,
        return 0;
 }
 
-/**
- *  @brief      wilc_mgmt_frame_register
- *  @details Notify driver that a management frame type was
- *              registered. Note that this callback may not sleep, and cannot run
- *                      concurrently with itself.
- *  @param[in]
- *  @return     NONE.
- *  @author    mdaftedar
- *  @date      01 JUL 2012
- *  @version
- */
 void wilc_mgmt_frame_register(struct wiphy *wiphy, struct wireless_dev *wdev,
                              u16 frame_type, bool reg)
 {
-
        struct wilc_priv *priv;
-       perInterface_wlan_t *nic;
+       struct wilc_vif *vif;
        struct wilc *wl;
 
        priv = wiphy_priv(wiphy);
-       nic = netdev_priv(priv->wdev->netdev);
-       wl = nic->wilc;
+       vif = netdev_priv(priv->wdev->netdev);
+       wl = vif->wilc;
 
        if (!frame_type)
                return;
@@ -2396,15 +2011,15 @@ void wilc_mgmt_frame_register(struct wiphy *wiphy, struct wireless_dev *wdev,
        switch (frame_type) {
        case PROBE_REQ:
        {
-               nic->g_struct_frame_reg[0].frame_type = frame_type;
-               nic->g_struct_frame_reg[0].reg = reg;
+               vif->g_struct_frame_reg[0].frame_type = frame_type;
+               vif->g_struct_frame_reg[0].reg = reg;
        }
        break;
 
        case ACTION:
        {
-               nic->g_struct_frame_reg[1].frame_type = frame_type;
-               nic->g_struct_frame_reg[1].reg = reg;
+               vif->g_struct_frame_reg[1].frame_type = frame_type;
+               vif->g_struct_frame_reg[1].reg = reg;
        }
        break;
 
@@ -2412,54 +2027,27 @@ void wilc_mgmt_frame_register(struct wiphy *wiphy, struct wireless_dev *wdev,
        {
                break;
        }
-
        }
-       /*If mac is closed, then return*/
+
        if (!wl->initialized) {
                PRINT_D(GENERIC_DBG, "Return since mac is closed\n");
                return;
        }
-       host_int_frame_register(priv->hWILCWFIDrv, frame_type, reg);
-
-
+       wilc_frame_register(vif, frame_type, reg);
 }
 
-/**
- *  @brief      set_cqm_rssi_config
- *  @details    Configure connection quality monitor RSSI threshold.
- *  @param[in]   struct wiphy *wiphy:
- *  @param[in] struct net_device *dev:
- *  @param[in]          s32 rssi_thold:
- *  @param[in] u32 rssi_hyst:
- *  @return     int : Return 0 on Success
- *  @author    mdaftedar
- *  @date      01 MAR 2012
- *  @version   1.0
- */
 static int set_cqm_rssi_config(struct wiphy *wiphy, struct net_device *dev,
                               s32 rssi_thold, u32 rssi_hyst)
 {
        PRINT_D(CFG80211_DBG, "Setting CQM RSSi Function\n");
        return 0;
-
 }
-/**
- *  @brief      dump_station
- *  @details    Configure connection quality monitor RSSI threshold.
- *  @param[in]   struct wiphy *wiphy:
- *  @param[in] struct net_device *dev
- *  @param[in]          int idx
- *  @param[in] u8 *mac
- *  @param[in] struct station_info *sinfo
- *  @return     int : Return 0 on Success
- *  @author    mdaftedar
- *  @date      01 MAR 2012
- *  @version   1.0
- */
+
 static int dump_station(struct wiphy *wiphy, struct net_device *dev,
                        int idx, u8 *mac, struct station_info *sinfo)
 {
        struct wilc_priv *priv;
+       struct wilc_vif *vif;
 
        PRINT_D(CFG80211_DBG, "Dumping station information\n");
 
@@ -2467,143 +2055,109 @@ static int dump_station(struct wiphy *wiphy, struct net_device *dev,
                return -ENOENT;
 
        priv = wiphy_priv(wiphy);
+       vif = netdev_priv(priv->dev);
 
        sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
 
-       host_int_get_rssi(priv->hWILCWFIDrv, &(sinfo->signal));
+       wilc_get_rssi(vif, &sinfo->signal);
 
        return 0;
-
 }
 
-
-/**
- *  @brief      set_power_mgmt
- *  @details
- *  @param[in]
- *  @return     int : Return 0 on Success.
- *  @author    mdaftedar
- *  @date      01 JUL 2012
- *  @version   1.0
- */
 static int set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
                          bool enabled, int timeout)
 {
        struct wilc_priv *priv;
+       struct wilc_vif *vif;
 
        PRINT_D(CFG80211_DBG, " Power save Enabled= %d , TimeOut = %d\n", enabled, timeout);
 
-       if (wiphy == NULL)
+       if (!wiphy)
                return -ENOENT;
 
        priv = wiphy_priv(wiphy);
-       if (priv->hWILCWFIDrv == NULL) {
+       vif = netdev_priv(priv->dev);
+       if (!priv->hWILCWFIDrv) {
                PRINT_ER("Driver is NULL\n");
                return -EIO;
        }
 
-       if (bEnablePS)
-               host_int_set_power_mgmt(priv->hWILCWFIDrv, enabled, timeout);
+       if (wilc_enable_ps)
+               wilc_set_power_mgmt(vif, enabled, timeout);
 
 
        return 0;
-
 }
 
-/**
- *  @brief      change_virtual_intf
- *  @details    Change type/configuration of virtual interface,
- *                      keep the struct wireless_dev's iftype updated.
- *  @param[in]   NONE
- *  @return     int : Return 0 on Success.
- *  @author    mdaftedar
- *  @date      01 MAR 2012
- *  @version   1.0
- */
-int wilc1000_wlan_init(struct net_device *dev, perInterface_wlan_t *p_nic);
-
 static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev,
                               enum nl80211_iftype type, u32 *flags, struct vif_params *params)
 {
        struct wilc_priv *priv;
-       perInterface_wlan_t *nic;
+       struct wilc_vif *vif;
        u8 interface_type;
        u16 TID = 0;
        u8 i;
        struct wilc *wl;
 
-       nic = netdev_priv(dev);
+       vif = netdev_priv(dev);
        priv = wiphy_priv(wiphy);
-       wl = nic->wilc;
+       wl = vif->wilc;
 
        PRINT_D(HOSTAPD_DBG, "In Change virtual interface function\n");
        PRINT_D(HOSTAPD_DBG, "Wireless interface name =%s\n", dev->name);
-       u8P2Plocalrandom = 0x01;
-       u8P2Precvrandom = 0x00;
-
-       bWilc_ie = false;
-
-       g_obtainingIP = false;
-       del_timer(&hDuringIpTimer);
+       p2p_local_random = 0x01;
+       p2p_recv_random = 0x00;
+       wilc_ie = false;
+       wilc_optaining_ip = false;
+       del_timer(&wilc_during_ip_timer);
        PRINT_D(GENERIC_DBG, "Changing virtual interface, enable scan\n");
-       /*Set WILC_CHANGING_VIR_IF register to disallow adding futrue keys to CE H/W*/
+
        if (g_ptk_keys_saved && g_gtk_keys_saved) {
-               set_machw_change_vir_if(dev, true);
+               wilc_set_machw_change_vir_if(dev, true);
        }
 
        switch (type) {
        case NL80211_IFTYPE_STATION:
-               connecting = 0;
+               wilc_connecting = 0;
                PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_STATION\n");
 
-               /* send delba over wlan interface */
-
-
                dev->ieee80211_ptr->iftype = type;
                priv->wdev->iftype = type;
-               nic->monitor_flag = 0;
-               nic->iftype = STATION_MODE;
+               vif->monitor_flag = 0;
+               vif->iftype = STATION_MODE;
 
-               /*Remove the enteries of the previously connected clients*/
                memset(priv->assoc_stainfo.au8Sta_AssociatedBss, 0, MAX_NUM_STA * ETH_ALEN);
-               interface_type = nic->iftype;
-               nic->iftype = STATION_MODE;
+               interface_type = vif->iftype;
+               vif->iftype = STATION_MODE;
 
                if (wl->initialized) {
-                       host_int_del_All_Rx_BASession(priv->hWILCWFIDrv,
-                                                     wl->vif[0].bssid, TID);
-                       /* ensure that the message Q is empty */
-                       host_int_wait_msg_queue_idle();
+                       wilc_del_all_rx_ba_session(vif, wl->vif[0]->bssid,
+                                                  TID);
+                       wilc_wait_msg_queue_idle();
 
-                       /*Eliminate host interface blocking state*/
                        up(&wl->cfg_event);
 
                        wilc1000_wlan_deinit(dev);
-                       wilc1000_wlan_init(dev, nic);
-                       g_wilc_initialized = 1;
-                       nic->iftype = interface_type;
+                       wilc1000_wlan_init(dev, vif);
+                       wilc_initialized = 1;
+                       vif->iftype = interface_type;
 
-                       /*Setting interface 1 drv handler and mac address in newly downloaded FW*/
-                       host_int_set_wfi_drv_handler(wl->vif[0].hif_drv);
-                       host_int_set_MacAddress(wl->vif[0].hif_drv,
-                                               wl->vif[0].src_addr);
-                       host_int_set_operation_mode(priv->hWILCWFIDrv, STATION_MODE);
+                       wilc_set_wfi_drv_handler(vif,
+                                                wilc_get_vif_idx(wl->vif[0]));
+                       wilc_set_mac_address(wl->vif[0], wl->vif[0]->src_addr);
+                       wilc_set_operation_mode(vif, STATION_MODE);
 
-                       /*Add saved WEP keys, if any*/
                        if (g_wep_keys_saved) {
-                               host_int_set_wep_default_key(wl->vif[0].hif_drv,
-                                                            g_key_wep_params.key_idx);
-                               host_int_add_wep_key_bss_sta(wl->vif[0].hif_drv,
-                                                            g_key_wep_params.key,
-                                                            g_key_wep_params.key_len,
-                                                            g_key_wep_params.key_idx);
+                               wilc_set_wep_default_keyid(wl->vif[0],
+                                               g_key_wep_params.key_idx);
+                               wilc_add_wep_key_bss_sta(wl->vif[0],
+                                               g_key_wep_params.key,
+                                               g_key_wep_params.key_len,
+                                               g_key_wep_params.key_idx);
                        }
 
-                       /*No matter the driver handler passed here, it will be overwriiten*/
-                       /*in Handle_FlushConnect() with gu8FlushedJoinReqDrvHandler*/
-                       host_int_flush_join_req(priv->hWILCWFIDrv);
+                       wilc_flush_join_req(vif);
 
-                       /*Add saved PTK and GTK keys, if any*/
                        if (g_ptk_keys_saved && g_gtk_keys_saved) {
                                PRINT_D(CFG80211_DBG, "ptk %x %x %x\n", g_key_ptk_params.key[0],
                                        g_key_ptk_params.key[1],
@@ -2611,15 +2165,15 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev,
                                PRINT_D(CFG80211_DBG, "gtk %x %x %x\n", g_key_gtk_params.key[0],
                                        g_key_gtk_params.key[1],
                                        g_key_gtk_params.key[2]);
-                               add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
-                                       wl->vif[0].ndev,
+                               add_key(wl->vif[0]->ndev->ieee80211_ptr->wiphy,
+                                       wl->vif[0]->ndev,
                                        g_add_ptk_key_params.key_idx,
                                        g_add_ptk_key_params.pairwise,
                                        g_add_ptk_key_params.mac_addr,
                                        (struct key_params *)(&g_key_ptk_params));
 
-                               add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
-                                       wl->vif[0].ndev,
+                               add_key(wl->vif[0]->ndev->ieee80211_ptr->wiphy,
+                                       wl->vif[0]->ndev,
                                        g_add_gtk_key_params.key_idx,
                                        g_add_gtk_key_params.pairwise,
                                        g_add_gtk_key_params.mac_addr,
@@ -2628,64 +2182,58 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev,
 
                        if (wl->initialized)    {
                                for (i = 0; i < num_reg_frame; i++) {
-                                       PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
-                                               nic->g_struct_frame_reg[i].reg);
-                                       host_int_frame_register(priv->hWILCWFIDrv,
-                                                               nic->g_struct_frame_reg[i].frame_type,
-                                                               nic->g_struct_frame_reg[i].reg);
+                                       PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", vif->g_struct_frame_reg[i].frame_type,
+                                               vif->g_struct_frame_reg[i].reg);
+                                       wilc_frame_register(vif,
+                                                               vif->g_struct_frame_reg[i].frame_type,
+                                                               vif->g_struct_frame_reg[i].reg);
                                }
                        }
 
-                       bEnablePS = true;
-                       host_int_set_power_mgmt(priv->hWILCWFIDrv, 1, 0);
+                       wilc_enable_ps = true;
+                       wilc_set_power_mgmt(vif, 1, 0);
                }
                break;
 
        case NL80211_IFTYPE_P2P_CLIENT:
-               bEnablePS = false;
-               host_int_set_power_mgmt(priv->hWILCWFIDrv, 0, 0);
-               connecting = 0;
+               wilc_enable_ps = false;
+               wilc_set_power_mgmt(vif, 0, 0);
+               wilc_connecting = 0;
                PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_P2P_CLIENT\n");
 
-               host_int_del_All_Rx_BASession(priv->hWILCWFIDrv,
-                                             wl->vif[0].bssid, TID);
+               wilc_del_all_rx_ba_session(vif, wl->vif[0]->bssid, TID);
 
                dev->ieee80211_ptr->iftype = type;
                priv->wdev->iftype = type;
-               nic->monitor_flag = 0;
+               vif->monitor_flag = 0;
 
                PRINT_D(HOSTAPD_DBG, "Downloading P2P_CONCURRENCY_FIRMWARE\n");
-               nic->iftype = CLIENT_MODE;
+               vif->iftype = CLIENT_MODE;
 
 
                if (wl->initialized)    {
-                       /* ensure that the message Q is empty */
-                       host_int_wait_msg_queue_idle();
+                       wilc_wait_msg_queue_idle();
 
                        wilc1000_wlan_deinit(dev);
-                       wilc1000_wlan_init(dev, nic);
-                       g_wilc_initialized = 1;
+                       wilc1000_wlan_init(dev, vif);
+                       wilc_initialized = 1;
 
-                       host_int_set_wfi_drv_handler(wl->vif[0].hif_drv);
-                       host_int_set_MacAddress(wl->vif[0].hif_drv,
-                                               wl->vif[0].src_addr);
-                       host_int_set_operation_mode(priv->hWILCWFIDrv, STATION_MODE);
+                       wilc_set_wfi_drv_handler(vif,
+                                                wilc_get_vif_idx(wl->vif[0]));
+                       wilc_set_mac_address(wl->vif[0], wl->vif[0]->src_addr);
+                       wilc_set_operation_mode(vif, STATION_MODE);
 
-                       /*Add saved WEP keys, if any*/
                        if (g_wep_keys_saved) {
-                               host_int_set_wep_default_key(wl->vif[0].hif_drv,
-                                                            g_key_wep_params.key_idx);
-                               host_int_add_wep_key_bss_sta(wl->vif[0].hif_drv,
-                                                            g_key_wep_params.key,
-                                                            g_key_wep_params.key_len,
-                                                            g_key_wep_params.key_idx);
+                               wilc_set_wep_default_keyid(wl->vif[0],
+                                               g_key_wep_params.key_idx);
+                               wilc_add_wep_key_bss_sta(wl->vif[0],
+                                               g_key_wep_params.key,
+                                               g_key_wep_params.key_len,
+                                               g_key_wep_params.key_idx);
                        }
 
-                       /*No matter the driver handler passed here, it will be overwriiten*/
-                       /*in Handle_FlushConnect() with gu8FlushedJoinReqDrvHandler*/
-                       host_int_flush_join_req(priv->hWILCWFIDrv);
+                       wilc_flush_join_req(vif);
 
-                       /*Add saved PTK and GTK keys, if any*/
                        if (g_ptk_keys_saved && g_gtk_keys_saved) {
                                PRINT_D(CFG80211_DBG, "ptk %x %x %x\n", g_key_ptk_params.key[0],
                                        g_key_ptk_params.key[1],
@@ -2693,59 +2241,58 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev,
                                PRINT_D(CFG80211_DBG, "gtk %x %x %x\n", g_key_gtk_params.key[0],
                                        g_key_gtk_params.key[1],
                                        g_key_gtk_params.key[2]);
-                               add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
-                                       wl->vif[0].ndev,
+                               add_key(wl->vif[0]->ndev->ieee80211_ptr->wiphy,
+                                       wl->vif[0]->ndev,
                                        g_add_ptk_key_params.key_idx,
                                        g_add_ptk_key_params.pairwise,
                                        g_add_ptk_key_params.mac_addr,
                                        (struct key_params *)(&g_key_ptk_params));
 
-                               add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
-                                       wl->vif[0].ndev,
+                               add_key(wl->vif[0]->ndev->ieee80211_ptr->wiphy,
+                                       wl->vif[0]->ndev,
                                        g_add_gtk_key_params.key_idx,
                                        g_add_gtk_key_params.pairwise,
                                        g_add_gtk_key_params.mac_addr,
                                        (struct key_params *)(&g_key_gtk_params));
                        }
 
-                       /*Refresh scan, to refresh the scan results to the wpa_supplicant. Set MachHw to false to enable further key installments*/
                        refresh_scan(priv, 1, true);
-                       set_machw_change_vir_if(dev, false);
+                       wilc_set_machw_change_vir_if(dev, false);
 
                        if (wl->initialized)    {
                                for (i = 0; i < num_reg_frame; i++) {
-                                       PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
-                                               nic->g_struct_frame_reg[i].reg);
-                                       host_int_frame_register(priv->hWILCWFIDrv,
-                                                               nic->g_struct_frame_reg[i].frame_type,
-                                                               nic->g_struct_frame_reg[i].reg);
+                                       PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", vif->g_struct_frame_reg[i].frame_type,
+                                               vif->g_struct_frame_reg[i].reg);
+                                       wilc_frame_register(vif,
+                                                               vif->g_struct_frame_reg[i].frame_type,
+                                                               vif->g_struct_frame_reg[i].reg);
                                }
                        }
                }
                break;
 
        case NL80211_IFTYPE_AP:
-               bEnablePS = false;
+               wilc_enable_ps = false;
                PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_AP %d\n", type);
                dev->ieee80211_ptr->iftype = type;
                priv->wdev->iftype = type;
-               nic->iftype = AP_MODE;
+               vif->iftype = AP_MODE;
                PRINT_D(CORECONFIG_DBG, "priv->hWILCWFIDrv[%p]\n", priv->hWILCWFIDrv);
 
                PRINT_D(HOSTAPD_DBG, "Downloading AP firmware\n");
-               linux_wlan_get_firmware(dev);
-               /*If wilc is running, then close-open to actually get new firmware running (serves P2P)*/
+               wilc_wlan_get_firmware(dev);
+
                if (wl->initialized)    {
-                       nic->iftype = AP_MODE;
-                       mac_close(dev);
-                       mac_open(dev);
+                       vif->iftype = AP_MODE;
+                       wilc_mac_close(dev);
+                       wilc_mac_open(dev);
 
                        for (i = 0; i < num_reg_frame; i++) {
-                               PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
-                                       nic->g_struct_frame_reg[i].reg);
-                               host_int_frame_register(priv->hWILCWFIDrv,
-                                                       nic->g_struct_frame_reg[i].frame_type,
-                                                       nic->g_struct_frame_reg[i].reg);
+                               PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", vif->g_struct_frame_reg[i].frame_type,
+                                       vif->g_struct_frame_reg[i].reg);
+                               wilc_frame_register(vif,
+                                                       vif->g_struct_frame_reg[i].frame_type,
+                                                       vif->g_struct_frame_reg[i].reg);
                        }
                }
                break;
@@ -2753,16 +2300,12 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev,
        case NL80211_IFTYPE_P2P_GO:
                PRINT_D(GENERIC_DBG, "start duringIP timer\n");
 
-               g_obtainingIP = true;
-               mod_timer(&hDuringIpTimer, jiffies + msecs_to_jiffies(duringIP_TIME));
-               host_int_set_power_mgmt(priv->hWILCWFIDrv, 0, 0);
-               /*Delete block ack has to be the latest config packet*/
-               /*sent before downloading new FW. This is because it blocks on*/
-               /*hWaitResponse semaphore, which allows previous config*/
-               /*packets to actually take action on old FW*/
-               host_int_del_All_Rx_BASession(priv->hWILCWFIDrv,
-                                             wl->vif[0].bssid, TID);
-               bEnablePS = false;
+               wilc_optaining_ip = true;
+               mod_timer(&wilc_during_ip_timer,
+                         jiffies + msecs_to_jiffies(during_ip_time));
+               wilc_set_power_mgmt(vif, 0, 0);
+               wilc_del_all_rx_ba_session(vif, wl->vif[0]->bssid, TID);
+               wilc_enable_ps = false;
                PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_GO\n");
                dev->ieee80211_ptr->iftype = type;
                priv->wdev->iftype = type;
@@ -2772,36 +2315,28 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev,
                PRINT_D(HOSTAPD_DBG, "Downloading P2P_CONCURRENCY_FIRMWARE\n");
 
 
-               nic->iftype = GO_MODE;
+               vif->iftype = GO_MODE;
 
-               /* ensure that the message Q is empty */
-               host_int_wait_msg_queue_idle();
+               wilc_wait_msg_queue_idle();
                wilc1000_wlan_deinit(dev);
-               wilc1000_wlan_init(dev, nic);
-               g_wilc_initialized = 1;
+               wilc1000_wlan_init(dev, vif);
+               wilc_initialized = 1;
 
+               wilc_set_wfi_drv_handler(vif, wilc_get_vif_idx(wl->vif[0]));
+               wilc_set_mac_address(wl->vif[0], wl->vif[0]->src_addr);
+               wilc_set_operation_mode(vif, AP_MODE);
 
-               /*Setting interface 1 drv handler and mac address in newly downloaded FW*/
-               host_int_set_wfi_drv_handler(wl->vif[0].hif_drv);
-               host_int_set_MacAddress(wl->vif[0].hif_drv,
-                                       wl->vif[0].src_addr);
-               host_int_set_operation_mode(priv->hWILCWFIDrv, AP_MODE);
-
-               /*Add saved WEP keys, if any*/
                if (g_wep_keys_saved) {
-                       host_int_set_wep_default_key(wl->vif[0].hif_drv,
-                                                    g_key_wep_params.key_idx);
-                       host_int_add_wep_key_bss_sta(wl->vif[0].hif_drv,
-                                                    g_key_wep_params.key,
-                                                    g_key_wep_params.key_len,
-                                                    g_key_wep_params.key_idx);
+                       wilc_set_wep_default_keyid(wl->vif[0],
+                                                  g_key_wep_params.key_idx);
+                       wilc_add_wep_key_bss_sta(wl->vif[0],
+                                                g_key_wep_params.key,
+                                                g_key_wep_params.key_len,
+                                                g_key_wep_params.key_idx);
                }
 
-               /*No matter the driver handler passed here, it will be overwriiten*/
-               /*in Handle_FlushConnect() with gu8FlushedJoinReqDrvHandler*/
-               host_int_flush_join_req(priv->hWILCWFIDrv);
+               wilc_flush_join_req(vif);
 
-               /*Add saved PTK and GTK keys, if any*/
                if (g_ptk_keys_saved && g_gtk_keys_saved) {
                        PRINT_D(CFG80211_DBG, "ptk %x %x %x cipher %x\n", g_key_ptk_params.key[0],
                                g_key_ptk_params.key[1],
@@ -2811,15 +2346,15 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev,
                                g_key_gtk_params.key[1],
                                g_key_gtk_params.key[2],
                                g_key_gtk_params.cipher);
-                       add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
-                               wl->vif[0].ndev,
+                       add_key(wl->vif[0]->ndev->ieee80211_ptr->wiphy,
+                               wl->vif[0]->ndev,
                                g_add_ptk_key_params.key_idx,
                                g_add_ptk_key_params.pairwise,
                                g_add_ptk_key_params.mac_addr,
                                (struct key_params *)(&g_key_ptk_params));
 
-                       add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
-                               wl->vif[0].ndev,
+                       add_key(wl->vif[0]->ndev->ieee80211_ptr->wiphy,
+                               wl->vif[0]->ndev,
                                g_add_gtk_key_params.key_idx,
                                g_add_gtk_key_params.pairwise,
                                g_add_gtk_key_params.mac_addr,
@@ -2828,11 +2363,11 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev,
 
                if (wl->initialized)    {
                        for (i = 0; i < num_reg_frame; i++) {
-                               PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
-                                       nic->g_struct_frame_reg[i].reg);
-                               host_int_frame_register(priv->hWILCWFIDrv,
-                                                       nic->g_struct_frame_reg[i].frame_type,
-                                                       nic->g_struct_frame_reg[i].reg);
+                               PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", vif->g_struct_frame_reg[i].frame_type,
+                                       vif->g_struct_frame_reg[i].reg);
+                               wilc_frame_register(vif,
+                                                       vif->g_struct_frame_reg[i].frame_type,
+                                                       vif->g_struct_frame_reg[i].reg);
                        }
                }
                break;
@@ -2845,32 +2380,6 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev,
        return 0;
 }
 
-/* (austin.2013-07-23)
- *
- *      To support revised cfg80211_ops
- *
- *              add_beacon --> start_ap
- *              set_beacon --> change_beacon
- *              del_beacon --> stop_ap
- *
- *              beacon_parameters  --> cfg80211_ap_settings
- *                                                              cfg80211_beacon_data
- *
- *      applicable for linux kernel 3.4+
- */
-
-/**
- *  @brief      start_ap
- *  @details    Add a beacon with given parameters, @head, @interval
- *                      and @dtim_period will be valid, @tail is optional.
- *  @param[in]   wiphy
- *  @param[in]   dev   The net device structure
- *  @param[in]   settings      cfg80211_ap_settings parameters for the beacon to be added
- *  @return     int : Return 0 on Success.
- *  @author    austin
- *  @date      23 JUL 2013
- *  @version   1.0
- */
 static int start_ap(struct wiphy *wiphy, struct net_device *dev,
                    struct cfg80211_ap_settings *settings)
 {
@@ -2878,11 +2387,11 @@ static int start_ap(struct wiphy *wiphy, struct net_device *dev,
        struct wilc_priv *priv;
        s32 s32Error = 0;
        struct wilc *wl;
-       perInterface_wlan_t *nic;
+       struct wilc_vif *vif;
 
        priv = wiphy_priv(wiphy);
-       nic = netdev_priv(dev);
-       wl = nic->wilc;
+       vif = netdev_priv(dev);
+       wl = vif ->wilc;
        PRINT_D(HOSTAPD_DBG, "Starting ap\n");
 
        PRINT_D(HOSTAPD_DBG, "Interval = %d\n DTIM period = %d\n Head length = %zu Tail length = %zu\n",
@@ -2893,73 +2402,53 @@ static int start_ap(struct wiphy *wiphy, struct net_device *dev,
        if (s32Error != 0)
                PRINT_ER("Error in setting channel\n");
 
-       linux_wlan_set_bssid(dev, wl->vif[0].src_addr);
+       wilc_wlan_set_bssid(dev, wl->vif[0]->src_addr);
 
-       s32Error = host_int_add_beacon(priv->hWILCWFIDrv,
-                                       settings->beacon_interval,
-                                       settings->dtim_period,
-                                       beacon->head_len, (u8 *)beacon->head,
-                                       beacon->tail_len, (u8 *)beacon->tail);
+       s32Error = wilc_add_beacon(vif, settings->beacon_interval,
+                                  settings->dtim_period, beacon->head_len,
+                                  (u8 *)beacon->head, beacon->tail_len,
+                                  (u8 *)beacon->tail);
 
        return s32Error;
 }
 
-/**
- *  @brief      change_beacon
- *  @details    Add a beacon with given parameters, @head, @interval
- *                      and @dtim_period will be valid, @tail is optional.
- *  @param[in]   wiphy
- *  @param[in]   dev   The net device structure
- *  @param[in]   beacon        cfg80211_beacon_data for the beacon to be changed
- *  @return     int : Return 0 on Success.
- *  @author    austin
- *  @date      23 JUL 2013
- *  @version   1.0
- */
 static int change_beacon(struct wiphy *wiphy, struct net_device *dev,
                         struct cfg80211_beacon_data *beacon)
 {
        struct wilc_priv *priv;
+       struct wilc_vif *vif;
        s32 s32Error = 0;
 
        priv = wiphy_priv(wiphy);
+       vif = netdev_priv(priv->dev);
        PRINT_D(HOSTAPD_DBG, "Setting beacon\n");
 
 
-       s32Error = host_int_add_beacon(priv->hWILCWFIDrv,
-                                       0,
-                                       0,
-                                       beacon->head_len, (u8 *)beacon->head,
-                                       beacon->tail_len, (u8 *)beacon->tail);
+       s32Error = wilc_add_beacon(vif, 0, 0, beacon->head_len,
+                                  (u8 *)beacon->head, beacon->tail_len,
+                                  (u8 *)beacon->tail);
 
        return s32Error;
 }
 
-/**
- *  @brief      stop_ap
- *  @details    Remove beacon configuration and stop sending the beacon.
- *  @param[in]
- *  @return     int : Return 0 on Success.
- *  @author    austin
- *  @date      23 JUL 2013
- *  @version   1.0
- */
 static int stop_ap(struct wiphy *wiphy, struct net_device *dev)
 {
        s32 s32Error = 0;
        struct wilc_priv *priv;
+       struct wilc_vif *vif;
        u8 NullBssid[ETH_ALEN] = {0};
 
        if (!wiphy)
                return -EFAULT;
 
        priv = wiphy_priv(wiphy);
+       vif = netdev_priv(priv->dev);
 
        PRINT_D(HOSTAPD_DBG, "Deleting beacon\n");
 
-       linux_wlan_set_bssid(dev, NullBssid);
+       wilc_wlan_set_bssid(dev, NullBssid);
 
-       s32Error = host_int_del_beacon(priv->hWILCWFIDrv);
+       s32Error = wilc_del_beacon(vif);
 
        if (s32Error)
                PRINT_ER("Host delete beacon fail\n");
@@ -2967,30 +2456,21 @@ static int stop_ap(struct wiphy *wiphy, struct net_device *dev)
        return s32Error;
 }
 
-/**
- *  @brief      add_station
- *  @details    Add a new station.
- *  @param[in]
- *  @return     int : Return 0 on Success.
- *  @author    mdaftedar
- *  @date      01 MAR 2012
- *  @version   1.0
- */
 static int add_station(struct wiphy *wiphy, struct net_device *dev,
                       const u8 *mac, struct station_parameters *params)
 {
        s32 s32Error = 0;
        struct wilc_priv *priv;
        struct add_sta_param strStaParams = { {0} };
-       perInterface_wlan_t *nic;
+       struct wilc_vif *vif;
 
        if (!wiphy)
                return -EFAULT;
 
        priv = wiphy_priv(wiphy);
-       nic = netdev_priv(dev);
+       vif = netdev_priv(dev);
 
-       if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) {
+       if (vif->iftype == AP_MODE || vif->iftype == GO_MODE) {
                memcpy(strStaParams.bssid, mac, ETH_ALEN);
                memcpy(priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid], mac, ETH_ALEN);
                strStaParams.aid = params->aid;
@@ -3005,7 +2485,7 @@ static int add_station(struct wiphy *wiphy, struct net_device *dev,
                PRINT_D(HOSTAPD_DBG, "Number of supported rates = %d\n",
                        strStaParams.rates_len);
 
-               if (params->ht_capa == NULL) {
+               if (!params->ht_capa) {
                        strStaParams.ht_supported = false;
                } else {
                        strStaParams.ht_supported = true;
@@ -3039,7 +2519,7 @@ static int add_station(struct wiphy *wiphy, struct net_device *dev,
                PRINT_D(HOSTAPD_DBG, "Flag Set = %d\n",
                        strStaParams.flags_set);
 
-               s32Error = host_int_add_station(priv->hWILCWFIDrv, &strStaParams);
+               s32Error = wilc_add_station(vif, &strStaParams);
                if (s32Error)
                        PRINT_ER("Host add station fail\n");
        }
@@ -3047,41 +2527,33 @@ static int add_station(struct wiphy *wiphy, struct net_device *dev,
        return s32Error;
 }
 
-/**
- *  @brief      del_station
- *  @details    Remove a station; @mac may be NULL to remove all stations.
- *  @param[in]
- *  @return     int : Return 0 on Success.
- *  @author    mdaftedar
- *  @date      01 MAR 2012
- *  @version   1.0
- */
 static int del_station(struct wiphy *wiphy, struct net_device *dev,
                       struct station_del_parameters *params)
 {
        const u8 *mac = params->mac;
        s32 s32Error = 0;
        struct wilc_priv *priv;
-       perInterface_wlan_t *nic;
+       struct wilc_vif *vif;
 
        if (!wiphy)
                return -EFAULT;
 
        priv = wiphy_priv(wiphy);
-       nic = netdev_priv(dev);
+       vif = netdev_priv(dev);
 
-       if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) {
+       if (vif->iftype == AP_MODE || vif->iftype == GO_MODE) {
                PRINT_D(HOSTAPD_DBG, "Deleting station\n");
 
 
-               if (mac == NULL) {
+               if (!mac) {
                        PRINT_D(HOSTAPD_DBG, "All associated stations\n");
-                       s32Error = host_int_del_allstation(priv->hWILCWFIDrv, priv->assoc_stainfo.au8Sta_AssociatedBss);
+                       s32Error = wilc_del_allstation(vif,
+                                    priv->assoc_stainfo.au8Sta_AssociatedBss);
                } else {
                        PRINT_D(HOSTAPD_DBG, "With mac address: %x%x%x%x%x%x\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
                }
 
-               s32Error = host_int_del_station(priv->hWILCWFIDrv, mac);
+               s32Error = wilc_del_station(vif, mac);
 
                if (s32Error)
                        PRINT_ER("Host delete station fail\n");
@@ -3089,22 +2561,13 @@ static int del_station(struct wiphy *wiphy, struct net_device *dev,
        return s32Error;
 }
 
-/**
- *  @brief      change_station
- *  @details    Modify a given station.
- *  @param[in]
- *  @return     int : Return 0 on Success.
- *  @author    mdaftedar
- *  @date      01 MAR 2012
- *  @version   1.0
- */
 static int change_station(struct wiphy *wiphy, struct net_device *dev,
                          const u8 *mac, struct station_parameters *params)
 {
        s32 s32Error = 0;
        struct wilc_priv *priv;
        struct add_sta_param strStaParams = { {0} };
-       perInterface_wlan_t *nic;
+       struct wilc_vif *vif;
 
 
        PRINT_D(HOSTAPD_DBG, "Change station paramters\n");
@@ -3113,9 +2576,9 @@ static int change_station(struct wiphy *wiphy, struct net_device *dev,
                return -EFAULT;
 
        priv = wiphy_priv(wiphy);
-       nic = netdev_priv(dev);
+       vif = netdev_priv(dev);
 
-       if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) {
+       if (vif->iftype == AP_MODE || vif->iftype == GO_MODE) {
                memcpy(strStaParams.bssid, mac, ETH_ALEN);
                strStaParams.aid = params->aid;
                strStaParams.rates_len = params->supported_rates_len;
@@ -3129,7 +2592,7 @@ static int change_station(struct wiphy *wiphy, struct net_device *dev,
                PRINT_D(HOSTAPD_DBG, "Number of supported rates = %d\n",
                        strStaParams.rates_len);
 
-               if (params->ht_capa == NULL) {
+               if (!params->ht_capa) {
                        strStaParams.ht_supported = false;
                } else {
                        strStaParams.ht_supported = true;
@@ -3163,23 +2626,13 @@ static int change_station(struct wiphy *wiphy, struct net_device *dev,
                PRINT_D(HOSTAPD_DBG, "Flag Set = %d\n",
                        strStaParams.flags_set);
 
-               s32Error = host_int_edit_station(priv->hWILCWFIDrv, &strStaParams);
+               s32Error = wilc_edit_station(vif, &strStaParams);
                if (s32Error)
                        PRINT_ER("Host edit station fail\n");
        }
        return s32Error;
 }
 
-
-/**
- *  @brief      add_virtual_intf
- *  @details
- *  @param[in]
- *  @return     int : Return 0 on Success.
- *  @author    mdaftedar
- *  @date      01 JUL 2012
- *  @version   1.0
- */
 static struct wireless_dev *add_virtual_intf(struct wiphy *wiphy,
                                             const char *name,
                                             unsigned char name_assign_type,
@@ -3187,7 +2640,7 @@ static struct wireless_dev *add_virtual_intf(struct wiphy *wiphy,
                                             u32 *flags,
                                             struct vif_params *params)
 {
-       perInterface_wlan_t *nic;
+       struct wilc_vif *vif;
        struct wilc_priv *priv;
        struct net_device *new_ifc = NULL;
 
@@ -3197,32 +2650,23 @@ static struct wireless_dev *add_virtual_intf(struct wiphy *wiphy,
 
        PRINT_D(HOSTAPD_DBG, "Adding monitor interface[%p]\n", priv->wdev->netdev);
 
-       nic = netdev_priv(priv->wdev->netdev);
+       vif = netdev_priv(priv->wdev->netdev);
 
 
        if (type == NL80211_IFTYPE_MONITOR) {
                PRINT_D(HOSTAPD_DBG, "Monitor interface mode: Initializing mon interface virtual device driver\n");
-               PRINT_D(HOSTAPD_DBG, "Adding monitor interface[%p]\n", nic->wilc_netdev);
-               new_ifc = WILC_WFI_init_mon_interface(name, nic->wilc_netdev);
-               if (new_ifc != NULL) {
+               PRINT_D(HOSTAPD_DBG, "Adding monitor interface[%p]\n", vif->ndev);
+               new_ifc = WILC_WFI_init_mon_interface(name, vif->ndev);
+               if (new_ifc) {
                        PRINT_D(HOSTAPD_DBG, "Setting monitor flag in private structure\n");
-                       nic = netdev_priv(priv->wdev->netdev);
-                       nic->monitor_flag = 1;
+                       vif = netdev_priv(priv->wdev->netdev);
+                       vif->monitor_flag = 1;
                } else
                        PRINT_ER("Error in initializing monitor interface\n ");
        }
        return priv->wdev;
 }
 
-/**
- *  @brief      del_virtual_intf
- *  @details
- *  @param[in]
- *  @return     int : Return 0 on Success.
- *  @author    mdaftedar
- *  @date      01 JUL 2012
- *  @version   1.0
- */
 static int del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
 {
        PRINT_D(HOSTAPD_DBG, "Deleting virtual interface\n");
@@ -3230,7 +2674,6 @@ static int del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
 }
 
 static struct cfg80211_ops wilc_cfg80211_ops = {
-
        .set_monitor_channel = set_channel,
        .scan = scan,
        .connect = connect,
@@ -3267,27 +2710,12 @@ static struct cfg80211_ops wilc_cfg80211_ops = {
 
 };
 
-
-
-
-
-/**
- *  @brief      WILC_WFI_update_stats
- *  @details    Modify parameters for a given BSS.
- *  @param[in]
- *  @return     int : Return 0 on Success.
- *  @author    mdaftedar
- *  @date      01 MAR 2012
- *  @version   1.0
- */
 int WILC_WFI_update_stats(struct wiphy *wiphy, u32 pktlen, u8 changed)
 {
-
        struct wilc_priv *priv;
 
        priv = wiphy_priv(wiphy);
        switch (changed) {
-
        case WILC_WFI_RX_PKT:
        {
                priv->netstats.rx_packets++;
@@ -3311,46 +2739,31 @@ int WILC_WFI_update_stats(struct wiphy *wiphy, u32 pktlen, u8 changed)
        return 0;
 }
 
-/**
- *  @brief      WILC_WFI_CfgAlloc
- *  @details    Allocation of the wireless device structure and assigning it
- *             to the cfg80211 operations structure.
- *  @param[in]   NONE
- *  @return     wireless_dev : Returns pointer to wireless_dev structure.
- *  @author    mdaftedar
- *  @date      01 MAR 2012
- *  @version   1.0
- */
-struct wireless_dev *WILC_WFI_CfgAlloc(void)
+static struct wireless_dev *WILC_WFI_CfgAlloc(void)
 {
-
        struct wireless_dev *wdev;
 
 
        PRINT_D(CFG80211_DBG, "Allocating wireless device\n");
-       /*Allocating the wireless device structure*/
+
        wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
        if (!wdev) {
                PRINT_ER("Cannot allocate wireless device\n");
                goto _fail_;
        }
 
-       /*Creating a new wiphy, linking wireless structure with the wiphy structure*/
        wdev->wiphy = wiphy_new(&wilc_cfg80211_ops, sizeof(struct wilc_priv));
        if (!wdev->wiphy) {
                PRINT_ER("Cannot allocate wiphy\n");
                goto _fail_mem_;
-
        }
 
-       /* enable 802.11n HT */
        WILC_WFI_band_2ghz.ht_cap.ht_supported = 1;
        WILC_WFI_band_2ghz.ht_cap.cap |= (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
        WILC_WFI_band_2ghz.ht_cap.mcs.rx_mask[0] = 0xff;
        WILC_WFI_band_2ghz.ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K;
        WILC_WFI_band_2ghz.ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE;
 
-       /*wiphy bands*/
        wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &WILC_WFI_band_2ghz;
 
        return wdev;
@@ -3359,18 +2772,9 @@ _fail_mem_:
        kfree(wdev);
 _fail_:
        return NULL;
-
 }
-/**
- *  @brief      wilc_create_wiphy
- *  @details    Registering of the wiphy structure and interface modes
- *  @param[in]   NONE
- *  @return     NONE
- *  @author    mdaftedar
- *  @date      01 MAR 2012
- *  @version   1.0
- */
-struct wireless_dev *wilc_create_wiphy(struct net_device *net)
+
+struct wireless_dev *wilc_create_wiphy(struct net_device *net, struct device *dev)
 {
        struct wilc_priv *priv;
        struct wireless_dev *wdev;
@@ -3379,38 +2783,25 @@ struct wireless_dev *wilc_create_wiphy(struct net_device *net)
        PRINT_D(CFG80211_DBG, "Registering wifi device\n");
 
        wdev = WILC_WFI_CfgAlloc();
-       if (wdev == NULL) {
+       if (!wdev) {
                PRINT_ER("CfgAlloc Failed\n");
                return NULL;
        }
 
-
-       /*Return hardware description structure (wiphy)'s priv*/
        priv = wdev_priv(wdev);
        sema_init(&(priv->SemHandleUpdateStats), 1);
-
-       /*Link the wiphy with wireless structure*/
        priv->wdev = wdev;
-
-       /*Maximum number of probed ssid to be added by user for the scan request*/
        wdev->wiphy->max_scan_ssids = MAX_NUM_PROBED_SSID;
-       /*Maximum number of pmkids to be cashed*/
        wdev->wiphy->max_num_pmkids = WILC_MAX_NUM_PMKIDS;
        PRINT_INFO(CFG80211_DBG, "Max number of PMKIDs = %d\n", wdev->wiphy->max_num_pmkids);
 
        wdev->wiphy->max_scan_ie_len = 1000;
-
-       /*signal strength in mBm (100*dBm) */
        wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
-
-       /*Set the availaible cipher suites*/
        wdev->wiphy->cipher_suites = cipher_suites;
        wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
-       /*Setting default managment types: for register action frame:  */
        wdev->wiphy->mgmt_stypes = wilc_wfi_cfg80211_mgmt_types;
 
        wdev->wiphy->max_remain_on_channel_duration = 500;
-       /*Setting the wiphy interfcae mode and type before registering the wiphy*/
        wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_MONITOR) | BIT(NL80211_IFTYPE_P2P_GO) |
                BIT(NL80211_IFTYPE_P2P_CLIENT);
        wdev->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
@@ -3422,36 +2813,21 @@ struct wireless_dev *wilc_create_wiphy(struct net_device *net)
                   wdev->wiphy->max_scan_ssids, wdev->wiphy->max_scan_ie_len, wdev->wiphy->signal_type,
                   wdev->wiphy->interface_modes, wdev->iftype);
 
-       #ifdef WILC_SDIO
-       set_wiphy_dev(wdev->wiphy, &local_sdio_func->dev);
-       #endif
+       set_wiphy_dev(wdev->wiphy, dev);
 
-       /*Register wiphy structure*/
        s32Error = wiphy_register(wdev->wiphy);
        if (s32Error) {
                PRINT_ER("Cannot register wiphy device\n");
-               /*should define what action to be taken in such failure*/
        } else {
                PRINT_D(CFG80211_DBG, "Successful Registering\n");
        }
 
        priv->dev = net;
        return wdev;
-
-
 }
-/**
- *  @brief      WILC_WFI_WiphyFree
- *  @details    Freeing allocation of the wireless device structure
- *  @param[in]   NONE
- *  @return     NONE
- *  @author    mdaftedar
- *  @date      01 MAR 2012
- *  @version   1.0
- */
+
 int wilc_init_host_int(struct net_device *net)
 {
-
        int s32Error = 0;
 
        struct wilc_priv *priv;
@@ -3460,7 +2836,7 @@ int wilc_init_host_int(struct net_device *net)
        priv = wdev_priv(net->ieee80211_ptr);
        if (op_ifcs == 0) {
                setup_timer(&hAgingTimer, remove_network_from_shadow, 0);
-               setup_timer(&hDuringIpTimer, clear_duringIP, 0);
+               setup_timer(&wilc_during_ip_timer, clear_duringIP, 0);
        }
        op_ifcs++;
        if (s32Error < 0) {
@@ -3473,29 +2849,21 @@ int wilc_init_host_int(struct net_device *net)
        priv->bInP2PlistenState = false;
 
        sema_init(&(priv->hSemScanReq), 1);
-       s32Error = host_int_init(net, &priv->hWILCWFIDrv);
+       s32Error = wilc_init(net, &priv->hWILCWFIDrv);
        if (s32Error)
                PRINT_ER("Error while initializing hostinterface\n");
 
        return s32Error;
 }
 
-/**
- *  @brief      WILC_WFI_WiphyFree
- *  @details    Freeing allocation of the wireless device structure
- *  @param[in]   NONE
- *  @return     NONE
- *  @author    mdaftedar
- *  @date      01 MAR 2012
- *  @version   1.0
- */
 int wilc_deinit_host_int(struct net_device *net)
 {
        int s32Error = 0;
-
+       struct wilc_vif *vif;
        struct wilc_priv *priv;
 
        priv = wdev_priv(net->ieee80211_ptr);
+       vif = netdev_priv(priv->dev);
 
        priv->gbAutoRateAdjusted = false;
 
@@ -3503,13 +2871,12 @@ int wilc_deinit_host_int(struct net_device *net)
 
        op_ifcs--;
 
-       s32Error = host_int_deinit(priv->hWILCWFIDrv);
+       s32Error = wilc_deinit(vif);
 
-       /* Clear the Shadow scan */
-       clear_shadow_scan(priv);
+       clear_shadow_scan();
        if (op_ifcs == 0) {
                PRINT_D(CORECONFIG_DBG, "destroy during ip\n");
-               del_timer_sync(&hDuringIpTimer);
+               del_timer_sync(&wilc_during_ip_timer);
        }
 
        if (s32Error)
@@ -3518,16 +2885,6 @@ int wilc_deinit_host_int(struct net_device *net)
        return s32Error;
 }
 
-
-/**
- *  @brief      WILC_WFI_WiphyFree
- *  @details    Freeing allocation of the wireless device structure
- *  @param[in]   NONE
- *  @return     NONE
- *  @author    mdaftedar
- *  @date      01 MAR 2012
- *  @version   1.0
- */
 void wilc_free_wiphy(struct net_device *net)
 {
        PRINT_D(CFG80211_DBG, "Unregistering wiphy\n");
index d7bdca1f4c5ba2c5d9fb3b59ec266368d1c0d9cf..ab53d9d5908113405deceb383a9a0308f278e17e 100644 (file)
 #define NM_WFI_CFGOPERATIONS
 #include "wilc_wfi_netdevice.h"
 
-/* The following macros describe the bitfield map used by the firmware to determine its 11i mode */
-#define NO_ENCRYPT             0
-#define ENCRYPT_ENABLED                BIT(0)
-#define WEP                    BIT(1)
-#define WEP_EXTENDED           BIT(2)
-#define WPA                    BIT(3)
-#define WPA2                   BIT(4)
-#define AES                    BIT(5)
-#define TKIP                   BIT(6)
-
-/*Public action frame index IDs*/
-#define FRAME_TYPE_ID                  0
-#define ACTION_CAT_ID                  24
-#define ACTION_SUBTYPE_ID              25
-#define P2P_PUB_ACTION_SUBTYPE         30
-
-/*Public action frame Attribute IDs*/
-#define ACTION_FRAME                   0xd0
-#define GO_INTENT_ATTR_ID              0x04
-#define CHANLIST_ATTR_ID               0x0b
-#define OPERCHAN_ATTR_ID               0x11
-#define PUB_ACTION_ATTR_ID             0x04
-#define P2PELEM_ATTR_ID                        0xdd
-
-/*Public action subtype values*/
-#define GO_NEG_REQ                     0x00
-#define GO_NEG_RSP                     0x01
-#define GO_NEG_CONF                    0x02
-#define P2P_INV_REQ                    0x03
-#define P2P_INV_RSP                    0x04
-#define PUBLIC_ACT_VENDORSPEC          0x09
-#define GAS_INTIAL_REQ                 0x0a
-#define GAS_INTIAL_RSP                 0x0b
-
-#define INVALID_CHANNEL                        0
-
-#define nl80211_SCAN_RESULT_EXPIRE     (3 * HZ)
-#define SCAN_RESULT_EXPIRE             (40 * HZ)
-
-static const u32 cipher_suites[] = {
-       WLAN_CIPHER_SUITE_WEP40,
-       WLAN_CIPHER_SUITE_WEP104,
-       WLAN_CIPHER_SUITE_TKIP,
-       WLAN_CIPHER_SUITE_CCMP,
-       WLAN_CIPHER_SUITE_AES_CMAC,
-};
-
-static const struct ieee80211_txrx_stypes
-       wilc_wfi_cfg80211_mgmt_types[NUM_NL80211_IFTYPES] = {
-       [NL80211_IFTYPE_STATION] = {
-               .tx = 0xffff,
-               .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
-                       BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
-       },
-       [NL80211_IFTYPE_AP] = {
-               .tx = 0xffff,
-               .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
-                       BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
-                       BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
-                       BIT(IEEE80211_STYPE_DISASSOC >> 4) |
-                       BIT(IEEE80211_STYPE_AUTH >> 4) |
-                       BIT(IEEE80211_STYPE_DEAUTH >> 4) |
-                       BIT(IEEE80211_STYPE_ACTION >> 4)
-       },
-       [NL80211_IFTYPE_P2P_CLIENT] = {
-               .tx = 0xffff,
-               .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
-                       BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
-                       BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
-                       BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
-                       BIT(IEEE80211_STYPE_DISASSOC >> 4) |
-                       BIT(IEEE80211_STYPE_AUTH >> 4) |
-                       BIT(IEEE80211_STYPE_DEAUTH >> 4)
-       }
-};
-
-/* Time to stay on the channel */
-#define WILC_WFI_DWELL_PASSIVE 100
-#define WILC_WFI_DWELL_ACTIVE  40
-
-struct wireless_dev *WILC_WFI_CfgAlloc(void);
-struct wireless_dev *wilc_create_wiphy(struct net_device *net);
+struct wireless_dev *wilc_create_wiphy(struct net_device *net, struct device *dev);
 void wilc_free_wiphy(struct net_device *net);
 int WILC_WFI_update_stats(struct wiphy *wiphy, u32 pktlen, u8 changed);
 int wilc_deinit_host_int(struct net_device *net);
@@ -102,8 +21,4 @@ struct net_device *WILC_WFI_init_mon_interface(const char *name, struct net_devi
 void wilc_mgmt_frame_register(struct wiphy *wiphy, struct wireless_dev *wdev,
                              u16 frame_type, bool reg);
 
-#define TCP_ACK_FILTER_LINK_SPEED_THRESH       54
-#define DEFAULT_LINK_SPEED                     72
-void enable_tcp_ack_filter(bool value);
-
 #endif
index 54ed72336775004feed1c7d5bbf53937b927a31c..98ac8ed04a06cf43c844b48f0cd2fe9e9f8d7e81 100644 (file)
@@ -149,6 +149,13 @@ typedef struct {
 } struct_frame_reg;
 
 struct wilc_vif {
+       u8 u8IfIdx;
+       u8 iftype;
+       int monitor_flag;
+       int mac_opened;
+       struct_frame_reg g_struct_frame_reg[num_reg_frame];
+       struct net_device_stats netstats;
+       struct wilc *wilc;
        u8 src_addr[ETH_ALEN];
        u8 bssid[ETH_ALEN];
        struct host_if_drv *hif_drv;
@@ -156,14 +163,15 @@ struct wilc_vif {
 };
 
 struct wilc {
+       const struct wilc_hif_func *hif_func;
+       int io_type;
        int mac_status;
+       int gpio;
        bool initialized;
-       #if (!defined WILC_SDIO) || (defined WILC_SDIO_IRQ_GPIO)
-       unsigned short dev_irq_num;
-       #endif
+       int dev_irq_num;
        int close;
        u8 vif_num;
-       struct wilc_vif vif[NUM_CONCURRENT_IFC];
+       struct wilc_vif *vif[NUM_CONCURRENT_IFC];
        u8 open_ifcs;
 
        struct semaphore txq_add_to_head_cs;
@@ -180,44 +188,54 @@ struct wilc {
 
        struct task_struct *txq_thread;
 
+       int quit;
+       int cfg_frame_in_use;
+       struct wilc_cfg_frame cfg_frame;
+       u32 cfg_frame_offset;
+       int cfg_seq_no;
+
+       u8 *rx_buffer;
+       u32 rx_buffer_offset;
+       u8 *tx_buffer;
+
+       unsigned long txq_spinlock_flags;
+
+       struct txq_entry_t *txq_head;
+       struct txq_entry_t *txq_tail;
+       int txq_entries;
+       int txq_exit;
+
+       struct rxq_entry_t *rxq_head;
+       struct rxq_entry_t *rxq_tail;
+       int rxq_entries;
+       int rxq_exit;
+
        unsigned char eth_src_address[NUM_CONCURRENT_IFC][6];
 
        const struct firmware *firmware;
 
-#ifdef WILC_SDIO
-       struct sdio_func *wilc_sdio_func;
-#else
-       struct spi_device *wilc_spidev;
-#endif
+       struct device *dev;
 };
 
-typedef struct {
-       u8 u8IfIdx;
-       u8 iftype;
-       int monitor_flag;
-       int mac_opened;
-       struct_frame_reg g_struct_frame_reg[num_reg_frame];
-       struct net_device *wilc_netdev;
-       struct net_device_stats netstats;
-       struct wilc *wilc;
-} perInterface_wlan_t;
-
 struct WILC_WFI_mon_priv {
        struct net_device *real_ndev;
 };
 
-extern struct wilc *g_linux_wlan;
-extern struct net_device *WILC_WFI_devs[];
-void frmw_to_linux(struct wilc *wilc, u8 *buff, u32 size, u32 pkt_offset);
-void linux_wlan_mac_indicate(struct wilc *wilc, int flag);
-void linux_wlan_rx_complete(void);
-void linux_wlan_dbg(u8 *buff);
-int linux_wlan_lock_timeout(void *vp, u32 timeout);
-void wl_wlan_cleanup(struct wilc *wilc);
-int wilc_netdev_init(struct wilc **wilc);
+int wilc1000_wlan_init(struct net_device *dev, struct wilc_vif *vif);
+
+void wilc_frmw_to_linux(struct wilc *wilc, u8 *buff, u32 size, u32 pkt_offset);
+void wilc_mac_indicate(struct wilc *wilc, int flag);
+void wilc_rx_complete(struct wilc *wilc);
+void wilc_dbg(u8 *buff);
+
+int wilc_lock_timeout(struct wilc *wilc, void *, u32 timeout);
+void wilc_netdev_cleanup(struct wilc *wilc);
+int wilc_netdev_init(struct wilc **wilc, struct device *, int io_type, int gpio,
+                    const struct wilc_hif_func *ops);
 void wilc1000_wlan_deinit(struct net_device *dev);
 void WILC_WFI_mgmt_rx(struct wilc *wilc, u8 *buff, u32 size);
-u16 set_machw_change_vir_if(struct net_device *dev, bool value);
-int linux_wlan_get_firmware(struct net_device *dev);
-int linux_wlan_set_bssid(struct net_device *wilc_netdev, u8 *bssid);
+u16 wilc_set_machw_change_vir_if(struct net_device *dev, bool value);
+int wilc_wlan_get_firmware(struct net_device *dev);
+int wilc_wlan_set_bssid(struct net_device *wilc_netdev, u8 *bssid);
+
 #endif
index 9d257b06c85374111900873e5baf41da79a1a128..83af51bb83e8bd775408b060ee20dd9a0bf4b7a5 100644 (file)
@@ -1,49 +1,15 @@
 #include "wilc_wlan_if.h"
+#include "wilc_wlan.h"
 #include "wilc_wfi_netdevice.h"
 #include "wilc_wlan_cfg.h"
 
-#ifdef WILC_SDIO
-extern struct wilc_hif_func hif_sdio;
-#else
-extern struct wilc_hif_func hif_spi;
+#ifdef WILC_OPTIMIZE_SLEEP_INT
+static inline void chip_allow_sleep(struct wilc *wilc);
 #endif
-u32 wilc_get_chipid(u8 update);
-
-typedef struct {
-       int quit;
-       wilc_wlan_io_func_t io_func;
-       struct wilc_hif_func hif_func;
-       int cfg_frame_in_use;
-       struct wilc_cfg_frame cfg_frame;
-       u32 cfg_frame_offset;
-       int cfg_seq_no;
-
-       #ifdef MEMORY_STATIC
-       u8 *rx_buffer;
-       u32 rx_buffer_offset;
-       #endif
-       u8 *tx_buffer;
-       u32 tx_buffer_offset;
-
-       unsigned long txq_spinlock_flags;
-
-       struct txq_entry_t *txq_head;
-       struct txq_entry_t *txq_tail;
-       int txq_entries;
-       int txq_exit;
-
-       struct rxq_entry_t *rxq_head;
-       struct rxq_entry_t *rxq_tail;
-       int rxq_entries;
-       int rxq_exit;
-} wilc_wlan_dev_t;
-
-static wilc_wlan_dev_t g_wlan;
-
-static inline void chip_allow_sleep(void);
-static inline void chip_wakeup(void);
+static inline void chip_wakeup(struct wilc *wilc);
 static u32 dbgflag = N_INIT | N_ERR | N_INTR | N_TXQ | N_RXQ;
 
+/* FIXME: replace with dev_debug() */
 static void wilc_debug(u32 flag, char *fmt, ...)
 {
        char buf[256];
@@ -54,72 +20,72 @@ static void wilc_debug(u32 flag, char *fmt, ...)
                vsprintf(buf, fmt, args);
                va_end(args);
 
-               linux_wlan_dbg(buf);
+               wilc_dbg(buf);
        }
 }
 
 static CHIP_PS_STATE_T chip_ps_state = CHIP_WAKEDUP;
 
-static inline void acquire_bus(BUS_ACQUIRE_T acquire)
+static inline void acquire_bus(struct wilc *wilc, BUS_ACQUIRE_T acquire)
 {
-       mutex_lock(&g_linux_wlan->hif_cs);
+       mutex_lock(&wilc->hif_cs);
        #ifndef WILC_OPTIMIZE_SLEEP_INT
        if (chip_ps_state != CHIP_WAKEDUP)
        #endif
        {
                if (acquire == ACQUIRE_AND_WAKEUP)
-                       chip_wakeup();
+                       chip_wakeup(wilc);
        }
 }
 
-static inline void release_bus(BUS_RELEASE_T release)
+static inline void release_bus(struct wilc *wilc, BUS_RELEASE_T release)
 {
        #ifdef WILC_OPTIMIZE_SLEEP_INT
        if (release == RELEASE_ALLOW_SLEEP)
-               chip_allow_sleep();
+               chip_allow_sleep(wilc);
        #endif
-       mutex_unlock(&g_linux_wlan->hif_cs);
+       mutex_unlock(&wilc->hif_cs);
 }
 
+#ifdef TCP_ACK_FILTER
 static void wilc_wlan_txq_remove(struct txq_entry_t *tqe)
 {
-       wilc_wlan_dev_t *p = &g_wlan;
-
-       if (tqe == p->txq_head) {
-               p->txq_head = tqe->next;
-               if (p->txq_head)
-                       p->txq_head->prev = NULL;
-       } else if (tqe == p->txq_tail)      {
-               p->txq_tail = (tqe->prev);
-               if (p->txq_tail)
-                       p->txq_tail->next = NULL;
+
+       if (tqe == wilc->txq_head) {
+               wilc->txq_head = tqe->next;
+               if (wilc->txq_head)
+                       wilc->txq_head->prev = NULL;
+       } else if (tqe == wilc->txq_tail) {
+               wilc->txq_tail = (tqe->prev);
+               if (wilc->txq_tail)
+                       wilc->txq_tail->next = NULL;
        } else {
                tqe->prev->next = tqe->next;
                tqe->next->prev = tqe->prev;
        }
-       p->txq_entries -= 1;
+       wilc->txq_entries -= 1;
 }
+#endif
 
 static struct txq_entry_t *
 wilc_wlan_txq_remove_from_head(struct net_device *dev)
 {
        struct txq_entry_t *tqe;
-       wilc_wlan_dev_t *p = &g_wlan;
        unsigned long flags;
-       perInterface_wlan_t *nic;
+       struct wilc_vif *vif;
        struct wilc *wilc;
 
-       nic = netdev_priv(dev);
-       wilc = nic->wilc;
+       vif = netdev_priv(dev);
+       wilc = vif->wilc;
 
        spin_lock_irqsave(&wilc->txq_spinlock, flags);
-       if (p->txq_head) {
-               tqe = p->txq_head;
-               p->txq_head = tqe->next;
-               if (p->txq_head)
-                       p->txq_head->prev = NULL;
+       if (wilc->txq_head) {
+               tqe = wilc->txq_head;
+               wilc->txq_head = tqe->next;
+               if (wilc->txq_head)
+                       wilc->txq_head->prev = NULL;
 
-               p->txq_entries -= 1;
+               wilc->txq_entries -= 1;
        } else {
                tqe = NULL;
        }
@@ -130,29 +96,28 @@ wilc_wlan_txq_remove_from_head(struct net_device *dev)
 static void wilc_wlan_txq_add_to_tail(struct net_device *dev,
                                      struct txq_entry_t *tqe)
 {
-       wilc_wlan_dev_t *p = &g_wlan;
        unsigned long flags;
-       perInterface_wlan_t *nic;
+       struct wilc_vif *vif;
        struct wilc *wilc;
 
-       nic = netdev_priv(dev);
-       wilc = nic->wilc;
+       vif = netdev_priv(dev);
+       wilc = vif->wilc;
 
        spin_lock_irqsave(&wilc->txq_spinlock, flags);
 
-       if (!p->txq_head) {
+       if (!wilc->txq_head) {
                tqe->next = NULL;
                tqe->prev = NULL;
-               p->txq_head = tqe;
-               p->txq_tail = tqe;
+               wilc->txq_head = tqe;
+               wilc->txq_tail = tqe;
        } else {
                tqe->next = NULL;
-               tqe->prev = p->txq_tail;
-               p->txq_tail->next = tqe;
-               p->txq_tail = tqe;
+               tqe->prev = wilc->txq_tail;
+               wilc->txq_tail->next = tqe;
+               wilc->txq_tail = tqe;
        }
-       p->txq_entries += 1;
-       PRINT_D(TX_DBG, "Number of entries in TxQ = %d\n", p->txq_entries);
+       wilc->txq_entries += 1;
+       PRINT_D(TX_DBG, "Number of entries in TxQ = %d\n", wilc->txq_entries);
 
        spin_unlock_irqrestore(&wilc->txq_spinlock, flags);
 
@@ -161,40 +126,37 @@ static void wilc_wlan_txq_add_to_tail(struct net_device *dev,
        up(&wilc->txq_event);
 }
 
-static int wilc_wlan_txq_add_to_head(struct txq_entry_t *tqe)
+static int wilc_wlan_txq_add_to_head(struct wilc *wilc, struct txq_entry_t *tqe)
 {
-       wilc_wlan_dev_t *p = &g_wlan;
        unsigned long flags;
-       if (linux_wlan_lock_timeout(&g_linux_wlan->txq_add_to_head_cs,
+       if (wilc_lock_timeout(wilc, &wilc->txq_add_to_head_cs,
                                    CFG_PKTS_TIMEOUT))
                return -1;
 
-       spin_lock_irqsave(&g_linux_wlan->txq_spinlock, flags);
+       spin_lock_irqsave(&wilc->txq_spinlock, flags);
 
-       if (!p->txq_head) {
+       if (!wilc->txq_head) {
                tqe->next = NULL;
                tqe->prev = NULL;
-               p->txq_head = tqe;
-               p->txq_tail = tqe;
+               wilc->txq_head = tqe;
+               wilc->txq_tail = tqe;
        } else {
-               tqe->next = p->txq_head;
+               tqe->next = wilc->txq_head;
                tqe->prev = NULL;
-               p->txq_head->prev = tqe;
-               p->txq_head = tqe;
+               wilc->txq_head->prev = tqe;
+               wilc->txq_head = tqe;
        }
-       p->txq_entries += 1;
-       PRINT_D(TX_DBG, "Number of entries in TxQ = %d\n", p->txq_entries);
+       wilc->txq_entries += 1;
+       PRINT_D(TX_DBG, "Number of entries in TxQ = %d\n", wilc->txq_entries);
 
-       spin_unlock_irqrestore(&g_linux_wlan->txq_spinlock, flags);
-       up(&g_linux_wlan->txq_add_to_head_cs);
-       up(&g_linux_wlan->txq_event);
+       spin_unlock_irqrestore(&wilc->txq_spinlock, flags);
+       up(&wilc->txq_add_to_head_cs);
+       up(&wilc->txq_event);
        PRINT_D(TX_DBG, "Wake up the txq_handler\n");
 
        return 0;
 }
 
-u32 total_acks = 0, dropped_acks = 0;
-
 #ifdef TCP_ACK_FILTER
 struct ack_session_info;
 struct ack_session_info {
@@ -211,16 +173,17 @@ struct pending_acks_info {
        struct txq_entry_t  *txqe;
 };
 
+
 #define NOT_TCP_ACK                    (-1)
 
 #define MAX_TCP_SESSION                25
 #define MAX_PENDING_ACKS               256
-struct ack_session_info ack_session_info[2 * MAX_TCP_SESSION];
-struct pending_acks_info pending_acks_info[MAX_PENDING_ACKS];
+static struct ack_session_info ack_session_info[2 * MAX_TCP_SESSION];
+static struct pending_acks_info pending_acks_info[MAX_PENDING_ACKS];
 
-u32 pending_base;
-u32 tcp_session;
-u32 pending_acks;
+static u32 pending_base;
+static u32 tcp_session;
+static u32 pending_acks;
 
 static inline int init_tcp_tracking(void)
 {
@@ -249,24 +212,22 @@ static inline int update_tcp_session(u32 index, u32 ack)
 static inline int add_tcp_pending_ack(u32 ack, u32 session_index,
                                      struct txq_entry_t *txqe)
 {
-       total_acks++;
        if (pending_acks < MAX_PENDING_ACKS) {
                pending_acks_info[pending_base + pending_acks].ack_num = ack;
                pending_acks_info[pending_base + pending_acks].txqe = txqe;
                pending_acks_info[pending_base + pending_acks].session_index = session_index;
-               txqe->index = pending_base + pending_acks;
+               txqe->tcp_pending_ack_idx = pending_base + pending_acks;
                pending_acks++;
        }
        return 0;
 }
-static inline int remove_TCP_related(void)
+static inline int remove_TCP_related(struct wilc *wilc)
 {
-       wilc_wlan_dev_t *p = &g_wlan;
        unsigned long flags;
 
-       spin_lock_irqsave(&g_linux_wlan->txq_spinlock, flags);
+       spin_lock_irqsave(&wilc->txq_spinlock, flags);
 
-       spin_unlock_irqrestore(&g_linux_wlan->txq_spinlock, flags);
+       spin_unlock_irqrestore(&wilc->txq_spinlock, flags);
        return 0;
 }
 
@@ -277,15 +238,13 @@ static inline int tcp_process(struct net_device *dev, struct txq_entry_t *tqe)
        u8 *buffer = tqe->buffer;
        unsigned short h_proto;
        int i;
-       wilc_wlan_dev_t *p = &g_wlan;
        unsigned long flags;
-       perInterface_wlan_t *nic;
+       struct wilc_vif *vif;
        struct wilc *wilc;
 
-       nic = netdev_priv(dev);
-       wilc = nic->wilc;
+       vif = netdev_priv(dev);
+       wilc = vif->wilc;
 
-       spin_lock_irqsave(&wilc->txq_spinlock, flags);
 
        eth_hdr_ptr = &buffer[0];
        h_proto = ntohs(*((unsigned short *)&eth_hdr_ptr[12]));
@@ -342,16 +301,15 @@ static inline int tcp_process(struct net_device *dev, struct txq_entry_t *tqe)
 
 static int wilc_wlan_txq_filter_dup_tcp_ack(struct net_device *dev)
 {
-       perInterface_wlan_t *nic;
+       struct wilc_vif *vif;
        struct wilc *wilc;
        u32 i = 0;
        u32 dropped = 0;
-       wilc_wlan_dev_t *p = &g_wlan;
 
-       nic = netdev_priv(dev);
-       wilc = nic->wilc;
+       vif = netdev_priv(dev);
+       wilc = vif->wilc;
 
-       spin_lock_irqsave(&wilc->txq_spinlock, p->txq_spinlock_flags);
+       spin_lock_irqsave(&wilc->txq_spinlock, wilc->txq_spinlock_flags);
        for (i = pending_base; i < (pending_base + pending_acks); i++) {
                if (pending_acks_info[i].ack_num < ack_session_info[pending_acks_info[i].session_index].bigger_ack_num) {
                        struct txq_entry_t *tqe;
@@ -361,7 +319,6 @@ static int wilc_wlan_txq_filter_dup_tcp_ack(struct net_device *dev)
                        tqe = pending_acks_info[i].txqe;
                        if (tqe) {
                                wilc_wlan_txq_remove(tqe);
-                               dropped_acks++;
                                tqe->status = 1;
                                if (tqe->tx_complete_func)
                                        tqe->tx_complete_func(tqe->priv,
@@ -379,10 +336,10 @@ static int wilc_wlan_txq_filter_dup_tcp_ack(struct net_device *dev)
        else
                pending_base = 0;
 
-       spin_unlock_irqrestore(&wilc->txq_spinlock, p->txq_spinlock_flags);
+       spin_unlock_irqrestore(&wilc->txq_spinlock, wilc->txq_spinlock_flags);
 
        while (dropped > 0) {
-               linux_wlan_lock_timeout(&wilc->txq_event, 1);
+               wilc_lock_timeout(wilc, &wilc->txq_event, 1);
                dropped--;
        }
 
@@ -390,27 +347,28 @@ static int wilc_wlan_txq_filter_dup_tcp_ack(struct net_device *dev)
 }
 #endif
 
-bool enabled = false;
+static bool enabled = false;
 
-void enable_tcp_ack_filter(bool value)
+void wilc_enable_tcp_ack_filter(bool value)
 {
        enabled = value;
 }
 
-bool is_tcp_ack_filter_enabled(void)
+#ifdef TCP_ACK_FILTER
+static bool is_tcp_ack_filter_enabled(void)
 {
        return enabled;
 }
+#endif
 
-static int wilc_wlan_txq_add_cfg_pkt(u8 *buffer, u32 buffer_size)
+static int wilc_wlan_txq_add_cfg_pkt(struct wilc *wilc, u8 *buffer, u32 buffer_size)
 {
-       wilc_wlan_dev_t *p = &g_wlan;
        struct txq_entry_t *tqe;
 
        PRINT_D(TX_DBG, "Adding config packet ...\n");
-       if (p->quit) {
+       if (wilc->quit) {
                PRINT_D(TX_DBG, "Return due to clear function\n");
-               up(&g_linux_wlan->cfg_event);
+               up(&wilc->cfg_event);
                return 0;
        }
 
@@ -426,11 +384,11 @@ static int wilc_wlan_txq_add_cfg_pkt(u8 *buffer, u32 buffer_size)
        tqe->tx_complete_func = NULL;
        tqe->priv = NULL;
 #ifdef TCP_ACK_FILTER
-       tqe->index = NOT_TCP_ACK;
+       tqe->tcp_pending_ack_idx = NOT_TCP_ACK;
 #endif
        PRINT_D(TX_DBG, "Adding the config packet at the Queue tail\n");
 
-       if (wilc_wlan_txq_add_to_head(tqe))
+       if (wilc_wlan_txq_add_to_head(wilc, tqe))
                return 0;
        return 1;
 }
@@ -438,10 +396,13 @@ static int wilc_wlan_txq_add_cfg_pkt(u8 *buffer, u32 buffer_size)
 int wilc_wlan_txq_add_net_pkt(struct net_device *dev, void *priv, u8 *buffer,
                              u32 buffer_size, wilc_tx_complete_func_t func)
 {
-       wilc_wlan_dev_t *p = &g_wlan;
        struct txq_entry_t *tqe;
+       struct wilc_vif *vif = netdev_priv(dev);
+       struct wilc *wilc;
+
+       wilc = vif->wilc;
 
-       if (p->quit)
+       if (wilc->quit)
                return 0;
 
        tqe = kmalloc(sizeof(*tqe), GFP_ATOMIC);
@@ -456,21 +417,24 @@ int wilc_wlan_txq_add_net_pkt(struct net_device *dev, void *priv, u8 *buffer,
 
        PRINT_D(TX_DBG, "Adding mgmt packet at the Queue tail\n");
 #ifdef TCP_ACK_FILTER
-       tqe->index = NOT_TCP_ACK;
+       tqe->tcp_pending_ack_idx = NOT_TCP_ACK;
        if (is_tcp_ack_filter_enabled())
                tcp_process(dev, tqe);
 #endif
        wilc_wlan_txq_add_to_tail(dev, tqe);
-       return p->txq_entries;
+       return wilc->txq_entries;
 }
 
 int wilc_wlan_txq_add_mgmt_pkt(struct net_device *dev, void *priv, u8 *buffer,
                               u32 buffer_size, wilc_tx_complete_func_t func)
 {
-       wilc_wlan_dev_t *p = &g_wlan;
        struct txq_entry_t *tqe;
+       struct wilc_vif *vif = netdev_priv(dev);
+       struct wilc *wilc;
+
+       wilc = vif->wilc;
 
-       if (p->quit)
+       if (wilc->quit)
                return 0;
 
        tqe = kmalloc(sizeof(*tqe), GFP_KERNEL);
@@ -483,7 +447,7 @@ int wilc_wlan_txq_add_mgmt_pkt(struct net_device *dev, void *priv, u8 *buffer,
        tqe->tx_complete_func = func;
        tqe->priv = priv;
 #ifdef TCP_ACK_FILTER
-       tqe->index = NOT_TCP_ACK;
+       tqe->tcp_pending_ack_idx = NOT_TCP_ACK;
 #endif
        PRINT_D(TX_DBG, "Adding Network packet at the Queue tail\n");
        wilc_wlan_txq_add_to_tail(dev, tqe);
@@ -492,13 +456,12 @@ int wilc_wlan_txq_add_mgmt_pkt(struct net_device *dev, void *priv, u8 *buffer,
 
 static struct txq_entry_t *wilc_wlan_txq_get_first(struct wilc *wilc)
 {
-       wilc_wlan_dev_t *p = &g_wlan;
        struct txq_entry_t *tqe;
        unsigned long flags;
 
        spin_lock_irqsave(&wilc->txq_spinlock, flags);
 
-       tqe = p->txq_head;
+       tqe = wilc->txq_head;
 
        spin_unlock_irqrestore(&wilc->txq_spinlock, flags);
 
@@ -520,41 +483,39 @@ static struct txq_entry_t *wilc_wlan_txq_get_next(struct wilc *wilc,
 
 static int wilc_wlan_rxq_add(struct wilc *wilc, struct rxq_entry_t *rqe)
 {
-       wilc_wlan_dev_t *p = &g_wlan;
 
-       if (p->quit)
+       if (wilc->quit)
                return 0;
 
        mutex_lock(&wilc->rxq_cs);
-       if (!p->rxq_head) {
+       if (!wilc->rxq_head) {
                PRINT_D(RX_DBG, "Add to Queue head\n");
                rqe->next = NULL;
-               p->rxq_head = rqe;
-               p->rxq_tail = rqe;
+               wilc->rxq_head = rqe;
+               wilc->rxq_tail = rqe;
        } else {
                PRINT_D(RX_DBG, "Add to Queue tail\n");
-               p->rxq_tail->next = rqe;
+               wilc->rxq_tail->next = rqe;
                rqe->next = NULL;
-               p->rxq_tail = rqe;
+               wilc->rxq_tail = rqe;
        }
-       p->rxq_entries += 1;
-       PRINT_D(RX_DBG, "Number of queue entries: %d\n", p->rxq_entries);
+       wilc->rxq_entries += 1;
+       PRINT_D(RX_DBG, "Number of queue entries: %d\n", wilc->rxq_entries);
        mutex_unlock(&wilc->rxq_cs);
-       return p->rxq_entries;
+       return wilc->rxq_entries;
 }
 
 static struct rxq_entry_t *wilc_wlan_rxq_remove(struct wilc *wilc)
 {
-       wilc_wlan_dev_t *p = &g_wlan;
 
        PRINT_D(RX_DBG, "Getting rxQ element\n");
-       if (p->rxq_head) {
+       if (wilc->rxq_head) {
                struct rxq_entry_t *rqe;
 
                mutex_lock(&wilc->rxq_cs);
-               rqe = p->rxq_head;
-               p->rxq_head = p->rxq_head->next;
-               p->rxq_entries -= 1;
+               rqe = wilc->rxq_head;
+               wilc->rxq_head = wilc->rxq_head->next;
+               wilc->rxq_entries -= 1;
                PRINT_D(RX_DBG, "RXQ entries decreased\n");
                mutex_unlock(&wilc->rxq_cs);
                return rqe;
@@ -565,144 +526,149 @@ static struct rxq_entry_t *wilc_wlan_rxq_remove(struct wilc *wilc)
 
 #ifdef WILC_OPTIMIZE_SLEEP_INT
 
-static inline void chip_allow_sleep(void)
+static inline void chip_allow_sleep(struct wilc *wilc)
 {
        u32 reg = 0;
 
-       g_wlan.hif_func.hif_read_reg(0xf0, &reg);
+       wilc->hif_func->hif_read_reg(wilc, 0xf0, &reg);
 
-       g_wlan.hif_func.hif_write_reg(0xf0, reg & ~BIT(0));
+       wilc->hif_func->hif_write_reg(wilc, 0xf0, reg & ~BIT(0));
 }
 
-static inline void chip_wakeup(void)
+static inline void chip_wakeup(struct wilc *wilc)
 {
        u32 reg, clk_status_reg, trials = 0;
        u32 sleep_time;
 
-       if ((g_wlan.io_func.io_type & 0x1) == HIF_SPI) {
+       if ((wilc->io_type & 0x1) == HIF_SPI) {
                do {
-                       g_wlan.hif_func.hif_read_reg(1, &reg);
-                       g_wlan.hif_func.hif_write_reg(1, reg | BIT(1));
-                       g_wlan.hif_func.hif_write_reg(1, reg & ~BIT(1));
+                       wilc->hif_func->hif_read_reg(wilc, 1, &reg);
+                       wilc->hif_func->hif_write_reg(wilc, 1, reg | BIT(1));
+                       wilc->hif_func->hif_write_reg(wilc, 1, reg & ~BIT(1));
 
                        do {
                                usleep_range(2 * 1000, 2 * 1000);
-                               if ((wilc_get_chipid(true) == 0))
+                               if ((wilc_get_chipid(wilc, true) == 0))
                                        wilc_debug(N_ERR, "Couldn't read chip id. Wake up failed\n");
 
-                       } while ((wilc_get_chipid(true) == 0) && ((++trials % 3) == 0));
+                       } while ((wilc_get_chipid(wilc, true) == 0) && ((++trials % 3) == 0));
 
-               } while (wilc_get_chipid(true) == 0);
-       } else if ((g_wlan.io_func.io_type & 0x1) == HIF_SDIO)   {
-               g_wlan.hif_func.hif_read_reg(0xf0, &reg);
+               } while (wilc_get_chipid(wilc, true) == 0);
+       } else if ((wilc->io_type & 0x1) == HIF_SDIO)    {
+               wilc->hif_func->hif_read_reg(wilc, 0xf0, &reg);
                do {
-                       g_wlan.hif_func.hif_write_reg(0xf0, reg | BIT(0));
-                       g_wlan.hif_func.hif_read_reg(0xf1, &clk_status_reg);
+                       wilc->hif_func->hif_write_reg(wilc, 0xf0,
+                                                     reg | BIT(0));
+                       wilc->hif_func->hif_read_reg(wilc, 0xf1,
+                                                    &clk_status_reg);
 
                        while (((clk_status_reg & 0x1) == 0) && (((++trials) % 3) == 0)) {
                                usleep_range(2 * 1000, 2 * 1000);
 
-                               g_wlan.hif_func.hif_read_reg(0xf1, &clk_status_reg);
+                               wilc->hif_func->hif_read_reg(wilc, 0xf1,
+                                                            &clk_status_reg);
 
                                if ((clk_status_reg & 0x1) == 0)
                                        wilc_debug(N_ERR, "clocks still OFF. Wake up failed\n");
                        }
                        if ((clk_status_reg & 0x1) == 0) {
-                               g_wlan.hif_func.hif_write_reg(0xf0, reg &
-                                                             (~BIT(0)));
+                               wilc->hif_func->hif_write_reg(wilc, 0xf0,
+                                                             reg & (~BIT(0)));
                        }
                } while ((clk_status_reg & 0x1) == 0);
        }
 
        if (chip_ps_state == CHIP_SLEEPING_MANUAL) {
-               g_wlan.hif_func.hif_read_reg(0x1C0C, &reg);
+               wilc->hif_func->hif_read_reg(wilc, 0x1C0C, &reg);
                reg &= ~BIT(0);
-               g_wlan.hif_func.hif_write_reg(0x1C0C, reg);
+               wilc->hif_func->hif_write_reg(wilc, 0x1C0C, reg);
 
-               if (wilc_get_chipid(false) >= 0x1002b0) {
+               if (wilc_get_chipid(wilc, false) >= 0x1002b0) {
                        u32 val32;
 
-                       g_wlan.hif_func.hif_read_reg(0x1e1c, &val32);
+                       wilc->hif_func->hif_read_reg(wilc, 0x1e1c, &val32);
                        val32 |= BIT(6);
-                       g_wlan.hif_func.hif_write_reg(0x1e1c, val32);
+                       wilc->hif_func->hif_write_reg(wilc, 0x1e1c, val32);
 
-                       g_wlan.hif_func.hif_read_reg(0x1e9c, &val32);
+                       wilc->hif_func->hif_read_reg(wilc, 0x1e9c, &val32);
                        val32 |= BIT(6);
-                       g_wlan.hif_func.hif_write_reg(0x1e9c, val32);
+                       wilc->hif_func->hif_write_reg(wilc, 0x1e9c, val32);
                }
        }
        chip_ps_state = CHIP_WAKEDUP;
 }
 #else
-static inline void chip_wakeup(void)
+static inline void chip_wakeup(struct wilc *wilc)
 {
        u32 reg, trials = 0;
 
        do {
-               if ((g_wlan.io_func.io_type & 0x1) == HIF_SPI) {
-                       g_wlan.hif_func.hif_read_reg(1, &reg);
-                       g_wlan.hif_func.hif_write_reg(1, reg & ~BIT(1));
-                       g_wlan.hif_func.hif_write_reg(1, reg | BIT(1));
-                       g_wlan.hif_func.hif_write_reg(1, reg  & ~BIT(1));
-               } else if ((g_wlan.io_func.io_type & 0x1) == HIF_SDIO)   {
-                       g_wlan.hif_func.hif_read_reg(0xf0, &reg);
-                       g_wlan.hif_func.hif_write_reg(0xf0, reg & ~BIT(0));
-                       g_wlan.hif_func.hif_write_reg(0xf0, reg | BIT(0));
-                       g_wlan.hif_func.hif_write_reg(0xf0, reg  & ~BIT(0));
+               if ((wilc->io_type & 0x1) == HIF_SPI) {
+                       wilc->hif_func->hif_read_reg(wilc, 1, &reg);
+                       wilc->hif_func->hif_write_reg(wilc, 1, reg & ~BIT(1));
+                       wilc->hif_func->hif_write_reg(wilc, 1, reg | BIT(1));
+                       wilc->hif_func->hif_write_reg(wilc, 1, reg  & ~BIT(1));
+               } else if ((wilc->io_type & 0x1) == HIF_SDIO)    {
+                       wilc->hif_func->hif_read_reg(wilc, 0xf0, &reg);
+                       wilc->hif_func->hif_write_reg(wilc, 0xf0,
+                                                     reg & ~BIT(0));
+                       wilc->hif_func->hif_write_reg(wilc, 0xf0,
+                                                     reg | BIT(0));
+                       wilc->hif_func->hif_write_reg(wilc, 0xf0,
+                                                     reg  & ~BIT(0));
                }
 
                do {
                        mdelay(3);
 
-                       if ((wilc_get_chipid(true) == 0))
+                       if ((wilc_get_chipid(wilc, true) == 0))
                                wilc_debug(N_ERR, "Couldn't read chip id. Wake up failed\n");
 
-               } while ((wilc_get_chipid(true) == 0) && ((++trials % 3) == 0));
+               } while ((wilc_get_chipid(wilc, true) == 0) && ((++trials % 3) == 0));
 
-       } while (wilc_get_chipid(true) == 0);
+       } while (wilc_get_chipid(wilc, true) == 0);
 
        if (chip_ps_state == CHIP_SLEEPING_MANUAL) {
-               g_wlan.hif_func.hif_read_reg(0x1C0C, &reg);
+               wilc->hif_func->hif_read_reg(wilc, 0x1C0C, &reg);
                reg &= ~BIT(0);
-               g_wlan.hif_func.hif_write_reg(0x1C0C, reg);
+               wilc->hif_func->hif_write_reg(wilc, 0x1C0C, reg);
 
-               if (wilc_get_chipid(false) >= 0x1002b0) {
+               if (wilc_get_chipid(wilc, false) >= 0x1002b0) {
                        u32 val32;
 
-                       g_wlan.hif_func.hif_read_reg(0x1e1c, &val32);
+                       wilc->hif_func->hif_read_reg(wilc, 0x1e1c, &val32);
                        val32 |= BIT(6);
-                       g_wlan.hif_func.hif_write_reg(0x1e1c, val32);
+                       wilc->hif_func->hif_write_reg(wilc, 0x1e1c, val32);
 
-                       g_wlan.hif_func.hif_read_reg(0x1e9c, &val32);
+                       wilc->hif_func->hif_read_reg(wilc, 0x1e9c, &val32);
                        val32 |= BIT(6);
-                       g_wlan.hif_func.hif_write_reg(0x1e9c, val32);
+                       wilc->hif_func->hif_write_reg(wilc, 0x1e9c, val32);
                }
        }
        chip_ps_state = CHIP_WAKEDUP;
 }
 #endif
-void chip_sleep_manually(void)
+void wilc_chip_sleep_manually(struct wilc *wilc)
 {
        if (chip_ps_state != CHIP_WAKEDUP)
                return;
-       acquire_bus(ACQUIRE_ONLY);
+       acquire_bus(wilc, ACQUIRE_ONLY);
 
 #ifdef WILC_OPTIMIZE_SLEEP_INT
-       chip_allow_sleep();
+       chip_allow_sleep(wilc);
 #endif
-       g_wlan.hif_func.hif_write_reg(0x10a8, 1);
+       wilc->hif_func->hif_write_reg(wilc, 0x10a8, 1);
 
        chip_ps_state = CHIP_SLEEPING_MANUAL;
-       release_bus(RELEASE_ONLY);
+       release_bus(wilc, RELEASE_ONLY);
 }
 
 int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count)
 {
-       wilc_wlan_dev_t *p = (wilc_wlan_dev_t *)&g_wlan;
        int i, entries = 0;
        u32 sum;
        u32 reg;
-       u8 *txb = p->tx_buffer;
+       u8 *txb;
        u32 offset = 0;
        int vmm_sz = 0;
        struct txq_entry_t *tqe;
@@ -710,18 +676,19 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count)
        int counter;
        int timeout;
        u32 vmm_table[WILC_VMM_TBL_SIZE];
-       perInterface_wlan_t *nic;
+       struct wilc_vif *vif;
        struct wilc *wilc;
 
-       nic = netdev_priv(dev);
-       wilc = nic->wilc;
+       vif = netdev_priv(dev);
+       wilc = vif->wilc;
 
-       p->txq_exit = 0;
+       txb = wilc->tx_buffer;
+       wilc->txq_exit = 0;
        do {
-               if (p->quit)
+               if (wilc->quit)
                        break;
 
-               linux_wlan_lock_timeout(&wilc->txq_add_to_head_cs,
+               wilc_lock_timeout(wilc, &wilc->txq_add_to_head_cs,
                                        CFG_PKTS_TIMEOUT);
 #ifdef TCP_ACK_FILTER
                wilc_wlan_txq_filter_dup_tcp_ack(dev);
@@ -758,9 +725,7 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count)
                                        vmm_table[i] |= BIT(10);
                                        PRINT_D(TX_DBG, "VMMTable entry changed for CFG packet = %d\n", vmm_table[i]);
                                }
-#ifdef BIG_ENDIAN
-                               vmm_table[i] = BYTE_SWAP(vmm_table[i]);
-#endif
+                               vmm_table[i] = cpu_to_le32(vmm_table[i]);
 
                                i++;
                                sum += vmm_sz;
@@ -778,10 +743,11 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count)
                        PRINT_D(TX_DBG, "Mark the last entry in VMM table - number of previous entries = %d\n", i);
                        vmm_table[i] = 0x0;
                }
-               acquire_bus(ACQUIRE_AND_WAKEUP);
+               acquire_bus(wilc, ACQUIRE_AND_WAKEUP);
                counter = 0;
                do {
-                       ret = p->hif_func.hif_read_reg(WILC_HOST_TX_CTRL, &reg);
+                       ret = wilc->hif_func->hif_read_reg(wilc, WILC_HOST_TX_CTRL,
+                                                      &reg);
                        if (!ret) {
                                wilc_debug(N_ERR, "[wilc txq]: fail can't read reg vmm_tbl_entry..\n");
                                break;
@@ -795,35 +761,36 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count)
                                if (counter > 200) {
                                        counter = 0;
                                        PRINT_D(TX_DBG, "Looping in tx ctrl , forcce quit\n");
-                                       ret = p->hif_func.hif_write_reg(WILC_HOST_TX_CTRL, 0);
+                                       ret = wilc->hif_func->hif_write_reg(wilc, WILC_HOST_TX_CTRL, 0);
                                        break;
                                }
                                PRINT_WRN(GENERIC_DBG, "[wilc txq]: warn, vmm table not clear yet, wait...\n");
-                               release_bus(RELEASE_ALLOW_SLEEP);
+                               release_bus(wilc, RELEASE_ALLOW_SLEEP);
                                usleep_range(3000, 3000);
-                               acquire_bus(ACQUIRE_AND_WAKEUP);
+                               acquire_bus(wilc, ACQUIRE_AND_WAKEUP);
                        }
-               } while (!p->quit);
+               } while (!wilc->quit);
 
                if (!ret)
                        goto _end_;
 
                timeout = 200;
                do {
-                       ret = p->hif_func.hif_block_tx(WILC_VMM_TBL_RX_SHADOW_BASE, (u8 *)vmm_table, ((i + 1) * 4));
+                       ret = wilc->hif_func->hif_block_tx(wilc, WILC_VMM_TBL_RX_SHADOW_BASE, (u8 *)vmm_table, ((i + 1) * 4));
                        if (!ret) {
                                wilc_debug(N_ERR, "ERR block TX of VMM table.\n");
                                break;
                        }
 
-                       ret = p->hif_func.hif_write_reg(WILC_HOST_VMM_CTL, 0x2);
+                       ret = wilc->hif_func->hif_write_reg(wilc, WILC_HOST_VMM_CTL,
+                                                       0x2);
                        if (!ret) {
                                wilc_debug(N_ERR, "[wilc txq]: fail can't write reg host_vmm_ctl..\n");
                                break;
                        }
 
                        do {
-                               ret = p->hif_func.hif_read_reg(WILC_HOST_VMM_CTL, &reg);
+                               ret = wilc->hif_func->hif_read_reg(wilc, WILC_HOST_VMM_CTL, &reg);
                                if (!ret) {
                                        wilc_debug(N_ERR, "[wilc txq]: fail can't read reg host_vmm_ctl..\n");
                                        break;
@@ -832,14 +799,14 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count)
                                        entries = ((reg >> 3) & 0x3f);
                                        break;
                                } else {
-                                       release_bus(RELEASE_ALLOW_SLEEP);
+                                       release_bus(wilc, RELEASE_ALLOW_SLEEP);
                                        usleep_range(3000, 3000);
-                                       acquire_bus(ACQUIRE_AND_WAKEUP);
+                                       acquire_bus(wilc, ACQUIRE_AND_WAKEUP);
                                        PRINT_WRN(GENERIC_DBG, "Can't get VMM entery - reg = %2x\n", reg);
                                }
                        } while (--timeout);
                        if (timeout <= 0) {
-                               ret = p->hif_func.hif_write_reg(WILC_HOST_VMM_CTL, 0x0);
+                               ret = wilc->hif_func->hif_write_reg(wilc, WILC_HOST_VMM_CTL, 0x0);
                                break;
                        }
 
@@ -849,13 +816,13 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count)
                        if (entries == 0) {
                                PRINT_WRN(GENERIC_DBG, "[wilc txq]: no more buffer in the chip (reg: %08x), retry later [[ %d, %x ]]\n", reg, i, vmm_table[i - 1]);
 
-                               ret = p->hif_func.hif_read_reg(WILC_HOST_TX_CTRL, &reg);
+                               ret = wilc->hif_func->hif_read_reg(wilc, WILC_HOST_TX_CTRL, &reg);
                                if (!ret) {
                                        wilc_debug(N_ERR, "[wilc txq]: fail can't read reg WILC_HOST_TX_CTRL..\n");
                                        break;
                                }
                                reg &= ~BIT(0);
-                               ret = p->hif_func.hif_write_reg(WILC_HOST_TX_CTRL, reg);
+                               ret = wilc->hif_func->hif_write_reg(wilc, WILC_HOST_TX_CTRL, reg);
                                if (!ret) {
                                        wilc_debug(N_ERR, "[wilc txq]: fail can't write reg WILC_HOST_TX_CTRL..\n");
                                        break;
@@ -874,7 +841,7 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count)
                        goto _end_;
                }
 
-               release_bus(RELEASE_ALLOW_SLEEP);
+               release_bus(wilc, RELEASE_ALLOW_SLEEP);
 
                offset = 0;
                i = 0;
@@ -883,9 +850,7 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count)
                        if (tqe && (vmm_table[i] != 0)) {
                                u32 header, buffer_offset;
 
-#ifdef BIG_ENDIAN
-                               vmm_table[i] = BYTE_SWAP(vmm_table[i]);
-#endif
+                               vmm_table[i] = cpu_to_le32(vmm_table[i]);
                                vmm_sz = (vmm_table[i] & 0x3ff);
                                vmm_sz *= 4;
                                header = (tqe->type << 31) |
@@ -896,9 +861,7 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count)
                                else
                                        header &= ~BIT(30);
 
-#ifdef BIG_ENDIAN
-                               header = BYTE_SWAP(header);
-#endif
+                               header = cpu_to_le32(header);
                                memcpy(&txb[offset], &header, 4);
                                if (tqe->type == WILC_CFG_PKT) {
                                        buffer_offset = ETH_CONFIG_PKT_HDR_OFFSET;
@@ -920,8 +883,8 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count)
                                        tqe->tx_complete_func(tqe->priv,
                                                              tqe->status);
                                #ifdef TCP_ACK_FILTER
-                               if (tqe->index != NOT_TCP_ACK)
-                                       pending_acks_info[tqe->index].txqe = NULL;
+                               if (tqe->tcp_pending_ack_idx != NOT_TCP_ACK)
+                                       pending_acks_info[tqe->tcp_pending_ack_idx].txqe = NULL;
                                #endif
                                kfree(tqe);
                        } else {
@@ -929,15 +892,15 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count)
                        }
                } while (--entries);
 
-               acquire_bus(ACQUIRE_AND_WAKEUP);
+               acquire_bus(wilc, ACQUIRE_AND_WAKEUP);
 
-               ret = p->hif_func.hif_clear_int_ext(ENABLE_TX_VMM);
+               ret = wilc->hif_func->hif_clear_int_ext(wilc, ENABLE_TX_VMM);
                if (!ret) {
                        wilc_debug(N_ERR, "[wilc txq]: fail can't start tx VMM ...\n");
                        goto _end_;
                }
 
-               ret = p->hif_func.hif_block_tx_ext(0, txb, offset);
+               ret = wilc->hif_func->hif_block_tx_ext(wilc, 0, txb, offset);
                if (!ret) {
                        wilc_debug(N_ERR, "[wilc txq]: fail can't block tx ext...\n");
                        goto _end_;
@@ -945,29 +908,28 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count)
 
 _end_:
 
-               release_bus(RELEASE_ALLOW_SLEEP);
+               release_bus(wilc, RELEASE_ALLOW_SLEEP);
                if (ret != 1)
                        break;
        } while (0);
        up(&wilc->txq_add_to_head_cs);
 
-       p->txq_exit = 1;
+       wilc->txq_exit = 1;
        PRINT_D(TX_DBG, "THREAD: Exiting txq\n");
-       *txq_count = p->txq_entries;
+       *txq_count = wilc->txq_entries;
        return ret;
 }
 
 static void wilc_wlan_handle_rxq(struct wilc *wilc)
 {
-       wilc_wlan_dev_t *p = &g_wlan;
        int offset = 0, size, has_packet = 0;
        u8 *buffer;
        struct rxq_entry_t *rqe;
 
-       p->rxq_exit = 0;
+       wilc->rxq_exit = 0;
 
        do {
-               if (p->quit) {
+               if (wilc->quit) {
                        PRINT_D(RX_DBG, "exit 1st do-while due to Clean_UP function\n");
                        up(&wilc->cfg_event);
                        break;
@@ -990,9 +952,7 @@ static void wilc_wlan_handle_rxq(struct wilc *wilc)
 
                        PRINT_D(RX_DBG, "In the 2nd do-while\n");
                        memcpy(&header, &buffer[offset], 4);
-#ifdef BIG_ENDIAN
-                       header = BYTE_SWAP(header);
-#endif
+                       header = cpu_to_le32(header);
                        PRINT_D(RX_DBG, "Header = %04x - Offset = %d\n",
                                header, offset);
 
@@ -1019,7 +979,7 @@ static void wilc_wlan_handle_rxq(struct wilc *wilc)
                        } else {
                                if (!is_cfg_packet) {
                                        if (pkt_len > 0) {
-                                               frmw_to_linux(wilc,
+                                               wilc_frmw_to_linux(wilc,
                                                              &buffer[offset],
                                                              pkt_len,
                                                              pkt_offset);
@@ -1028,16 +988,16 @@ static void wilc_wlan_handle_rxq(struct wilc *wilc)
                                } else {
                                        struct wilc_cfg_rsp rsp;
 
-                                       wilc_wlan_cfg_indicate_rx(&buffer[pkt_offset + offset], pkt_len, &rsp);
+                                       wilc_wlan_cfg_indicate_rx(wilc, &buffer[pkt_offset + offset], pkt_len, &rsp);
                                        if (rsp.type == WILC_CFG_RSP) {
-                                               PRINT_D(RX_DBG, "p->cfg_seq_no = %d - rsp.seq_no = %d\n", p->cfg_seq_no, rsp.seq_no);
-                                               if (p->cfg_seq_no == rsp.seq_no)
+                                               PRINT_D(RX_DBG, "wilc->cfg_seq_no = %d - rsp.seq_no = %d\n", wilc->cfg_seq_no, rsp.seq_no);
+                                               if (wilc->cfg_seq_no == rsp.seq_no)
                                                        up(&wilc->cfg_event);
                                        } else if (rsp.type == WILC_CFG_RSP_STATUS) {
-                                               linux_wlan_mac_indicate(wilc, WILC_MAC_INDICATE_STATUS);
+                                               wilc_mac_indicate(wilc, WILC_MAC_INDICATE_STATUS);
 
                                        } else if (rsp.type == WILC_CFG_RSP_SCAN) {
-                                               linux_wlan_mac_indicate(wilc, WILC_MAC_INDICATE_SCAN);
+                                               wilc_mac_indicate(wilc, WILC_MAC_INDICATE_SCAN);
                                        }
                                }
                        }
@@ -1045,42 +1005,42 @@ static void wilc_wlan_handle_rxq(struct wilc *wilc)
                        if (offset >= size)
                                break;
                } while (1);
-#ifndef MEMORY_STATIC
-               kfree(buffer);
-#endif
                kfree(rqe);
 
                if (has_packet)
-                       linux_wlan_rx_complete();
+                       wilc_rx_complete(wilc);
 
        } while (1);
 
-       p->rxq_exit = 1;
+       wilc->rxq_exit = 1;
        PRINT_D(RX_DBG, "THREAD: Exiting RX thread\n");
 }
 
-static void wilc_unknown_isr_ext(void)
+static void wilc_unknown_isr_ext(struct wilc *wilc)
 {
-       g_wlan.hif_func.hif_clear_int_ext(0);
+       wilc->hif_func->hif_clear_int_ext(wilc, 0);
 }
 
-static void wilc_pllupdate_isr_ext(u32 int_stats)
+static void wilc_pllupdate_isr_ext(struct wilc *wilc, u32 int_stats)
 {
        int trials = 10;
 
-       g_wlan.hif_func.hif_clear_int_ext(PLL_INT_CLR);
+       wilc->hif_func->hif_clear_int_ext(wilc, PLL_INT_CLR);
 
-       mdelay(WILC_PLL_TO);
+       if (wilc->io_type == HIF_SDIO)
+               mdelay(WILC_PLL_TO_SDIO);
+       else
+               mdelay(WILC_PLL_TO_SPI);
 
-       while (!(ISWILC1000(wilc_get_chipid(true)) && --trials)) {
+       while (!(ISWILC1000(wilc_get_chipid(wilc, true)) && --trials)) {
                PRINT_D(TX_DBG, "PLL update retrying\n");
                mdelay(1);
        }
 }
 
-static void wilc_sleeptimer_isr_ext(u32 int_stats1)
+static void wilc_sleeptimer_isr_ext(struct wilc *wilc, u32 int_stats1)
 {
-       g_wlan.hif_func.hif_clear_int_ext(SLEEP_INT_CLR);
+       wilc->hif_func->hif_clear_int_ext(wilc, SLEEP_INT_CLR);
 #ifndef WILC_OPTIMIZE_SLEEP_INT
        chip_ps_state = CHIP_SLEEPING_AUTO;
 #endif
@@ -1088,10 +1048,7 @@ static void wilc_sleeptimer_isr_ext(u32 int_stats1)
 
 static void wilc_wlan_handle_isr_ext(struct wilc *wilc, u32 int_status)
 {
-       wilc_wlan_dev_t *p = &g_wlan;
-#ifdef MEMORY_STATIC
-       u32 offset = p->rx_buffer_offset;
-#endif
+       u32 offset = wilc->rx_buffer_offset;
        u8 *buffer = NULL;
        u32 size;
        u32 retries = 0;
@@ -1104,32 +1061,25 @@ static void wilc_wlan_handle_isr_ext(struct wilc *wilc, u32 int_status)
                u32 time = 0;
 
                wilc_debug(N_ERR, "RX Size equal zero ... Trying to read it again for %d time\n", time++);
-               p->hif_func.hif_read_size(&size);
+               wilc->hif_func->hif_read_size(wilc, &size);
                size = ((size & 0x7fff) << 2);
                retries++;
        }
 
        if (size > 0) {
-#ifdef MEMORY_STATIC
                if (LINUX_RX_SIZE - offset < size)
                        offset = 0;
 
-               if (p->rx_buffer) {
-                       buffer = &p->rx_buffer[offset];
+               if (wilc->rx_buffer) {
+                       buffer = &wilc->rx_buffer[offset];
                } else {
                        wilc_debug(N_ERR, "[wilc isr]: fail Rx Buffer is NULL...drop the packets (%d)\n", size);
                        goto _end_;
                }
 
-#else
-               buffer = kmalloc(size, GFP_KERNEL);
-               if (!buffer) {
-                       usleep_range(100 * 1000, 100 * 1000);
-                       goto _end_;
-               }
-#endif
-               p->hif_func.hif_clear_int_ext(DATA_INT_CLR | ENABLE_RX_VMM);
-               ret = p->hif_func.hif_block_rx_ext(0, buffer, size);
+               wilc->hif_func->hif_clear_int_ext(wilc,
+                                             DATA_INT_CLR | ENABLE_RX_VMM);
+               ret = wilc->hif_func->hif_block_rx_ext(wilc, 0, buffer, size);
 
                if (!ret) {
                        wilc_debug(N_ERR, "[wilc isr]: fail block rx...\n");
@@ -1137,10 +1087,8 @@ static void wilc_wlan_handle_isr_ext(struct wilc *wilc, u32 int_status)
                }
 _end_:
                if (ret) {
-#ifdef MEMORY_STATIC
                        offset += size;
-                       p->rx_buffer_offset = offset;
-#endif
+                       wilc->rx_buffer_offset = offset;
                        rqe = kmalloc(sizeof(*rqe), GFP_KERNEL);
                        if (rqe) {
                                rqe->buffer = buffer;
@@ -1148,24 +1096,20 @@ _end_:
                                PRINT_D(RX_DBG, "rxq entery Size= %d - Address = %p\n", rqe->buffer_size, rqe->buffer);
                                wilc_wlan_rxq_add(wilc, rqe);
                        }
-               } else {
-#ifndef MEMORY_STATIC
-                       kfree(buffer);
-#endif
                }
        }
        wilc_wlan_handle_rxq(wilc);
 }
 
-void wilc_handle_isr(void *wilc)
+void wilc_handle_isr(struct wilc *wilc)
 {
        u32 int_status;
 
-       acquire_bus(ACQUIRE_AND_WAKEUP);
-       g_wlan.hif_func.hif_read_int(&int_status);
+       acquire_bus(wilc, ACQUIRE_AND_WAKEUP);
+       wilc->hif_func->hif_read_int(wilc, &int_status);
 
        if (int_status & PLL_INT_EXT)
-               wilc_pllupdate_isr_ext(int_status);
+               wilc_pllupdate_isr_ext(wilc, int_status);
 
        if (int_status & DATA_INT_EXT) {
                wilc_wlan_handle_isr_ext(wilc, int_status);
@@ -1174,20 +1118,17 @@ void wilc_handle_isr(void *wilc)
        #endif
        }
        if (int_status & SLEEP_INT_EXT)
-               wilc_sleeptimer_isr_ext(int_status);
+               wilc_sleeptimer_isr_ext(wilc, int_status);
 
        if (!(int_status & (ALL_INT_EXT))) {
-#ifdef WILC_SDIO
-               PRINT_D(TX_DBG, ">> UNKNOWN_INTERRUPT - 0x%08x\n", int_status);
-#endif
-               wilc_unknown_isr_ext();
+               wilc_unknown_isr_ext(wilc);
        }
-       release_bus(RELEASE_ALLOW_SLEEP);
+       release_bus(wilc, RELEASE_ALLOW_SLEEP);
 }
+EXPORT_SYMBOL_GPL(wilc_handle_isr);
 
-int wilc_wlan_firmware_download(const u8 *buffer, u32 buffer_size)
+int wilc_wlan_firmware_download(struct wilc *wilc, const u8 *buffer, u32 buffer_size)
 {
-       wilc_wlan_dev_t *p = &g_wlan;
        u32 offset;
        u32 addr, size, size2, blksz;
        u8 *dma_buffer;
@@ -1208,11 +1149,9 @@ int wilc_wlan_firmware_download(const u8 *buffer, u32 buffer_size)
        do {
                memcpy(&addr, &buffer[offset], 4);
                memcpy(&size, &buffer[offset + 4], 4);
-#ifdef BIG_ENDIAN
-               addr = BYTE_SWAP(addr);
-               size = BYTE_SWAP(size);
-#endif
-               acquire_bus(ACQUIRE_ONLY);
+               addr = cpu_to_le32(addr);
+               size = cpu_to_le32(size);
+               acquire_bus(wilc, ACQUIRE_ONLY);
                offset += 8;
                while (((int)size) && (offset < buffer_size)) {
                        if (size <= blksz)
@@ -1221,7 +1160,8 @@ int wilc_wlan_firmware_download(const u8 *buffer, u32 buffer_size)
                                size2 = blksz;
 
                        memcpy(dma_buffer, &buffer[offset], size2);
-                       ret = p->hif_func.hif_block_tx(addr, dma_buffer, size2);
+                       ret = wilc->hif_func->hif_block_tx(wilc, addr, dma_buffer,
+                                                      size2);
                        if (!ret)
                                break;
 
@@ -1229,7 +1169,7 @@ int wilc_wlan_firmware_download(const u8 *buffer, u32 buffer_size)
                        offset += size2;
                        size -= size2;
                }
-               release_bus(RELEASE_ONLY);
+               release_bus(wilc, RELEASE_ONLY);
 
                if (!ret) {
                        ret = -EIO;
@@ -1248,31 +1188,29 @@ _fail_1:
        return (ret < 0) ? ret : 0;
 }
 
-int wilc_wlan_start(void)
+int wilc_wlan_start(struct wilc *wilc)
 {
-       wilc_wlan_dev_t *p = &g_wlan;
        u32 reg = 0;
        int ret;
        u32 chipid;
 
-       if (p->io_func.io_type == HIF_SDIO) {
+       if (wilc->io_type == HIF_SDIO) {
                reg = 0;
                reg |= BIT(3);
-       } else if (p->io_func.io_type == HIF_SPI) {
+       } else if (wilc->io_type == HIF_SPI) {
                reg = 1;
        }
-       acquire_bus(ACQUIRE_ONLY);
-       ret = p->hif_func.hif_write_reg(WILC_VMM_CORE_CFG, reg);
+       acquire_bus(wilc, ACQUIRE_ONLY);
+       ret = wilc->hif_func->hif_write_reg(wilc, WILC_VMM_CORE_CFG, reg);
        if (!ret) {
                wilc_debug(N_ERR, "[wilc start]: fail write reg vmm_core_cfg...\n");
-               release_bus(RELEASE_ONLY);
+               release_bus(wilc, RELEASE_ONLY);
                ret = -EIO;
                return ret;
        }
        reg = 0;
-#ifdef WILC_SDIO_IRQ_GPIO
-       reg |= WILC_HAVE_SDIO_IRQ_GPIO;
-#endif
+       if (wilc->io_type == HIF_SDIO && wilc->dev_irq_num)
+               reg |= WILC_HAVE_SDIO_IRQ_GPIO;
 
 #ifdef WILC_DISABLE_PMU
 #else
@@ -1297,76 +1235,72 @@ int wilc_wlan_start(void)
        reg |= WILC_HAVE_DISABLE_WILC_UART;
 #endif
 
-       ret = p->hif_func.hif_write_reg(WILC_GP_REG_1, reg);
+       ret = wilc->hif_func->hif_write_reg(wilc, WILC_GP_REG_1, reg);
        if (!ret) {
                wilc_debug(N_ERR, "[wilc start]: fail write WILC_GP_REG_1 ...\n");
-               release_bus(RELEASE_ONLY);
+               release_bus(wilc, RELEASE_ONLY);
                ret = -EIO;
                return ret;
        }
 
-       p->hif_func.hif_sync_ext(NUM_INT_EXT);
+       wilc->hif_func->hif_sync_ext(wilc, NUM_INT_EXT);
 
-       ret = p->hif_func.hif_read_reg(0x1000, &chipid);
+       ret = wilc->hif_func->hif_read_reg(wilc, 0x1000, &chipid);
        if (!ret) {
                wilc_debug(N_ERR, "[wilc start]: fail read reg 0x1000 ...\n");
-               release_bus(RELEASE_ONLY);
+               release_bus(wilc, RELEASE_ONLY);
                ret = -EIO;
                return ret;
        }
 
-       p->hif_func.hif_read_reg(WILC_GLB_RESET_0, &reg);
+       wilc->hif_func->hif_read_reg(wilc, WILC_GLB_RESET_0, &reg);
        if ((reg & BIT(10)) == BIT(10)) {
                reg &= ~BIT(10);
-               p->hif_func.hif_write_reg(WILC_GLB_RESET_0, reg);
-               p->hif_func.hif_read_reg(WILC_GLB_RESET_0, &reg);
+               wilc->hif_func->hif_write_reg(wilc, WILC_GLB_RESET_0, reg);
+               wilc->hif_func->hif_read_reg(wilc, WILC_GLB_RESET_0, &reg);
        }
 
        reg |= BIT(10);
-       ret = p->hif_func.hif_write_reg(WILC_GLB_RESET_0, reg);
-       p->hif_func.hif_read_reg(WILC_GLB_RESET_0, &reg);
-       release_bus(RELEASE_ONLY);
+       ret = wilc->hif_func->hif_write_reg(wilc, WILC_GLB_RESET_0, reg);
+       wilc->hif_func->hif_read_reg(wilc, WILC_GLB_RESET_0, &reg);
+       release_bus(wilc, RELEASE_ONLY);
 
        return (ret < 0) ? ret : 0;
 }
 
-void wilc_wlan_global_reset(void)
+void wilc_wlan_global_reset(struct wilc *wilc)
 {
-
-       wilc_wlan_dev_t *p = &g_wlan;
-
-       acquire_bus(ACQUIRE_AND_WAKEUP);
-       p->hif_func.hif_write_reg(WILC_GLB_RESET_0, 0x0);
-       release_bus(RELEASE_ONLY);
+       acquire_bus(wilc, ACQUIRE_AND_WAKEUP);
+       wilc->hif_func->hif_write_reg(wilc, WILC_GLB_RESET_0, 0x0);
+       release_bus(wilc, RELEASE_ONLY);
 }
-int wilc_wlan_stop(void)
+int wilc_wlan_stop(struct wilc *wilc)
 {
-       wilc_wlan_dev_t *p = &g_wlan;
        u32 reg = 0;
        int ret;
        u8 timeout = 10;
-       acquire_bus(ACQUIRE_AND_WAKEUP);
+       acquire_bus(wilc, ACQUIRE_AND_WAKEUP);
 
-       ret = p->hif_func.hif_read_reg(WILC_GLB_RESET_0, &reg);
+       ret = wilc->hif_func->hif_read_reg(wilc, WILC_GLB_RESET_0, &reg);
        if (!ret) {
                PRINT_ER("Error while reading reg\n");
-               release_bus(RELEASE_ALLOW_SLEEP);
+               release_bus(wilc, RELEASE_ALLOW_SLEEP);
                return ret;
        }
 
        reg &= ~BIT(10);
-       ret = p->hif_func.hif_write_reg(WILC_GLB_RESET_0, reg);
+       ret = wilc->hif_func->hif_write_reg(wilc, WILC_GLB_RESET_0, reg);
        if (!ret) {
                PRINT_ER("Error while writing reg\n");
-               release_bus(RELEASE_ALLOW_SLEEP);
+               release_bus(wilc, RELEASE_ALLOW_SLEEP);
                return ret;
        }
 
        do {
-               ret = p->hif_func.hif_read_reg(WILC_GLB_RESET_0, &reg);
+               ret = wilc->hif_func->hif_read_reg(wilc, WILC_GLB_RESET_0, &reg);
                if (!ret) {
                        PRINT_ER("Error while reading reg\n");
-                       release_bus(RELEASE_ALLOW_SLEEP);
+                       release_bus(wilc, RELEASE_ALLOW_SLEEP);
                        return ret;
                }
                PRINT_D(GENERIC_DBG, "Read RESET Reg %x : Retry%d\n",
@@ -1376,15 +1310,17 @@ int wilc_wlan_stop(void)
                        PRINT_D(GENERIC_DBG, "Bit 10 not reset : Retry %d\n",
                                timeout);
                        reg &= ~BIT(10);
-                       ret = p->hif_func.hif_write_reg(WILC_GLB_RESET_0, reg);
+                       ret = wilc->hif_func->hif_write_reg(wilc, WILC_GLB_RESET_0,
+                                                       reg);
                        timeout--;
                } else {
                        PRINT_D(GENERIC_DBG, "Bit 10 reset after : Retry %d\n",
                                timeout);
-                       ret = p->hif_func.hif_read_reg(WILC_GLB_RESET_0, &reg);
+                       ret = wilc->hif_func->hif_read_reg(wilc, WILC_GLB_RESET_0,
+                                                      &reg);
                        if (!ret) {
                                PRINT_ER("Error while reading reg\n");
-                               release_bus(RELEASE_ALLOW_SLEEP);
+                               release_bus(wilc, RELEASE_ALLOW_SLEEP);
                                return ret;
                        }
                        PRINT_D(GENERIC_DBG, "Read RESET Reg %x : Retry%d\n",
@@ -1396,30 +1332,29 @@ int wilc_wlan_stop(void)
        reg = (BIT(0) | BIT(1) | BIT(2) | BIT(3) | BIT(8) | BIT(9) | BIT(26) |
               BIT(29) | BIT(30) | BIT(31));
 
-       p->hif_func.hif_write_reg(WILC_GLB_RESET_0, reg);
+       wilc->hif_func->hif_write_reg(wilc, WILC_GLB_RESET_0, reg);
        reg = (u32)~BIT(10);
 
-       ret = p->hif_func.hif_write_reg(WILC_GLB_RESET_0, reg);
+       ret = wilc->hif_func->hif_write_reg(wilc, WILC_GLB_RESET_0, reg);
 
-       release_bus(RELEASE_ALLOW_SLEEP);
+       release_bus(wilc, RELEASE_ALLOW_SLEEP);
 
        return ret;
 }
 
 void wilc_wlan_cleanup(struct net_device *dev)
 {
-       wilc_wlan_dev_t *p = &g_wlan;
        struct txq_entry_t *tqe;
        struct rxq_entry_t *rqe;
        u32 reg = 0;
        int ret;
-       perInterface_wlan_t *nic;
+       struct wilc_vif *vif;
        struct wilc *wilc;
 
-       nic = netdev_priv(dev);
-       wilc = nic->wilc;
+       vif = netdev_priv(dev);
+       wilc = vif->wilc;
 
-       p->quit = 1;
+       wilc->quit = 1;
        do {
                tqe = wilc_wlan_txq_remove_from_head(dev);
                if (!tqe)
@@ -1433,41 +1368,37 @@ void wilc_wlan_cleanup(struct net_device *dev)
                rqe = wilc_wlan_rxq_remove(wilc);
                if (!rqe)
                        break;
-#ifndef MEMORY_STATIC
-               kfree(rqe->buffer);
-#endif
                kfree(rqe);
        } while (1);
 
-       #ifdef MEMORY_STATIC
-       kfree(p->rx_buffer);
-       p->rx_buffer = NULL;
-       #endif
-       kfree(p->tx_buffer);
+       kfree(wilc->rx_buffer);
+       wilc->rx_buffer = NULL;
+       kfree(wilc->tx_buffer);
+       wilc->tx_buffer = NULL;
 
-       acquire_bus(ACQUIRE_AND_WAKEUP);
+       acquire_bus(wilc, ACQUIRE_AND_WAKEUP);
 
-       ret = p->hif_func.hif_read_reg(WILC_GP_REG_0, &reg);
+       ret = wilc->hif_func->hif_read_reg(wilc, WILC_GP_REG_0, &reg);
        if (!ret) {
                PRINT_ER("Error while reading reg\n");
-               release_bus(RELEASE_ALLOW_SLEEP);
+               release_bus(wilc, RELEASE_ALLOW_SLEEP);
        }
        PRINT_ER("Writing ABORT reg\n");
-       ret = p->hif_func.hif_write_reg(WILC_GP_REG_0, (reg | ABORT_INT));
+       ret = wilc->hif_func->hif_write_reg(wilc, WILC_GP_REG_0,
+                                       (reg | ABORT_INT));
        if (!ret) {
                PRINT_ER("Error while writing reg\n");
-               release_bus(RELEASE_ALLOW_SLEEP);
+               release_bus(wilc, RELEASE_ALLOW_SLEEP);
        }
-       release_bus(RELEASE_ALLOW_SLEEP);
-       p->hif_func.hif_deinit(NULL);
+       release_bus(wilc, RELEASE_ALLOW_SLEEP);
+       wilc->hif_func->hif_deinit(NULL);
 }
 
-static int wilc_wlan_cfg_commit(int type, u32 drv_handler)
+static int wilc_wlan_cfg_commit(struct wilc *wilc, int type, u32 drv_handler)
 {
-       wilc_wlan_dev_t *p = &g_wlan;
-       struct wilc_cfg_frame *cfg = &p->cfg_frame;
-       int total_len = p->cfg_frame_offset + 4 + DRIVER_HANDLER_SIZE;
-       int seq_no = p->cfg_seq_no % 256;
+       struct wilc_cfg_frame *cfg = &wilc->cfg_frame;
+       int total_len = wilc->cfg_frame_offset + 4 + DRIVER_HANDLER_SIZE;
+       int seq_no = wilc->cfg_seq_no % 256;
        int driver_handler = (u32)drv_handler;
 
        if (type == WILC_CFG_SET)
@@ -1481,87 +1412,87 @@ static int wilc_wlan_cfg_commit(int type, u32 drv_handler)
        cfg->wid_header[5] = (u8)(driver_handler >> 8);
        cfg->wid_header[6] = (u8)(driver_handler >> 16);
        cfg->wid_header[7] = (u8)(driver_handler >> 24);
-       p->cfg_seq_no = seq_no;
+       wilc->cfg_seq_no = seq_no;
 
-       if (!wilc_wlan_txq_add_cfg_pkt(&cfg->wid_header[0], total_len))
+       if (!wilc_wlan_txq_add_cfg_pkt(wilc, &cfg->wid_header[0], total_len))
                return -1;
 
        return 0;
 }
 
-int wilc_wlan_cfg_set(int start, u32 wid, u8 *buffer, u32 buffer_size,
-                     int commit, u32 drv_handler)
+int wilc_wlan_cfg_set(struct wilc *wilc, int start, u32 wid, u8 *buffer,
+                     u32 buffer_size, int commit, u32 drv_handler)
 {
-       wilc_wlan_dev_t *p = &g_wlan;
        u32 offset;
        int ret_size;
 
-       if (p->cfg_frame_in_use)
+       if (wilc->cfg_frame_in_use)
                return 0;
 
        if (start)
-               p->cfg_frame_offset = 0;
+               wilc->cfg_frame_offset = 0;
 
-       offset = p->cfg_frame_offset;
-       ret_size = wilc_wlan_cfg_set_wid(p->cfg_frame.frame, offset, (u16)wid,
-                                        buffer, buffer_size);
+       offset = wilc->cfg_frame_offset;
+       ret_size = wilc_wlan_cfg_set_wid(wilc->cfg_frame.frame, offset,
+                                        (u16)wid, buffer, buffer_size);
        offset += ret_size;
-       p->cfg_frame_offset = offset;
+       wilc->cfg_frame_offset = offset;
 
        if (commit) {
                PRINT_D(TX_DBG, "[WILC]PACKET Commit with sequence number %d\n",
-                       p->cfg_seq_no);
+                       wilc->cfg_seq_no);
                PRINT_D(RX_DBG, "Processing cfg_set()\n");
-               p->cfg_frame_in_use = 1;
+               wilc->cfg_frame_in_use = 1;
 
-               if (wilc_wlan_cfg_commit(WILC_CFG_SET, drv_handler))
+               if (wilc_wlan_cfg_commit(wilc, WILC_CFG_SET, drv_handler))
                        ret_size = 0;
 
-               if (linux_wlan_lock_timeout(&g_linux_wlan->cfg_event,
+               if (wilc_lock_timeout(wilc, &wilc->cfg_event,
                                            CFG_PKTS_TIMEOUT)) {
                        PRINT_D(TX_DBG, "Set Timed Out\n");
                        ret_size = 0;
                }
-               p->cfg_frame_in_use = 0;
-               p->cfg_frame_offset = 0;
-               p->cfg_seq_no += 1;
+               wilc->cfg_frame_in_use = 0;
+               wilc->cfg_frame_offset = 0;
+               wilc->cfg_seq_no += 1;
        }
 
        return ret_size;
 }
 
-int wilc_wlan_cfg_get(int start, u32 wid, int commit, u32 drv_handler)
+int wilc_wlan_cfg_get(struct wilc *wilc, int start, u32 wid, int commit,
+                     u32 drv_handler)
 {
-       wilc_wlan_dev_t *p = &g_wlan;
        u32 offset;
        int ret_size;
 
-       if (p->cfg_frame_in_use)
+       if (wilc->cfg_frame_in_use)
                return 0;
 
        if (start)
-               p->cfg_frame_offset = 0;
+               wilc->cfg_frame_offset = 0;
 
-       offset = p->cfg_frame_offset;
-       ret_size = wilc_wlan_cfg_get_wid(p->cfg_frame.frame, offset, (u16)wid);
+       offset = wilc->cfg_frame_offset;
+       ret_size = wilc_wlan_cfg_get_wid(wilc->cfg_frame.frame, offset,
+                                        (u16)wid);
        offset += ret_size;
-       p->cfg_frame_offset = offset;
+       wilc->cfg_frame_offset = offset;
 
        if (commit) {
-               p->cfg_frame_in_use = 1;
+               wilc->cfg_frame_in_use = 1;
 
-               if (wilc_wlan_cfg_commit(WILC_CFG_QUERY, drv_handler))
+               if (wilc_wlan_cfg_commit(wilc, WILC_CFG_QUERY, drv_handler))
                        ret_size = 0;
 
-               if (linux_wlan_lock_timeout(&g_linux_wlan->cfg_event,
+               if (wilc_lock_timeout(wilc, &wilc->cfg_event,
                                            CFG_PKTS_TIMEOUT)) {
                        PRINT_D(TX_DBG, "Get Timed Out\n");
                        ret_size = 0;
                }
                PRINT_D(GENERIC_DBG, "[WILC]Get Response received\n");
-               p->cfg_frame_in_use = 0;
-               p->cfg_frame_offset = 0;
-               p->cfg_seq_no += 1;
+               wilc->cfg_frame_in_use = 0;
+               wilc->cfg_frame_offset = 0;
+               wilc->cfg_seq_no += 1;
        }
 
        return ret_size;
@@ -1576,58 +1507,53 @@ int wilc_wlan_cfg_get_val(u32 wid, u8 *buffer, u32 buffer_size)
        return ret;
 }
 
-void wilc_bus_set_max_speed(void)
-{
-       g_wlan.hif_func.hif_set_max_bus_speed();
-}
-
-void wilc_bus_set_default_speed(void)
-{
-       g_wlan.hif_func.hif_set_default_bus_speed();
-}
-
-u32 init_chip(struct net_device *dev)
+static u32 init_chip(struct net_device *dev)
 {
        u32 chipid;
        u32 reg, ret = 0;
+       struct wilc_vif *vif;
+       struct wilc *wilc;
 
-       acquire_bus(ACQUIRE_ONLY);
+       vif = netdev_priv(dev);
+       wilc = vif->wilc;
 
-       chipid = wilc_get_chipid(true);
+       acquire_bus(wilc, ACQUIRE_ONLY);
+
+       chipid = wilc_get_chipid(wilc, true);
 
        if ((chipid & 0xfff) != 0xa0) {
-               ret = g_wlan.hif_func.hif_read_reg(0x1118, &reg);
+               ret = wilc->hif_func->hif_read_reg(wilc, 0x1118, &reg);
                if (!ret) {
                        wilc_debug(N_ERR, "[wilc start]: fail read reg 0x1118 ...\n");
                        return ret;
                }
                reg |= BIT(0);
-               ret = g_wlan.hif_func.hif_write_reg(0x1118, reg);
+               ret = wilc->hif_func->hif_write_reg(wilc, 0x1118, reg);
                if (!ret) {
                        wilc_debug(N_ERR, "[wilc start]: fail write reg 0x1118 ...\n");
                        return ret;
                }
-               ret = g_wlan.hif_func.hif_write_reg(0xc0000, 0x71);
+               ret = wilc->hif_func->hif_write_reg(wilc, 0xc0000, 0x71);
                if (!ret) {
                        wilc_debug(N_ERR, "[wilc start]: fail write reg 0xc0000 ...\n");
                        return ret;
                }
        }
 
-       release_bus(RELEASE_ONLY);
+       release_bus(wilc, RELEASE_ONLY);
 
        return ret;
 }
 
-u32 wilc_get_chipid(u8 update)
+u32 wilc_get_chipid(struct wilc *wilc, u8 update)
 {
        static u32 chipid;
        u32 tempchipid = 0;
        u32 rfrevid;
 
        if (chipid == 0 || update != 0) {
-               g_wlan.hif_func.hif_read_reg(0x1000, &tempchipid);
-               g_wlan.hif_func.hif_read_reg(0x13f4, &rfrevid);
+               wilc->hif_func->hif_read_reg(wilc, 0x1000, &tempchipid);
+               wilc->hif_func->hif_read_reg(wilc, 0x13f4, &rfrevid);
                if (!ISWILC1000(tempchipid)) {
                        chipid = 0;
                        goto _fail_;
@@ -1652,61 +1578,44 @@ _fail_:
        return chipid;
 }
 
-int wilc_wlan_init(struct net_device *dev, wilc_wlan_inp_t *inp)
+int wilc_wlan_init(struct net_device *dev)
 {
        int ret = 0;
-       perInterface_wlan_t *nic = netdev_priv(dev);
+       struct wilc_vif *vif = netdev_priv(dev);
        struct wilc *wilc;
 
-       wilc = nic->wilc;
+       wilc = vif->wilc;
 
        PRINT_D(INIT_DBG, "Initializing WILC_Wlan ...\n");
 
-       memset((void *)&g_wlan, 0, sizeof(wilc_wlan_dev_t));
-       memcpy((void *)&g_wlan.io_func, (void *)&inp->io_func,
-              sizeof(wilc_wlan_io_func_t));
-
-#ifdef WILC_SDIO
-       if (!hif_sdio.hif_init(wilc, wilc_debug)) {
-               ret = -EIO;
-               goto _fail_;
-       }
-       memcpy((void *)&g_wlan.hif_func, &hif_sdio,
-              sizeof(struct wilc_hif_func));
-#else
-       if (!hif_spi.hif_init(wilc, wilc_debug)) {
+       if (!wilc->hif_func->hif_init(wilc)) {
                ret = -EIO;
                goto _fail_;
        }
-       memcpy((void *)&g_wlan.hif_func, &hif_spi,
-              sizeof(struct wilc_hif_func));
-#endif
 
        if (!wilc_wlan_cfg_init(wilc_debug)) {
                ret = -ENOBUFS;
                goto _fail_;
        }
 
-       if (!g_wlan.tx_buffer)
-               g_wlan.tx_buffer = kmalloc(LINUX_TX_SIZE, GFP_KERNEL);
-       PRINT_D(TX_DBG, "g_wlan.tx_buffer = %p\n", g_wlan.tx_buffer);
+       if (!wilc->tx_buffer)
+               wilc->tx_buffer = kmalloc(LINUX_TX_SIZE, GFP_KERNEL);
+       PRINT_D(TX_DBG, "wilc->tx_buffer = %p\n", wilc->tx_buffer);
 
-       if (!g_wlan.tx_buffer) {
+       if (!wilc->tx_buffer) {
                ret = -ENOBUFS;
                PRINT_ER("Can't allocate Tx Buffer");
                goto _fail_;
        }
 
-#if defined(MEMORY_STATIC)
-       if (!g_wlan.rx_buffer)
-               g_wlan.rx_buffer = kmalloc(LINUX_RX_SIZE, GFP_KERNEL);
-       PRINT_D(TX_DBG, "g_wlan.rx_buffer =%p\n", g_wlan.rx_buffer);
-       if (!g_wlan.rx_buffer) {
+       if (!wilc->rx_buffer)
+               wilc->rx_buffer = kmalloc(LINUX_RX_SIZE, GFP_KERNEL);
+       PRINT_D(TX_DBG, "wilc->rx_buffer =%p\n", wilc->rx_buffer);
+       if (!wilc->rx_buffer) {
                ret = -ENOBUFS;
                PRINT_ER("Can't allocate Rx Buffer");
                goto _fail_;
        }
-#endif
 
        if (!init_chip(dev)) {
                ret = -EIO;
@@ -1720,28 +1629,27 @@ int wilc_wlan_init(struct net_device *dev, wilc_wlan_inp_t *inp)
 
 _fail_:
 
-  #ifdef MEMORY_STATIC
-       kfree(g_wlan.rx_buffer);
-       g_wlan.rx_buffer = NULL;
-  #endif
-       kfree(g_wlan.tx_buffer);
-       g_wlan.tx_buffer = NULL;
+       kfree(wilc->rx_buffer);
+       wilc->rx_buffer = NULL;
+       kfree(wilc->tx_buffer);
+       wilc->tx_buffer = NULL;
 
        return ret;
 }
 
-u16 set_machw_change_vir_if(struct net_device *dev, bool value)
+u16 wilc_set_machw_change_vir_if(struct net_device *dev, bool value)
 {
        u16 ret;
        u32 reg;
-       perInterface_wlan_t *nic;
+       struct wilc_vif *vif;
        struct wilc *wilc;
 
-       nic = netdev_priv(dev);
-       wilc = nic->wilc;
+       vif = netdev_priv(dev);
+       wilc = vif->wilc;
 
        mutex_lock(&wilc->hif_cs);
-       ret = (&g_wlan)->hif_func.hif_read_reg(WILC_CHANGING_VIR_IF, &reg);
+       ret = wilc->hif_func->hif_read_reg(wilc, WILC_CHANGING_VIR_IF,
+                                              &reg);
        if (!ret)
                PRINT_ER("Error while Reading reg WILC_CHANGING_VIR_IF\n");
 
@@ -1750,7 +1658,8 @@ u16 set_machw_change_vir_if(struct net_device *dev, bool value)
        else
                reg &= ~BIT(31);
 
-       ret = (&g_wlan)->hif_func.hif_write_reg(WILC_CHANGING_VIR_IF, reg);
+       ret = wilc->hif_func->hif_write_reg(wilc, WILC_CHANGING_VIR_IF,
+                                               reg);
 
        if (!ret)
                PRINT_ER("Error while writing reg WILC_CHANGING_VIR_IF\n");
index 64fd019595cec90192060a924a3b5e9b0bf098de..2edd7445f4a33a526e4f2a989a5328486826bb99 100644 (file)
@@ -1,7 +1,10 @@
 #ifndef WILC_WLAN_H
 #define WILC_WLAN_H
 
+#include <linux/types.h>
+
 #define ISWILC1000(id)                 ((id & 0xfffff000) == 0x100000 ? 1 : 0)
+
 /********************************************
  *
  *      Mac eth header length
 #define ETH_CONFIG_PKT_HDR_OFFSET      (ETH_ETHERNET_HDR_OFFSET + \
                                         ETH_CONFIG_PKT_HDR_LEN)
 
-/********************************************
- *
- *      Endian Conversion
- *
- ********************************************/
-
-#define BYTE_SWAP(val)                 (((val & 0x000000FF) << 24) + \
-                                        ((val & 0x0000FF00) << 8) + \
-                                        ((val & 0x00FF0000) >> 8) + \
-                                        ((val & 0xFF000000) >> 24))
-
 /********************************************
  *
  *      Register Defines
 #define WILC_CFG_RSP_STATUS    2
 #define WILC_CFG_RSP_SCAN      3
 
-#ifdef WILC_SDIO
-#define WILC_PLL_TO            4
-#else
-#define WILC_PLL_TO            2
-#endif
+#define WILC_PLL_TO_SDIO       4
+#define WILC_PLL_TO_SPI                2
 #define ABORT_INT              BIT(31)
 
 /*******************************************/
@@ -216,7 +205,7 @@ struct txq_entry_t {
        struct txq_entry_t *next;
        struct txq_entry_t *prev;
        int type;
-       int index;
+       int tcp_pending_ack_idx;
        u8 *buffer;
        int buffer_size;
        void *priv;
@@ -237,24 +226,25 @@ struct rxq_entry_t {
  ********************************************/
 struct wilc;
 struct wilc_hif_func {
-       int (*hif_init)(struct wilc *, wilc_debug_func);
-       int (*hif_deinit)(void *);
-       int (*hif_read_reg)(u32, u32 *);
-       int (*hif_write_reg)(u32, u32);
-       int (*hif_block_rx)(u32, u8 *, u32);
-       int (*hif_block_tx)(u32, u8 *, u32);
-       int (*hif_sync)(void);
-       int (*hif_clear_int)(void);
-       int (*hif_read_int)(u32 *);
-       int (*hif_clear_int_ext)(u32);
-       int (*hif_read_size)(u32 *);
-       int (*hif_block_tx_ext)(u32, u8 *, u32);
-       int (*hif_block_rx_ext)(u32, u8 *, u32);
-       int (*hif_sync_ext)(int);
-       void (*hif_set_max_bus_speed)(void);
-       void (*hif_set_default_bus_speed)(void);
+       int (*hif_init)(struct wilc *);
+       int (*hif_deinit)(struct wilc *);
+       int (*hif_read_reg)(struct wilc *, u32, u32 *);
+       int (*hif_write_reg)(struct wilc *, u32, u32);
+       int (*hif_block_rx)(struct wilc *, u32, u8 *, u32);
+       int (*hif_block_tx)(struct wilc *, u32, u8 *, u32);
+       int (*hif_read_int)(struct wilc *, u32 *);
+       int (*hif_clear_int_ext)(struct wilc *, u32);
+       int (*hif_read_size)(struct wilc *, u32 *);
+       int (*hif_block_tx_ext)(struct wilc *, u32, u8 *, u32);
+       int (*hif_block_rx_ext)(struct wilc *, u32, u8 *, u32);
+       int (*hif_sync_ext)(struct wilc *, int);
+       int (*enable_interrupt)(struct wilc *nic);
+       void (*disable_interrupt)(struct wilc *nic);
 };
 
+extern const struct wilc_hif_func wilc_hif_spi;
+extern const struct wilc_hif_func wilc_hif_sdio;
+
 /********************************************
  *
  *      Configuration Structure
@@ -276,19 +266,35 @@ struct wilc_cfg_rsp {
        u32 seq_no;
 };
 
-int wilc_wlan_firmware_download(const u8 *buffer, u32 buffer_size);
-int wilc_wlan_start(void);
-int wilc_wlan_stop(void);
+struct wilc;
+
+int wilc_wlan_firmware_download(struct wilc *wilc, const u8 *buffer, u32 buffer_size);
+int wilc_wlan_start(struct wilc *);
+int wilc_wlan_stop(struct wilc *);
 int wilc_wlan_txq_add_net_pkt(struct net_device *dev, void *priv, u8 *buffer,
                              u32 buffer_size, wilc_tx_complete_func_t func);
 int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count);
-void wilc_handle_isr(void *wilc);
+void wilc_handle_isr(struct wilc *wilc);
 void wilc_wlan_cleanup(struct net_device *dev);
-int wilc_wlan_cfg_set(int start, u32 wid, u8 *buffer, u32 buffer_size,
-                     int commit, u32 drv_handler);
-int wilc_wlan_cfg_get(int start, u32 wid, int commit, u32 drv_handler);
+int wilc_wlan_cfg_set(struct wilc *wilc, int start, u32 wid, u8 *buffer,
+                     u32 buffer_size, int commit, u32 drv_handler);
+int wilc_wlan_cfg_get(struct wilc *wilc, int start, u32 wid, int commit,
+                     u32 drv_handler);
 int wilc_wlan_cfg_get_val(u32 wid, u8 *buffer, u32 buffer_size);
 int wilc_wlan_txq_add_mgmt_pkt(struct net_device *dev, void *priv, u8 *buffer,
                               u32 buffer_size, wilc_tx_complete_func_t func);
-void chip_sleep_manually(void);
+void wilc_chip_sleep_manually(struct wilc *wilc);
+
+void wilc_enable_tcp_ack_filter(bool value);
+int wilc_wlan_get_num_conn_ifcs(struct wilc *);
+int wilc_mac_xmit(struct sk_buff *skb, struct net_device *dev);
+
+int wilc_mac_open(struct net_device *ndev);
+int wilc_mac_close(struct net_device *ndev);
+
+int wilc_wlan_set_bssid(struct net_device *wilc_netdev, u8 *pBSSID);
+void WILC_WFI_p2p_rx(struct net_device *dev, u8 *buff, u32 size);
+
+extern bool wilc_enable_ps;
+
 #endif
index e23796392e9c16d051f24d23652a824cfbfb1249..b72c77bb35f117ead4dc81bec28cbc23d6739309 100644 (file)
@@ -275,9 +275,7 @@ static void wilc_wlan_parse_response_frame(u8 *info, int size)
        while (size > 0) {
                i = 0;
                wid = info[0] | (info[1] << 8);
-#ifdef BIG_ENDIAN
-               wid = BYTE_SWAP(wid);
-#endif
+               wid = cpu_to_le32(wid);
                PRINT_INFO(GENERIC_DBG, "Processing response for %d seq %d\n", wid, seq++);
                switch ((wid >> 12) & 0x7) {
                case WID_CHAR:
@@ -300,11 +298,7 @@ static void wilc_wlan_parse_response_frame(u8 *info, int size)
                                        break;
 
                                if (g_cfg_hword[i].id == wid) {
-#ifdef BIG_ENDIAN
-                                       g_cfg_hword[i].val = (info[3] << 8) | (info[4]);
-#else
-                                       g_cfg_hword[i].val = info[3] | (info[4] << 8);
-#endif
+                                       g_cfg_hword[i].val = cpu_to_le16(info[3] | (info[4] << 8));
                                        break;
                                }
                                i++;
@@ -318,11 +312,7 @@ static void wilc_wlan_parse_response_frame(u8 *info, int size)
                                        break;
 
                                if (g_cfg_word[i].id == wid) {
-#ifdef BIG_ENDIAN
-                                       g_cfg_word[i].val = (info[3] << 24) | (info[4] << 16) | (info[5] << 8) | (info[6]);
-#else
-                                       g_cfg_word[i].val = info[3] | (info[4] << 8) | (info[5] << 16) | (info[6] << 24);
-#endif
+                                       g_cfg_word[i].val = cpu_to_le32(info[3] | (info[4] << 8) | (info[5] << 16) | (info[6] << 24));
                                        break;
                                }
                                i++;
@@ -505,7 +495,8 @@ int wilc_wlan_cfg_get_wid_value(u16 wid, u8 *buffer, u32 buffer_size)
        return ret;
 }
 
-int wilc_wlan_cfg_indicate_rx(u8 *frame, int size, struct wilc_cfg_rsp *rsp)
+int wilc_wlan_cfg_indicate_rx(struct wilc *wilc, u8 *frame, int size,
+                             struct wilc_cfg_rsp *rsp)
 {
        int ret = 1;
        u8 msg_type;
@@ -532,17 +523,17 @@ int wilc_wlan_cfg_indicate_rx(u8 *frame, int size, struct wilc_cfg_rsp *rsp)
                rsp->seq_no = msg_id;
                /*call host interface info parse as well*/
                PRINT_INFO(RX_DBG, "Info message received\n");
-               GnrlAsyncInfoReceived(frame - 4, size + 4);
+               wilc_gnrl_async_info_received(wilc, frame - 4, size + 4);
                break;
 
        case 'N':
-               NetworkInfoReceived(frame - 4, size + 4);
+               wilc_network_info_received(wilc, frame - 4, size + 4);
                rsp->type = 0;
                break;
 
        case 'S':
                PRINT_INFO(RX_DBG, "Scan Notification Received\n");
-               host_int_ScanCompleteReceived(frame - 4, size + 4);
+               wilc_scan_complete_received(wilc, frame - 4, size + 4);
                break;
 
        default:
index 443b2d5b6db85b02557159f6fb9290652b9e546b..5f74eb83562fae3f585e476d3dd377bd7413de7d 100644 (file)
@@ -30,10 +30,12 @@ typedef struct {
        u8 *str;
 } wilc_cfg_str_t;
 
+struct wilc;
 int wilc_wlan_cfg_set_wid(u8 *frame, u32 offset, u16 id, u8 *buf, int size);
 int wilc_wlan_cfg_get_wid(u8 *frame, u32 offset, u16 id);
 int wilc_wlan_cfg_get_wid_value(u16 wid, u8 *buffer, u32 buffer_size);
-int wilc_wlan_cfg_indicate_rx(u8 *frame, int size, struct wilc_cfg_rsp *rsp);
+int wilc_wlan_cfg_indicate_rx(struct wilc *wilc, u8 *frame, int size,
+                             struct wilc_cfg_rsp *rsp);
 int wilc_wlan_cfg_init(wilc_debug_func func);
 
 #endif
index 5980ece49daa1cf27abea024a057b8531f6593dc..618903caff542068cfab5ea81fccd7370afc7e85 100644 (file)
@@ -72,10 +72,6 @@ typedef struct {
        u32 block_size;
 } sdio_cmd53_t;
 
-typedef struct {
-       int io_type;
-} wilc_wlan_io_func_t;
-
 #define WILC_MAC_INDICATE_STATUS       0x1
 #define WILC_MAC_STATUS_INIT           -1
 #define WILC_MAC_STATUS_READY          0
@@ -83,10 +79,6 @@ typedef struct {
 
 #define WILC_MAC_INDICATE_SCAN         0x2
 
-typedef struct {
-       wilc_wlan_io_func_t io_func;
-} wilc_wlan_inp_t;
-
 struct tx_complete_data {
        int size;
        void *buff;
@@ -917,10 +909,10 @@ typedef enum {
        WID_MAX                         = 0xFFFF
 } WID_T;
 
-int wilc_wlan_init(struct net_device *dev, wilc_wlan_inp_t *inp);
-
+struct wilc;
+int wilc_wlan_init(struct net_device *dev);
 void wilc_bus_set_max_speed(void);
 void wilc_bus_set_default_speed(void);
-u32 wilc_get_chipid(u8 update);
+u32 wilc_get_chipid(struct wilc *wilc, u8 update);
 
 #endif
index 342a07c58d89400643b26236875d6ffa6a91062e..72204fbf2bb13be5cdb7211ca6001b58f0c4fbc6 100644 (file)
@@ -4074,6 +4074,17 @@ reject:
        return iscsit_add_reject(conn, ISCSI_REASON_BOOKMARK_NO_RESOURCES, buf);
 }
 
+static bool iscsi_target_check_conn_state(struct iscsi_conn *conn)
+{
+       bool ret;
+
+       spin_lock_bh(&conn->state_lock);
+       ret = (conn->conn_state != TARG_CONN_STATE_LOGGED_IN);
+       spin_unlock_bh(&conn->state_lock);
+
+       return ret;
+}
+
 int iscsi_target_rx_thread(void *arg)
 {
        int ret, rc;
@@ -4091,7 +4102,7 @@ int iscsi_target_rx_thread(void *arg)
         * incoming iscsi/tcp socket I/O, and/or failing the connection.
         */
        rc = wait_for_completion_interruptible(&conn->rx_login_comp);
-       if (rc < 0)
+       if (rc < 0 || iscsi_target_check_conn_state(conn))
                return 0;
 
        if (conn->conn_transport->transport_type == ISCSI_INFINIBAND) {
index 5c964c09c89ff25e6076b272d4afff1a0466a372..9fc9117d0f226a9e3f559d73697de025fc30fd72 100644 (file)
@@ -388,6 +388,7 @@ err:
        if (login->login_complete) {
                if (conn->rx_thread && conn->rx_thread_active) {
                        send_sig(SIGINT, conn->rx_thread, 1);
+                       complete(&conn->rx_login_comp);
                        kthread_stop(conn->rx_thread);
                }
                if (conn->tx_thread && conn->tx_thread_active) {
index 51d1734d5390409e2c98a34c4ad9fc787c1fc362..2cbea2af7cd032512572a07275f713aef366475b 100644 (file)
@@ -208,7 +208,7 @@ int iscsi_create_default_params(struct iscsi_param_list **param_list_ptr)
        if (!pl) {
                pr_err("Unable to allocate memory for"
                                " struct iscsi_param_list.\n");
-               return -;
+               return -ENOMEM;
        }
        INIT_LIST_HEAD(&pl->param_list);
        INIT_LIST_HEAD(&pl->extra_response_list);
@@ -578,7 +578,7 @@ int iscsi_copy_param_list(
        param_list = kzalloc(sizeof(struct iscsi_param_list), GFP_KERNEL);
        if (!param_list) {
                pr_err("Unable to allocate memory for struct iscsi_param_list.\n");
-               return -1;
+               return -ENOMEM;
        }
        INIT_LIST_HEAD(&param_list->param_list);
        INIT_LIST_HEAD(&param_list->extra_response_list);
@@ -629,7 +629,7 @@ int iscsi_copy_param_list(
 
 err_out:
        iscsi_release_param_list(param_list);
-       return -1;
+       return -ENOMEM;
 }
 
 static void iscsi_release_extra_responses(struct iscsi_param_list *param_list)
@@ -729,7 +729,7 @@ static int iscsi_add_notunderstood_response(
        if (!extra_response) {
                pr_err("Unable to allocate memory for"
                        " struct iscsi_extra_response.\n");
-               return -1;
+               return -ENOMEM;
        }
        INIT_LIST_HEAD(&extra_response->er_list);
 
@@ -1370,7 +1370,7 @@ int iscsi_decode_text_input(
        tmpbuf = kzalloc(length + 1, GFP_KERNEL);
        if (!tmpbuf) {
                pr_err("Unable to allocate %u + 1 bytes for tmpbuf.\n", length);
-               return -1;
+               return -ENOMEM;
        }
 
        memcpy(tmpbuf, textbuf, length);
index 0b4b2a67d9f9ed597479f1f2c0ea356126f55006..98698d87574262226bcf893da2cb3d3849e6df32 100644 (file)
@@ -371,7 +371,8 @@ sbc_setup_write_same(struct se_cmd *cmd, unsigned char *flags, struct sbc_ops *o
        return 0;
 }
 
-static sense_reason_t xdreadwrite_callback(struct se_cmd *cmd, bool success)
+static sense_reason_t xdreadwrite_callback(struct se_cmd *cmd, bool success,
+                                          int *post_ret)
 {
        unsigned char *buf, *addr;
        struct scatterlist *sg;
@@ -437,7 +438,8 @@ sbc_execute_rw(struct se_cmd *cmd)
                               cmd->data_direction);
 }
 
-static sense_reason_t compare_and_write_post(struct se_cmd *cmd, bool success)
+static sense_reason_t compare_and_write_post(struct se_cmd *cmd, bool success,
+                                            int *post_ret)
 {
        struct se_device *dev = cmd->se_dev;
 
@@ -447,8 +449,10 @@ static sense_reason_t compare_and_write_post(struct se_cmd *cmd, bool success)
         * sent to the backend driver.
         */
        spin_lock_irq(&cmd->t_state_lock);
-       if ((cmd->transport_state & CMD_T_SENT) && !cmd->scsi_status)
+       if ((cmd->transport_state & CMD_T_SENT) && !cmd->scsi_status) {
                cmd->se_cmd_flags |= SCF_COMPARE_AND_WRITE_POST;
+               *post_ret = 1;
+       }
        spin_unlock_irq(&cmd->t_state_lock);
 
        /*
@@ -460,7 +464,8 @@ static sense_reason_t compare_and_write_post(struct se_cmd *cmd, bool success)
        return TCM_NO_SENSE;
 }
 
-static sense_reason_t compare_and_write_callback(struct se_cmd *cmd, bool success)
+static sense_reason_t compare_and_write_callback(struct se_cmd *cmd, bool success,
+                                                int *post_ret)
 {
        struct se_device *dev = cmd->se_dev;
        struct scatterlist *write_sg = NULL, *sg;
@@ -556,11 +561,11 @@ static sense_reason_t compare_and_write_callback(struct se_cmd *cmd, bool succes
 
                if (block_size < PAGE_SIZE) {
                        sg_set_page(&write_sg[i], m.page, block_size,
-                                   block_size);
+                                   m.piter.sg->offset + block_size);
                } else {
                        sg_miter_next(&m);
                        sg_set_page(&write_sg[i], m.page, block_size,
-                                   0);
+                                   m.piter.sg->offset);
                }
                len -= block_size;
                i++;
index 273c72b2b83dc016b2a317b778a8c391eebcb9c8..81a6b3e07687232df9b2bba5d77c1caf01d6c6e8 100644 (file)
@@ -246,7 +246,7 @@ static ssize_t target_stat_lu_prod_show(struct config_item *item, char *page)
        char str[sizeof(dev->t10_wwn.model)+1];
 
        /* scsiLuProductId */
-       for (i = 0; i < sizeof(dev->t10_wwn.vendor); i++)
+       for (i = 0; i < sizeof(dev->t10_wwn.model); i++)
                str[i] = ISPRINT(dev->t10_wwn.model[i]) ?
                        dev->t10_wwn.model[i] : ' ';
        str[i] = '\0';
index 5b2820312310ec21bf83824efa318caab132e046..28fb3016370faf1048bd361c1b98d2c3855483c8 100644 (file)
@@ -130,6 +130,9 @@ void core_tmr_abort_task(
                if (tmr->ref_task_tag != ref_tag)
                        continue;
 
+               if (!kref_get_unless_zero(&se_cmd->cmd_kref))
+                       continue;
+
                printk("ABORT_TASK: Found referenced %s task_tag: %llu\n",
                        se_cmd->se_tfo->get_fabric_name(), ref_tag);
 
@@ -139,13 +142,15 @@ void core_tmr_abort_task(
                               " skipping\n", ref_tag);
                        spin_unlock(&se_cmd->t_state_lock);
                        spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags);
+
+                       target_put_sess_cmd(se_cmd);
+
                        goto out;
                }
                se_cmd->transport_state |= CMD_T_ABORTED;
                spin_unlock(&se_cmd->t_state_lock);
 
                list_del_init(&se_cmd->se_cmd_list);
-               kref_get(&se_cmd->cmd_kref);
                spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags);
 
                cancel_work_sync(&se_cmd->work);
index 5bacc7b5ed6d85cf54d6d8fe445dcac08ee8081b..4fdcee2006d1698f4b4e8689c7976ea161a34685 100644 (file)
@@ -1658,7 +1658,7 @@ bool target_stop_cmd(struct se_cmd *cmd, unsigned long *flags)
 void transport_generic_request_failure(struct se_cmd *cmd,
                sense_reason_t sense_reason)
 {
-       int ret = 0;
+       int ret = 0, post_ret = 0;
 
        pr_debug("-----[ Storage Engine Exception for cmd: %p ITT: 0x%08llx"
                " CDB: 0x%02x\n", cmd, cmd->tag, cmd->t_task_cdb[0]);
@@ -1680,7 +1680,7 @@ void transport_generic_request_failure(struct se_cmd *cmd,
         */
        if ((cmd->se_cmd_flags & SCF_COMPARE_AND_WRITE) &&
             cmd->transport_complete_callback)
-               cmd->transport_complete_callback(cmd, false);
+               cmd->transport_complete_callback(cmd, false, &post_ret);
 
        switch (sense_reason) {
        case TCM_NON_EXISTENT_LUN:
@@ -2068,11 +2068,13 @@ static void target_complete_ok_work(struct work_struct *work)
         */
        if (cmd->transport_complete_callback) {
                sense_reason_t rc;
+               bool caw = (cmd->se_cmd_flags & SCF_COMPARE_AND_WRITE);
+               bool zero_dl = !(cmd->data_length);
+               int post_ret = 0;
 
-               rc = cmd->transport_complete_callback(cmd, true);
-               if (!rc && !(cmd->se_cmd_flags & SCF_COMPARE_AND_WRITE_POST)) {
-                       if ((cmd->se_cmd_flags & SCF_COMPARE_AND_WRITE) &&
-                           !cmd->data_length)
+               rc = cmd->transport_complete_callback(cmd, true, &post_ret);
+               if (!rc && !post_ret) {
+                       if (caw && zero_dl)
                                goto queue_rsp;
 
                        return;
@@ -2507,23 +2509,24 @@ out:
 EXPORT_SYMBOL(target_get_sess_cmd);
 
 static void target_release_cmd_kref(struct kref *kref)
-               __releases(&se_cmd->se_sess->sess_cmd_lock)
 {
        struct se_cmd *se_cmd = container_of(kref, struct se_cmd, cmd_kref);
        struct se_session *se_sess = se_cmd->se_sess;
+       unsigned long flags;
 
+       spin_lock_irqsave(&se_sess->sess_cmd_lock, flags);
        if (list_empty(&se_cmd->se_cmd_list)) {
-               spin_unlock(&se_sess->sess_cmd_lock);
+               spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags);
                se_cmd->se_tfo->release_cmd(se_cmd);
                return;
        }
        if (se_sess->sess_tearing_down && se_cmd->cmd_wait_set) {
-               spin_unlock(&se_sess->sess_cmd_lock);
+               spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags);
                complete(&se_cmd->cmd_wait_comp);
                return;
        }
        list_del(&se_cmd->se_cmd_list);
-       spin_unlock(&se_sess->sess_cmd_lock);
+       spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags);
 
        se_cmd->se_tfo->release_cmd(se_cmd);
 }
@@ -2539,8 +2542,7 @@ int target_put_sess_cmd(struct se_cmd *se_cmd)
                se_cmd->se_tfo->release_cmd(se_cmd);
                return 1;
        }
-       return kref_put_spinlock_irqsave(&se_cmd->cmd_kref, target_release_cmd_kref,
-                       &se_sess->sess_cmd_lock);
+       return kref_put(&se_cmd->cmd_kref, target_release_cmd_kref);
 }
 EXPORT_SYMBOL(target_put_sess_cmd);
 
index 937cebf7663324b53a7fa773f519403a3953b87d..5e6d6cb348fc1c902ea74079357430d5dfb0d44a 100644 (file)
@@ -638,7 +638,7 @@ static int tcmu_check_expired_cmd(int id, void *p, void *data)
        if (test_bit(TCMU_CMD_BIT_EXPIRED, &cmd->flags))
                return 0;
 
-       if (!time_after(cmd->deadline, jiffies))
+       if (!time_after(jiffies, cmd->deadline))
                return 0;
 
        set_bit(TCMU_CMD_BIT_EXPIRED, &cmd->flags);
@@ -1101,8 +1101,6 @@ tcmu_parse_cdb(struct se_cmd *cmd)
 
 static const struct target_backend_ops tcmu_ops = {
        .name                   = "user",
-       .inquiry_prod           = "USER",
-       .inquiry_rev            = TCMU_VERSION,
        .owner                  = THIS_MODULE,
        .transport_flags        = TRANSPORT_FLAG_PASSTHROUGH,
        .attach_hba             = tcmu_attach_hba,
index c463c89b90efd89c9cf1a29b8472b25e41bf6c17..8cc4ac64a91c36347b9307addb88ae99d545d2b7 100644 (file)
@@ -382,7 +382,7 @@ endmenu
 
 config QCOM_SPMI_TEMP_ALARM
        tristate "Qualcomm SPMI PMIC Temperature Alarm"
-       depends on OF && (SPMI || COMPILE_TEST) && IIO
+       depends on OF && SPMI && IIO
        select REGMAP_SPMI
        help
          This enables a thermal sysfs driver for Qualcomm plug-and-play (QPNP)
index c8fe3cac2e0e04d8196694f264b6d9f4fcd5cc5d..c5547bd711dbe2b4d681e54213e25e992afb51af 100644 (file)
@@ -55,6 +55,7 @@
 #define TEMPSENSE2_PANIC_VALUE_SHIFT   16
 #define TEMPSENSE2_PANIC_VALUE_MASK    0xfff0000
 
+#define OCOTP_MEM0                     0x0480
 #define OCOTP_ANA1                     0x04e0
 
 /* The driver supports 1 passive trip point and 1 critical trip point */
@@ -64,12 +65,6 @@ enum imx_thermal_trip {
        IMX_TRIP_NUM,
 };
 
-/*
- * It defines the temperature in millicelsius for passive trip point
- * that will trigger cooling action when crossed.
- */
-#define IMX_TEMP_PASSIVE               85000
-
 #define IMX_POLLING_DELAY              2000 /* millisecond */
 #define IMX_PASSIVE_DELAY              1000
 
@@ -100,12 +95,14 @@ struct imx_thermal_data {
        u32 c1, c2; /* See formula in imx_get_sensor_data() */
        int temp_passive;
        int temp_critical;
+       int temp_max;
        int alarm_temp;
        int last_temp;
        bool irq_enabled;
        int irq;
        struct clk *thermal_clk;
        const struct thermal_soc_data *socdata;
+       const char *temp_grade;
 };
 
 static void imx_set_panic_temp(struct imx_thermal_data *data,
@@ -285,10 +282,12 @@ static int imx_set_trip_temp(struct thermal_zone_device *tz, int trip,
 {
        struct imx_thermal_data *data = tz->devdata;
 
+       /* do not allow changing critical threshold */
        if (trip == IMX_TRIP_CRITICAL)
                return -EPERM;
 
-       if (temp < 0 || temp > IMX_TEMP_PASSIVE)
+       /* do not allow passive to be set higher than critical */
+       if (temp < 0 || temp > data->temp_critical)
                return -EINVAL;
 
        data->temp_passive = temp;
@@ -404,17 +403,39 @@ static int imx_get_sensor_data(struct platform_device *pdev)
        data->c1 = temp64;
        data->c2 = n1 * data->c1 + 1000 * t1;
 
-       /*
-        * Set the default passive cooling trip point,
-        * can be changed from userspace.
-        */
-       data->temp_passive = IMX_TEMP_PASSIVE;
+       /* use OTP for thermal grade */
+       ret = regmap_read(map, OCOTP_MEM0, &val);
+       if (ret) {
+               dev_err(&pdev->dev, "failed to read temp grade: %d\n", ret);
+               return ret;
+       }
+
+       /* The maximum die temp is specified by the Temperature Grade */
+       switch ((val >> 6) & 0x3) {
+       case 0: /* Commercial (0 to 95C) */
+               data->temp_grade = "Commercial";
+               data->temp_max = 95000;
+               break;
+       case 1: /* Extended Commercial (-20 to 105C) */
+               data->temp_grade = "Extended Commercial";
+               data->temp_max = 105000;
+               break;
+       case 2: /* Industrial (-40 to 105C) */
+               data->temp_grade = "Industrial";
+               data->temp_max = 105000;
+               break;
+       case 3: /* Automotive (-40 to 125C) */
+               data->temp_grade = "Automotive";
+               data->temp_max = 125000;
+               break;
+       }
 
        /*
-        * The maximum die temperature set to 20 C higher than
-        * IMX_TEMP_PASSIVE.
+        * Set the critical trip point at 5C under max
+        * Set the passive trip point at 10C under max (can change via sysfs)
         */
-       data->temp_critical = 1000 * 20 + data->temp_passive;
+       data->temp_critical = data->temp_max - (1000 * 5);
+       data->temp_passive = data->temp_max - (1000 * 10);
 
        return 0;
 }
@@ -551,6 +572,11 @@ static int imx_thermal_probe(struct platform_device *pdev)
                return ret;
        }
 
+       dev_info(&pdev->dev, "%s CPU temperature grade - max:%dC"
+                " critical:%dC passive:%dC\n", data->temp_grade,
+                data->temp_max / 1000, data->temp_critical / 1000,
+                data->temp_passive / 1000);
+
        /* Enable measurements at ~ 10 Hz */
        regmap_write(map, TEMPSENSE1 + REG_CLR, TEMPSENSE1_MEASURE_FREQ);
        measure_freq = DIV_ROUND_UP(32768, 10); /* 10 Hz */
index 42b7d4253b9446511150c6b599ac548f82e04f1a..be4eedcb839ac22158fe180c2abc37df712d9511 100644 (file)
@@ -964,7 +964,7 @@ void of_thermal_destroy_zones(void)
 
        np = of_find_node_by_name(NULL, "thermal-zones");
        if (!np) {
-               pr_err("unable to find thermal zones\n");
+               pr_debug("unable to find thermal zones\n");
                return;
        }
 
index f0fbea386869a66d9ab60fdcc7f74d7e0179b095..1246aa6fcab0caeda03ace6806c4df2d46c1f164 100644 (file)
@@ -174,7 +174,6 @@ static void estimate_pid_constants(struct thermal_zone_device *tz,
 /**
  * pid_controller() - PID controller
  * @tz:        thermal zone we are operating in
- * @current_temp:      the current temperature in millicelsius
  * @control_temp:      the target temperature in millicelsius
  * @max_allocatable_power:     maximum allocatable power for this thermal zone
  *
@@ -191,7 +190,6 @@ static void estimate_pid_constants(struct thermal_zone_device *tz,
  * Return: The power budget for the next period.
  */
 static u32 pid_controller(struct thermal_zone_device *tz,
-                         int current_temp,
                          int control_temp,
                          u32 max_allocatable_power)
 {
@@ -211,7 +209,7 @@ static u32 pid_controller(struct thermal_zone_device *tz,
                                       true);
        }
 
-       err = control_temp - current_temp;
+       err = control_temp - tz->temperature;
        err = int_to_frac(err);
 
        /* Calculate the proportional term */
@@ -332,7 +330,6 @@ static void divvy_up_power(u32 *req_power, u32 *max_power, int num_actors,
 }
 
 static int allocate_power(struct thermal_zone_device *tz,
-                         int current_temp,
                          int control_temp)
 {
        struct thermal_instance *instance;
@@ -418,8 +415,7 @@ static int allocate_power(struct thermal_zone_device *tz,
                i++;
        }
 
-       power_range = pid_controller(tz, current_temp, control_temp,
-                                    max_allocatable_power);
+       power_range = pid_controller(tz, control_temp, max_allocatable_power);
 
        divvy_up_power(weighted_req_power, max_power, num_actors,
                       total_weighted_req_power, power_range, granted_power,
@@ -444,8 +440,8 @@ static int allocate_power(struct thermal_zone_device *tz,
        trace_thermal_power_allocator(tz, req_power, total_req_power,
                                      granted_power, total_granted_power,
                                      num_actors, power_range,
-                                     max_allocatable_power, current_temp,
-                                     control_temp - current_temp);
+                                     max_allocatable_power, tz->temperature,
+                                     control_temp - tz->temperature);
 
        kfree(req_power);
 unlock:
@@ -612,7 +608,7 @@ static void power_allocator_unbind(struct thermal_zone_device *tz)
 static int power_allocator_throttle(struct thermal_zone_device *tz, int trip)
 {
        int ret;
-       int switch_on_temp, control_temp, current_temp;
+       int switch_on_temp, control_temp;
        struct power_allocator_params *params = tz->governor_data;
 
        /*
@@ -622,15 +618,9 @@ static int power_allocator_throttle(struct thermal_zone_device *tz, int trip)
        if (trip != params->trip_max_desired_temperature)
                return 0;
 
-       ret = thermal_zone_get_temp(tz, &current_temp);
-       if (ret) {
-               dev_warn(&tz->device, "Failed to get temperature: %d\n", ret);
-               return ret;
-       }
-
        ret = tz->ops->get_trip_temp(tz, params->trip_switch_on,
                                     &switch_on_temp);
-       if (!ret && (current_temp < switch_on_temp)) {
+       if (!ret && (tz->temperature < switch_on_temp)) {
                tz->passive = 0;
                reset_pid_controller(params);
                allow_maximum_power(tz);
@@ -648,7 +638,7 @@ static int power_allocator_throttle(struct thermal_zone_device *tz, int trip)
                return ret;
        }
 
-       return allocate_power(tz, current_temp, control_temp);
+       return allocate_power(tz, control_temp);
 }
 
 static struct thermal_governor thermal_gov_power_allocator = {
index 5d4ae7d705e0024528c8d52d56134bd92e280ea1..13d01edc7a043812611719bf7a342260f09ababa 100644 (file)
@@ -361,6 +361,24 @@ static irqreturn_t rcar_thermal_irq(int irq, void *data)
 /*
  *             platform functions
  */
+static int rcar_thermal_remove(struct platform_device *pdev)
+{
+       struct rcar_thermal_common *common = platform_get_drvdata(pdev);
+       struct device *dev = &pdev->dev;
+       struct rcar_thermal_priv *priv;
+
+       rcar_thermal_for_each_priv(priv, common) {
+               if (rcar_has_irq_support(priv))
+                       rcar_thermal_irq_disable(priv);
+               thermal_zone_device_unregister(priv->zone);
+       }
+
+       pm_runtime_put(dev);
+       pm_runtime_disable(dev);
+
+       return 0;
+}
+
 static int rcar_thermal_probe(struct platform_device *pdev)
 {
        struct rcar_thermal_common *common;
@@ -377,6 +395,8 @@ static int rcar_thermal_probe(struct platform_device *pdev)
        if (!common)
                return -ENOMEM;
 
+       platform_set_drvdata(pdev, common);
+
        INIT_LIST_HEAD(&common->head);
        spin_lock_init(&common->lock);
        common->dev = dev;
@@ -454,43 +474,16 @@ static int rcar_thermal_probe(struct platform_device *pdev)
                rcar_thermal_common_write(common, ENR, enr_bits);
        }
 
-       platform_set_drvdata(pdev, common);
-
        dev_info(dev, "%d sensor probed\n", i);
 
        return 0;
 
 error_unregister:
-       rcar_thermal_for_each_priv(priv, common) {
-               if (rcar_has_irq_support(priv))
-                       rcar_thermal_irq_disable(priv);
-               thermal_zone_device_unregister(priv->zone);
-       }
-
-       pm_runtime_put(dev);
-       pm_runtime_disable(dev);
+       rcar_thermal_remove(pdev);
 
        return ret;
 }
 
-static int rcar_thermal_remove(struct platform_device *pdev)
-{
-       struct rcar_thermal_common *common = platform_get_drvdata(pdev);
-       struct device *dev = &pdev->dev;
-       struct rcar_thermal_priv *priv;
-
-       rcar_thermal_for_each_priv(priv, common) {
-               if (rcar_has_irq_support(priv))
-                       rcar_thermal_irq_disable(priv);
-               thermal_zone_device_unregister(priv->zone);
-       }
-
-       pm_runtime_put(dev);
-       pm_runtime_disable(dev);
-
-       return 0;
-}
-
 static const struct of_device_id rcar_thermal_dt_ids[] = {
        { .compatible = "renesas,rcar-thermal", },
        {},
index 9787e8aa509fc406ab4fe5c8ff46811bac19b2de..e845841ab036cc82033d0a6829058a0f15f2543e 100644 (file)
@@ -1,6 +1,9 @@
 /*
  * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd
  *
+ * Copyright (c) 2015, Fuzhou Rockchip Electronics Co., Ltd
+ * Caesar Wang <wxt@rock-chips.com>
+ *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
  * version 2, as published by the Free Software Foundation.
@@ -45,17 +48,50 @@ enum tshut_polarity {
 };
 
 /**
- * The system has three Temperature Sensors.  channel 0 is reserved,
- * channel 1 is for CPU, and channel 2 is for GPU.
+ * The system has two Temperature Sensors.
+ * sensor0 is for CPU, and sensor1 is for GPU.
  */
 enum sensor_id {
-       SENSOR_CPU = 1,
+       SENSOR_CPU = 0,
        SENSOR_GPU,
 };
 
+/**
+* The conversion table has the adc value and temperature.
+* ADC_DECREMENT is the adc value decremnet.(e.g. v2_code_table)
+* ADC_INCREMNET is the adc value incremnet.(e.g. v3_code_table)
+*/
+enum adc_sort_mode {
+       ADC_DECREMENT = 0,
+       ADC_INCREMENT,
+};
+
+/**
+ * The max sensors is two in rockchip SoCs.
+ * Two sensors: CPU and GPU sensor.
+ */
+#define SOC_MAX_SENSORS        2
+
+struct chip_tsadc_table {
+       const struct tsadc_table *id;
+
+       /* the array table size*/
+       unsigned int length;
+
+       /* that analogic mask data */
+       u32 data_mask;
+
+       /* the sort mode is adc value that increment or decrement in table */
+       enum adc_sort_mode mode;
+};
+
 struct rockchip_tsadc_chip {
+       /* The sensor id of chip correspond to the ADC channel */
+       int chn_id[SOC_MAX_SENSORS];
+       int chn_num;
+
        /* The hardware-controlled tshut property */
-       long tshut_temp;
+       int tshut_temp;
        enum tshut_mode tshut_mode;
        enum tshut_polarity tshut_polarity;
 
@@ -65,37 +101,40 @@ struct rockchip_tsadc_chip {
        void (*control)(void __iomem *reg, bool on);
 
        /* Per-sensor methods */
-       int (*get_temp)(int chn, void __iomem *reg, int *temp);
-       void (*set_tshut_temp)(int chn, void __iomem *reg, long temp);
+       int (*get_temp)(struct chip_tsadc_table table,
+                       int chn, void __iomem *reg, int *temp);
+       void (*set_tshut_temp)(struct chip_tsadc_table table,
+                              int chn, void __iomem *reg, int temp);
        void (*set_tshut_mode)(int chn, void __iomem *reg, enum tshut_mode m);
+
+       /* Per-table methods */
+       struct chip_tsadc_table table;
 };
 
 struct rockchip_thermal_sensor {
        struct rockchip_thermal_data *thermal;
        struct thermal_zone_device *tzd;
-       enum sensor_id id;
+       int id;
 };
 
-#define NUM_SENSORS    2 /* Ignore unused sensor 0 */
-
 struct rockchip_thermal_data {
        const struct rockchip_tsadc_chip *chip;
        struct platform_device *pdev;
        struct reset_control *reset;
 
-       struct rockchip_thermal_sensor sensors[NUM_SENSORS];
+       struct rockchip_thermal_sensor sensors[SOC_MAX_SENSORS];
 
        struct clk *clk;
        struct clk *pclk;
 
        void __iomem *regs;
 
-       long tshut_temp;
+       int tshut_temp;
        enum tshut_mode tshut_mode;
        enum tshut_polarity tshut_polarity;
 };
 
-/* TSADC V2 Sensor info define: */
+/* TSADC Sensor info define: */
 #define TSADCV2_AUTO_CON                       0x04
 #define TSADCV2_INT_EN                         0x08
 #define TSADCV2_INT_PD                         0x0c
@@ -117,6 +156,8 @@ struct rockchip_thermal_data {
 #define TSADCV2_INT_PD_CLEAR_MASK              ~BIT(8)
 
 #define TSADCV2_DATA_MASK                      0xfff
+#define TSADCV3_DATA_MASK                      0x3ff
+
 #define TSADCV2_HIGHT_INT_DEBOUNCE_COUNT       4
 #define TSADCV2_HIGHT_TSHUT_DEBOUNCE_COUNT     4
 #define TSADCV2_AUTO_PERIOD_TIME               250 /* msec */
@@ -124,7 +165,7 @@ struct rockchip_thermal_data {
 
 struct tsadc_table {
        u32 code;
-       long temp;
+       int temp;
 };
 
 static const struct tsadc_table v2_code_table[] = {
@@ -165,21 +206,61 @@ static const struct tsadc_table v2_code_table[] = {
        {3421, 125000},
 };
 
-static u32 rk_tsadcv2_temp_to_code(long temp)
+static const struct tsadc_table v3_code_table[] = {
+       {0, -40000},
+       {106, -40000},
+       {108, -35000},
+       {110, -30000},
+       {112, -25000},
+       {114, -20000},
+       {116, -15000},
+       {118, -10000},
+       {120, -5000},
+       {122, 0},
+       {124, 5000},
+       {126, 10000},
+       {128, 15000},
+       {130, 20000},
+       {132, 25000},
+       {134, 30000},
+       {136, 35000},
+       {138, 40000},
+       {140, 45000},
+       {142, 50000},
+       {144, 55000},
+       {146, 60000},
+       {148, 65000},
+       {150, 70000},
+       {152, 75000},
+       {154, 80000},
+       {156, 85000},
+       {158, 90000},
+       {160, 95000},
+       {162, 100000},
+       {163, 105000},
+       {165, 110000},
+       {167, 115000},
+       {169, 120000},
+       {171, 125000},
+       {TSADCV3_DATA_MASK, 125000},
+};
+
+static u32 rk_tsadcv2_temp_to_code(struct chip_tsadc_table table,
+                                  int temp)
 {
        int high, low, mid;
 
        low = 0;
-       high = ARRAY_SIZE(v2_code_table) - 1;
+       high = table.length - 1;
        mid = (high + low) / 2;
 
-       if (temp < v2_code_table[low].temp || temp > v2_code_table[high].temp)
+       if (temp < table.id[low].temp || temp > table.id[high].temp)
                return 0;
 
        while (low <= high) {
-               if (temp == v2_code_table[mid].temp)
-                       return v2_code_table[mid].code;
-               else if (temp < v2_code_table[mid].temp)
+               if (temp == table.id[mid].temp)
+                       return table.id[mid].code;
+               else if (temp < table.id[mid].temp)
                        high = mid - 1;
                else
                        low = mid + 1;
@@ -189,29 +270,54 @@ static u32 rk_tsadcv2_temp_to_code(long temp)
        return 0;
 }
 
-static int rk_tsadcv2_code_to_temp(u32 code, int *temp)
+static int rk_tsadcv2_code_to_temp(struct chip_tsadc_table table, u32 code,
+                                  int *temp)
 {
        unsigned int low = 1;
-       unsigned int high = ARRAY_SIZE(v2_code_table) - 1;
+       unsigned int high = table.length - 1;
        unsigned int mid = (low + high) / 2;
        unsigned int num;
        unsigned long denom;
 
-       BUILD_BUG_ON(ARRAY_SIZE(v2_code_table) < 2);
-
-       code &= TSADCV2_DATA_MASK;
-       if (code < v2_code_table[high].code)
-               return -EAGAIN;         /* Incorrect reading */
-
-       while (low <= high) {
-               if (code >= v2_code_table[mid].code &&
-                   code < v2_code_table[mid - 1].code)
-                       break;
-               else if (code < v2_code_table[mid].code)
-                       low = mid + 1;
-               else
-                       high = mid - 1;
-               mid = (low + high) / 2;
+       WARN_ON(table.length < 2);
+
+       switch (table.mode) {
+       case ADC_DECREMENT:
+               code &= table.data_mask;
+               if (code < table.id[high].code)
+                       return -EAGAIN;         /* Incorrect reading */
+
+               while (low <= high) {
+                       if (code >= table.id[mid].code &&
+                           code < table.id[mid - 1].code)
+                               break;
+                       else if (code < table.id[mid].code)
+                               low = mid + 1;
+                       else
+                               high = mid - 1;
+
+                       mid = (low + high) / 2;
+               }
+               break;
+       case ADC_INCREMENT:
+               code &= table.data_mask;
+               if (code < table.id[low].code)
+                       return -EAGAIN;         /* Incorrect reading */
+
+               while (low <= high) {
+                       if (code >= table.id[mid - 1].code &&
+                           code < table.id[mid].code)
+                               break;
+                       else if (code > table.id[mid].code)
+                               low = mid + 1;
+                       else
+                               high = mid - 1;
+
+                       mid = (low + high) / 2;
+               }
+               break;
+       default:
+               pr_err("Invalid the conversion table\n");
        }
 
        /*
@@ -220,24 +326,28 @@ static int rk_tsadcv2_code_to_temp(u32 code, int *temp)
         * temperature between 2 table entries is linear and interpolate
         * to produce less granular result.
         */
-       num = v2_code_table[mid].temp - v2_code_table[mid - 1].temp;
-       num *= v2_code_table[mid - 1].code - code;
-       denom = v2_code_table[mid - 1].code - v2_code_table[mid].code;
-       *temp = v2_code_table[mid - 1].temp + (num / denom);
+       num = table.id[mid].temp - v2_code_table[mid - 1].temp;
+       num *= abs(table.id[mid - 1].code - code);
+       denom = abs(table.id[mid - 1].code - table.id[mid].code);
+       *temp = table.id[mid - 1].temp + (num / denom);
 
        return 0;
 }
 
 /**
- * rk_tsadcv2_initialize - initialize TASDC Controller
- * (1) Set TSADCV2_AUTO_PERIOD, configure the interleave between
- * every two accessing of TSADC in normal operation.
- * (2) Set TSADCV2_AUTO_PERIOD_HT, configure the interleave between
- * every two accessing of TSADC after the temperature is higher
- * than COM_SHUT or COM_INT.
- * (3) Set TSADCV2_HIGH_INT_DEBOUNCE and TSADC_HIGHT_TSHUT_DEBOUNCE,
- * if the temperature is higher than COMP_INT or COMP_SHUT for
- * "debounce" times, TSADC controller will generate interrupt or TSHUT.
+ * rk_tsadcv2_initialize - initialize TASDC Controller.
+ *
+ * (1) Set TSADC_V2_AUTO_PERIOD:
+ *     Configure the interleave between every two accessing of
+ *     TSADC in normal operation.
+ *
+ * (2) Set TSADCV2_AUTO_PERIOD_HT:
+ *     Configure the interleave between every two accessing of
+ *     TSADC after the temperature is higher than COM_SHUT or COM_INT.
+ *
+ * (3) Set TSADCV2_HIGH_INT_DEBOUNCE and TSADC_HIGHT_TSHUT_DEBOUNCE:
+ *     If the temperature is higher than COMP_INT or COMP_SHUT for
+ *     "debounce" times, TSADC controller will generate interrupt or TSHUT.
  */
 static void rk_tsadcv2_initialize(void __iomem *regs,
                                  enum tshut_polarity tshut_polarity)
@@ -279,20 +389,22 @@ static void rk_tsadcv2_control(void __iomem *regs, bool enable)
        writel_relaxed(val, regs + TSADCV2_AUTO_CON);
 }
 
-static int rk_tsadcv2_get_temp(int chn, void __iomem *regs, int *temp)
+static int rk_tsadcv2_get_temp(struct chip_tsadc_table table,
+                              int chn, void __iomem *regs, int *temp)
 {
        u32 val;
 
        val = readl_relaxed(regs + TSADCV2_DATA(chn));
 
-       return rk_tsadcv2_code_to_temp(val, temp);
+       return rk_tsadcv2_code_to_temp(table, val, temp);
 }
 
-static void rk_tsadcv2_tshut_temp(int chn, void __iomem *regs, long temp)
+static void rk_tsadcv2_tshut_temp(struct chip_tsadc_table table,
+                                 int chn, void __iomem *regs, int temp)
 {
        u32 tshut_value, val;
 
-       tshut_value = rk_tsadcv2_temp_to_code(temp);
+       tshut_value = rk_tsadcv2_temp_to_code(table, temp);
        writel_relaxed(tshut_value, regs + TSADCV2_COMP_SHUT(chn));
 
        /* TSHUT will be valid */
@@ -318,6 +430,10 @@ static void rk_tsadcv2_tshut_mode(int chn, void __iomem *regs,
 }
 
 static const struct rockchip_tsadc_chip rk3288_tsadc_data = {
+       .chn_id[SENSOR_CPU] = 1, /* cpu sensor is channel 1 */
+       .chn_id[SENSOR_GPU] = 2, /* gpu sensor is channel 2 */
+       .chn_num = 2, /* two channels for tsadc */
+
        .tshut_mode = TSHUT_MODE_GPIO, /* default TSHUT via GPIO give PMIC */
        .tshut_polarity = TSHUT_LOW_ACTIVE, /* default TSHUT LOW ACTIVE */
        .tshut_temp = 95000,
@@ -328,6 +444,37 @@ static const struct rockchip_tsadc_chip rk3288_tsadc_data = {
        .get_temp = rk_tsadcv2_get_temp,
        .set_tshut_temp = rk_tsadcv2_tshut_temp,
        .set_tshut_mode = rk_tsadcv2_tshut_mode,
+
+       .table = {
+               .id = v2_code_table,
+               .length = ARRAY_SIZE(v2_code_table),
+               .data_mask = TSADCV2_DATA_MASK,
+               .mode = ADC_DECREMENT,
+       },
+};
+
+static const struct rockchip_tsadc_chip rk3368_tsadc_data = {
+       .chn_id[SENSOR_CPU] = 0, /* cpu sensor is channel 0 */
+       .chn_id[SENSOR_GPU] = 1, /* gpu sensor is channel 1 */
+       .chn_num = 2, /* two channels for tsadc */
+
+       .tshut_mode = TSHUT_MODE_GPIO, /* default TSHUT via GPIO give PMIC */
+       .tshut_polarity = TSHUT_LOW_ACTIVE, /* default TSHUT LOW ACTIVE */
+       .tshut_temp = 95000,
+
+       .initialize = rk_tsadcv2_initialize,
+       .irq_ack = rk_tsadcv2_irq_ack,
+       .control = rk_tsadcv2_control,
+       .get_temp = rk_tsadcv2_get_temp,
+       .set_tshut_temp = rk_tsadcv2_tshut_temp,
+       .set_tshut_mode = rk_tsadcv2_tshut_mode,
+
+       .table = {
+               .id = v3_code_table,
+               .length = ARRAY_SIZE(v3_code_table),
+               .data_mask = TSADCV3_DATA_MASK,
+               .mode = ADC_INCREMENT,
+       },
 };
 
 static const struct of_device_id of_rockchip_thermal_match[] = {
@@ -335,6 +482,10 @@ static const struct of_device_id of_rockchip_thermal_match[] = {
                .compatible = "rockchip,rk3288-tsadc",
                .data = (void *)&rk3288_tsadc_data,
        },
+       {
+               .compatible = "rockchip,rk3368-tsadc",
+               .data = (void *)&rk3368_tsadc_data,
+       },
        { /* end */ },
 };
 MODULE_DEVICE_TABLE(of, of_rockchip_thermal_match);
@@ -357,7 +508,7 @@ static irqreturn_t rockchip_thermal_alarm_irq_thread(int irq, void *dev)
 
        thermal->chip->irq_ack(thermal->regs);
 
-       for (i = 0; i < ARRAY_SIZE(thermal->sensors); i++)
+       for (i = 0; i < thermal->chip->chn_num; i++)
                thermal_zone_device_update(thermal->sensors[i].tzd);
 
        return IRQ_HANDLED;
@@ -370,7 +521,8 @@ static int rockchip_thermal_get_temp(void *_sensor, int *out_temp)
        const struct rockchip_tsadc_chip *tsadc = sensor->thermal->chip;
        int retval;
 
-       retval = tsadc->get_temp(sensor->id, thermal->regs, out_temp);
+       retval = tsadc->get_temp(tsadc->table,
+                                sensor->id, thermal->regs, out_temp);
        dev_dbg(&thermal->pdev->dev, "sensor %d - temp: %d, retval: %d\n",
                sensor->id, *out_temp, retval);
 
@@ -389,7 +541,7 @@ static int rockchip_configure_from_dt(struct device *dev,
 
        if (of_property_read_u32(np, "rockchip,hw-tshut-temp", &shut_temp)) {
                dev_warn(dev,
-                        "Missing tshut temp property, using default %ld\n",
+                        "Missing tshut temp property, using default %d\n",
                         thermal->chip->tshut_temp);
                thermal->tshut_temp = thermal->chip->tshut_temp;
        } else {
@@ -397,7 +549,7 @@ static int rockchip_configure_from_dt(struct device *dev,
        }
 
        if (thermal->tshut_temp > INT_MAX) {
-               dev_err(dev, "Invalid tshut temperature specified: %ld\n",
+               dev_err(dev, "Invalid tshut temperature specified: %d\n",
                        thermal->tshut_temp);
                return -ERANGE;
        }
@@ -442,13 +594,14 @@ static int
 rockchip_thermal_register_sensor(struct platform_device *pdev,
                                 struct rockchip_thermal_data *thermal,
                                 struct rockchip_thermal_sensor *sensor,
-                                enum sensor_id id)
+                                int id)
 {
        const struct rockchip_tsadc_chip *tsadc = thermal->chip;
        int error;
 
        tsadc->set_tshut_mode(id, thermal->regs, thermal->tshut_mode);
-       tsadc->set_tshut_temp(id, thermal->regs, thermal->tshut_temp);
+       tsadc->set_tshut_temp(tsadc->table, id, thermal->regs,
+                             thermal->tshut_temp);
 
        sensor->thermal = thermal;
        sensor->id = id;
@@ -481,7 +634,7 @@ static int rockchip_thermal_probe(struct platform_device *pdev)
        const struct of_device_id *match;
        struct resource *res;
        int irq;
-       int i;
+       int i, j;
        int error;
 
        match = of_match_node(of_rockchip_thermal_match, np);
@@ -556,22 +709,19 @@ static int rockchip_thermal_probe(struct platform_device *pdev)
 
        thermal->chip->initialize(thermal->regs, thermal->tshut_polarity);
 
-       error = rockchip_thermal_register_sensor(pdev, thermal,
-                                                &thermal->sensors[0],
-                                                SENSOR_CPU);
-       if (error) {
-               dev_err(&pdev->dev,
-                       "failed to register CPU thermal sensor: %d\n", error);
-               goto err_disable_pclk;
-       }
-
-       error = rockchip_thermal_register_sensor(pdev, thermal,
-                                                &thermal->sensors[1],
-                                                SENSOR_GPU);
-       if (error) {
-               dev_err(&pdev->dev,
-                       "failed to register GPU thermal sensor: %d\n", error);
-               goto err_unregister_cpu_sensor;
+       for (i = 0; i < thermal->chip->chn_num; i++) {
+               error = rockchip_thermal_register_sensor(pdev, thermal,
+                                               &thermal->sensors[i],
+                                               thermal->chip->chn_id[i]);
+               if (error) {
+                       dev_err(&pdev->dev,
+                               "failed to register sensor[%d] : error = %d\n",
+                               i, error);
+                       for (j = 0; j < i; j++)
+                               thermal_zone_of_sensor_unregister(&pdev->dev,
+                                               thermal->sensors[j].tzd);
+                       goto err_disable_pclk;
+               }
        }
 
        error = devm_request_threaded_irq(&pdev->dev, irq, NULL,
@@ -581,22 +731,23 @@ static int rockchip_thermal_probe(struct platform_device *pdev)
        if (error) {
                dev_err(&pdev->dev,
                        "failed to request tsadc irq: %d\n", error);
-               goto err_unregister_gpu_sensor;
+               goto err_unregister_sensor;
        }
 
        thermal->chip->control(thermal->regs, true);
 
-       for (i = 0; i < ARRAY_SIZE(thermal->sensors); i++)
+       for (i = 0; i < thermal->chip->chn_num; i++)
                rockchip_thermal_toggle_sensor(&thermal->sensors[i], true);
 
        platform_set_drvdata(pdev, thermal);
 
        return 0;
 
-err_unregister_gpu_sensor:
-       thermal_zone_of_sensor_unregister(&pdev->dev, thermal->sensors[1].tzd);
-err_unregister_cpu_sensor:
-       thermal_zone_of_sensor_unregister(&pdev->dev, thermal->sensors[0].tzd);
+err_unregister_sensor:
+       while (i--)
+               thermal_zone_of_sensor_unregister(&pdev->dev,
+                                                 thermal->sensors[i].tzd);
+
 err_disable_pclk:
        clk_disable_unprepare(thermal->pclk);
 err_disable_clk:
@@ -610,7 +761,7 @@ static int rockchip_thermal_remove(struct platform_device *pdev)
        struct rockchip_thermal_data *thermal = platform_get_drvdata(pdev);
        int i;
 
-       for (i = 0; i < ARRAY_SIZE(thermal->sensors); i++) {
+       for (i = 0; i < thermal->chip->chn_num; i++) {
                struct rockchip_thermal_sensor *sensor = &thermal->sensors[i];
 
                rockchip_thermal_toggle_sensor(sensor, false);
@@ -631,7 +782,7 @@ static int __maybe_unused rockchip_thermal_suspend(struct device *dev)
        struct rockchip_thermal_data *thermal = platform_get_drvdata(pdev);
        int i;
 
-       for (i = 0; i < ARRAY_SIZE(thermal->sensors); i++)
+       for (i = 0; i < thermal->chip->chn_num; i++)
                rockchip_thermal_toggle_sensor(&thermal->sensors[i], false);
 
        thermal->chip->control(thermal->regs, false);
@@ -663,18 +814,19 @@ static int __maybe_unused rockchip_thermal_resume(struct device *dev)
 
        thermal->chip->initialize(thermal->regs, thermal->tshut_polarity);
 
-       for (i = 0; i < ARRAY_SIZE(thermal->sensors); i++) {
-               enum sensor_id id = thermal->sensors[i].id;
+       for (i = 0; i < thermal->chip->chn_num; i++) {
+               int id = thermal->sensors[i].id;
 
                thermal->chip->set_tshut_mode(id, thermal->regs,
                                              thermal->tshut_mode);
-               thermal->chip->set_tshut_temp(id, thermal->regs,
+               thermal->chip->set_tshut_temp(thermal->chip->table,
+                                             id, thermal->regs,
                                              thermal->tshut_temp);
        }
 
        thermal->chip->control(thermal->regs, true);
 
-       for (i = 0; i < ARRAY_SIZE(thermal->sensors); i++)
+       for (i = 0; i < thermal->chip->chn_num; i++)
                rockchip_thermal_toggle_sensor(&thermal->sensors[i], true);
 
        pinctrl_pm_select_default_state(dev);
index b30e7423549b04b0e7d442a128048b4221c68062..26ca4f910cb020aae539f29b260a98fe1eee92b0 100644 (file)
@@ -1838,6 +1838,11 @@ static const struct usb_device_id acm_ids[] = {
        },
 #endif
 
+       /* Exclude Infineon Flash Loader utility */
+       { USB_DEVICE(0x058b, 0x0041),
+       .driver_info = IGNORE_DEVICE,
+       },
+
        /* control interfaces without any protocol set */
        { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM,
                USB_CDC_PROTO_NONE) },
index 7caff020106e23f26f9c3bb9c34585885064848d..5050760f5e17cf3872952ae5fa6a40d01aab394b 100644 (file)
@@ -115,7 +115,8 @@ static void usb_parse_ss_endpoint_companion(struct device *ddev, int cfgno,
                   USB_SS_MULT(desc->bmAttributes) > 3) {
                dev_warn(ddev, "Isoc endpoint has Mult of %d in "
                                "config %d interface %d altsetting %d ep %d: "
-                               "setting to 3\n", desc->bmAttributes + 1,
+                               "setting to 3\n",
+                               USB_SS_MULT(desc->bmAttributes),
                                cfgno, inum, asnum, ep->desc.bEndpointAddress);
                ep->ss_ep_comp.bmAttributes = 2;
        }
index bdeadc112d29f9b4545bf3ab82645b52982f5cfd..a5cc032ef77a8da22b86d9b29e4090e897d0bcc1 100644 (file)
@@ -124,6 +124,10 @@ struct usb_hub *usb_hub_to_struct_hub(struct usb_device *hdev)
 
 int usb_device_supports_lpm(struct usb_device *udev)
 {
+       /* Some devices have trouble with LPM */
+       if (udev->quirks & USB_QUIRK_NO_LPM)
+               return 0;
+
        /* USB 2.1 (and greater) devices indicate LPM support through
         * their USB 2.0 Extended Capabilities BOS descriptor.
         */
@@ -4512,6 +4516,8 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1,
                goto fail;
        }
 
+       usb_detect_quirks(udev);
+
        if (udev->wusb == 0 && le16_to_cpu(udev->descriptor.bcdUSB) >= 0x0201) {
                retval = usb_get_bos_descriptor(udev);
                if (!retval) {
@@ -4710,7 +4716,6 @@ static void hub_port_connect(struct usb_hub *hub, int port1, u16 portstatus,
                if (status < 0)
                        goto loop;
 
-               usb_detect_quirks(udev);
                if (udev->quirks & USB_QUIRK_DELAY_INIT)
                        msleep(1000);
 
@@ -5326,9 +5331,6 @@ static int usb_reset_and_verify_device(struct usb_device *udev)
        if (udev->usb2_hw_lpm_enabled == 1)
                usb_set_usb2_hardware_lpm(udev, 0);
 
-       bos = udev->bos;
-       udev->bos = NULL;
-
        /* Disable LPM and LTM while we reset the device and reinstall the alt
         * settings.  Device-initiated LPM settings, and system exit latency
         * settings are cleared when the device is reset, so we have to set
@@ -5337,15 +5339,18 @@ static int usb_reset_and_verify_device(struct usb_device *udev)
        ret = usb_unlocked_disable_lpm(udev);
        if (ret) {
                dev_err(&udev->dev, "%s Failed to disable LPM\n.", __func__);
-               goto re_enumerate;
+               goto re_enumerate_no_bos;
        }
        ret = usb_disable_ltm(udev);
        if (ret) {
                dev_err(&udev->dev, "%s Failed to disable LTM\n.",
                                __func__);
-               goto re_enumerate;
+               goto re_enumerate_no_bos;
        }
 
+       bos = udev->bos;
+       udev->bos = NULL;
+
        for (i = 0; i < SET_CONFIG_TRIES; ++i) {
 
                /* ep0 maxpacket size may change; let the HCD know about it.
@@ -5442,10 +5447,11 @@ done:
        return 0;
 
 re_enumerate:
-       /* LPM state doesn't matter when we're about to destroy the device. */
-       hub_port_logical_disconnect(parent_hub, port1);
        usb_release_bos_descriptor(udev);
        udev->bos = bos;
+re_enumerate_no_bos:
+       /* LPM state doesn't matter when we're about to destroy the device. */
+       hub_port_logical_disconnect(parent_hub, port1);
        return -ENODEV;
 }
 
index 210618319f10a4110bc53191fc8a06a860992c3a..5487fe308f01b7be30bcecebc12726a295f9daa9 100644 (file)
@@ -206,7 +206,7 @@ static int link_peers(struct usb_port *left, struct usb_port *right)
                else
                        method = "default";
 
-               pr_warn("usb: failed to peer %s and %s by %s (%s:%s) (%s:%s)\n",
+               pr_debug("usb: failed to peer %s and %s by %s (%s:%s) (%s:%s)\n",
                        dev_name(&left->dev), dev_name(&right->dev), method,
                        dev_name(&left->dev),
                        lpeer ? dev_name(&lpeer->dev) : "none",
@@ -265,7 +265,7 @@ static void link_peers_report(struct usb_port *left, struct usb_port *right)
        if (rc == 0) {
                dev_dbg(&left->dev, "peered to %s\n", dev_name(&right->dev));
        } else {
-               dev_warn(&left->dev, "failed to peer to %s (%d)\n",
+               dev_dbg(&left->dev, "failed to peer to %s (%d)\n",
                                dev_name(&right->dev), rc);
                pr_warn_once("usb: port power management may be unreliable\n");
                usb_port_block_power_off = 1;
index f5a381945db2886a77e23a8fcf40ba9a34bb7fe7..6dc810bce295ab22dbb10b47755dddb421f96957 100644 (file)
@@ -125,6 +125,9 @@ static const struct usb_device_id usb_quirk_list[] = {
        { USB_DEVICE(0x04f3, 0x016f), .driver_info =
                        USB_QUIRK_DEVICE_QUALIFIER },
 
+       { USB_DEVICE(0x04f3, 0x21b8), .driver_info =
+                       USB_QUIRK_DEVICE_QUALIFIER },
+
        /* Roland SC-8820 */
        { USB_DEVICE(0x0582, 0x0007), .driver_info = USB_QUIRK_RESET_RESUME },
 
@@ -199,6 +202,12 @@ static const struct usb_device_id usb_quirk_list[] = {
        { USB_DEVICE(0x1a0a, 0x0200), .driver_info =
                        USB_QUIRK_LINEAR_UFRAME_INTR_BINTERVAL },
 
+       /* Blackmagic Design Intensity Shuttle */
+       { USB_DEVICE(0x1edb, 0xbd3b), .driver_info = USB_QUIRK_NO_LPM },
+
+       /* Blackmagic Design UltraStudio SDI */
+       { USB_DEVICE(0x1edb, 0xbd4f), .driver_info = USB_QUIRK_NO_LPM },
+
        { }  /* terminating entry must be last */
 };
 
index e61d773cf65e71e27a41f3c7d8e5306939d08908..39c1cbf0e75d9a5957b1567def5d23fb3631a015 100644 (file)
@@ -125,9 +125,11 @@ static int __dwc2_lowlevel_hw_enable(struct dwc2_hsotg *hsotg)
        if (ret)
                return ret;
 
-       ret = clk_prepare_enable(hsotg->clk);
-       if (ret)
-               return ret;
+       if (hsotg->clk) {
+               ret = clk_prepare_enable(hsotg->clk);
+               if (ret)
+                       return ret;
+       }
 
        if (hsotg->uphy)
                ret = usb_phy_init(hsotg->uphy);
@@ -175,7 +177,8 @@ static int __dwc2_lowlevel_hw_disable(struct dwc2_hsotg *hsotg)
        if (ret)
                return ret;
 
-       clk_disable_unprepare(hsotg->clk);
+       if (hsotg->clk)
+               clk_disable_unprepare(hsotg->clk);
 
        ret = regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies),
                                     hsotg->supplies);
@@ -212,14 +215,41 @@ static int dwc2_lowlevel_hw_init(struct dwc2_hsotg *hsotg)
         */
        hsotg->phy = devm_phy_get(hsotg->dev, "usb2-phy");
        if (IS_ERR(hsotg->phy)) {
-               hsotg->phy = NULL;
+               ret = PTR_ERR(hsotg->phy);
+               switch (ret) {
+               case -ENODEV:
+               case -ENOSYS:
+                       hsotg->phy = NULL;
+                       break;
+               case -EPROBE_DEFER:
+                       return ret;
+               default:
+                       dev_err(hsotg->dev, "error getting phy %d\n", ret);
+                       return ret;
+               }
+       }
+
+       if (!hsotg->phy) {
                hsotg->uphy = devm_usb_get_phy(hsotg->dev, USB_PHY_TYPE_USB2);
-               if (IS_ERR(hsotg->uphy))
-                       hsotg->uphy = NULL;
-               else
-                       hsotg->plat = dev_get_platdata(hsotg->dev);
+               if (IS_ERR(hsotg->uphy)) {
+                       ret = PTR_ERR(hsotg->uphy);
+                       switch (ret) {
+                       case -ENODEV:
+                       case -ENXIO:
+                               hsotg->uphy = NULL;
+                               break;
+                       case -EPROBE_DEFER:
+                               return ret;
+                       default:
+                               dev_err(hsotg->dev, "error getting usb phy %d\n",
+                                       ret);
+                               return ret;
+                       }
+               }
        }
 
+       hsotg->plat = dev_get_platdata(hsotg->dev);
+
        if (hsotg->phy) {
                /*
                 * If using the generic PHY framework, check if the PHY bus
@@ -229,11 +259,6 @@ static int dwc2_lowlevel_hw_init(struct dwc2_hsotg *hsotg)
                        hsotg->phyif = GUSBCFG_PHYIF8;
        }
 
-       if (!hsotg->phy && !hsotg->uphy && !hsotg->plat) {
-               dev_err(hsotg->dev, "no platform data or transceiver defined\n");
-               return -EPROBE_DEFER;
-       }
-
        /* Clock */
        hsotg->clk = devm_clk_get(hsotg->dev, "otg");
        if (IS_ERR(hsotg->clk)) {
@@ -342,20 +367,6 @@ static int dwc2_driver_probe(struct platform_device *dev)
        if (retval)
                return retval;
 
-       irq = platform_get_irq(dev, 0);
-       if (irq < 0) {
-               dev_err(&dev->dev, "missing IRQ resource\n");
-               return irq;
-       }
-
-       dev_dbg(hsotg->dev, "registering common handler for irq%d\n",
-               irq);
-       retval = devm_request_irq(hsotg->dev, irq,
-                                 dwc2_handle_common_intr, IRQF_SHARED,
-                                 dev_name(hsotg->dev), hsotg);
-       if (retval)
-               return retval;
-
        res = platform_get_resource(dev, IORESOURCE_MEM, 0);
        hsotg->regs = devm_ioremap_resource(&dev->dev, res);
        if (IS_ERR(hsotg->regs))
@@ -390,6 +401,20 @@ static int dwc2_driver_probe(struct platform_device *dev)
 
        dwc2_set_all_params(hsotg->core_params, -1);
 
+       irq = platform_get_irq(dev, 0);
+       if (irq < 0) {
+               dev_err(&dev->dev, "missing IRQ resource\n");
+               return irq;
+       }
+
+       dev_dbg(hsotg->dev, "registering common handler for irq%d\n",
+               irq);
+       retval = devm_request_irq(hsotg->dev, irq,
+                                 dwc2_handle_common_intr, IRQF_SHARED,
+                                 dev_name(hsotg->dev), hsotg);
+       if (retval)
+               return retval;
+
        retval = dwc2_lowlevel_hw_enable(hsotg);
        if (retval)
                return retval;
index e24a01cc98df4a43f2fd556e44b1557dce778d33..a58376fd65fe6d788fa817d5600696bfd431c791 100644 (file)
@@ -1078,6 +1078,7 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req)
         * little bit faster.
         */
        if (!usb_endpoint_xfer_isoc(dep->endpoint.desc) &&
+                       !usb_endpoint_xfer_int(dep->endpoint.desc) &&
                        !(dep->flags & DWC3_EP_BUSY)) {
                ret = __dwc3_gadget_kick_transfer(dep, 0, true);
                goto out;
index adc6d52efa4639387c30bcde2ae7cee95331b1bc..cf43e9e18368dcd84668b9378b1036b17276b593 100644 (file)
@@ -423,7 +423,7 @@ static ssize_t __ffs_ep0_read_events(struct ffs_data *ffs, char __user *buf,
        spin_unlock_irq(&ffs->ev.waitq.lock);
        mutex_unlock(&ffs->mutex);
 
-       return unlikely(__copy_to_user(buf, events, size)) ? -EFAULT : size;
+       return unlikely(copy_to_user(buf, events, size)) ? -EFAULT : size;
 }
 
 static ssize_t ffs_ep0_read(struct file *file, char __user *buf,
@@ -513,7 +513,7 @@ static ssize_t ffs_ep0_read(struct file *file, char __user *buf,
 
                /* unlocks spinlock */
                ret = __ffs_ep0_queue_wait(ffs, data, len);
-               if (likely(ret > 0) && unlikely(__copy_to_user(buf, data, len)))
+               if (likely(ret > 0) && unlikely(copy_to_user(buf, data, len)))
                        ret = -EFAULT;
                goto done_mutex;
 
@@ -3493,7 +3493,7 @@ static char *ffs_prepare_buffer(const char __user *buf, size_t len)
        if (unlikely(!data))
                return ERR_PTR(-ENOMEM);
 
-       if (unlikely(__copy_from_user(data, buf, len))) {
+       if (unlikely(copy_from_user(data, buf, len))) {
                kfree(data);
                return ERR_PTR(-EFAULT);
        }
index 42acb45e1ab42dd9436244bec16d4903603d6089..898a570319f17c3128b7a44878ebc09ea7242961 100644 (file)
@@ -370,6 +370,7 @@ static int f_midi_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
                if (err) {
                        ERROR(midi, "%s queue req: %d\n",
                                    midi->out_ep->name, err);
+                       free_ep_req(midi->out_ep, req);
                }
        }
 
@@ -545,7 +546,7 @@ static void f_midi_transmit(struct f_midi *midi, struct usb_request *req)
                }
        }
 
-       if (req->length > 0) {
+       if (req->length > 0 && ep->enabled) {
                int err;
 
                err = usb_ep_queue(ep, req, GFP_ATOMIC);
index 289ebca316d3f4ab0e136a14858bb7275eee53c0..ad8c9b05572d7421885ff161d32543f8942eb90d 100644 (file)
@@ -20,7 +20,7 @@
 #define UVC_ATTR(prefix, cname, aname) \
 static struct configfs_attribute prefix##attr_##cname = { \
        .ca_name        = __stringify(aname),                           \
-       .ca_mode        = S_IRUGO,                                      \
+       .ca_mode        = S_IRUGO | S_IWUGO,                            \
        .ca_owner       = THIS_MODULE,                                  \
        .show           = prefix##cname##_show,                         \
        .store          = prefix##cname##_store,                        \
index 670ac0b12f00842ad7a5b840c941f2e8a8a7f1cc..001a3b74a993ea677dd65650a4457f5f14376a7c 100644 (file)
@@ -2536,6 +2536,9 @@ static int pxa_udc_suspend(struct platform_device *_dev, pm_message_t state)
        udc->pullup_resume = udc->pullup_on;
        dplus_pullup(udc, 0);
 
+       if (udc->driver)
+               udc->driver->disconnect(&udc->gadget);
+
        return 0;
 }
 
index 342ffd1401222179589906ccc1d09ec102a1f03b..8c6e15bd6ff0b27ce2e8cb22c2fe03e9866f1768 100644 (file)
@@ -473,6 +473,8 @@ static int ohci_hcd_at91_drv_probe(struct platform_device *pdev)
        if (!pdata)
                return -ENOMEM;
 
+       pdev->dev.platform_data = pdata;
+
        if (!of_property_read_u32(np, "num-ports", &ports))
                pdata->ports = ports;
 
@@ -483,6 +485,7 @@ static int ohci_hcd_at91_drv_probe(struct platform_device *pdev)
                 */
                if (i >= pdata->ports) {
                        pdata->vbus_pin[i] = -EINVAL;
+                       pdata->overcurrent_pin[i] = -EINVAL;
                        continue;
                }
 
@@ -513,10 +516,8 @@ static int ohci_hcd_at91_drv_probe(struct platform_device *pdev)
        }
 
        at91_for_each_port(i) {
-               if (i >= pdata->ports) {
-                       pdata->overcurrent_pin[i] = -EINVAL;
-                       continue;
-               }
+               if (i >= pdata->ports)
+                       break;
 
                pdata->overcurrent_pin[i] =
                        of_get_named_gpio_flags(np, "atmel,oc-gpio", i, &flags);
@@ -552,8 +553,6 @@ static int ohci_hcd_at91_drv_probe(struct platform_device *pdev)
                }
        }
 
-       pdev->dev.platform_data = pdata;
-
        device_init_wakeup(&pdev->dev, 1);
        return usb_hcd_at91_probe(&ohci_at91_hc_driver, pdev);
 }
index dc31c425ce0179551b27e2d7a900f1bb7b411ad8..9f1c0538b211217d21184ef2527f764933aace0d 100644 (file)
@@ -377,6 +377,10 @@ static int qset_fill_page_list(struct whc *whc, struct whc_std *std, gfp_t mem_f
        if (std->pl_virt == NULL)
                return -ENOMEM;
        std->dma_addr = dma_map_single(whc->wusbhc.dev, std->pl_virt, pl_len, DMA_TO_DEVICE);
+       if (dma_mapping_error(whc->wusbhc.dev, std->dma_addr)) {
+               kfree(std->pl_virt);
+               return -EFAULT;
+       }
 
        for (p = 0; p < std->num_pointers; p++) {
                std->pl_virt[p].buf_ptr = cpu_to_le64(dma_addr);
index 0230965fb78cf3433702932625aee270dbf90535..f980c239eded9bd5e9615ebf96deefce5c7ec591 100644 (file)
@@ -733,8 +733,30 @@ static u32 xhci_get_port_status(struct usb_hcd *hcd,
                if ((raw_port_status & PORT_RESET) ||
                                !(raw_port_status & PORT_PE))
                        return 0xffffffff;
-               if (time_after_eq(jiffies,
-                                       bus_state->resume_done[wIndex])) {
+               /* did port event handler already start resume timing? */
+               if (!bus_state->resume_done[wIndex]) {
+                       /* If not, maybe we are in a host initated resume? */
+                       if (test_bit(wIndex, &bus_state->resuming_ports)) {
+                               /* Host initated resume doesn't time the resume
+                                * signalling using resume_done[].
+                                * It manually sets RESUME state, sleeps 20ms
+                                * and sets U0 state. This should probably be
+                                * changed, but not right now.
+                                */
+                       } else {
+                               /* port resume was discovered now and here,
+                                * start resume timing
+                                */
+                               unsigned long timeout = jiffies +
+                                       msecs_to_jiffies(USB_RESUME_TIMEOUT);
+
+                               set_bit(wIndex, &bus_state->resuming_ports);
+                               bus_state->resume_done[wIndex] = timeout;
+                               mod_timer(&hcd->rh_timer, timeout);
+                       }
+               /* Has resume been signalled for USB_RESUME_TIME yet? */
+               } else if (time_after_eq(jiffies,
+                                        bus_state->resume_done[wIndex])) {
                        int time_left;
 
                        xhci_dbg(xhci, "Resume USB2 port %d\n",
@@ -775,13 +797,26 @@ static u32 xhci_get_port_status(struct usb_hcd *hcd,
                } else {
                        /*
                         * The resume has been signaling for less than
-                        * 20ms. Report the port status as SUSPEND,
-                        * let the usbcore check port status again
-                        * and clear resume signaling later.
+                        * USB_RESUME_TIME. Report the port status as SUSPEND,
+                        * let the usbcore check port status again and clear
+                        * resume signaling later.
                         */
                        status |= USB_PORT_STAT_SUSPEND;
                }
        }
+       /*
+        * Clear stale usb2 resume signalling variables in case port changed
+        * state during resume signalling. For example on error
+        */
+       if ((bus_state->resume_done[wIndex] ||
+            test_bit(wIndex, &bus_state->resuming_ports)) &&
+           (raw_port_status & PORT_PLS_MASK) != XDEV_U3 &&
+           (raw_port_status & PORT_PLS_MASK) != XDEV_RESUME) {
+               bus_state->resume_done[wIndex] = 0;
+               clear_bit(wIndex, &bus_state->resuming_ports);
+       }
+
+
        if ((raw_port_status & PORT_PLS_MASK) == XDEV_U0 &&
            (raw_port_status & PORT_POWER)) {
                if (bus_state->suspended_ports & (1 << wIndex)) {
@@ -1115,6 +1150,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
                                if ((temp & PORT_PE) == 0)
                                        goto error;
 
+                               set_bit(wIndex, &bus_state->resuming_ports);
                                xhci_set_link_state(xhci, port_array, wIndex,
                                                        XDEV_RESUME);
                                spin_unlock_irqrestore(&xhci->lock, flags);
@@ -1122,6 +1158,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
                                spin_lock_irqsave(&xhci->lock, flags);
                                xhci_set_link_state(xhci, port_array, wIndex,
                                                        XDEV_U0);
+                               clear_bit(wIndex, &bus_state->resuming_ports);
                        }
                        bus_state->port_c_suspend |= 1 << wIndex;
 
index 17f6897acde2a5a7674ccff44ddc55f0db192166..c62109091d12855f7b5bb0e2b44a0b6b516cc88b 100644 (file)
@@ -188,10 +188,14 @@ static void xhci_pme_acpi_rtd3_enable(struct pci_dev *dev)
                0xb7, 0x0c, 0x34, 0xac, 0x01, 0xe9, 0xbf, 0x45,
                0xb7, 0xe6, 0x2b, 0x34, 0xec, 0x93, 0x1e, 0x23,
        };
-       acpi_evaluate_dsm(ACPI_HANDLE(&dev->dev), intel_dsm_uuid, 3, 1, NULL);
+       union acpi_object *obj;
+
+       obj = acpi_evaluate_dsm(ACPI_HANDLE(&dev->dev), intel_dsm_uuid, 3, 1,
+                               NULL);
+       ACPI_FREE(obj);
 }
 #else
-       static void xhci_pme_acpi_rtd3_enable(struct pci_dev *dev) { }
+static void xhci_pme_acpi_rtd3_enable(struct pci_dev *dev) { }
 #endif /* CONFIG_ACPI */
 
 /* called during probe() after chip reset completes */
index 6c5e8133cf87c4b203e2072de5b7275c4d944365..eeaa6c6bd540870f8065338a61ee37d838c6b07e 100644 (file)
@@ -1583,7 +1583,8 @@ static void handle_port_status(struct xhci_hcd *xhci,
                         */
                        bogus_port_status = true;
                        goto cleanup;
-               } else {
+               } else if (!test_bit(faked_port_index,
+                                    &bus_state->resuming_ports)) {
                        xhci_dbg(xhci, "resume HS port %d\n", port_id);
                        bus_state->resume_done[faked_port_index] = jiffies +
                                msecs_to_jiffies(USB_RESUME_TIMEOUT);
index dfa44d3e8eee469c9b8321fed57056ebe5813a2a..3f912705dcef93a5f27e6979f8aea9a6972b44eb 100644 (file)
@@ -4778,8 +4778,16 @@ int xhci_update_hub_device(struct usb_hcd *hcd, struct usb_device *hdev,
        ctrl_ctx->add_flags |= cpu_to_le32(SLOT_FLAG);
        slot_ctx = xhci_get_slot_ctx(xhci, config_cmd->in_ctx);
        slot_ctx->dev_info |= cpu_to_le32(DEV_HUB);
+       /*
+        * refer to section 6.2.2: MTT should be 0 for full speed hub,
+        * but it may be already set to 1 when setup an xHCI virtual
+        * device, so clear it anyway.
+        */
        if (tt->multi)
                slot_ctx->dev_info |= cpu_to_le32(DEV_MTT);
+       else if (hdev->speed == USB_SPEED_FULL)
+               slot_ctx->dev_info &= cpu_to_le32(~DEV_MTT);
+
        if (xhci->hci_version > 0x95) {
                xhci_dbg(xhci, "xHCI version %x needs hub "
                                "TT think time and number of ports\n",
index 1f2037bbeb0d1619572a2912bda7fa6e2c168ac0..45c83baf675dfb341089ca2f399ae636b45b0de5 100644 (file)
@@ -159,7 +159,7 @@ config USB_TI_CPPI_DMA
 
 config USB_TI_CPPI41_DMA
        bool 'TI CPPI 4.1 (AM335x)'
-       depends on ARCH_OMAP
+       depends on ARCH_OMAP && DMADEVICES
        select TI_CPPI41
 
 config USB_TUSB_OMAP_DMA
index 18cfc0a361cb340612bdf943d79a6302694afc43..ee9ff7028b926b1a7303afb261c3b261f91c9da4 100644 (file)
@@ -2017,7 +2017,6 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
        /* We need musb_read/write functions initialized for PM */
        pm_runtime_use_autosuspend(musb->controller);
        pm_runtime_set_autosuspend_delay(musb->controller, 200);
-       pm_runtime_irq_safe(musb->controller);
        pm_runtime_enable(musb->controller);
 
        /* The musb_platform_init() call:
@@ -2095,6 +2094,7 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
 #ifndef CONFIG_MUSB_PIO_ONLY
        if (!musb->ops->dma_init || !musb->ops->dma_exit) {
                dev_err(dev, "DMA controller not set\n");
+               status = -ENODEV;
                goto fail2;
        }
        musb_dma_controller_create = musb->ops->dma_init;
@@ -2218,6 +2218,12 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
 
        pm_runtime_put(musb->controller);
 
+       /*
+        * For why this is currently needed, see commit 3e43a0725637
+        * ("usb: musb: core: add pm_runtime_irq_safe()")
+        */
+       pm_runtime_irq_safe(musb->controller);
+
        return 0;
 
 fail5:
index 80eb991c2506c758315cc2e6e1f39b6ebbf319f4..0d19a6d61a71f7ccb7a55e1b90a7d5d5f27db535 100644 (file)
@@ -1506,7 +1506,6 @@ static int msm_otg_read_dt(struct platform_device *pdev, struct msm_otg *motg)
 {
        struct msm_otg_platform_data *pdata;
        struct extcon_dev *ext_id, *ext_vbus;
-       const struct of_device_id *id;
        struct device_node *node = pdev->dev.of_node;
        struct property *prop;
        int len, ret, words;
@@ -1518,8 +1517,9 @@ static int msm_otg_read_dt(struct platform_device *pdev, struct msm_otg *motg)
 
        motg->pdata = pdata;
 
-       id = of_match_device(msm_otg_dt_match, &pdev->dev);
-       pdata->phy_type = (enum msm_usb_phy_type) id->data;
+       pdata->phy_type = (enum msm_usb_phy_type)of_device_get_match_data(&pdev->dev);
+       if (!pdata->phy_type)
+               return 1;
 
        motg->link_rst = devm_reset_control_get(&pdev->dev, "link");
        if (IS_ERR(motg->link_rst))
index b7536af777ab9c4f083d7b88ff2bfe093fca9e21..c2936dc48ca7b45b0e5c186859d2879569719323 100644 (file)
@@ -143,12 +143,17 @@ static const struct mxs_phy_data imx6sx_phy_data = {
        .flags = MXS_PHY_DISCONNECT_LINE_WITHOUT_VBUS,
 };
 
+static const struct mxs_phy_data imx6ul_phy_data = {
+       .flags = MXS_PHY_DISCONNECT_LINE_WITHOUT_VBUS,
+};
+
 static const struct of_device_id mxs_phy_dt_ids[] = {
        { .compatible = "fsl,imx6sx-usbphy", .data = &imx6sx_phy_data, },
        { .compatible = "fsl,imx6sl-usbphy", .data = &imx6sl_phy_data, },
        { .compatible = "fsl,imx6q-usbphy", .data = &imx6q_phy_data, },
        { .compatible = "fsl,imx23-usbphy", .data = &imx23_phy_data, },
        { .compatible = "fsl,vf610-usbphy", .data = &vf610_phy_data, },
+       { .compatible = "fsl,imx6ul-usbphy", .data = &imx6ul_phy_data, },
        { /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, mxs_phy_dt_ids);
index de4f97d84a822ffd746b5550dcb68da08b581438..8f7a78e7097598a50e9d7ba3cc72831b41af25b8 100644 (file)
@@ -131,7 +131,8 @@ static void __usbhsg_queue_pop(struct usbhsg_uep *uep,
        struct device *dev = usbhsg_gpriv_to_dev(gpriv);
        struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv);
 
-       dev_dbg(dev, "pipe %d : queue pop\n", usbhs_pipe_number(pipe));
+       if (pipe)
+               dev_dbg(dev, "pipe %d : queue pop\n", usbhs_pipe_number(pipe));
 
        ureq->req.status = status;
        spin_unlock(usbhs_priv_to_lock(priv));
@@ -685,7 +686,13 @@ static int usbhsg_ep_dequeue(struct usb_ep *ep, struct usb_request *req)
        struct usbhsg_request *ureq = usbhsg_req_to_ureq(req);
        struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep);
 
-       usbhs_pkt_pop(pipe, usbhsg_ureq_to_pkt(ureq));
+       if (pipe)
+               usbhs_pkt_pop(pipe, usbhsg_ureq_to_pkt(ureq));
+
+       /*
+        * To dequeue a request, this driver should call the usbhsg_queue_pop()
+        * even if the pipe is NULL.
+        */
        usbhsg_queue_pop(uep, ureq, -ECONNRESET);
 
        return 0;
index eac7ccaa3c859cc3bae90e897fc071caa7168cfd..7d4f51a32e66fcb2b7568af975fcd5574edd7f88 100644 (file)
@@ -132,7 +132,6 @@ static const struct usb_device_id id_table[] = {
        { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */
        { USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */
        { USB_DEVICE(0x10C4, 0xEA70) }, /* Silicon Labs factory default */
-       { USB_DEVICE(0x10C4, 0xEA80) }, /* Silicon Labs factory default */
        { USB_DEVICE(0x10C4, 0xEA71) }, /* Infinity GPS-MIC-1 Radio Monophone */
        { USB_DEVICE(0x10C4, 0xF001) }, /* Elan Digital Systems USBscope50 */
        { USB_DEVICE(0x10C4, 0xF002) }, /* Elan Digital Systems USBwave12 */
index 3658662898fcb170fcdca07a8a676383e4d70347..a204782ae530e1de8f7982f869a94f9b80ce9dad 100644 (file)
@@ -53,6 +53,7 @@ DEVICE(funsoft, FUNSOFT_IDS);
 
 /* Infineon Flashloader driver */
 #define FLASHLOADER_IDS()              \
+       { USB_DEVICE_INTERFACE_CLASS(0x058b, 0x0041, USB_CLASS_CDC_DATA) }, \
        { USB_DEVICE(0x8087, 0x0716) }
 DEVICE(flashloader, FLASHLOADER_IDS);
 
index e6915166443607283f8229eaca83fac38ed68377..5c66d3f7a6d070c54632751af97ef3c3d660744b 100644 (file)
@@ -796,6 +796,10 @@ static int uas_slave_configure(struct scsi_device *sdev)
        if (devinfo->flags & US_FL_NO_REPORT_OPCODES)
                sdev->no_report_opcodes = 1;
 
+       /* A few buggy USB-ATA bridges don't understand FUA */
+       if (devinfo->flags & US_FL_BROKEN_FUA)
+               sdev->broken_fua = 1;
+
        scsi_change_queue_depth(sdev, devinfo->qdepth - 2);
        return 0;
 }
index 6b2479123de7762f7145c93fdcd58efb11f51093..7ffe4209067bb35b62220660997b4d83344706ed 100644 (file)
@@ -1987,7 +1987,7 @@ UNUSUAL_DEV(  0x14cd, 0x6600, 0x0201, 0x0201,
                US_FL_IGNORE_RESIDUE ),
 
 /* Reported by Michael Büsch <m@bues.ch> */
-UNUSUAL_DEV(  0x152d, 0x0567, 0x0114, 0x0114,
+UNUSUAL_DEV(  0x152d, 0x0567, 0x0114, 0x0116,
                "JMicron",
                "USB to ATA/ATAPI Bridge",
                USB_SC_DEVICE, USB_PR_DEVICE, NULL,
index c85ea530085f12d86ca691d82122f04e9f2166ae..ccc113e83d88e2b1e69e207989a5d5b49d526ae2 100644 (file)
@@ -132,7 +132,7 @@ UNUSUAL_DEV(0x152d, 0x0567, 0x0000, 0x9999,
                "JMicron",
                "JMS567",
                USB_SC_DEVICE, USB_PR_DEVICE, NULL,
-               US_FL_NO_REPORT_OPCODES),
+               US_FL_BROKEN_FUA | US_FL_NO_REPORT_OPCODES),
 
 /* Reported-by: Hans de Goede <hdegoede@redhat.com> */
 UNUSUAL_DEV(0x2109, 0x0711, 0x0000, 0x9999,
index da6e2ce77495b21ec127209664567b7e2f8f467e..850d86ca685b273344271eda7c95ad4f82b28244 100644 (file)
@@ -31,21 +31,6 @@ menuconfig VFIO
 
          If you don't know what to do here, say N.
 
-menuconfig VFIO_NOIOMMU
-       bool "VFIO No-IOMMU support"
-       depends on VFIO
-       help
-         VFIO is built on the ability to isolate devices using the IOMMU.
-         Only with an IOMMU can userspace access to DMA capable devices be
-         considered secure.  VFIO No-IOMMU mode enables IOMMU groups for
-         devices without IOMMU backing for the purpose of re-using the VFIO
-         infrastructure in a non-secure mode.  Use of this mode will result
-         in an unsupportable kernel and will therefore taint the kernel.
-         Device assignment to virtual machines is also not possible with
-         this mode since there is no IOMMU to provide DMA translation.
-
-         If you don't know what to do here, say N.
-
 source "drivers/vfio/pci/Kconfig"
 source "drivers/vfio/platform/Kconfig"
 source "virt/lib/Kconfig"
index 32b88bd2c82c7e3a3f4cd8cae11a253a171c76fa..56bf6dbb93db7ac281a0af4fa01a8d212fd87670 100644 (file)
@@ -940,13 +940,13 @@ static int vfio_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
        if (pdev->hdr_type != PCI_HEADER_TYPE_NORMAL)
                return -EINVAL;
 
-       group = vfio_iommu_group_get(&pdev->dev);
+       group = iommu_group_get(&pdev->dev);
        if (!group)
                return -EINVAL;
 
        vdev = kzalloc(sizeof(*vdev), GFP_KERNEL);
        if (!vdev) {
-               vfio_iommu_group_put(group, &pdev->dev);
+               iommu_group_put(group);
                return -ENOMEM;
        }
 
@@ -957,7 +957,7 @@ static int vfio_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 
        ret = vfio_add_group_dev(&pdev->dev, &vfio_pci_ops, vdev);
        if (ret) {
-               vfio_iommu_group_put(group, &pdev->dev);
+               iommu_group_put(group);
                kfree(vdev);
                return ret;
        }
@@ -993,7 +993,7 @@ static void vfio_pci_remove(struct pci_dev *pdev)
        if (!vdev)
                return;
 
-       vfio_iommu_group_put(pdev->dev.iommu_group, &pdev->dev);
+       iommu_group_put(pdev->dev.iommu_group);
        kfree(vdev);
 
        if (vfio_pci_is_vga(pdev)) {
@@ -1035,7 +1035,7 @@ static pci_ers_result_t vfio_pci_aer_err_detected(struct pci_dev *pdev,
        return PCI_ERS_RESULT_CAN_RECOVER;
 }
 
-static struct pci_error_handlers vfio_err_handlers = {
+static const struct pci_error_handlers vfio_err_handlers = {
        .error_detected = vfio_pci_aer_err_detected,
 };
 
index f1625dcfbb23d49d6b0586977a203462df0e75a5..b1cc3a768784426fbf7616316aa9731f21b77ddb 100644 (file)
@@ -92,7 +92,6 @@ static struct platform_driver vfio_platform_driver = {
        .remove         = vfio_platform_remove,
        .driver = {
                .name   = "vfio-platform",
-               .owner  = THIS_MODULE,
        },
 };
 
index a1c50d63079200ce90741ccd55e60bc703c73eb2..418cdd9ba3f4841353c5cbdddb345e9363578736 100644 (file)
@@ -51,13 +51,10 @@ static vfio_platform_reset_fn_t vfio_platform_lookup_reset(const char *compat,
 
 static void vfio_platform_get_reset(struct vfio_platform_device *vdev)
 {
-       char modname[256];
-
        vdev->reset = vfio_platform_lookup_reset(vdev->compat,
                                                &vdev->reset_module);
        if (!vdev->reset) {
-               snprintf(modname, 256, "vfio-reset:%s", vdev->compat);
-               request_module(modname);
+               request_module("vfio-reset:%s", vdev->compat);
                vdev->reset = vfio_platform_lookup_reset(vdev->compat,
                                                         &vdev->reset_module);
        }
index de632da2e22f60d4eee042631821c1a4a9b7e558..6070b793cbcb244d98a784bf6c41a5f0fabb662b 100644 (file)
@@ -62,7 +62,6 @@ struct vfio_container {
        struct rw_semaphore             group_lock;
        struct vfio_iommu_driver        *iommu_driver;
        void                            *iommu_data;
-       bool                            noiommu;
 };
 
 struct vfio_unbound_dev {
@@ -85,7 +84,6 @@ struct vfio_group {
        struct list_head                unbound_list;
        struct mutex                    unbound_lock;
        atomic_t                        opened;
-       bool                            noiommu;
 };
 
 struct vfio_device {
@@ -97,147 +95,6 @@ struct vfio_device {
        void                            *device_data;
 };
 
-#ifdef CONFIG_VFIO_NOIOMMU
-static bool noiommu __read_mostly;
-module_param_named(enable_unsafe_noiommu_support,
-                  noiommu, bool, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(enable_unsafe_noiommu_mode, "Enable UNSAFE, no-IOMMU mode.  This mode provides no device isolation, no DMA translation, no host kernel protection, cannot be used for device assignment to virtual machines, requires RAWIO permissions, and will taint the kernel.  If you do not know what this is for, step away. (default: false)");
-#endif
-
-/*
- * vfio_iommu_group_{get,put} are only intended for VFIO bus driver probe
- * and remove functions, any use cases other than acquiring the first
- * reference for the purpose of calling vfio_add_group_dev() or removing
- * that symmetric reference after vfio_del_group_dev() should use the raw
- * iommu_group_{get,put} functions.  In particular, vfio_iommu_group_put()
- * removes the device from the dummy group and cannot be nested.
- */
-struct iommu_group *vfio_iommu_group_get(struct device *dev)
-{
-       struct iommu_group *group;
-       int __maybe_unused ret;
-
-       group = iommu_group_get(dev);
-
-#ifdef CONFIG_VFIO_NOIOMMU
-       /*
-        * With noiommu enabled, an IOMMU group will be created for a device
-        * that doesn't already have one and doesn't have an iommu_ops on their
-        * bus.  We use iommu_present() again in the main code to detect these
-        * fake groups.
-        */
-       if (group || !noiommu || iommu_present(dev->bus))
-               return group;
-
-       group = iommu_group_alloc();
-       if (IS_ERR(group))
-               return NULL;
-
-       iommu_group_set_name(group, "vfio-noiommu");
-       ret = iommu_group_add_device(group, dev);
-       iommu_group_put(group);
-       if (ret)
-               return NULL;
-
-       /*
-        * Where to taint?  At this point we've added an IOMMU group for a
-        * device that is not backed by iommu_ops, therefore any iommu_
-        * callback using iommu_ops can legitimately Oops.  So, while we may
-        * be about to give a DMA capable device to a user without IOMMU
-        * protection, which is clearly taint-worthy, let's go ahead and do
-        * it here.
-        */
-       add_taint(TAINT_USER, LOCKDEP_STILL_OK);
-       dev_warn(dev, "Adding kernel taint for vfio-noiommu group on device\n");
-#endif
-
-       return group;
-}
-EXPORT_SYMBOL_GPL(vfio_iommu_group_get);
-
-void vfio_iommu_group_put(struct iommu_group *group, struct device *dev)
-{
-#ifdef CONFIG_VFIO_NOIOMMU
-       if (!iommu_present(dev->bus))
-               iommu_group_remove_device(dev);
-#endif
-
-       iommu_group_put(group);
-}
-EXPORT_SYMBOL_GPL(vfio_iommu_group_put);
-
-#ifdef CONFIG_VFIO_NOIOMMU
-static void *vfio_noiommu_open(unsigned long arg)
-{
-       if (arg != VFIO_NOIOMMU_IOMMU)
-               return ERR_PTR(-EINVAL);
-       if (!capable(CAP_SYS_RAWIO))
-               return ERR_PTR(-EPERM);
-
-       return NULL;
-}
-
-static void vfio_noiommu_release(void *iommu_data)
-{
-}
-
-static long vfio_noiommu_ioctl(void *iommu_data,
-                              unsigned int cmd, unsigned long arg)
-{
-       if (cmd == VFIO_CHECK_EXTENSION)
-               return arg == VFIO_NOIOMMU_IOMMU ? 1 : 0;
-
-       return -ENOTTY;
-}
-
-static int vfio_iommu_present(struct device *dev, void *unused)
-{
-       return iommu_present(dev->bus) ? 1 : 0;
-}
-
-static int vfio_noiommu_attach_group(void *iommu_data,
-                                    struct iommu_group *iommu_group)
-{
-       return iommu_group_for_each_dev(iommu_group, NULL,
-                                       vfio_iommu_present) ? -EINVAL : 0;
-}
-
-static void vfio_noiommu_detach_group(void *iommu_data,
-                                     struct iommu_group *iommu_group)
-{
-}
-
-static struct vfio_iommu_driver_ops vfio_noiommu_ops = {
-       .name = "vfio-noiommu",
-       .owner = THIS_MODULE,
-       .open = vfio_noiommu_open,
-       .release = vfio_noiommu_release,
-       .ioctl = vfio_noiommu_ioctl,
-       .attach_group = vfio_noiommu_attach_group,
-       .detach_group = vfio_noiommu_detach_group,
-};
-
-static struct vfio_iommu_driver vfio_noiommu_driver = {
-       .ops = &vfio_noiommu_ops,
-};
-
-/*
- * Wrap IOMMU drivers, the noiommu driver is the one and only driver for
- * noiommu groups (and thus containers) and not available for normal groups.
- */
-#define vfio_for_each_iommu_driver(con, pos)                           \
-       for (pos = con->noiommu ? &vfio_noiommu_driver :                \
-            list_first_entry(&vfio.iommu_drivers_list,                 \
-                             struct vfio_iommu_driver, vfio_next);     \
-            (con->noiommu ? pos != NULL :                              \
-                       &pos->vfio_next != &vfio.iommu_drivers_list);   \
-             pos = con->noiommu ? NULL : list_next_entry(pos, vfio_next))
-#else
-#define vfio_for_each_iommu_driver(con, pos)                           \
-       list_for_each_entry(pos, &vfio.iommu_drivers_list, vfio_next)
-#endif
-
-
 /**
  * IOMMU driver registration
  */
@@ -342,8 +199,7 @@ static void vfio_group_unlock_and_free(struct vfio_group *group)
 /**
  * Group objects - create, release, get, put, search
  */
-static struct vfio_group *vfio_create_group(struct iommu_group *iommu_group,
-                                           bool noiommu)
+static struct vfio_group *vfio_create_group(struct iommu_group *iommu_group)
 {
        struct vfio_group *group, *tmp;
        struct device *dev;
@@ -361,7 +217,6 @@ static struct vfio_group *vfio_create_group(struct iommu_group *iommu_group,
        atomic_set(&group->container_users, 0);
        atomic_set(&group->opened, 0);
        group->iommu_group = iommu_group;
-       group->noiommu = noiommu;
 
        group->nb.notifier_call = vfio_iommu_group_notifier;
 
@@ -397,8 +252,7 @@ static struct vfio_group *vfio_create_group(struct iommu_group *iommu_group,
 
        dev = device_create(vfio.class, NULL,
                            MKDEV(MAJOR(vfio.group_devt), minor),
-                           group, "%s%d", noiommu ? "noiommu-" : "",
-                           iommu_group_id(iommu_group));
+                           group, "%d", iommu_group_id(iommu_group));
        if (IS_ERR(dev)) {
                vfio_free_group_minor(minor);
                vfio_group_unlock_and_free(group);
@@ -682,7 +536,7 @@ static int vfio_group_nb_add_dev(struct vfio_group *group, struct device *dev)
                return 0;
 
        /* TODO Prevent device auto probing */
-       WARN("Device %s added to live group %d!\n", dev_name(dev),
+       WARN(1, "Device %s added to live group %d!\n", dev_name(dev),
             iommu_group_id(group->iommu_group));
 
        return 0;
@@ -786,8 +640,7 @@ int vfio_add_group_dev(struct device *dev,
 
        group = vfio_group_get_from_iommu(iommu_group);
        if (!group) {
-               group = vfio_create_group(iommu_group,
-                                         !iommu_present(dev->bus));
+               group = vfio_create_group(iommu_group);
                if (IS_ERR(group)) {
                        iommu_group_put(iommu_group);
                        return PTR_ERR(group);
@@ -999,7 +852,8 @@ static long vfio_ioctl_check_extension(struct vfio_container *container,
                 */
                if (!driver) {
                        mutex_lock(&vfio.iommu_drivers_lock);
-                       vfio_for_each_iommu_driver(container, driver) {
+                       list_for_each_entry(driver, &vfio.iommu_drivers_list,
+                                           vfio_next) {
                                if (!try_module_get(driver->ops->owner))
                                        continue;
 
@@ -1068,7 +922,7 @@ static long vfio_ioctl_set_iommu(struct vfio_container *container,
        }
 
        mutex_lock(&vfio.iommu_drivers_lock);
-       vfio_for_each_iommu_driver(container, driver) {
+       list_for_each_entry(driver, &vfio.iommu_drivers_list, vfio_next) {
                void *data;
 
                if (!try_module_get(driver->ops->owner))
@@ -1333,9 +1187,6 @@ static int vfio_group_set_container(struct vfio_group *group, int container_fd)
        if (atomic_read(&group->container_users))
                return -EINVAL;
 
-       if (group->noiommu && !capable(CAP_SYS_RAWIO))
-               return -EPERM;
-
        f = fdget(container_fd);
        if (!f.file)
                return -EBADF;
@@ -1351,13 +1202,6 @@ static int vfio_group_set_container(struct vfio_group *group, int container_fd)
 
        down_write(&container->group_lock);
 
-       /* Real groups and fake groups cannot mix */
-       if (!list_empty(&container->group_list) &&
-           container->noiommu != group->noiommu) {
-               ret = -EPERM;
-               goto unlock_out;
-       }
-
        driver = container->iommu_driver;
        if (driver) {
                ret = driver->ops->attach_group(container->iommu_data,
@@ -1367,7 +1211,6 @@ static int vfio_group_set_container(struct vfio_group *group, int container_fd)
        }
 
        group->container = container;
-       container->noiommu = group->noiommu;
        list_add(&group->container_next, &container->group_list);
 
        /* Get a reference on the container and mark a user within the group */
@@ -1398,9 +1241,6 @@ static int vfio_group_get_device_fd(struct vfio_group *group, char *buf)
            !group->container->iommu_driver || !vfio_group_viable(group))
                return -EINVAL;
 
-       if (group->noiommu && !capable(CAP_SYS_RAWIO))
-               return -EPERM;
-
        device = vfio_device_get_from_name(group, buf);
        if (!device)
                return -ENODEV;
@@ -1443,10 +1283,6 @@ static int vfio_group_get_device_fd(struct vfio_group *group, char *buf)
 
        fd_install(ret, filep);
 
-       if (group->noiommu)
-               dev_warn(device->dev, "vfio-noiommu device opened by user "
-                        "(%s:%d)\n", current->comm, task_pid_nr(current));
-
        return ret;
 }
 
@@ -1535,11 +1371,6 @@ static int vfio_group_fops_open(struct inode *inode, struct file *filep)
        if (!group)
                return -ENODEV;
 
-       if (group->noiommu && !capable(CAP_SYS_RAWIO)) {
-               vfio_group_put(group);
-               return -EPERM;
-       }
-
        /* Do we need multiple instances of the group open?  Seems not. */
        opened = atomic_cmpxchg(&group->opened, 0, 1);
        if (opened) {
@@ -1702,11 +1533,6 @@ struct vfio_group *vfio_group_get_external_user(struct file *filep)
        if (!atomic_inc_not_zero(&group->container_users))
                return ERR_PTR(-EINVAL);
 
-       if (group->noiommu) {
-               atomic_dec(&group->container_users);
-               return ERR_PTR(-EPERM);
-       }
-
        if (!group->container->iommu_driver ||
                        !vfio_group_viable(group)) {
                atomic_dec(&group->container_users);
index eec2f11809ff2463d2a714224925af9c679fead1..ad2146a9ab2d4b19cca5469402c203ade61e8545 100644 (file)
@@ -819,7 +819,7 @@ long vhost_vring_ioctl(struct vhost_dev *d, int ioctl, void __user *argp)
                BUILD_BUG_ON(__alignof__ *vq->used > VRING_USED_ALIGN_SIZE);
                if ((a.avail_user_addr & (VRING_AVAIL_ALIGN_SIZE - 1)) ||
                    (a.used_user_addr & (VRING_USED_ALIGN_SIZE - 1)) ||
-                   (a.log_guest_addr & (sizeof(u64) - 1))) {
+                   (a.log_guest_addr & (VRING_USED_ALIGN_SIZE - 1))) {
                        r = -EINVAL;
                        break;
                }
@@ -1369,7 +1369,7 @@ int vhost_get_vq_desc(struct vhost_virtqueue *vq,
        /* Grab the next descriptor number they're advertising, and increment
         * the index we've seen. */
        if (unlikely(__get_user(ring_head,
-                               &vq->avail->ring[last_avail_idx % vq->num]))) {
+                               &vq->avail->ring[last_avail_idx & (vq->num - 1)]))) {
                vq_err(vq, "Failed to read head: idx %d address %p\n",
                       last_avail_idx,
                       &vq->avail->ring[last_avail_idx % vq->num]);
@@ -1489,7 +1489,7 @@ static int __vhost_add_used_n(struct vhost_virtqueue *vq,
        u16 old, new;
        int start;
 
-       start = vq->last_used_idx % vq->num;
+       start = vq->last_used_idx & (vq->num - 1);
        used = vq->used->ring + start;
        if (count == 1) {
                if (__put_user(heads[0].id, &used->id)) {
@@ -1531,7 +1531,7 @@ int vhost_add_used_n(struct vhost_virtqueue *vq, struct vring_used_elem *heads,
 {
        int start, n, r;
 
-       start = vq->last_used_idx % vq->num;
+       start = vq->last_used_idx & (vq->num - 1);
        n = vq->num - start;
        if (n < count) {
                r = __vhost_add_used_n(vq, heads, n);
index b1877d73fa563d6d48f2d55b7958f02daa8d9ad7..7062bb0975a521f1a28125c092c2f0d0bbd35787 100644 (file)
@@ -412,6 +412,7 @@ static int virtio_init(void)
 static void __exit virtio_exit(void)
 {
        bus_unregister(&virtio_bus);
+       ida_destroy(&virtio_index_ida);
 }
 core_initcall(virtio_init);
 module_exit(virtio_exit);
index 096b857e7b75abad526f487c84392d863c3c6b06..ee663c458b20a449c353c5ea0df4632933087e66 100644 (file)
@@ -80,6 +80,12 @@ struct vring_virtqueue {
        /* Last used index we've seen. */
        u16 last_used_idx;
 
+       /* Last written value to avail->flags */
+       u16 avail_flags_shadow;
+
+       /* Last written value to avail->idx in guest byte order */
+       u16 avail_idx_shadow;
+
        /* How to notify other side. FIXME: commonalize hcalls! */
        bool (*notify)(struct virtqueue *vq);
 
@@ -109,7 +115,7 @@ static struct vring_desc *alloc_indirect(struct virtqueue *_vq,
         * otherwise virt_to_phys will give us bogus addresses in the
         * virtqueue.
         */
-       gfp &= ~(__GFP_HIGHMEM | __GFP_HIGH);
+       gfp &= ~__GFP_HIGHMEM;
 
        desc = kmalloc(total_sg * sizeof(struct vring_desc), gfp);
        if (!desc)
@@ -235,13 +241,14 @@ static inline int virtqueue_add(struct virtqueue *_vq,
 
        /* Put entry in available array (but don't update avail->idx until they
         * do sync). */
-       avail = virtio16_to_cpu(_vq->vdev, vq->vring.avail->idx) & (vq->vring.num - 1);
+       avail = vq->avail_idx_shadow & (vq->vring.num - 1);
        vq->vring.avail->ring[avail] = cpu_to_virtio16(_vq->vdev, head);
 
        /* Descriptors and available array need to be set before we expose the
         * new available array entries. */
        virtio_wmb(vq->weak_barriers);
-       vq->vring.avail->idx = cpu_to_virtio16(_vq->vdev, virtio16_to_cpu(_vq->vdev, vq->vring.avail->idx) + 1);
+       vq->avail_idx_shadow++;
+       vq->vring.avail->idx = cpu_to_virtio16(_vq->vdev, vq->avail_idx_shadow);
        vq->num_added++;
 
        pr_debug("Added buffer head %i to %p\n", head, vq);
@@ -354,8 +361,8 @@ bool virtqueue_kick_prepare(struct virtqueue *_vq)
         * event. */
        virtio_mb(vq->weak_barriers);
 
-       old = virtio16_to_cpu(_vq->vdev, vq->vring.avail->idx) - vq->num_added;
-       new = virtio16_to_cpu(_vq->vdev, vq->vring.avail->idx);
+       old = vq->avail_idx_shadow - vq->num_added;
+       new = vq->avail_idx_shadow;
        vq->num_added = 0;
 
 #ifdef DEBUG
@@ -510,7 +517,7 @@ void *virtqueue_get_buf(struct virtqueue *_vq, unsigned int *len)
        /* If we expect an interrupt for the next entry, tell host
         * by writing event index and flush out the write before
         * the read in the next get_buf call. */
-       if (!(vq->vring.avail->flags & cpu_to_virtio16(_vq->vdev, VRING_AVAIL_F_NO_INTERRUPT))) {
+       if (!(vq->avail_flags_shadow & VRING_AVAIL_F_NO_INTERRUPT)) {
                vring_used_event(&vq->vring) = cpu_to_virtio16(_vq->vdev, vq->last_used_idx);
                virtio_mb(vq->weak_barriers);
        }
@@ -537,7 +544,11 @@ void virtqueue_disable_cb(struct virtqueue *_vq)
 {
        struct vring_virtqueue *vq = to_vvq(_vq);
 
-       vq->vring.avail->flags |= cpu_to_virtio16(_vq->vdev, VRING_AVAIL_F_NO_INTERRUPT);
+       if (!(vq->avail_flags_shadow & VRING_AVAIL_F_NO_INTERRUPT)) {
+               vq->avail_flags_shadow |= VRING_AVAIL_F_NO_INTERRUPT;
+               vq->vring.avail->flags = cpu_to_virtio16(_vq->vdev, vq->avail_flags_shadow);
+       }
+
 }
 EXPORT_SYMBOL_GPL(virtqueue_disable_cb);
 
@@ -565,7 +576,10 @@ unsigned virtqueue_enable_cb_prepare(struct virtqueue *_vq)
        /* Depending on the VIRTIO_RING_F_EVENT_IDX feature, we need to
         * either clear the flags bit or point the event index at the next
         * entry. Always do both to keep code simple. */
-       vq->vring.avail->flags &= cpu_to_virtio16(_vq->vdev, ~VRING_AVAIL_F_NO_INTERRUPT);
+       if (vq->avail_flags_shadow & VRING_AVAIL_F_NO_INTERRUPT) {
+               vq->avail_flags_shadow &= ~VRING_AVAIL_F_NO_INTERRUPT;
+               vq->vring.avail->flags = cpu_to_virtio16(_vq->vdev, vq->avail_flags_shadow);
+       }
        vring_used_event(&vq->vring) = cpu_to_virtio16(_vq->vdev, last_used_idx = vq->last_used_idx);
        END_USE(vq);
        return last_used_idx;
@@ -633,9 +647,12 @@ bool virtqueue_enable_cb_delayed(struct virtqueue *_vq)
        /* Depending on the VIRTIO_RING_F_USED_EVENT_IDX feature, we need to
         * either clear the flags bit or point the event index at the next
         * entry. Always do both to keep code simple. */
-       vq->vring.avail->flags &= cpu_to_virtio16(_vq->vdev, ~VRING_AVAIL_F_NO_INTERRUPT);
+       if (vq->avail_flags_shadow & VRING_AVAIL_F_NO_INTERRUPT) {
+               vq->avail_flags_shadow &= ~VRING_AVAIL_F_NO_INTERRUPT;
+               vq->vring.avail->flags = cpu_to_virtio16(_vq->vdev, vq->avail_flags_shadow);
+       }
        /* TODO: tune this threshold */
-       bufs = (u16)(virtio16_to_cpu(_vq->vdev, vq->vring.avail->idx) - vq->last_used_idx) * 3 / 4;
+       bufs = (u16)(vq->avail_idx_shadow - vq->last_used_idx) * 3 / 4;
        vring_used_event(&vq->vring) = cpu_to_virtio16(_vq->vdev, vq->last_used_idx + bufs);
        virtio_mb(vq->weak_barriers);
        if (unlikely((u16)(virtio16_to_cpu(_vq->vdev, vq->vring.used->idx) - vq->last_used_idx) > bufs)) {
@@ -670,7 +687,8 @@ void *virtqueue_detach_unused_buf(struct virtqueue *_vq)
                /* detach_buf clears data, so grab it now. */
                buf = vq->data[i];
                detach_buf(vq, i);
-               vq->vring.avail->idx = cpu_to_virtio16(_vq->vdev, virtio16_to_cpu(_vq->vdev, vq->vring.avail->idx) - 1);
+               vq->avail_idx_shadow--;
+               vq->vring.avail->idx = cpu_to_virtio16(_vq->vdev, vq->avail_idx_shadow);
                END_USE(vq);
                return buf;
        }
@@ -735,6 +753,8 @@ struct virtqueue *vring_new_virtqueue(unsigned int index,
        vq->weak_barriers = weak_barriers;
        vq->broken = false;
        vq->last_used_idx = 0;
+       vq->avail_flags_shadow = 0;
+       vq->avail_idx_shadow = 0;
        vq->num_added = 0;
        list_add_tail(&vq->vq.list, &vdev->vqs);
 #ifdef DEBUG
@@ -746,8 +766,10 @@ struct virtqueue *vring_new_virtqueue(unsigned int index,
        vq->event = virtio_has_feature(vdev, VIRTIO_RING_F_EVENT_IDX);
 
        /* No callback?  Tell other side not to bother us. */
-       if (!callback)
-               vq->vring.avail->flags |= cpu_to_virtio16(vdev, VRING_AVAIL_F_NO_INTERRUPT);
+       if (!callback) {
+               vq->avail_flags_shadow |= VRING_AVAIL_F_NO_INTERRUPT;
+               vq->vring.avail->flags = cpu_to_virtio16(vdev, vq->avail_flags_shadow);
+       }
 
        /* Put everything in free lists. */
        vq->free_head = 0;
index 7a8a6c6952e92b7fd2b659e1e2e0f4cbd2c39919..1c427beffadd97b3e95522fc9236193006d58fcc 100644 (file)
@@ -446,7 +446,7 @@ config MAX63XX_WATCHDOG
 
 config IMX2_WDT
        tristate "IMX2+ Watchdog"
-       depends on ARCH_MXC
+       depends on ARCH_MXC || ARCH_LAYERSCAPE
        select REGMAP_MMIO
        select WATCHDOG_CORE
        help
index 6ad9df948711080ca3c87464d0195bdd3c0d9feb..b751f43d76ed5c9d8e168389a1238b9218bee46f 100644 (file)
@@ -123,6 +123,7 @@ static int mtk_wdt_stop(struct watchdog_device *wdt_dev)
 
        reg = readl(wdt_base + WDT_MODE);
        reg &= ~WDT_MODE_EN;
+       reg |= WDT_MODE_KEY;
        iowrite32(reg, wdt_base + WDT_MODE);
 
        return 0;
index d96bee017fd3caa2fbcde961cc3ba9941b34c341..6f17c935a6cf86b1fcb47856532a8d6374bd0d82 100644 (file)
@@ -205,7 +205,7 @@ static int omap_wdt_set_timeout(struct watchdog_device *wdog,
 
 static unsigned int omap_wdt_get_timeleft(struct watchdog_device *wdog)
 {
-       struct omap_wdt_dev *wdev = watchdog_get_drvdata(wdog);
+       struct omap_wdt_dev *wdev = to_omap_wdt_dev(wdog);
        void __iomem *base = wdev->base;
        u32 value;
 
index 4224b3ec83a5515dc76a57507ec81122dd9316e1..313cd1c6fda0efcfa03897f1d23fc18b138e3779 100644 (file)
@@ -80,7 +80,7 @@ static unsigned int heartbeat = DEFAULT_HEARTBEAT;
 
 static DEFINE_SPINLOCK(io_lock);
 static void __iomem    *wdt_base;
-struct clk             *wdt_clk;
+static struct clk      *wdt_clk;
 
 static int pnx4008_wdt_start(struct watchdog_device *wdd)
 {
@@ -161,7 +161,7 @@ static int pnx4008_wdt_probe(struct platform_device *pdev)
        if (IS_ERR(wdt_clk))
                return PTR_ERR(wdt_clk);
 
-       ret = clk_enable(wdt_clk);
+       ret = clk_prepare_enable(wdt_clk);
        if (ret)
                return ret;
 
@@ -184,7 +184,7 @@ static int pnx4008_wdt_probe(struct platform_device *pdev)
        return 0;
 
 disable_clk:
-       clk_disable(wdt_clk);
+       clk_disable_unprepare(wdt_clk);
        return ret;
 }
 
@@ -192,7 +192,7 @@ static int pnx4008_wdt_remove(struct platform_device *pdev)
 {
        watchdog_unregister_device(&pnx4008_wdd);
 
-       clk_disable(wdt_clk);
+       clk_disable_unprepare(wdt_clk);
 
        return 0;
 }
index 7f97cdd53f29624f6c732b0e44c0448a856c8a5c..9ec57608da82931e6f2a913246825ff9be11e034 100644 (file)
@@ -140,8 +140,10 @@ static int tegra_wdt_set_timeout(struct watchdog_device *wdd,
 {
        wdd->timeout = timeout;
 
-       if (watchdog_active(wdd))
+       if (watchdog_active(wdd)) {
+               tegra_wdt_stop(wdd);
                return tegra_wdt_start(wdd);
+       }
 
        return 0;
 }
index 91bf55a2002497eca6de68258515484ba9f13efa..20e2bba10400910cfbd86a68d3d6f988b9d77dec 100644 (file)
@@ -224,7 +224,7 @@ static int wdt_keepalive(void)
 
 static int wdt_set_timeout(int t)
 {
-       int tmrval;
+       unsigned int tmrval;
 
        /*
         * Convert seconds to watchdog counter time units, rounding up.
index 849500e4e14d14af7dd29fe7737d77d62f87a36d..524c22146429d7c87acc8682976031c2f8a727d6 100644 (file)
@@ -39,6 +39,7 @@
 #include <asm/irq.h>
 #include <asm/idle.h>
 #include <asm/io_apic.h>
+#include <asm/i8259.h>
 #include <asm/xen/pci.h>
 #endif
 #include <asm/sync_bitops.h>
@@ -420,7 +421,7 @@ static int __must_check xen_allocate_irq_gsi(unsigned gsi)
                return xen_allocate_irq_dynamic();
 
        /* Legacy IRQ descriptors are already allocated by the arch. */
-       if (gsi < NR_IRQS_LEGACY)
+       if (gsi < nr_legacy_irqs())
                irq = gsi;
        else
                irq = irq_alloc_desc_at(gsi, -1);
@@ -446,7 +447,7 @@ static void xen_free_irq(unsigned irq)
        kfree(info);
 
        /* Legacy IRQ descriptors are managed by the arch. */
-       if (irq < NR_IRQS_LEGACY)
+       if (irq < nr_legacy_irqs())
                return;
 
        irq_free_desc(irq);
index 00f40f051d95668b01ebf6b4c17e6f0e90912198..38272ad245516c272ab571bed1a5c962f4a0e808 100644 (file)
@@ -49,6 +49,8 @@
 #include <linux/init.h>
 #include <linux/mutex.h>
 #include <linux/cpu.h>
+#include <linux/mm.h>
+#include <linux/vmalloc.h>
 
 #include <xen/xen.h>
 #include <xen/events.h>
 struct per_user_data {
        struct mutex bind_mutex; /* serialize bind/unbind operations */
        struct rb_root evtchns;
+       unsigned int nr_evtchns;
 
        /* Notification ring, accessed via /dev/xen/evtchn. */
-#define EVTCHN_RING_SIZE     (PAGE_SIZE / sizeof(evtchn_port_t))
-#define EVTCHN_RING_MASK(_i) ((_i)&(EVTCHN_RING_SIZE-1))
+       unsigned int ring_size;
        evtchn_port_t *ring;
        unsigned int ring_cons, ring_prod, ring_overflow;
        struct mutex ring_cons_mutex; /* protect against concurrent readers */
@@ -80,10 +82,41 @@ struct user_evtchn {
        bool enabled;
 };
 
+static evtchn_port_t *evtchn_alloc_ring(unsigned int size)
+{
+       evtchn_port_t *ring;
+       size_t s = size * sizeof(*ring);
+
+       ring = kmalloc(s, GFP_KERNEL);
+       if (!ring)
+               ring = vmalloc(s);
+
+       return ring;
+}
+
+static void evtchn_free_ring(evtchn_port_t *ring)
+{
+       kvfree(ring);
+}
+
+static unsigned int evtchn_ring_offset(struct per_user_data *u,
+                                      unsigned int idx)
+{
+       return idx & (u->ring_size - 1);
+}
+
+static evtchn_port_t *evtchn_ring_entry(struct per_user_data *u,
+                                       unsigned int idx)
+{
+       return u->ring + evtchn_ring_offset(u, idx);
+}
+
 static int add_evtchn(struct per_user_data *u, struct user_evtchn *evtchn)
 {
        struct rb_node **new = &(u->evtchns.rb_node), *parent = NULL;
 
+       u->nr_evtchns++;
+
        while (*new) {
                struct user_evtchn *this;
 
@@ -107,6 +140,7 @@ static int add_evtchn(struct per_user_data *u, struct user_evtchn *evtchn)
 
 static void del_evtchn(struct per_user_data *u, struct user_evtchn *evtchn)
 {
+       u->nr_evtchns--;
        rb_erase(&evtchn->node, &u->evtchns);
        kfree(evtchn);
 }
@@ -144,8 +178,8 @@ static irqreturn_t evtchn_interrupt(int irq, void *data)
 
        spin_lock(&u->ring_prod_lock);
 
-       if ((u->ring_prod - u->ring_cons) < EVTCHN_RING_SIZE) {
-               u->ring[EVTCHN_RING_MASK(u->ring_prod)] = evtchn->port;
+       if ((u->ring_prod - u->ring_cons) < u->ring_size) {
+               *evtchn_ring_entry(u, u->ring_prod) = evtchn->port;
                wmb(); /* Ensure ring contents visible */
                if (u->ring_cons == u->ring_prod++) {
                        wake_up_interruptible(&u->evtchn_wait);
@@ -200,10 +234,10 @@ static ssize_t evtchn_read(struct file *file, char __user *buf,
        }
 
        /* Byte lengths of two chunks. Chunk split (if any) is at ring wrap. */
-       if (((c ^ p) & EVTCHN_RING_SIZE) != 0) {
-               bytes1 = (EVTCHN_RING_SIZE - EVTCHN_RING_MASK(c)) *
+       if (((c ^ p) & u->ring_size) != 0) {
+               bytes1 = (u->ring_size - evtchn_ring_offset(u, c)) *
                        sizeof(evtchn_port_t);
-               bytes2 = EVTCHN_RING_MASK(p) * sizeof(evtchn_port_t);
+               bytes2 = evtchn_ring_offset(u, p) * sizeof(evtchn_port_t);
        } else {
                bytes1 = (p - c) * sizeof(evtchn_port_t);
                bytes2 = 0;
@@ -219,7 +253,7 @@ static ssize_t evtchn_read(struct file *file, char __user *buf,
 
        rc = -EFAULT;
        rmb(); /* Ensure that we see the port before we copy it. */
-       if (copy_to_user(buf, &u->ring[EVTCHN_RING_MASK(c)], bytes1) ||
+       if (copy_to_user(buf, evtchn_ring_entry(u, c), bytes1) ||
            ((bytes2 != 0) &&
             copy_to_user(&buf[bytes1], &u->ring[0], bytes2)))
                goto unlock_out;
@@ -278,6 +312,66 @@ static ssize_t evtchn_write(struct file *file, const char __user *buf,
        return rc;
 }
 
+static int evtchn_resize_ring(struct per_user_data *u)
+{
+       unsigned int new_size;
+       evtchn_port_t *new_ring, *old_ring;
+       unsigned int p, c;
+
+       /*
+        * Ensure the ring is large enough to capture all possible
+        * events. i.e., one free slot for each bound event.
+        */
+       if (u->nr_evtchns <= u->ring_size)
+               return 0;
+
+       if (u->ring_size == 0)
+               new_size = 64;
+       else
+               new_size = 2 * u->ring_size;
+
+       new_ring = evtchn_alloc_ring(new_size);
+       if (!new_ring)
+               return -ENOMEM;
+
+       old_ring = u->ring;
+
+       /*
+        * Access to the ring contents is serialized by either the
+        * prod /or/ cons lock so take both when resizing.
+        */
+       mutex_lock(&u->ring_cons_mutex);
+       spin_lock_irq(&u->ring_prod_lock);
+
+       /*
+        * Copy the old ring contents to the new ring.
+        *
+        * If the ring contents crosses the end of the current ring,
+        * it needs to be copied in two chunks.
+        *
+        * +---------+    +------------------+
+        * |34567  12| -> |       1234567    |
+        * +-----p-c-+    +------------------+
+        */
+       p = evtchn_ring_offset(u, u->ring_prod);
+       c = evtchn_ring_offset(u, u->ring_cons);
+       if (p < c) {
+               memcpy(new_ring + c, u->ring + c, (u->ring_size - c) * sizeof(*u->ring));
+               memcpy(new_ring + u->ring_size, u->ring, p * sizeof(*u->ring));
+       } else
+               memcpy(new_ring + c, u->ring + c, (p - c) * sizeof(*u->ring));
+
+       u->ring = new_ring;
+       u->ring_size = new_size;
+
+       spin_unlock_irq(&u->ring_prod_lock);
+       mutex_unlock(&u->ring_cons_mutex);
+
+       evtchn_free_ring(old_ring);
+
+       return 0;
+}
+
 static int evtchn_bind_to_user(struct per_user_data *u, int port)
 {
        struct user_evtchn *evtchn;
@@ -305,6 +399,10 @@ static int evtchn_bind_to_user(struct per_user_data *u, int port)
        if (rc < 0)
                goto err;
 
+       rc = evtchn_resize_ring(u);
+       if (rc < 0)
+               goto err;
+
        rc = bind_evtchn_to_irqhandler(port, evtchn_interrupt, 0,
                                       u->name, evtchn);
        if (rc < 0)
@@ -503,13 +601,6 @@ static int evtchn_open(struct inode *inode, struct file *filp)
 
        init_waitqueue_head(&u->evtchn_wait);
 
-       u->ring = (evtchn_port_t *)__get_free_page(GFP_KERNEL);
-       if (u->ring == NULL) {
-               kfree(u->name);
-               kfree(u);
-               return -ENOMEM;
-       }
-
        mutex_init(&u->bind_mutex);
        mutex_init(&u->ring_cons_mutex);
        spin_lock_init(&u->ring_prod_lock);
@@ -532,7 +623,7 @@ static int evtchn_release(struct inode *inode, struct file *filp)
                evtchn_unbind_from_user(u, evtchn);
        }
 
-       free_page((unsigned long)u->ring);
+       evtchn_free_ring(u->ring);
        kfree(u->name);
        kfree(u);
 
index 2ea0b3b2a91d2585a2d37f8ead07f08f32c79826..1be5dd048622f6c8c4f9aa805514b9fd5b5c5d7b 100644 (file)
@@ -804,7 +804,7 @@ static int gntdev_mmap(struct file *flip, struct vm_area_struct *vma)
 
        vma->vm_ops = &gntdev_vmops;
 
-       vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
+       vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP | VM_IO;
 
        if (use_ptemod)
                vma->vm_flags |= VM_DONTCOPY;
index 699941e906672b87eb1b5199f7966e29528e0116..511078586fa13543c30ac887dbb4e825888efee0 100644 (file)
@@ -451,9 +451,9 @@ void v9fs_evict_inode(struct inode *inode)
 {
        struct v9fs_inode *v9inode = V9FS_I(inode);
 
-       truncate_inode_pages_final(inode->i_mapping);
+       truncate_inode_pages_final(&inode->i_data);
        clear_inode(inode);
-       filemap_fdatawrite(inode->i_mapping);
+       filemap_fdatawrite(&inode->i_data);
 
        v9fs_cache_inode_put_cookie(inode);
        /* clunk the fid stashed in writeback_fid */
index c25639e907bd21a194aecedc6c60a93fb4994375..44d4a1e9244e74e923d7b26018d4b420aa2e1323 100644 (file)
@@ -1523,11 +1523,14 @@ static void __blkdev_put(struct block_device *bdev, fmode_t mode, int for_part)
                WARN_ON_ONCE(bdev->bd_holders);
                sync_blockdev(bdev);
                kill_bdev(bdev);
+
+               bdev_write_inode(bdev);
                /*
-                * ->release can cause the queue to disappear, so flush all
-                * dirty data before.
+                * Detaching bdev inode from its wb in __destroy_inode()
+                * is too late: the queue which embeds its bdi (along with
+                * root wb) can be gone as soon as we put_disk() below.
                 */
-               bdev_write_inode(bdev);
+               inode_detach_wb(bdev->bd_inode);
        }
        if (bdev->bd_contains == bdev) {
                if (disk->fops->release)
index 6dcdb2ec921185ae350aa0f2ff49cd65eaa0d500..d453d62ab0c6e322b3c0df0a05b20daa6751d5ad 100644 (file)
@@ -355,7 +355,7 @@ static int __resolve_indirect_ref(struct btrfs_fs_info *fs_info,
 
        index = srcu_read_lock(&fs_info->subvol_srcu);
 
-       root = btrfs_read_fs_root_no_name(fs_info, &root_key);
+       root = btrfs_get_fs_root(fs_info, &root_key, false);
        if (IS_ERR(root)) {
                srcu_read_unlock(&fs_info->subvol_srcu, index);
                ret = PTR_ERR(root);
index 8c58191249cc14c33c376bb0c8c0a469cb95b894..35489e7129a7e8de9d0232279d41d3bbd19ae1df 100644 (file)
@@ -3416,6 +3416,7 @@ int btrfs_cross_ref_exist(struct btrfs_trans_handle *trans,
 struct btrfs_block_group_cache *btrfs_lookup_block_group(
                                                 struct btrfs_fs_info *info,
                                                 u64 bytenr);
+void btrfs_get_block_group(struct btrfs_block_group_cache *cache);
 void btrfs_put_block_group(struct btrfs_block_group_cache *cache);
 int get_block_group_index(struct btrfs_block_group_cache *cache);
 struct extent_buffer *btrfs_alloc_tree_block(struct btrfs_trans_handle *trans,
@@ -3479,6 +3480,9 @@ int btrfs_make_block_group(struct btrfs_trans_handle *trans,
                           struct btrfs_root *root, u64 bytes_used,
                           u64 type, u64 chunk_objectid, u64 chunk_offset,
                           u64 size);
+struct btrfs_trans_handle *btrfs_start_trans_remove_block_group(
+                               struct btrfs_fs_info *fs_info,
+                               const u64 chunk_offset);
 int btrfs_remove_block_group(struct btrfs_trans_handle *trans,
                             struct btrfs_root *root, u64 group_start,
                             struct extent_map *em);
index acf3ed11cfb60e95b685aeb009e4d72fbdba3c3b..4b89680a192338c7a70a4c909e3c4374abe41284 100644 (file)
@@ -124,7 +124,7 @@ static int block_group_bits(struct btrfs_block_group_cache *cache, u64 bits)
        return (cache->flags & bits) == bits;
 }
 
-static void btrfs_get_block_group(struct btrfs_block_group_cache *cache)
+void btrfs_get_block_group(struct btrfs_block_group_cache *cache)
 {
        atomic_inc(&cache->count);
 }
@@ -5915,19 +5915,6 @@ static int update_block_group(struct btrfs_trans_handle *trans,
                        set_extent_dirty(info->pinned_extents,
                                         bytenr, bytenr + num_bytes - 1,
                                         GFP_NOFS | __GFP_NOFAIL);
-                       /*
-                        * No longer have used bytes in this block group, queue
-                        * it for deletion.
-                        */
-                       if (old_val == 0) {
-                               spin_lock(&info->unused_bgs_lock);
-                               if (list_empty(&cache->bg_list)) {
-                                       btrfs_get_block_group(cache);
-                                       list_add_tail(&cache->bg_list,
-                                                     &info->unused_bgs);
-                               }
-                               spin_unlock(&info->unused_bgs_lock);
-                       }
                }
 
                spin_lock(&trans->transaction->dirty_bgs_lock);
@@ -5939,6 +5926,22 @@ static int update_block_group(struct btrfs_trans_handle *trans,
                }
                spin_unlock(&trans->transaction->dirty_bgs_lock);
 
+               /*
+                * No longer have used bytes in this block group, queue it for
+                * deletion. We do this after adding the block group to the
+                * dirty list to avoid races between cleaner kthread and space
+                * cache writeout.
+                */
+               if (!alloc && old_val == 0) {
+                       spin_lock(&info->unused_bgs_lock);
+                       if (list_empty(&cache->bg_list)) {
+                               btrfs_get_block_group(cache);
+                               list_add_tail(&cache->bg_list,
+                                             &info->unused_bgs);
+                       }
+                       spin_unlock(&info->unused_bgs_lock);
+               }
+
                btrfs_put_block_group(cache);
                total -= num_bytes;
                bytenr += num_bytes;
@@ -8105,21 +8108,47 @@ reada:
 }
 
 /*
- * TODO: Modify related function to add related node/leaf to dirty_extent_root,
- * for later qgroup accounting.
- *
- * Current, this function does nothing.
+ * These may not be seen by the usual inc/dec ref code so we have to
+ * add them here.
  */
+static int record_one_subtree_extent(struct btrfs_trans_handle *trans,
+                                    struct btrfs_root *root, u64 bytenr,
+                                    u64 num_bytes)
+{
+       struct btrfs_qgroup_extent_record *qrecord;
+       struct btrfs_delayed_ref_root *delayed_refs;
+
+       qrecord = kmalloc(sizeof(*qrecord), GFP_NOFS);
+       if (!qrecord)
+               return -ENOMEM;
+
+       qrecord->bytenr = bytenr;
+       qrecord->num_bytes = num_bytes;
+       qrecord->old_roots = NULL;
+
+       delayed_refs = &trans->transaction->delayed_refs;
+       spin_lock(&delayed_refs->lock);
+       if (btrfs_qgroup_insert_dirty_extent(delayed_refs, qrecord))
+               kfree(qrecord);
+       spin_unlock(&delayed_refs->lock);
+
+       return 0;
+}
+
 static int account_leaf_items(struct btrfs_trans_handle *trans,
                              struct btrfs_root *root,
                              struct extent_buffer *eb)
 {
        int nr = btrfs_header_nritems(eb);
-       int i, extent_type;
+       int i, extent_type, ret;
        struct btrfs_key key;
        struct btrfs_file_extent_item *fi;
        u64 bytenr, num_bytes;
 
+       /* We can be called directly from walk_up_proc() */
+       if (!root->fs_info->quota_enabled)
+               return 0;
+
        for (i = 0; i < nr; i++) {
                btrfs_item_key_to_cpu(eb, &key, i);
 
@@ -8138,6 +8167,10 @@ static int account_leaf_items(struct btrfs_trans_handle *trans,
                        continue;
 
                num_bytes = btrfs_file_extent_disk_num_bytes(eb, fi);
+
+               ret = record_one_subtree_extent(trans, root, bytenr, num_bytes);
+               if (ret)
+                       return ret;
        }
        return 0;
 }
@@ -8206,8 +8239,6 @@ static int adjust_slots_upwards(struct btrfs_root *root,
 
 /*
  * root_eb is the subtree root and is locked before this function is called.
- * TODO: Modify this function to mark all (including complete shared node)
- * to dirty_extent_root to allow it get accounted in qgroup.
  */
 static int account_shared_subtree(struct btrfs_trans_handle *trans,
                                  struct btrfs_root *root,
@@ -8285,6 +8316,11 @@ walk_down:
                        btrfs_tree_read_lock(eb);
                        btrfs_set_lock_blocking_rw(eb, BTRFS_READ_LOCK);
                        path->locks[level] = BTRFS_READ_LOCK_BLOCKING;
+
+                       ret = record_one_subtree_extent(trans, root, child_bytenr,
+                                                       root->nodesize);
+                       if (ret)
+                               goto out;
                }
 
                if (level == 0) {
@@ -10256,6 +10292,47 @@ out:
        return ret;
 }
 
+struct btrfs_trans_handle *
+btrfs_start_trans_remove_block_group(struct btrfs_fs_info *fs_info,
+                                    const u64 chunk_offset)
+{
+       struct extent_map_tree *em_tree = &fs_info->mapping_tree.map_tree;
+       struct extent_map *em;
+       struct map_lookup *map;
+       unsigned int num_items;
+
+       read_lock(&em_tree->lock);
+       em = lookup_extent_mapping(em_tree, chunk_offset, 1);
+       read_unlock(&em_tree->lock);
+       ASSERT(em && em->start == chunk_offset);
+
+       /*
+        * We need to reserve 3 + N units from the metadata space info in order
+        * to remove a block group (done at btrfs_remove_chunk() and at
+        * btrfs_remove_block_group()), which are used for:
+        *
+        * 1 unit for adding the free space inode's orphan (located in the tree
+        * of tree roots).
+        * 1 unit for deleting the block group item (located in the extent
+        * tree).
+        * 1 unit for deleting the free space item (located in tree of tree
+        * roots).
+        * N units for deleting N device extent items corresponding to each
+        * stripe (located in the device tree).
+        *
+        * In order to remove a block group we also need to reserve units in the
+        * system space info in order to update the chunk tree (update one or
+        * more device items and remove one chunk item), but this is done at
+        * btrfs_remove_chunk() through a call to check_system_chunk().
+        */
+       map = (struct map_lookup *)em->bdev;
+       num_items = 3 + map->num_stripes;
+       free_extent_map(em);
+
+       return btrfs_start_transaction_fallback_global_rsv(fs_info->extent_root,
+                                                          num_items, 1);
+}
+
 /*
  * Process the unused_bgs list and remove any that don't have any allocated
  * space inside of them.
@@ -10322,8 +10399,8 @@ void btrfs_delete_unused_bgs(struct btrfs_fs_info *fs_info)
                 * Want to do this before we do anything else so we can recover
                 * properly if we fail to join the transaction.
                 */
-               /* 1 for btrfs_orphan_reserve_metadata() */
-               trans = btrfs_start_transaction(root, 1);
+               trans = btrfs_start_trans_remove_block_group(fs_info,
+                                                    block_group->key.objectid);
                if (IS_ERR(trans)) {
                        btrfs_dec_block_group_ro(root, block_group);
                        ret = PTR_ERR(trans);
index 977e715f0bf21a4ea8908700cfe4207dee1fe95d..72e73461c0643bbf128504c93a9c47dd377784aa 100644 (file)
@@ -1882,8 +1882,13 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
        struct btrfs_log_ctx ctx;
        int ret = 0;
        bool full_sync = 0;
-       const u64 len = end - start + 1;
+       u64 len;
 
+       /*
+        * The range length can be represented by u64, we have to do the typecasts
+        * to avoid signed overflow if it's [0, LLONG_MAX] eg. from fsync()
+        */
+       len = (u64)end - (u64)start + 1;
        trace_btrfs_sync_file(file, datasync);
 
        /*
@@ -2071,8 +2076,7 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
                        }
                }
                if (!full_sync) {
-                       ret = btrfs_wait_ordered_range(inode, start,
-                                                      end - start + 1);
+                       ret = btrfs_wait_ordered_range(inode, start, len);
                        if (ret) {
                                btrfs_end_transaction(trans, root);
                                goto out;
index 994490d5fa6423dee4971e0ff013777d853fe6a6..a70c5790f8f5908f08f606d097fe33e6966af36b 100644 (file)
@@ -4046,9 +4046,7 @@ int btrfs_unlink_inode(struct btrfs_trans_handle *trans,
  */
 static struct btrfs_trans_handle *__unlink_start_trans(struct inode *dir)
 {
-       struct btrfs_trans_handle *trans;
        struct btrfs_root *root = BTRFS_I(dir)->root;
-       int ret;
 
        /*
         * 1 for the possible orphan item
@@ -4057,27 +4055,7 @@ static struct btrfs_trans_handle *__unlink_start_trans(struct inode *dir)
         * 1 for the inode ref
         * 1 for the inode
         */
-       trans = btrfs_start_transaction(root, 5);
-       if (!IS_ERR(trans) || PTR_ERR(trans) != -ENOSPC)
-               return trans;
-
-       if (PTR_ERR(trans) == -ENOSPC) {
-               u64 num_bytes = btrfs_calc_trans_metadata_size(root, 5);
-
-               trans = btrfs_start_transaction(root, 0);
-               if (IS_ERR(trans))
-                       return trans;
-               ret = btrfs_cond_migrate_bytes(root->fs_info,
-                                              &root->fs_info->trans_block_rsv,
-                                              num_bytes, 5);
-               if (ret) {
-                       btrfs_end_transaction(trans, root);
-                       return ERR_PTR(ret);
-               }
-               trans->block_rsv = &root->fs_info->trans_block_rsv;
-               trans->bytes_reserved = num_bytes;
-       }
-       return trans;
+       return btrfs_start_transaction_fallback_global_rsv(root, 5, 5);
 }
 
 static int btrfs_unlink(struct inode *dir, struct dentry *dentry)
index 93e12c18ffd736ec77351ecb0443bbfec606a938..5279fdae7142fbe3177a556a020ed1af3a7aa8f1 100644 (file)
@@ -993,9 +993,10 @@ int btrfs_quota_disable(struct btrfs_trans_handle *trans,
        mutex_lock(&fs_info->qgroup_ioctl_lock);
        if (!fs_info->quota_root)
                goto out;
-       spin_lock(&fs_info->qgroup_lock);
        fs_info->quota_enabled = 0;
        fs_info->pending_quota_state = 0;
+       btrfs_qgroup_wait_for_completion(fs_info);
+       spin_lock(&fs_info->qgroup_lock);
        quota_root = fs_info->quota_root;
        fs_info->quota_root = NULL;
        fs_info->qgroup_flags &= ~BTRFS_QGROUP_STATUS_FLAG_ON;
@@ -1461,6 +1462,8 @@ struct btrfs_qgroup_extent_record
        struct btrfs_qgroup_extent_record *entry;
        u64 bytenr = record->bytenr;
 
+       assert_spin_locked(&delayed_refs->lock);
+
        while (*p) {
                parent_node = *p;
                entry = rb_entry(parent_node, struct btrfs_qgroup_extent_record,
index 2907a77fb1f6f4670885a7985ab40ed3e79c4925..b091d94ceef68013e992161b0aaf31b47cc645dc 100644 (file)
@@ -3432,7 +3432,9 @@ out:
 static noinline_for_stack int scrub_chunk(struct scrub_ctx *sctx,
                                          struct btrfs_device *scrub_dev,
                                          u64 chunk_offset, u64 length,
-                                         u64 dev_offset, int is_dev_replace)
+                                         u64 dev_offset,
+                                         struct btrfs_block_group_cache *cache,
+                                         int is_dev_replace)
 {
        struct btrfs_mapping_tree *map_tree =
                &sctx->dev_root->fs_info->mapping_tree;
@@ -3445,8 +3447,18 @@ static noinline_for_stack int scrub_chunk(struct scrub_ctx *sctx,
        em = lookup_extent_mapping(&map_tree->map_tree, chunk_offset, 1);
        read_unlock(&map_tree->map_tree.lock);
 
-       if (!em)
-               return -EINVAL;
+       if (!em) {
+               /*
+                * Might have been an unused block group deleted by the cleaner
+                * kthread or relocation.
+                */
+               spin_lock(&cache->lock);
+               if (!cache->removed)
+                       ret = -EINVAL;
+               spin_unlock(&cache->lock);
+
+               return ret;
+       }
 
        map = (struct map_lookup *)em->bdev;
        if (em->start != chunk_offset)
@@ -3483,6 +3495,7 @@ int scrub_enumerate_chunks(struct scrub_ctx *sctx,
        u64 length;
        u64 chunk_offset;
        int ret = 0;
+       int ro_set;
        int slot;
        struct extent_buffer *l;
        struct btrfs_key key;
@@ -3568,7 +3581,21 @@ int scrub_enumerate_chunks(struct scrub_ctx *sctx,
                scrub_pause_on(fs_info);
                ret = btrfs_inc_block_group_ro(root, cache);
                scrub_pause_off(fs_info);
-               if (ret) {
+
+               if (ret == 0) {
+                       ro_set = 1;
+               } else if (ret == -ENOSPC) {
+                       /*
+                        * btrfs_inc_block_group_ro return -ENOSPC when it
+                        * failed in creating new chunk for metadata.
+                        * It is not a problem for scrub/replace, because
+                        * metadata are always cowed, and our scrub paused
+                        * commit_transactions.
+                        */
+                       ro_set = 0;
+               } else {
+                       btrfs_warn(fs_info, "failed setting block group ro, ret=%d\n",
+                                  ret);
                        btrfs_put_block_group(cache);
                        break;
                }
@@ -3577,7 +3604,7 @@ int scrub_enumerate_chunks(struct scrub_ctx *sctx,
                dev_replace->cursor_left = found_key.offset;
                dev_replace->item_needs_writeback = 1;
                ret = scrub_chunk(sctx, scrub_dev, chunk_offset, length,
-                                 found_key.offset, is_dev_replace);
+                                 found_key.offset, cache, is_dev_replace);
 
                /*
                 * flush, submit all pending read and write bios, afterwards
@@ -3611,7 +3638,30 @@ int scrub_enumerate_chunks(struct scrub_ctx *sctx,
 
                scrub_pause_off(fs_info);
 
-               btrfs_dec_block_group_ro(root, cache);
+               if (ro_set)
+                       btrfs_dec_block_group_ro(root, cache);
+
+               /*
+                * We might have prevented the cleaner kthread from deleting
+                * this block group if it was already unused because we raced
+                * and set it to RO mode first. So add it back to the unused
+                * list, otherwise it might not ever be deleted unless a manual
+                * balance is triggered or it becomes used and unused again.
+                */
+               spin_lock(&cache->lock);
+               if (!cache->removed && !cache->ro && cache->reserved == 0 &&
+                   btrfs_block_group_used(&cache->item) == 0) {
+                       spin_unlock(&cache->lock);
+                       spin_lock(&fs_info->unused_bgs_lock);
+                       if (list_empty(&cache->bg_list)) {
+                               btrfs_get_block_group(cache);
+                               list_add_tail(&cache->bg_list,
+                                             &fs_info->unused_bgs);
+                       }
+                       spin_unlock(&fs_info->unused_bgs_lock);
+               } else {
+                       spin_unlock(&cache->lock);
+               }
 
                btrfs_put_block_group(cache);
                if (ret)
index c8c3d70c31ffad4e02acd04e0f7dcaa54ad0fe2b..8b72b005bfb9a212518a711a2e476c2d70b47b24 100644 (file)
@@ -898,8 +898,10 @@ int btrfs_test_free_space_cache(void)
        }
 
        root = btrfs_alloc_dummy_root();
-       if (!root)
+       if (IS_ERR(root)) {
+               ret = PTR_ERR(root);
                goto out;
+       }
 
        root->fs_info = btrfs_alloc_dummy_fs_info();
        if (!root->fs_info)
index 418c6a2ad7d88658f8624d99a1ba0e9e84c13d45..3367a3c6f214f5ca248a79fff36c6404a49fbf4f 100644 (file)
@@ -592,6 +592,38 @@ struct btrfs_trans_handle *btrfs_start_transaction(struct btrfs_root *root,
        return start_transaction(root, num_items, TRANS_START,
                                 BTRFS_RESERVE_FLUSH_ALL);
 }
+struct btrfs_trans_handle *btrfs_start_transaction_fallback_global_rsv(
+                                       struct btrfs_root *root,
+                                       unsigned int num_items,
+                                       int min_factor)
+{
+       struct btrfs_trans_handle *trans;
+       u64 num_bytes;
+       int ret;
+
+       trans = btrfs_start_transaction(root, num_items);
+       if (!IS_ERR(trans) || PTR_ERR(trans) != -ENOSPC)
+               return trans;
+
+       trans = btrfs_start_transaction(root, 0);
+       if (IS_ERR(trans))
+               return trans;
+
+       num_bytes = btrfs_calc_trans_metadata_size(root, num_items);
+       ret = btrfs_cond_migrate_bytes(root->fs_info,
+                                      &root->fs_info->trans_block_rsv,
+                                      num_bytes,
+                                      min_factor);
+       if (ret) {
+               btrfs_end_transaction(trans, root);
+               return ERR_PTR(ret);
+       }
+
+       trans->block_rsv = &root->fs_info->trans_block_rsv;
+       trans->bytes_reserved = num_bytes;
+
+       return trans;
+}
 
 struct btrfs_trans_handle *btrfs_start_transaction_lflush(
                                        struct btrfs_root *root,
index b05b2f64d9133313f1af231c4a4254ff16972f00..0da21ca9b3fb312a7ec77b4e8314a9e4b3410075 100644 (file)
@@ -185,6 +185,10 @@ int btrfs_end_transaction(struct btrfs_trans_handle *trans,
                          struct btrfs_root *root);
 struct btrfs_trans_handle *btrfs_start_transaction(struct btrfs_root *root,
                                                   unsigned int num_items);
+struct btrfs_trans_handle *btrfs_start_transaction_fallback_global_rsv(
+                                       struct btrfs_root *root,
+                                       unsigned int num_items,
+                                       int min_factor);
 struct btrfs_trans_handle *btrfs_start_transaction_lflush(
                                        struct btrfs_root *root,
                                        unsigned int num_items);
index a6df8fdc1312ce78e97f9f90037ff5b236a58a92..45645220660996773b1f76cd1d526d4aeae33dac 100644 (file)
@@ -1973,8 +1973,7 @@ void btrfs_rm_dev_replace_remove_srcdev(struct btrfs_fs_info *fs_info,
        if (srcdev->writeable) {
                fs_devices->rw_devices--;
                /* zero out the old super if it is writable */
-               btrfs_scratch_superblocks(srcdev->bdev,
-                                       rcu_str_deref(srcdev->name));
+               btrfs_scratch_superblocks(srcdev->bdev, srcdev->name->str);
        }
 
        if (srcdev->bdev)
@@ -2024,8 +2023,7 @@ void btrfs_destroy_dev_replace_tgtdev(struct btrfs_fs_info *fs_info,
        btrfs_sysfs_rm_device_link(fs_info->fs_devices, tgtdev);
 
        if (tgtdev->bdev) {
-               btrfs_scratch_superblocks(tgtdev->bdev,
-                                       rcu_str_deref(tgtdev->name));
+               btrfs_scratch_superblocks(tgtdev->bdev, tgtdev->name->str);
                fs_info->fs_devices->open_devices--;
        }
        fs_info->fs_devices->num_devices--;
@@ -2853,7 +2851,8 @@ static int btrfs_relocate_chunk(struct btrfs_root *root, u64 chunk_offset)
        if (ret)
                return ret;
 
-       trans = btrfs_start_transaction(root, 0);
+       trans = btrfs_start_trans_remove_block_group(root->fs_info,
+                                                    chunk_offset);
        if (IS_ERR(trans)) {
                ret = PTR_ERR(trans);
                btrfs_std_error(root->fs_info, ret, NULL);
@@ -3123,7 +3122,7 @@ static int chunk_profiles_filter(u64 chunk_type,
        return 1;
 }
 
-static int chunk_usage_filter(struct btrfs_fs_info *fs_info, u64 chunk_offset,
+static int chunk_usage_range_filter(struct btrfs_fs_info *fs_info, u64 chunk_offset,
                              struct btrfs_balance_args *bargs)
 {
        struct btrfs_block_group_cache *cache;
@@ -3156,7 +3155,7 @@ static int chunk_usage_filter(struct btrfs_fs_info *fs_info, u64 chunk_offset,
        return ret;
 }
 
-static int chunk_usage_range_filter(struct btrfs_fs_info *fs_info,
+static int chunk_usage_filter(struct btrfs_fs_info *fs_info,
                u64 chunk_offset, struct btrfs_balance_args *bargs)
 {
        struct btrfs_block_group_cache *cache;
index ec571237273208fcb87f7be1c473b0c6a1392b50..d5c84f6b13538a338d90560b6520be4fe56c3125 100644 (file)
@@ -382,7 +382,7 @@ struct map_lookup {
 #define BTRFS_BALANCE_ARGS_LIMIT       (1ULL << 5)
 #define BTRFS_BALANCE_ARGS_LIMIT_RANGE (1ULL << 6)
 #define BTRFS_BALANCE_ARGS_STRIPES_RANGE (1ULL << 7)
-#define BTRFS_BALANCE_ARGS_USAGE_RANGE (1ULL << 8)
+#define BTRFS_BALANCE_ARGS_USAGE_RANGE (1ULL << 10)
 
 #define BTRFS_BALANCE_ARGS_MASK                        \
        (BTRFS_BALANCE_ARGS_PROFILES |          \
index 6b66dd5d15408676ab6510f7ce415164fe5c0571..a329f5ba35aad8649ce3f644b9b11913c57cc5f8 100644 (file)
@@ -1831,11 +1831,11 @@ cifs_invalidate_mapping(struct inode *inode)
  * @word: long word containing the bit lock
  */
 static int
-cifs_wait_bit_killable(struct wait_bit_key *key)
+cifs_wait_bit_killable(struct wait_bit_key *key, int mode)
 {
-       if (fatal_signal_pending(current))
-               return -ERESTARTSYS;
        freezable_schedule_unsafe();
+       if (signal_pending_state(mode, current))
+               return -ERESTARTSYS;
        return 0;
 }
 
index cb5337d8c273a5dd58e97d9be587fb56d643e52a..602e8441bc0fb6b094ec96dfb3273ff73b8b1506 100644 (file)
@@ -1169,6 +1169,16 @@ do_blockdev_direct_IO(struct kiocb *iocb, struct inode *inode,
                }
        }
 
+       /* Once we sampled i_size check for reads beyond EOF */
+       dio->i_size = i_size_read(inode);
+       if (iov_iter_rw(iter) == READ && offset >= dio->i_size) {
+               if (dio->flags & DIO_LOCKING)
+                       mutex_unlock(&inode->i_mutex);
+               kmem_cache_free(dio_cache, dio);
+               retval = 0;
+               goto out;
+       }
+
        /*
         * For file extending writes updating i_size before data writeouts
         * complete can expose uninitialized blocks in dumb filesystems.
@@ -1222,7 +1232,6 @@ do_blockdev_direct_IO(struct kiocb *iocb, struct inode *inode,
        sdio.next_block_for_io = -1;
 
        dio->iocb = iocb;
-       dio->i_size = i_size_read(inode);
 
        spin_lock_init(&dio->bio_lock);
        dio->refcount = 1;
index 87e9d796cf7dd9ae2e4e0f221867dc69e8ea28df..3a37bd3f9637811c3b86e5c05be5aa47f32819c3 100644 (file)
@@ -421,7 +421,7 @@ static void lowcomms_write_space(struct sock *sk)
 
        if (test_and_clear_bit(CF_APP_LIMITED, &con->flags)) {
                con->sock->sk->sk_write_pending--;
-               clear_bit(SOCK_ASYNC_NOSPACE, &con->sock->flags);
+               clear_bit(SOCKWQ_ASYNC_NOSPACE, &con->sock->flags);
        }
 
        if (!test_and_set_bit(CF_WRITE_PENDING, &con->flags))
@@ -1448,7 +1448,7 @@ static void send_to_sock(struct connection *con)
                                              msg_flags);
                        if (ret == -EAGAIN || ret == 0) {
                                if (ret == -EAGAIN &&
-                                   test_bit(SOCK_ASYNC_NOSPACE, &con->sock->flags) &&
+                                   test_bit(SOCKWQ_ASYNC_NOSPACE, &con->sock->flags) &&
                                    !test_and_set_bit(CF_APP_LIMITED, &con->flags)) {
                                        /* Notify TCP that we're limited by the
                                         * application window size.
index 73c64daa0f5517b4ff8271bd17e25740bb83d506..60f03b78914e3012e50c90a9e9069aff615467be 100644 (file)
@@ -592,10 +592,7 @@ static struct page *__r4w_get_page(void *priv, u64 offset, bool *uptodate)
                        }
                        unlock_page(page);
                }
-               if (PageDirty(page) || PageWriteback(page))
-                       *uptodate = true;
-               else
-                       *uptodate = PageUptodate(page);
+               *uptodate = PageUptodate(page);
                EXOFS_DBGMSG2("index=0x%lx uptodate=%d\n", index, *uptodate);
                return page;
        } else {
index af06830bfc00c743369737551e7bceea3b61eede..1a0835073663ff3f1dad1f376328de5e2b1332ce 100644 (file)
@@ -389,7 +389,7 @@ int ext4_encrypted_zeroout(struct inode *inode, struct ext4_extent *ex)
        struct ext4_crypto_ctx  *ctx;
        struct page             *ciphertext_page = NULL;
        struct bio              *bio;
-       ext4_lblk_t             lblk = ex->ee_block;
+       ext4_lblk_t             lblk = le32_to_cpu(ex->ee_block);
        ext4_fsblk_t            pblk = ext4_ext_pblock(ex);
        unsigned int            len = ext4_ext_get_actual_len(ex);
        int                     ret, err = 0;
index 750063f7a50c6cc2b9808318538762be67ce098d..cc7ca4e87144a540332213ce03b63e80e601f40e 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/seqlock.h>
 #include <linux/mutex.h>
 #include <linux/timer.h>
+#include <linux/version.h>
 #include <linux/wait.h>
 #include <linux/blockgroup_lock.h>
 #include <linux/percpu_counter.h>
@@ -727,19 +728,55 @@ struct move_extent {
        <= (EXT4_GOOD_OLD_INODE_SIZE +                  \
            (einode)->i_extra_isize))                   \
 
+/*
+ * We use an encoding that preserves the times for extra epoch "00":
+ *
+ * extra  msb of                         adjust for signed
+ * epoch  32-bit                         32-bit tv_sec to
+ * bits   time    decoded 64-bit tv_sec  64-bit tv_sec      valid time range
+ * 0 0    1    -0x80000000..-0x00000001  0x000000000 1901-12-13..1969-12-31
+ * 0 0    0    0x000000000..0x07fffffff  0x000000000 1970-01-01..2038-01-19
+ * 0 1    1    0x080000000..0x0ffffffff  0x100000000 2038-01-19..2106-02-07
+ * 0 1    0    0x100000000..0x17fffffff  0x100000000 2106-02-07..2174-02-25
+ * 1 0    1    0x180000000..0x1ffffffff  0x200000000 2174-02-25..2242-03-16
+ * 1 0    0    0x200000000..0x27fffffff  0x200000000 2242-03-16..2310-04-04
+ * 1 1    1    0x280000000..0x2ffffffff  0x300000000 2310-04-04..2378-04-22
+ * 1 1    0    0x300000000..0x37fffffff  0x300000000 2378-04-22..2446-05-10
+ *
+ * Note that previous versions of the kernel on 64-bit systems would
+ * incorrectly use extra epoch bits 1,1 for dates between 1901 and
+ * 1970.  e2fsck will correct this, assuming that it is run on the
+ * affected filesystem before 2242.
+ */
+
 static inline __le32 ext4_encode_extra_time(struct timespec *time)
 {
-       return cpu_to_le32((sizeof(time->tv_sec) > 4 ?
-                          (time->tv_sec >> 32) & EXT4_EPOCH_MASK : 0) |
-                          ((time->tv_nsec << EXT4_EPOCH_BITS) & EXT4_NSEC_MASK));
+       u32 extra = sizeof(time->tv_sec) > 4 ?
+               ((time->tv_sec - (s32)time->tv_sec) >> 32) & EXT4_EPOCH_MASK : 0;
+       return cpu_to_le32(extra | (time->tv_nsec << EXT4_EPOCH_BITS));
 }
 
 static inline void ext4_decode_extra_time(struct timespec *time, __le32 extra)
 {
-       if (sizeof(time->tv_sec) > 4)
-              time->tv_sec |= (__u64)(le32_to_cpu(extra) & EXT4_EPOCH_MASK)
-                              << 32;
-       time->tv_nsec = (le32_to_cpu(extra) & EXT4_NSEC_MASK) >> EXT4_EPOCH_BITS;
+       if (unlikely(sizeof(time->tv_sec) > 4 &&
+                       (extra & cpu_to_le32(EXT4_EPOCH_MASK)))) {
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,20,0)
+               /* Handle legacy encoding of pre-1970 dates with epoch
+                * bits 1,1.  We assume that by kernel version 4.20,
+                * everyone will have run fsck over the affected
+                * filesystems to correct the problem.  (This
+                * backwards compatibility may be removed before this
+                * time, at the discretion of the ext4 developers.)
+                */
+               u64 extra_bits = le32_to_cpu(extra) & EXT4_EPOCH_MASK;
+               if (extra_bits == 3 && ((time->tv_sec) & 0x80000000) != 0)
+                       extra_bits = 0;
+               time->tv_sec += extra_bits << 32;
+#else
+               time->tv_sec += (u64)(le32_to_cpu(extra) & EXT4_EPOCH_MASK) << 32;
+#endif
+       }
+       time->tv_nsec = (le32_to_cpu(extra) & EXT4_NSEC_MASK) >> EXT4_EPOCH_BITS;
 }
 
 #define EXT4_INODE_SET_XTIME(xtime, inode, raw_inode)                         \
index abe2401ce405669f0d315319f5275a9fc321c697..e8e7af62ac95fc4e5268c32df1bc496a337202a7 100644 (file)
@@ -52,7 +52,7 @@ static const char *ext4_encrypted_follow_link(struct dentry *dentry, void **cook
        /* Symlink is encrypted */
        sd = (struct ext4_encrypted_symlink_data *)caddr;
        cstr.name = sd->encrypted_path;
-       cstr.len  = le32_to_cpu(sd->len);
+       cstr.len  = le16_to_cpu(sd->len);
        if ((cstr.len +
             sizeof(struct ext4_encrypted_symlink_data) - 1) >
            max_size) {
index 1b57c72f4a009aafc8c3510eac81dd9d8a5f9482..1420a3c614afb1a4c06e87471163acf01b3b98d8 100644 (file)
@@ -358,7 +358,7 @@ static int name##_open(struct inode *inode, struct file *file) \
        return single_open(file, ext4_seq_##name##_show, PDE_DATA(inode)); \
 } \
 \
-const struct file_operations ext4_seq_##name##_fops = { \
+static const struct file_operations ext4_seq_##name##_fops = { \
        .owner          = THIS_MODULE, \
        .open           = name##_open, \
        .read           = seq_read, \
index eae2c11268bcb484075cfd08482beeb172dd66bc..8e3ee1936c7e38ba381b33c26b2f1847422a613f 100644 (file)
@@ -549,6 +549,8 @@ static int cuse_channel_release(struct inode *inode, struct file *file)
                unregister_chrdev_region(cc->cdev->dev, 1);
                cdev_del(cc->cdev);
        }
+       /* Base reference is now owned by "fud" */
+       fuse_conn_put(&cc->fc);
 
        rc = fuse_dev_release(inode, file);     /* puts the base reference */
 
index e0faf8f2c868a26b80331ef78c89db85091715ea..570ca4053c805eb76acd76a44161f8349a9a6325 100644 (file)
@@ -1049,6 +1049,7 @@ static ssize_t fuse_fill_write_pages(struct fuse_req *req,
                tmp = iov_iter_copy_from_user_atomic(page, ii, offset, bytes);
                flush_dcache_page(page);
 
+               iov_iter_advance(ii, tmp);
                if (!tmp) {
                        unlock_page(page);
                        page_cache_release(page);
@@ -1061,7 +1062,6 @@ static ssize_t fuse_fill_write_pages(struct fuse_req *req,
                req->page_descs[req->num_pages].length = tmp;
                req->num_pages++;
 
-               iov_iter_advance(ii, tmp);
                count += tmp;
                pos += tmp;
                offset += tmp;
index 89463eee67914643a02ce711463e62fac0b83c8d..ca181e81c765518d4a599025c914adbac626e739 100644 (file)
@@ -1009,7 +1009,8 @@ out:
 }
 
 /* Fast check whether buffer is already attached to the required transaction */
-static bool jbd2_write_access_granted(handle_t *handle, struct buffer_head *bh)
+static bool jbd2_write_access_granted(handle_t *handle, struct buffer_head *bh,
+                                                       bool undo)
 {
        struct journal_head *jh;
        bool ret = false;
@@ -1036,6 +1037,9 @@ static bool jbd2_write_access_granted(handle_t *handle, struct buffer_head *bh)
        jh = READ_ONCE(bh->b_private);
        if (!jh)
                goto out;
+       /* For undo access buffer must have data copied */
+       if (undo && !jh->b_committed_data)
+               goto out;
        if (jh->b_transaction != handle->h_transaction &&
            jh->b_next_transaction != handle->h_transaction)
                goto out;
@@ -1073,7 +1077,7 @@ int jbd2_journal_get_write_access(handle_t *handle, struct buffer_head *bh)
        struct journal_head *jh;
        int rc;
 
-       if (jbd2_write_access_granted(handle, bh))
+       if (jbd2_write_access_granted(handle, bh, false))
                return 0;
 
        jh = jbd2_journal_add_journal_head(bh);
@@ -1210,7 +1214,7 @@ int jbd2_journal_get_undo_access(handle_t *handle, struct buffer_head *bh)
        char *committed_data = NULL;
 
        JBUFFER_TRACE(jh, "entry");
-       if (jbd2_write_access_granted(handle, bh))
+       if (jbd2_write_access_granted(handle, bh, true))
                return 0;
 
        jh = jbd2_journal_add_journal_head(bh);
@@ -2152,6 +2156,7 @@ static int journal_unmap_buffer(journal_t *journal, struct buffer_head *bh,
 
                if (!buffer_dirty(bh)) {
                        /* bdflush has written it.  We can drop it now */
+                       __jbd2_journal_remove_checkpoint(jh);
                        goto zap_buffer;
                }
 
@@ -2181,6 +2186,7 @@ static int journal_unmap_buffer(journal_t *journal, struct buffer_head *bh,
                                /* The orphan record's transaction has
                                 * committed.  We can cleanse this buffer */
                                clear_buffer_jbddirty(bh);
+                               __jbd2_journal_remove_checkpoint(jh);
                                goto zap_buffer;
                        }
                }
index d84d7c7515fc44415f11488f192e52ef3c9c9990..0c3974cd3ecd55670ccab51c596b0b141cbdd721 100644 (file)
@@ -1996,7 +1996,6 @@ static const char *path_init(struct nameidata *nd, unsigned flags)
        nd->last_type = LAST_ROOT; /* if there are only slashes... */
        nd->flags = flags | LOOKUP_JUMPED | LOOKUP_PARENT;
        nd->depth = 0;
-       nd->total_link_count = 0;
        if (flags & LOOKUP_ROOT) {
                struct dentry *root = nd->root.dentry;
                struct inode *inode = root->d_inode;
index 326d9e10d83370f56061220c51e72a42de0595b2..c7e8b87da5b24d13dff36f5d2510244c01b7abf4 100644 (file)
@@ -75,11 +75,11 @@ nfs_fattr_to_ino_t(struct nfs_fattr *fattr)
  * nfs_wait_bit_killable - helper for functions that are sleeping on bit locks
  * @word: long word containing the bit lock
  */
-int nfs_wait_bit_killable(struct wait_bit_key *key)
+int nfs_wait_bit_killable(struct wait_bit_key *key, int mode)
 {
-       if (fatal_signal_pending(current))
-               return -ERESTARTSYS;
        freezable_schedule_unsafe();
+       if (signal_pending_state(mode, current))
+               return -ERESTARTSYS;
        return 0;
 }
 EXPORT_SYMBOL_GPL(nfs_wait_bit_killable);
@@ -618,7 +618,10 @@ void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr,
                nfs_inc_stats(inode, NFSIOS_SETATTRTRUNC);
                nfs_vmtruncate(inode, attr->ia_size);
        }
-       nfs_update_inode(inode, fattr);
+       if (fattr->valid)
+               nfs_update_inode(inode, fattr);
+       else
+               NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ATTR;
        spin_unlock(&inode->i_lock);
 }
 EXPORT_SYMBOL_GPL(nfs_setattr_update_inode);
@@ -1824,7 +1827,11 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
                if ((long)fattr->gencount - (long)nfsi->attr_gencount > 0)
                        nfsi->attr_gencount = fattr->gencount;
        }
-       invalid &= ~NFS_INO_INVALID_ATTR;
+
+       /* Don't declare attrcache up to date if there were no attrs! */
+       if (fattr->valid != 0)
+               invalid &= ~NFS_INO_INVALID_ATTR;
+
        /* Don't invalidate the data if we were to blame */
        if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode)
                                || S_ISLNK(inode->i_mode)))
index 56cfde26fb9cea0100a99bb7c3fe8a2be813dc63..9dea85f7f918ec410c5281f959e6f546c1700bf2 100644 (file)
@@ -379,7 +379,7 @@ extern int nfs_drop_inode(struct inode *);
 extern void nfs_clear_inode(struct inode *);
 extern void nfs_evict_inode(struct inode *);
 void nfs_zap_acl_cache(struct inode *inode);
-extern int nfs_wait_bit_killable(struct wait_bit_key *key);
+extern int nfs_wait_bit_killable(struct wait_bit_key *key, int mode);
 
 /* super.c */
 extern const struct super_operations nfs_sops;
index 3e92a3cde15d8b61878a7c2ce7d13da1cf01b290..6b1ce9825430c7c9659b49ac9bff545b620bd7bb 100644 (file)
@@ -14,7 +14,7 @@
 #include "pnfs.h"
 #include "internal.h"
 
-#define NFSDBG_FACILITY NFSDBG_PNFS
+#define NFSDBG_FACILITY NFSDBG_PROC
 
 static int nfs42_set_rw_stateid(nfs4_stateid *dst, struct file *file,
                                fmode_t fmode)
@@ -284,6 +284,7 @@ static int _nfs42_proc_clone(struct rpc_message *msg, struct file *src_f,
                .dst_fh = NFS_FH(dst_inode),
                .src_offset = src_offset,
                .dst_offset = dst_offset,
+               .count = count,
                .dst_bitmask = server->cache_consistency_bitmask,
        };
        struct nfs42_clone_res res = {
index 223bedda64ae49f3d94226677e652e31da4c8d84..10410e8b58530389d7efb18352e8a6253d12b267 100644 (file)
@@ -33,7 +33,7 @@ static int nfs_get_cb_ident_idr(struct nfs_client *clp, int minorversion)
                return ret;
        idr_preload(GFP_KERNEL);
        spin_lock(&nn->nfs_client_lock);
-       ret = idr_alloc(&nn->cb_ident_idr, clp, 0, 0, GFP_NOWAIT);
+       ret = idr_alloc(&nn->cb_ident_idr, clp, 1, 0, GFP_NOWAIT);
        if (ret >= 0)
                clp->cl_cb_ident = ret;
        spin_unlock(&nn->nfs_client_lock);
index 4aa571956cd618499df260f6bcf6a0f7c2df8045..db9b5fea5b3ef12f6eacf36cd2154c2db7d4d9f2 100644 (file)
@@ -7,6 +7,7 @@
 #include <linux/file.h>
 #include <linux/falloc.h>
 #include <linux/nfs_fs.h>
+#include <uapi/linux/btrfs.h>  /* BTRFS_IOC_CLONE/BTRFS_IOC_CLONE_RANGE */
 #include "delegation.h"
 #include "internal.h"
 #include "iostat.h"
@@ -203,6 +204,7 @@ nfs42_ioctl_clone(struct file *dst_file, unsigned long srcfd,
        struct fd src_file;
        struct inode *src_inode;
        unsigned int bs = server->clone_blksize;
+       bool same_inode = false;
        int ret;
 
        /* dst file must be opened for writing */
@@ -221,10 +223,8 @@ nfs42_ioctl_clone(struct file *dst_file, unsigned long srcfd,
 
        src_inode = file_inode(src_file.file);
 
-       /* src and dst must be different files */
-       ret = -EINVAL;
        if (src_inode == dst_inode)
-               goto out_fput;
+               same_inode = true;
 
        /* src file must be opened for reading */
        if (!(src_file.file->f_mode & FMODE_READ))
@@ -249,8 +249,16 @@ nfs42_ioctl_clone(struct file *dst_file, unsigned long srcfd,
                        goto out_fput;
        }
 
+       /* verify if ranges are overlapped within the same file */
+       if (same_inode) {
+               if (dst_off + count > src_off && dst_off < src_off + count)
+                       goto out_fput;
+       }
+
        /* XXX: do we lock at all? what if server needs CB_RECALL_LAYOUT? */
-       if (dst_inode < src_inode) {
+       if (same_inode) {
+               mutex_lock(&src_inode->i_mutex);
+       } else if (dst_inode < src_inode) {
                mutex_lock_nested(&dst_inode->i_mutex, I_MUTEX_PARENT);
                mutex_lock_nested(&src_inode->i_mutex, I_MUTEX_CHILD);
        } else {
@@ -275,7 +283,9 @@ nfs42_ioctl_clone(struct file *dst_file, unsigned long srcfd,
                truncate_inode_pages_range(&dst_inode->i_data, dst_off, dst_off + count - 1);
 
 out_unlock:
-       if (dst_inode < src_inode) {
+       if (same_inode) {
+               mutex_unlock(&src_inode->i_mutex);
+       } else if (dst_inode < src_inode) {
                mutex_unlock(&src_inode->i_mutex);
                mutex_unlock(&dst_inode->i_mutex);
        } else {
@@ -291,46 +301,31 @@ out_drop_write:
 
 static long nfs42_ioctl_clone_range(struct file *dst_file, void __user *argp)
 {
-       struct nfs_ioctl_clone_range_args args;
+       struct btrfs_ioctl_clone_range_args args;
 
        if (copy_from_user(&args, argp, sizeof(args)))
                return -EFAULT;
 
-       return nfs42_ioctl_clone(dst_file, args.src_fd, args.src_off, args.dst_off, args.count);
-}
-#else
-static long nfs42_ioctl_clone(struct file *dst_file, unsigned long srcfd,
-               u64 src_off, u64 dst_off, u64 count)
-{
-       return -ENOTTY;
-}
-
-static long nfs42_ioctl_clone_range(struct file *dst_file, void __user *argp)
-{
-       return -ENOTTY;
+       return nfs42_ioctl_clone(dst_file, args.src_fd, args.src_offset,
+                                args.dest_offset, args.src_length);
 }
-#endif /* CONFIG_NFS_V4_2 */
 
 long nfs4_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
        void __user *argp = (void __user *)arg;
 
        switch (cmd) {
-       case NFS_IOC_CLONE:
+       case BTRFS_IOC_CLONE:
                return nfs42_ioctl_clone(file, arg, 0, 0, 0);
-       case NFS_IOC_CLONE_RANGE:
+       case BTRFS_IOC_CLONE_RANGE:
                return nfs42_ioctl_clone_range(file, argp);
        }
 
        return -ENOTTY;
 }
+#endif /* CONFIG_NFS_V4_2 */
 
 const struct file_operations nfs4_file_operations = {
-#ifdef CONFIG_NFS_V4_2
-       .llseek         = nfs4_file_llseek,
-#else
-       .llseek         = nfs_file_llseek,
-#endif
        .read_iter      = nfs_file_read,
        .write_iter     = nfs_file_write,
        .mmap           = nfs_file_mmap,
@@ -342,14 +337,14 @@ const struct file_operations nfs4_file_operations = {
        .flock          = nfs_flock,
        .splice_read    = nfs_file_splice_read,
        .splice_write   = iter_file_splice_write,
-#ifdef CONFIG_NFS_V4_2
-       .fallocate      = nfs42_fallocate,
-#endif /* CONFIG_NFS_V4_2 */
        .check_flags    = nfs_check_flags,
        .setlease       = simple_nosetlease,
-#ifdef CONFIG_COMPAT
+#ifdef CONFIG_NFS_V4_2
+       .llseek         = nfs4_file_llseek,
+       .fallocate      = nfs42_fallocate,
        .unlocked_ioctl = nfs4_ioctl,
-#else
        .compat_ioctl   = nfs4_ioctl,
-#endif /* CONFIG_COMPAT */
+#else
+       .llseek         = nfs_file_llseek,
+#endif
 };
index 765a035593638cfd17b4aedd646c0362068343c6..89818036f035b01eaaa4e45797205d53f48e9934 100644 (file)
@@ -7866,7 +7866,7 @@ static void nfs4_layoutget_done(struct rpc_task *task, void *calldata)
                        spin_unlock(&inode->i_lock);
                goto out_restart;
        }
-       if (nfs4_async_handle_error(task, server, state, NULL) == -EAGAIN)
+       if (nfs4_async_handle_error(task, server, state, &lgp->timeout) == -EAGAIN)
                goto out_restart;
 out:
        dprintk("<-- %s\n", __func__);
index dfed4f5c8fccf91a91b5669461d4a3f490b12cb2..4e4441216804ec550f2c135ef0f393f4f7a1426c 100644 (file)
@@ -3615,6 +3615,7 @@ static int decode_attr_fs_locations(struct xdr_stream *xdr, uint32_t *bitmap, st
        status = 0;
        if (unlikely(!(bitmap[0] & FATTR4_WORD0_FS_LOCATIONS)))
                goto out;
+       bitmap[0] &= ~FATTR4_WORD0_FS_LOCATIONS;
        status = -EIO;
        /* Ignore borken servers that return unrequested attrs */
        if (unlikely(res == NULL))
index 5c0c6b58157f906d6c35ce737a6d4a5623027bf1..9aebffb4050597e1daae74f28375d86335f73e0c 100644 (file)
@@ -476,10 +476,7 @@ static struct page *__r4w_get_page(void *priv, u64 offset, bool *uptodate)
                }
                unlock_page(page);
        }
-       if (PageDirty(page) || PageWriteback(page))
-               *uptodate = true;
-       else
-               *uptodate = PageUptodate(page);
+       *uptodate = PageUptodate(page);
        dprintk("%s: index=0x%lx uptodate=%d\n", __func__, index, *uptodate);
        return page;
 }
index fe3ddd20ff89095331ad854bafb4b26bc019e01e..452a011ba0d8a33e9e4b9afd858f82858185f57e 100644 (file)
@@ -129,7 +129,7 @@ __nfs_iocounter_wait(struct nfs_io_counter *c)
                set_bit(NFS_IO_INPROGRESS, &c->flags);
                if (atomic_read(&c->io_count) == 0)
                        break;
-               ret = nfs_wait_bit_killable(&q.key);
+               ret = nfs_wait_bit_killable(&q.key, TASK_KILLABLE);
        } while (atomic_read(&c->io_count) != 0 && !ret);
        finish_wait(wq, &q.wait);
        return ret;
index 93496c0598375409876f4a25f95d90ef7feb7334..bec0384499f76dd1acc8fb13bbf34c2ee17e6a9b 100644 (file)
@@ -872,33 +872,38 @@ send_layoutget(struct pnfs_layout_hdr *lo,
 
        dprintk("--> %s\n", __func__);
 
-       lgp = kzalloc(sizeof(*lgp), gfp_flags);
-       if (lgp == NULL)
-               return NULL;
+       /*
+        * Synchronously retrieve layout information from server and
+        * store in lseg. If we race with a concurrent seqid morphing
+        * op, then re-send the LAYOUTGET.
+        */
+       do {
+               lgp = kzalloc(sizeof(*lgp), gfp_flags);
+               if (lgp == NULL)
+                       return NULL;
+
+               i_size = i_size_read(ino);
+
+               lgp->args.minlength = PAGE_CACHE_SIZE;
+               if (lgp->args.minlength > range->length)
+                       lgp->args.minlength = range->length;
+               if (range->iomode == IOMODE_READ) {
+                       if (range->offset >= i_size)
+                               lgp->args.minlength = 0;
+                       else if (i_size - range->offset < lgp->args.minlength)
+                               lgp->args.minlength = i_size - range->offset;
+               }
+               lgp->args.maxcount = PNFS_LAYOUT_MAXSIZE;
+               lgp->args.range = *range;
+               lgp->args.type = server->pnfs_curr_ld->id;
+               lgp->args.inode = ino;
+               lgp->args.ctx = get_nfs_open_context(ctx);
+               lgp->gfp_flags = gfp_flags;
+               lgp->cred = lo->plh_lc_cred;
 
-       i_size = i_size_read(ino);
+               lseg = nfs4_proc_layoutget(lgp, gfp_flags);
+       } while (lseg == ERR_PTR(-EAGAIN));
 
-       lgp->args.minlength = PAGE_CACHE_SIZE;
-       if (lgp->args.minlength > range->length)
-               lgp->args.minlength = range->length;
-       if (range->iomode == IOMODE_READ) {
-               if (range->offset >= i_size)
-                       lgp->args.minlength = 0;
-               else if (i_size - range->offset < lgp->args.minlength)
-                       lgp->args.minlength = i_size - range->offset;
-       }
-       lgp->args.maxcount = PNFS_LAYOUT_MAXSIZE;
-       lgp->args.range = *range;
-       lgp->args.type = server->pnfs_curr_ld->id;
-       lgp->args.inode = ino;
-       lgp->args.ctx = get_nfs_open_context(ctx);
-       lgp->gfp_flags = gfp_flags;
-       lgp->cred = lo->plh_lc_cred;
-
-       /* Synchronously retrieve layout information from server and
-        * store in lseg.
-        */
-       lseg = nfs4_proc_layoutget(lgp, gfp_flags);
        if (IS_ERR(lseg)) {
                switch (PTR_ERR(lseg)) {
                case -ENOMEM:
@@ -1461,11 +1466,11 @@ static bool pnfs_within_mdsthreshold(struct nfs_open_context *ctx,
 }
 
 /* stop waiting if someone clears NFS_LAYOUT_RETRY_LAYOUTGET bit. */
-static int pnfs_layoutget_retry_bit_wait(struct wait_bit_key *key)
+static int pnfs_layoutget_retry_bit_wait(struct wait_bit_key *key, int mode)
 {
        if (!test_bit(NFS_LAYOUT_RETRY_LAYOUTGET, key->flags))
                return 1;
-       return nfs_wait_bit_killable(key);
+       return nfs_wait_bit_killable(key, mode);
 }
 
 static bool pnfs_prepare_to_retry_layoutget(struct pnfs_layout_hdr *lo)
@@ -1687,6 +1692,7 @@ pnfs_layout_process(struct nfs4_layoutget *lgp)
                /* existing state ID, make sure the sequence number matches. */
                if (pnfs_layout_stateid_blocked(lo, &res->stateid)) {
                        dprintk("%s forget reply due to sequence\n", __func__);
+                       status = -EAGAIN;
                        goto out_forget_reply;
                }
                pnfs_set_layout_stateid(lo, &res->stateid, false);
index a03f6f433075c02d3c87c192b362d2c7f2e96952..3123408da9352b365e8bb3ca5e619a8f188cdc5a 100644 (file)
@@ -367,13 +367,11 @@ static int ocfs2_mknod(struct inode *dir,
                goto leave;
        }
 
-       status = posix_acl_create(dir, &mode, &default_acl, &acl);
+       status = posix_acl_create(dir, &inode->i_mode, &default_acl, &acl);
        if (status) {
                mlog_errno(status);
                goto leave;
        }
-       /* update inode->i_mode after mask with "umask". */
-       inode->i_mode = mode;
 
        handle = ocfs2_start_trans(osb, ocfs2_mknod_credits(osb->sb,
                                                            S_ISDIR(mode),
index 871fcb67be9741f2aab81f3d6552306dedf4c967..0a8983492d917bbc61888559e8417f738eb607be 100644 (file)
@@ -195,8 +195,7 @@ int ovl_set_attr(struct dentry *upperdentry, struct kstat *stat)
 
 static int ovl_copy_up_locked(struct dentry *workdir, struct dentry *upperdir,
                              struct dentry *dentry, struct path *lowerpath,
-                             struct kstat *stat, struct iattr *attr,
-                             const char *link)
+                             struct kstat *stat, const char *link)
 {
        struct inode *wdir = workdir->d_inode;
        struct inode *udir = upperdir->d_inode;
@@ -240,8 +239,6 @@ static int ovl_copy_up_locked(struct dentry *workdir, struct dentry *upperdir,
 
        mutex_lock(&newdentry->d_inode->i_mutex);
        err = ovl_set_attr(newdentry, stat);
-       if (!err && attr)
-               err = notify_change(newdentry, attr, NULL);
        mutex_unlock(&newdentry->d_inode->i_mutex);
        if (err)
                goto out_cleanup;
@@ -286,8 +283,7 @@ out_cleanup:
  * that point the file will have already been copied up anyway.
  */
 int ovl_copy_up_one(struct dentry *parent, struct dentry *dentry,
-                   struct path *lowerpath, struct kstat *stat,
-                   struct iattr *attr)
+                   struct path *lowerpath, struct kstat *stat)
 {
        struct dentry *workdir = ovl_workdir(dentry);
        int err;
@@ -345,26 +341,19 @@ int ovl_copy_up_one(struct dentry *parent, struct dentry *dentry,
        }
        upperdentry = ovl_dentry_upper(dentry);
        if (upperdentry) {
-               unlock_rename(workdir, upperdir);
+               /* Raced with another copy-up?  Nothing to do, then... */
                err = 0;
-               /* Raced with another copy-up?  Do the setattr here */
-               if (attr) {
-                       mutex_lock(&upperdentry->d_inode->i_mutex);
-                       err = notify_change(upperdentry, attr, NULL);
-                       mutex_unlock(&upperdentry->d_inode->i_mutex);
-               }
-               goto out_put_cred;
+               goto out_unlock;
        }
 
        err = ovl_copy_up_locked(workdir, upperdir, dentry, lowerpath,
-                                stat, attr, link);
+                                stat, link);
        if (!err) {
                /* Restore timestamps on parent (best effort) */
                ovl_set_timestamps(upperdir, &pstat);
        }
 out_unlock:
        unlock_rename(workdir, upperdir);
-out_put_cred:
        revert_creds(old_cred);
        put_cred(override_cred);
 
@@ -406,7 +395,7 @@ int ovl_copy_up(struct dentry *dentry)
                ovl_path_lower(next, &lowerpath);
                err = vfs_getattr(&lowerpath, &stat);
                if (!err)
-                       err = ovl_copy_up_one(parent, next, &lowerpath, &stat, NULL);
+                       err = ovl_copy_up_one(parent, next, &lowerpath, &stat);
 
                dput(parent);
                dput(next);
index ec0c2a050043afbb3eff4c7451930dc6d86006ec..4060ffde87225c81114d086c000773d4019255b5 100644 (file)
@@ -12,8 +12,7 @@
 #include <linux/xattr.h>
 #include "overlayfs.h"
 
-static int ovl_copy_up_last(struct dentry *dentry, struct iattr *attr,
-                           bool no_data)
+static int ovl_copy_up_truncate(struct dentry *dentry)
 {
        int err;
        struct dentry *parent;
@@ -30,10 +29,8 @@ static int ovl_copy_up_last(struct dentry *dentry, struct iattr *attr,
        if (err)
                goto out_dput_parent;
 
-       if (no_data)
-               stat.size = 0;
-
-       err = ovl_copy_up_one(parent, dentry, &lowerpath, &stat, attr);
+       stat.size = 0;
+       err = ovl_copy_up_one(parent, dentry, &lowerpath, &stat);
 
 out_dput_parent:
        dput(parent);
@@ -49,13 +46,13 @@ int ovl_setattr(struct dentry *dentry, struct iattr *attr)
        if (err)
                goto out;
 
-       upperdentry = ovl_dentry_upper(dentry);
-       if (upperdentry) {
+       err = ovl_copy_up(dentry);
+       if (!err) {
+               upperdentry = ovl_dentry_upper(dentry);
+
                mutex_lock(&upperdentry->d_inode->i_mutex);
                err = notify_change(upperdentry, attr, NULL);
                mutex_unlock(&upperdentry->d_inode->i_mutex);
-       } else {
-               err = ovl_copy_up_last(dentry, attr, false);
        }
        ovl_drop_write(dentry);
 out:
@@ -353,7 +350,7 @@ struct inode *ovl_d_select_inode(struct dentry *dentry, unsigned file_flags)
                        return ERR_PTR(err);
 
                if (file_flags & O_TRUNC)
-                       err = ovl_copy_up_last(dentry, NULL, true);
+                       err = ovl_copy_up_truncate(dentry);
                else
                        err = ovl_copy_up(dentry);
                ovl_drop_write(dentry);
index ea5a40b06e3ad3f9e114bd7d3aab8b931b567051..e17154aeaae4761ca8ec466b96afe913cd40c322 100644 (file)
@@ -194,7 +194,6 @@ void ovl_cleanup(struct inode *dir, struct dentry *dentry);
 /* copy_up.c */
 int ovl_copy_up(struct dentry *dentry);
 int ovl_copy_up_one(struct dentry *parent, struct dentry *dentry,
-                   struct path *lowerpath, struct kstat *stat,
-                   struct iattr *attr);
+                   struct path *lowerpath, struct kstat *stat);
 int ovl_copy_xattr(struct dentry *old, struct dentry *new);
 int ovl_set_attr(struct dentry *upper, struct kstat *stat);
index 801c21cd77fe4f1d344aed6fa7b28369972d82b2..4cf700d50b4037e6c334b0647cdb81b816f9ef65 100644 (file)
@@ -809,6 +809,13 @@ static int splice_from_pipe_feed(struct pipe_inode_info *pipe, struct splice_des
  */
 static int splice_from_pipe_next(struct pipe_inode_info *pipe, struct splice_desc *sd)
 {
+       /*
+        * Check for signal early to make process killable when there are
+        * always buffers available
+        */
+       if (signal_pending(current))
+               return -ERESTARTSYS;
+
        while (!pipe->nrbufs) {
                if (!pipe->writers)
                        return 0;
@@ -884,6 +891,7 @@ ssize_t __splice_from_pipe(struct pipe_inode_info *pipe, struct splice_desc *sd,
 
        splice_from_pipe_begin(sd);
        do {
+               cond_resched();
                ret = splice_from_pipe_next(pipe, sd);
                if (ret > 0)
                        ret = splice_from_pipe_feed(pipe, sd, actor);
index 590ad9206e3f4e761d2c2ad95cfaedfa76b47e16..02fa1dcc5969f6b596a6c527170fcf9193c437e5 100644 (file)
@@ -162,15 +162,8 @@ void sysv_set_inode(struct inode *inode, dev_t rdev)
                inode->i_fop = &sysv_dir_operations;
                inode->i_mapping->a_ops = &sysv_aops;
        } else if (S_ISLNK(inode->i_mode)) {
-               if (inode->i_blocks) {
-                       inode->i_op = &sysv_symlink_inode_operations;
-                       inode->i_mapping->a_ops = &sysv_aops;
-               } else {
-                       inode->i_op = &simple_symlink_inode_operations;
-                       inode->i_link = (char *)SYSV_I(inode)->i_data;
-                       nd_terminate_link(inode->i_link, inode->i_size,
-                               sizeof(SYSV_I(inode)->i_data) - 1);
-               }
+               inode->i_op = &sysv_symlink_inode_operations;
+               inode->i_mapping->a_ops = &sysv_aops;
        } else
                init_special_inode(inode, inode->i_mode, rdev);
 }
index db284bff29dcceb39360d458cec3a194745955f8..9dbb739cafa0c16dda9d011d30ce8cd9b4091fd4 100644 (file)
@@ -5,7 +5,7 @@
  * Copyright 2001 Red Hat, Inc.
  * Based on code from mm/memory.c Copyright Linus Torvalds and others.
  *
- * Copyright 2011 Red Hat, Inc., Peter Zijlstra <pzijlstr@redhat.com>
+ * Copyright 2011 Red Hat, Inc., Peter Zijlstra
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
index 0b921ae06cd83585e1d1cf2adb6baf665f203013..0a271ca1f7c7ec12199b4c9781bb5aa5ded75dae 100644 (file)
@@ -309,6 +309,11 @@ struct drm_file {
        unsigned universal_planes:1;
        /* true if client understands atomic properties */
        unsigned atomic:1;
+       /*
+        * This client is allowed to gain master privileges for @master.
+        * Protected by struct drm_device::master_mutex.
+        */
+       unsigned allowed_master:1;
 
        struct pid *pid;
        kuid_t uid;
@@ -910,6 +915,7 @@ extern int drm_open(struct inode *inode, struct file *filp);
 extern ssize_t drm_read(struct file *filp, char __user *buffer,
                        size_t count, loff_t *offset);
 extern int drm_release(struct inode *inode, struct file *filp);
+extern int drm_new_set_master(struct drm_device *dev, struct drm_file *fpriv);
 
                                /* Mapping support (drm_vm.h) */
 extern unsigned int drm_poll(struct file *filp, struct poll_table_struct *wait);
@@ -947,6 +953,10 @@ extern void drm_send_vblank_event(struct drm_device *dev, unsigned int pipe,
                                  struct drm_pending_vblank_event *e);
 extern void drm_crtc_send_vblank_event(struct drm_crtc *crtc,
                                       struct drm_pending_vblank_event *e);
+extern void drm_arm_vblank_event(struct drm_device *dev, unsigned int pipe,
+                                struct drm_pending_vblank_event *e);
+extern void drm_crtc_arm_vblank_event(struct drm_crtc *crtc,
+                                     struct drm_pending_vblank_event *e);
 extern bool drm_handle_vblank(struct drm_device *dev, unsigned int pipe);
 extern bool drm_crtc_handle_vblank(struct drm_crtc *crtc);
 extern int drm_vblank_get(struct drm_device *dev, unsigned int pipe);
index 9c747cb14ad88809b9c77df72d8c0563f0230319..d2f41477f8ae77600a8683890b3615766b9a3701 100644 (file)
@@ -342,10 +342,10 @@ int kvm_vgic_inject_mapped_irq(struct kvm *kvm, int cpuid,
                               struct irq_phys_map *map, bool level);
 void vgic_v3_dispatch_sgi(struct kvm_vcpu *vcpu, u64 reg);
 int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu);
-int kvm_vgic_vcpu_active_irq(struct kvm_vcpu *vcpu);
 struct irq_phys_map *kvm_vgic_map_phys_irq(struct kvm_vcpu *vcpu,
                                           int virt_irq, int irq);
 int kvm_vgic_unmap_phys_irq(struct kvm_vcpu *vcpu, struct irq_phys_map *map);
+bool kvm_vgic_map_is_active(struct kvm_vcpu *vcpu, struct irq_phys_map *map);
 
 #define irqchip_in_kernel(k)   (!!((k)->arch.vgic.in_kernel))
 #define vgic_initialized(k)    (!!((k)->arch.vgic.nr_cpus))
index 05483393999534d91425b01c4573a5a4aa494fbc..1991aea2ec4cff401b84db2841ac60fe28f00080 100644 (file)
@@ -870,8 +870,8 @@ static inline int acpi_dev_get_property(struct acpi_device *adev,
 }
 
 static inline int acpi_node_get_property_reference(struct fwnode_handle *fwnode,
-                               const char *name, const char *cells_name,
-                               size_t index, struct acpi_reference_args *args)
+                               const char *name, size_t index,
+                               struct acpi_reference_args *args)
 {
        return -ENXIO;
 }
index 2b8ed123ad36b26bc26956293452937d3ac1b90e..defeaac0745f1b26340d7a13f5b73810de743193 100644 (file)
@@ -107,7 +107,7 @@ static inline __u64 ror64(__u64 word, unsigned int shift)
  */
 static inline __u32 rol32(__u32 word, unsigned int shift)
 {
-       return (word << shift) | (word >> (32 - shift));
+       return (word << shift) | (word >> ((-shift) & 31));
 }
 
 /**
index c0d2b7927c1f5a73afc2a56552116d86c04ca947..0169ba2e2e64b9c4bba07bf72b9c1194fe2db08a 100644 (file)
@@ -254,6 +254,7 @@ struct queue_limits {
        unsigned long           virt_boundary_mask;
 
        unsigned int            max_hw_sectors;
+       unsigned int            max_dev_sectors;
        unsigned int            chunk_sectors;
        unsigned int            max_sectors;
        unsigned int            max_segment_size;
@@ -773,7 +774,6 @@ extern void blk_rq_set_block_pc(struct request *);
 extern void blk_requeue_request(struct request_queue *, struct request *);
 extern void blk_add_request_payload(struct request *rq, struct page *page,
                unsigned int len);
-extern int blk_rq_check_limits(struct request_queue *q, struct request *rq);
 extern int blk_lld_busy(struct request_queue *q);
 extern int blk_rq_prep_clone(struct request *rq, struct request *rq_src,
                             struct bio_set *bs, gfp_t gfp_mask,
@@ -960,7 +960,6 @@ extern struct request_queue *blk_init_allocated_queue(struct request_queue *,
 extern void blk_cleanup_queue(struct request_queue *);
 extern void blk_queue_make_request(struct request_queue *, make_request_fn *);
 extern void blk_queue_bounce_limit(struct request_queue *, u64);
-extern void blk_limits_max_hw_sectors(struct queue_limits *, unsigned int);
 extern void blk_queue_max_hw_sectors(struct request_queue *, unsigned int);
 extern void blk_queue_chunk_sectors(struct request_queue *, unsigned int);
 extern void blk_queue_max_segments(struct request_queue *, unsigned short);
index de464e6683b68f247492d69a02b463f6bfb4b3df..83d1926c61e4567b881bfbc26b75b802c428cbc3 100644 (file)
@@ -40,6 +40,7 @@ struct bpf_map {
        struct user_struct *user;
        const struct bpf_map_ops *ops;
        struct work_struct work;
+       atomic_t usercnt;
 };
 
 struct bpf_map_type_list {
@@ -167,8 +168,10 @@ struct bpf_prog *bpf_prog_get(u32 ufd);
 void bpf_prog_put(struct bpf_prog *prog);
 void bpf_prog_put_rcu(struct bpf_prog *prog);
 
-struct bpf_map *bpf_map_get(u32 ufd);
+struct bpf_map *bpf_map_get_with_uref(u32 ufd);
 struct bpf_map *__bpf_map_get(struct fd f);
+void bpf_map_inc(struct bpf_map *map, bool uref);
+void bpf_map_put_with_uref(struct bpf_map *map);
 void bpf_map_put(struct bpf_map *map);
 
 extern int sysctl_unprivileged_bpf_disabled;
index 60d44b26276d84a77d7f7e3379ae12821a8b3eeb..06b77f9dd3f2052ac87f970b8aa8c195b78f7ada 100644 (file)
@@ -90,7 +90,6 @@ enum {
  */
 struct cgroup_file {
        /* do not access any fields from outside cgroup core */
-       struct list_head node;                  /* anchored at css->files */
        struct kernfs_node *kn;
 };
 
@@ -134,9 +133,6 @@ struct cgroup_subsys_state {
         */
        u64 serial_nr;
 
-       /* all cgroup_files associated with this css */
-       struct list_head files;
-
        /* percpu_ref killing and RCU release */
        struct rcu_head rcu_head;
        struct work_struct destroy_work;
@@ -426,12 +422,9 @@ struct cgroup_subsys {
        void (*css_reset)(struct cgroup_subsys_state *css);
        void (*css_e_css_changed)(struct cgroup_subsys_state *css);
 
-       int (*can_attach)(struct cgroup_subsys_state *css,
-                         struct cgroup_taskset *tset);
-       void (*cancel_attach)(struct cgroup_subsys_state *css,
-                             struct cgroup_taskset *tset);
-       void (*attach)(struct cgroup_subsys_state *css,
-                      struct cgroup_taskset *tset);
+       int (*can_attach)(struct cgroup_taskset *tset);
+       void (*cancel_attach)(struct cgroup_taskset *tset);
+       void (*attach)(struct cgroup_taskset *tset);
        int (*can_fork)(struct task_struct *task, void **priv_p);
        void (*cancel_fork)(struct task_struct *task, void *priv);
        void (*fork)(struct task_struct *task, void *priv);
index 22e3754f89c511374af4ca8ac5a518786dcd6d88..cb91b44f5f7877d5899403b26ca1d9231c1ac9b6 100644 (file)
@@ -88,6 +88,7 @@ int cgroup_transfer_tasks(struct cgroup *to, struct cgroup *from);
 int cgroup_add_dfl_cftypes(struct cgroup_subsys *ss, struct cftype *cfts);
 int cgroup_add_legacy_cftypes(struct cgroup_subsys *ss, struct cftype *cfts);
 int cgroup_rm_cftypes(struct cftype *cfts);
+void cgroup_file_notify(struct cgroup_file *cfile);
 
 char *task_cgroup_path(struct task_struct *task, char *buf, size_t buflen);
 int cgroupstats_build(struct cgroupstats *stats, struct dentry *dentry);
@@ -119,8 +120,10 @@ struct cgroup_subsys_state *css_rightmost_descendant(struct cgroup_subsys_state
 struct cgroup_subsys_state *css_next_descendant_post(struct cgroup_subsys_state *pos,
                                                     struct cgroup_subsys_state *css);
 
-struct task_struct *cgroup_taskset_first(struct cgroup_taskset *tset);
-struct task_struct *cgroup_taskset_next(struct cgroup_taskset *tset);
+struct task_struct *cgroup_taskset_first(struct cgroup_taskset *tset,
+                                        struct cgroup_subsys_state **dst_cssp);
+struct task_struct *cgroup_taskset_next(struct cgroup_taskset *tset,
+                                       struct cgroup_subsys_state **dst_cssp);
 
 void css_task_iter_start(struct cgroup_subsys_state *css,
                         struct css_task_iter *it);
@@ -235,30 +238,39 @@ void css_task_iter_end(struct css_task_iter *it);
 /**
  * cgroup_taskset_for_each - iterate cgroup_taskset
  * @task: the loop cursor
+ * @dst_css: the destination css
  * @tset: taskset to iterate
  *
  * @tset may contain multiple tasks and they may belong to multiple
- * processes.  When there are multiple tasks in @tset, if a task of a
- * process is in @tset, all tasks of the process are in @tset.  Also, all
- * are guaranteed to share the same source and destination csses.
+ * processes.
+ *
+ * On the v2 hierarchy, there may be tasks from multiple processes and they
+ * may not share the source or destination csses.
+ *
+ * On traditional hierarchies, when there are multiple tasks in @tset, if a
+ * task of a process is in @tset, all tasks of the process are in @tset.
+ * Also, all are guaranteed to share the same source and destination csses.
  *
  * Iteration is not in any specific order.
  */
-#define cgroup_taskset_for_each(task, tset)                            \
-       for ((task) = cgroup_taskset_first((tset)); (task);             \
-            (task) = cgroup_taskset_next((tset)))
+#define cgroup_taskset_for_each(task, dst_css, tset)                   \
+       for ((task) = cgroup_taskset_first((tset), &(dst_css));         \
+            (task);                                                    \
+            (task) = cgroup_taskset_next((tset), &(dst_css)))
 
 /**
  * cgroup_taskset_for_each_leader - iterate group leaders in a cgroup_taskset
  * @leader: the loop cursor
+ * @dst_css: the destination css
  * @tset: takset to iterate
  *
  * Iterate threadgroup leaders of @tset.  For single-task migrations, @tset
  * may not contain any.
  */
-#define cgroup_taskset_for_each_leader(leader, tset)                   \
-       for ((leader) = cgroup_taskset_first((tset)); (leader);         \
-            (leader) = cgroup_taskset_next((tset)))                    \
+#define cgroup_taskset_for_each_leader(leader, dst_css, tset)          \
+       for ((leader) = cgroup_taskset_first((tset), &(dst_css));       \
+            (leader);                                                  \
+            (leader) = cgroup_taskset_next((tset), &(dst_css)))        \
                if ((leader) != (leader)->group_leader)                 \
                        ;                                               \
                else
@@ -516,19 +528,6 @@ static inline void pr_cont_cgroup_path(struct cgroup *cgrp)
        pr_cont_kernfs_path(cgrp->kn);
 }
 
-/**
- * cgroup_file_notify - generate a file modified event for a cgroup_file
- * @cfile: target cgroup_file
- *
- * @cfile must have been obtained by setting cftype->file_offset.
- */
-static inline void cgroup_file_notify(struct cgroup_file *cfile)
-{
-       /* might not have been created due to one of the CFTYPE selector flags */
-       if (cfile->kn)
-               kernfs_notify(cfile->kn);
-}
-
 #else /* !CONFIG_CGROUPS */
 
 struct cgroup_subsys_state;
index ef4c5b1a860f5c610c0ee4646aa2b729aa81f71a..177c7680c1a8a81bcc942497ee228c148fbf5a0b 100644 (file)
@@ -77,6 +77,7 @@ struct cpufreq_policy {
        unsigned int            suspend_freq; /* freq to set during suspend */
 
        unsigned int            policy; /* see above */
+       unsigned int            last_policy; /* policy before unplug */
        struct cpufreq_governor *governor; /* see below */
        void                    *governor_data;
        bool                    governor_enabled; /* governor start/stop flag */
index cc92268af89ae02e8a26fe08f671485b2ca67bc3..6ac3cad9aef109171a5882ee2c5afb30e230c8d4 100644 (file)
@@ -27,7 +27,7 @@
 #ifdef __KERNEL__
 
 extern int dns_query(const char *type, const char *name, size_t namelen,
-                    const char *options, char **_result, time_t *_expiry);
+                    const char *options, char **_result, time64_t *_expiry);
 
 #endif /* KERNEL */
 
index 0ef2a97ccdb50bc83baaf727f37d2fa034eea036..402753bccafa37b4ec1e597902f608548fbdbd22 100644 (file)
@@ -227,7 +227,7 @@ struct ipv6_pinfo {
        struct ipv6_ac_socklist *ipv6_ac_list;
        struct ipv6_fl_socklist __rcu *ipv6_fl_list;
 
-       struct ipv6_txoptions   *opt;
+       struct ipv6_txoptions __rcu     *opt;
        struct sk_buff          *pktoptions;
        struct sk_buff          *rxpmtu;
        struct inet6_cork       cork;
index c9ae0c6ec050569fc592b6f07b3ce1fa052bcc59..d5d798b35c1f6c105c81d0993bce6140bc4fc83b 100644 (file)
@@ -330,6 +330,7 @@ struct rdists {
 };
 
 struct irq_domain;
+struct device_node;
 int its_cpu_init(void);
 int its_init(struct device_node *node, struct rdists *rdists,
             struct irq_domain *domain);
index 8dde55974f186bca7c1488866aaacdd805c347b3..0536524bb9eb6467013a51a70ed28b576494e649 100644 (file)
@@ -5,7 +5,7 @@
  * Jump label support
  *
  * Copyright (C) 2009-2012 Jason Baron <jbaron@redhat.com>
- * Copyright (C) 2011-2012 Peter Zijlstra <pzijlstr@redhat.com>
+ * Copyright (C) 2011-2012 Red Hat, Inc., Peter Zijlstra
  *
  * DEPRECATED API:
  *
index d0a1f99e24e3eb43219e9f8b8aad400c1cc867a9..4894c6888bc6cfb95e50d43366784769faf9b281 100644 (file)
@@ -25,7 +25,7 @@
 
 #ifdef CONFIG_DEBUG_KMEMLEAK
 
-extern void kmemleak_init(void) __ref;
+extern void kmemleak_init(void) __init;
 extern void kmemleak_alloc(const void *ptr, size_t size, int min_count,
                           gfp_t gfp) __ref;
 extern void kmemleak_alloc_percpu(const void __percpu *ptr, size_t size,
index 484604d184be7380807868d9a12edc80e9064db3..e15828fd71f1b589780b933549e3b07c9652c1e9 100644 (file)
@@ -19,7 +19,6 @@
 #include <linux/atomic.h>
 #include <linux/kernel.h>
 #include <linux/mutex.h>
-#include <linux/spinlock.h>
 
 struct kref {
        atomic_t refcount;
@@ -99,38 +98,6 @@ static inline int kref_put(struct kref *kref, void (*release)(struct kref *kref)
        return kref_sub(kref, 1, release);
 }
 
-/**
- * kref_put_spinlock_irqsave - decrement refcount for object.
- * @kref: object.
- * @release: pointer to the function that will clean up the object when the
- *          last reference to the object is released.
- *          This pointer is required, and it is not acceptable to pass kfree
- *          in as this function.
- * @lock: lock to take in release case
- *
- * Behaves identical to kref_put with one exception.  If the reference count
- * drops to zero, the lock will be taken atomically wrt dropping the reference
- * count.  The release function has to call spin_unlock() without _irqrestore.
- */
-static inline int kref_put_spinlock_irqsave(struct kref *kref,
-               void (*release)(struct kref *kref),
-               spinlock_t *lock)
-{
-       unsigned long flags;
-
-       WARN_ON(release == NULL);
-       if (atomic_add_unless(&kref->refcount, -1, 1))
-               return 0;
-       spin_lock_irqsave(lock, flags);
-       if (atomic_dec_and_test(&kref->refcount)) {
-               release(kref);
-               local_irq_restore(flags);
-               return 1;
-       }
-       spin_unlock_irqrestore(lock, flags);
-       return 0;
-}
-
 static inline int kref_put_mutex(struct kref *kref,
                                 void (*release)(struct kref *kref),
                                 struct mutex *lock)
index 5706a2108f0a67826ed644dce761edd21a6a05c0..c923350ca20a5a53453576f360e52498de232abe 100644 (file)
@@ -460,6 +460,17 @@ static inline struct kvm_vcpu *kvm_get_vcpu(struct kvm *kvm, int i)
             (vcpup = kvm_get_vcpu(kvm, idx)) != NULL; \
             idx++)
 
+static inline struct kvm_vcpu *kvm_get_vcpu_by_id(struct kvm *kvm, int id)
+{
+       struct kvm_vcpu *vcpu;
+       int i;
+
+       kvm_for_each_vcpu(i, vcpu, kvm)
+               if (vcpu->vcpu_id == id)
+                       return vcpu;
+       return NULL;
+}
+
 #define kvm_for_each_memslot(memslot, slots)   \
        for (memslot = &slots->memslots[0];     \
              memslot < slots->memslots + KVM_MEM_SLOTS_NUM && memslot->npages;\
index 83577f8fd15bcd0f8693ef6a1a2a9fb216b32b2b..600c1e0626a5ff6c91df3a0b2f2fcf0ef485fedf 100644 (file)
@@ -210,6 +210,7 @@ enum {
        ATA_FLAG_SLAVE_POSS     = (1 << 0), /* host supports slave dev */
                                            /* (doesn't imply presence) */
        ATA_FLAG_SATA           = (1 << 1),
+       ATA_FLAG_NO_LOG_PAGE    = (1 << 5), /* do not issue log page read */
        ATA_FLAG_NO_ATAPI       = (1 << 6), /* No ATAPI support */
        ATA_FLAG_PIO_DMA        = (1 << 7), /* PIO cmds via DMA */
        ATA_FLAG_PIO_LBA48      = (1 << 8), /* Host DMA engine is LBA28 only */
index 69c9057e1ab89330b1ed22cd0681bf5440ce0096..034117b3be5f7d91e5e869ea9e856f51964ebac6 100644 (file)
@@ -50,15 +50,21 @@ enum {
        NVM_IO_DUAL_ACCESS      = 0x1,
        NVM_IO_QUAD_ACCESS      = 0x2,
 
+       /* NAND Access Modes */
        NVM_IO_SUSPEND          = 0x80,
        NVM_IO_SLC_MODE         = 0x100,
        NVM_IO_SCRAMBLE_DISABLE = 0x200,
+
+       /* Block Types */
+       NVM_BLK_T_FREE          = 0x0,
+       NVM_BLK_T_BAD           = 0x1,
+       NVM_BLK_T_DEV           = 0x2,
+       NVM_BLK_T_HOST          = 0x4,
 };
 
 struct nvm_id_group {
        u8      mtype;
        u8      fmtype;
-       u16     res16;
        u8      num_ch;
        u8      num_lun;
        u8      num_pln;
@@ -74,9 +80,9 @@ struct nvm_id_group {
        u32     tbet;
        u32     tbem;
        u32     mpos;
+       u32     mccap;
        u16     cpar;
-       u8      res[913];
-} __packed;
+};
 
 struct nvm_addr_format {
        u8      ch_offset;
@@ -91,19 +97,15 @@ struct nvm_addr_format {
        u8      pg_len;
        u8      sect_offset;
        u8      sect_len;
-       u8      res[4];
 };
 
 struct nvm_id {
        u8      ver_id;
        u8      vmnt;
        u8      cgrps;
-       u8      res[5];
        u32     cap;
        u32     dom;
        struct nvm_addr_format ppaf;
-       u8      ppat;
-       u8      resv[224];
        struct nvm_id_group groups[4];
 } __packed;
 
@@ -123,39 +125,28 @@ struct nvm_tgt_instance {
 #define NVM_VERSION_MINOR 0
 #define NVM_VERSION_PATCH 0
 
-#define NVM_SEC_BITS (8)
-#define NVM_PL_BITS  (6)
-#define NVM_PG_BITS  (16)
 #define NVM_BLK_BITS (16)
-#define NVM_LUN_BITS (10)
+#define NVM_PG_BITS  (16)
+#define NVM_SEC_BITS (8)
+#define NVM_PL_BITS  (8)
+#define NVM_LUN_BITS (8)
 #define NVM_CH_BITS  (8)
 
 struct ppa_addr {
+       /* Generic structure for all addresses */
        union {
-               /* Channel-based PPA format in nand 4x2x2x2x8x10 */
-               struct {
-                       u64 ch          : 4;
-                       u64 sec         : 2; /* 4 sectors per page */
-                       u64 pl          : 2; /* 4 planes per LUN */
-                       u64 lun         : 2; /* 4 LUNs per channel */
-                       u64 pg          : 8; /* 256 pages per block */
-                       u64 blk         : 10;/* 1024 blocks per plane */
-                       u64 resved              : 36;
-               } chnl;
-
-               /* Generic structure for all addresses */
                struct {
+                       u64 blk         : NVM_BLK_BITS;
+                       u64 pg          : NVM_PG_BITS;
                        u64 sec         : NVM_SEC_BITS;
                        u64 pl          : NVM_PL_BITS;
-                       u64 pg          : NVM_PG_BITS;
-                       u64 blk         : NVM_BLK_BITS;
                        u64 lun         : NVM_LUN_BITS;
                        u64 ch          : NVM_CH_BITS;
                } g;
 
                u64 ppa;
        };
-} __packed;
+};
 
 struct nvm_rq {
        struct nvm_tgt_instance *ins;
@@ -191,18 +182,18 @@ static inline void *nvm_rq_to_pdu(struct nvm_rq *rqdata)
 struct nvm_block;
 
 typedef int (nvm_l2p_update_fn)(u64, u32, __le64 *, void *);
-typedef int (nvm_bb_update_fn)(u32, void *, unsigned int, void *);
-typedef int (nvm_id_fn)(struct request_queue *, struct nvm_id *);
-typedef int (nvm_get_l2p_tbl_fn)(struct request_queue *, u64, u32,
+typedef int (nvm_bb_update_fn)(struct ppa_addr, int, u8 *, void *);
+typedef int (nvm_id_fn)(struct nvm_dev *, struct nvm_id *);
+typedef int (nvm_get_l2p_tbl_fn)(struct nvm_dev *, u64, u32,
                                nvm_l2p_update_fn *, void *);
-typedef int (nvm_op_bb_tbl_fn)(struct request_queue *, int, unsigned int,
+typedef int (nvm_op_bb_tbl_fn)(struct nvm_dev *, struct ppa_addr, int,
                                nvm_bb_update_fn *, void *);
-typedef int (nvm_op_set_bb_fn)(struct request_queue *, struct nvm_rq *, int);
-typedef int (nvm_submit_io_fn)(struct request_queue *, struct nvm_rq *);
-typedef int (nvm_erase_blk_fn)(struct request_queue *, struct nvm_rq *);
-typedef void *(nvm_create_dma_pool_fn)(struct request_queue *, char *);
+typedef int (nvm_op_set_bb_fn)(struct nvm_dev *, struct nvm_rq *, int);
+typedef int (nvm_submit_io_fn)(struct nvm_dev *, struct nvm_rq *);
+typedef int (nvm_erase_blk_fn)(struct nvm_dev *, struct nvm_rq *);
+typedef void *(nvm_create_dma_pool_fn)(struct nvm_dev *, char *);
 typedef void (nvm_destroy_dma_pool_fn)(void *);
-typedef void *(nvm_dev_dma_alloc_fn)(struct request_queue *, void *, gfp_t,
+typedef void *(nvm_dev_dma_alloc_fn)(struct nvm_dev *, void *, gfp_t,
                                                                dma_addr_t *);
 typedef void (nvm_dev_dma_free_fn)(void *, void*, dma_addr_t);
 
@@ -210,7 +201,7 @@ struct nvm_dev_ops {
        nvm_id_fn               *identity;
        nvm_get_l2p_tbl_fn      *get_l2p_tbl;
        nvm_op_bb_tbl_fn        *get_bb_tbl;
-       nvm_op_set_bb_fn        *set_bb;
+       nvm_op_set_bb_fn        *set_bb_tbl;
 
        nvm_submit_io_fn        *submit_io;
        nvm_erase_blk_fn        *erase_block;
@@ -220,7 +211,7 @@ struct nvm_dev_ops {
        nvm_dev_dma_alloc_fn    *dev_dma_alloc;
        nvm_dev_dma_free_fn     *dev_dma_free;
 
-       uint8_t                 max_phys_sect;
+       unsigned int            max_phys_sect;
 };
 
 struct nvm_lun {
@@ -229,7 +220,9 @@ struct nvm_lun {
        int lun_id;
        int chnl_id;
 
+       unsigned int nr_inuse_blocks;   /* Number of used blocks */
        unsigned int nr_free_blocks;    /* Number of unused blocks */
+       unsigned int nr_bad_blocks;     /* Number of bad blocks */
        struct nvm_block *blocks;
 
        spinlock_t lock;
@@ -263,8 +256,7 @@ struct nvm_dev {
        int blks_per_lun;
        int sec_size;
        int oob_size;
-       int addr_mode;
-       struct nvm_addr_format addr_format;
+       struct nvm_addr_format ppaf;
 
        /* Calculated/Cached values. These do not reflect the actual usable
         * blocks at run-time.
@@ -290,118 +282,45 @@ struct nvm_dev {
        char name[DISK_NAME_LEN];
 };
 
-/* fallback conversion */
-static struct ppa_addr __generic_to_linear_addr(struct nvm_dev *dev,
-                                                       struct ppa_addr r)
+static inline struct ppa_addr generic_to_dev_addr(struct nvm_dev *dev,
+                                               struct ppa_addr r)
 {
        struct ppa_addr l;
 
-       l.ppa = r.g.sec +
-               r.g.pg  * dev->sec_per_pg +
-               r.g.blk * (dev->pgs_per_blk *
-                               dev->sec_per_pg) +
-               r.g.lun * (dev->blks_per_lun *
-                               dev->pgs_per_blk *
-                               dev->sec_per_pg) +
-               r.g.ch * (dev->blks_per_lun *
-                               dev->pgs_per_blk *
-                               dev->luns_per_chnl *
-                               dev->sec_per_pg);
+       l.ppa = ((u64)r.g.blk) << dev->ppaf.blk_offset;
+       l.ppa |= ((u64)r.g.pg) << dev->ppaf.pg_offset;
+       l.ppa |= ((u64)r.g.sec) << dev->ppaf.sect_offset;
+       l.ppa |= ((u64)r.g.pl) << dev->ppaf.pln_offset;
+       l.ppa |= ((u64)r.g.lun) << dev->ppaf.lun_offset;
+       l.ppa |= ((u64)r.g.ch) << dev->ppaf.ch_offset;
 
        return l;
 }
 
-/* fallback conversion */
-static struct ppa_addr __linear_to_generic_addr(struct nvm_dev *dev,
-                                                       struct ppa_addr r)
+static inline struct ppa_addr dev_to_generic_addr(struct nvm_dev *dev,
+                                               struct ppa_addr r)
 {
        struct ppa_addr l;
-       int secs, pgs, blks, luns;
-       sector_t ppa = r.ppa;
-
-       l.ppa = 0;
-
-       div_u64_rem(ppa, dev->sec_per_pg, &secs);
-       l.g.sec = secs;
 
-       sector_div(ppa, dev->sec_per_pg);
-       div_u64_rem(ppa, dev->sec_per_blk, &pgs);
-       l.g.pg = pgs;
-
-       sector_div(ppa, dev->pgs_per_blk);
-       div_u64_rem(ppa, dev->blks_per_lun, &blks);
-       l.g.blk = blks;
-
-       sector_div(ppa, dev->blks_per_lun);
-       div_u64_rem(ppa, dev->luns_per_chnl, &luns);
-       l.g.lun = luns;
-
-       sector_div(ppa, dev->luns_per_chnl);
-       l.g.ch = ppa;
-
-       return l;
-}
-
-static struct ppa_addr __generic_to_chnl_addr(struct ppa_addr r)
-{
-       struct ppa_addr l;
-
-       l.ppa = 0;
-
-       l.chnl.sec = r.g.sec;
-       l.chnl.pl = r.g.pl;
-       l.chnl.pg = r.g.pg;
-       l.chnl.blk = r.g.blk;
-       l.chnl.lun = r.g.lun;
-       l.chnl.ch = r.g.ch;
-
-       return l;
-}
-
-static struct ppa_addr __chnl_to_generic_addr(struct ppa_addr r)
-{
-       struct ppa_addr l;
-
-       l.ppa = 0;
-
-       l.g.sec = r.chnl.sec;
-       l.g.pl = r.chnl.pl;
-       l.g.pg = r.chnl.pg;
-       l.g.blk = r.chnl.blk;
-       l.g.lun = r.chnl.lun;
-       l.g.ch = r.chnl.ch;
+       /*
+        * (r.ppa << X offset) & X len bitmask. X eq. blk, pg, etc.
+        */
+       l.g.blk = (r.ppa >> dev->ppaf.blk_offset) &
+                                       (((1 << dev->ppaf.blk_len) - 1));
+       l.g.pg |= (r.ppa >> dev->ppaf.pg_offset) &
+                                       (((1 << dev->ppaf.pg_len) - 1));
+       l.g.sec |= (r.ppa >> dev->ppaf.sect_offset) &
+                                       (((1 << dev->ppaf.sect_len) - 1));
+       l.g.pl |= (r.ppa >> dev->ppaf.pln_offset) &
+                                       (((1 << dev->ppaf.pln_len) - 1));
+       l.g.lun |= (r.ppa >> dev->ppaf.lun_offset) &
+                                       (((1 << dev->ppaf.lun_len) - 1));
+       l.g.ch |= (r.ppa >> dev->ppaf.ch_offset) &
+                                       (((1 << dev->ppaf.ch_len) - 1));
 
        return l;
 }
 
-static inline struct ppa_addr addr_to_generic_mode(struct nvm_dev *dev,
-                                               struct ppa_addr gppa)
-{
-       switch (dev->addr_mode) {
-       case NVM_ADDRMODE_LINEAR:
-               return __linear_to_generic_addr(dev, gppa);
-       case NVM_ADDRMODE_CHANNEL:
-               return __chnl_to_generic_addr(gppa);
-       default:
-               BUG();
-       }
-       return gppa;
-}
-
-static inline struct ppa_addr generic_to_addr_mode(struct nvm_dev *dev,
-                                               struct ppa_addr gppa)
-{
-       switch (dev->addr_mode) {
-       case NVM_ADDRMODE_LINEAR:
-               return __generic_to_linear_addr(dev, gppa);
-       case NVM_ADDRMODE_CHANNEL:
-               return __generic_to_chnl_addr(gppa);
-       default:
-               BUG();
-       }
-       return gppa;
-}
-
 static inline int ppa_empty(struct ppa_addr ppa_addr)
 {
        return (ppa_addr.ppa == ADDR_EMPTY);
@@ -468,7 +387,7 @@ typedef int (nvmm_end_io_fn)(struct nvm_rq *, int);
 typedef int (nvmm_erase_blk_fn)(struct nvm_dev *, struct nvm_block *,
                                                                unsigned long);
 typedef struct nvm_lun *(nvmm_get_lun_fn)(struct nvm_dev *, int);
-typedef void (nvmm_free_blocks_print_fn)(struct nvm_dev *);
+typedef void (nvmm_lun_info_print_fn)(struct nvm_dev *);
 
 struct nvmm_type {
        const char *name;
@@ -492,7 +411,7 @@ struct nvmm_type {
        nvmm_get_lun_fn *get_lun;
 
        /* Statistics */
-       nvmm_free_blocks_print_fn *free_blocks_print;
+       nvmm_lun_info_print_fn *lun_info_print;
        struct list_head list;
 };
 
index 70400dc7660f72028cd6ce84cf6ec90b69537137..c57e424d914b70fc5032f9b6d1ec918e8e195c64 100644 (file)
@@ -2,7 +2,7 @@
  * Runtime locking correctness validator
  *
  *  Copyright (C) 2006,2007 Red Hat, Inc., Ingo Molnar <mingo@redhat.com>
- *  Copyright (C) 2007 Red Hat, Inc., Peter Zijlstra <pzijlstr@redhat.com>
+ *  Copyright (C) 2007 Red Hat, Inc., Peter Zijlstra
  *
  * see Documentation/locking/lockdep-design.txt for more details.
  */
index 7501626ab5293414c29df692edb6fa7122871c84..d3133be12d922521e24528480edbdb31659a7007 100644 (file)
@@ -426,6 +426,17 @@ enum {
        MLX4_MAX_FAST_REG_PAGES = 511,
 };
 
+enum {
+       /*
+        * Max wqe size for rdma read is 512 bytes, so this
+        * limits our max_sge_rd as the wqe needs to fit:
+        * - ctrl segment (16 bytes)
+        * - rdma segment (16 bytes)
+        * - scatter elements (16 bytes each)
+        */
+       MLX4_MAX_SGE_RD = (512 - 16 - 16) / 16
+};
+
 enum {
        MLX4_DEV_PMC_SUBTYPE_GUID_INFO   = 0x14,
        MLX4_DEV_PMC_SUBTYPE_PORT_INFO   = 0x15,
index 70ac5e28e6b737f7aac7b0b27d929adacf4aad12..0b4ac7da583a8b2dff7983b4602cb9a81887ea86 100644 (file)
@@ -34,8 +34,12 @@ struct inode;
 struct file;
 struct net;
 
-#define SOCK_ASYNC_NOSPACE     0
-#define SOCK_ASYNC_WAITDATA    1
+/* Historically, SOCKWQ_ASYNC_NOSPACE & SOCKWQ_ASYNC_WAITDATA were located
+ * in sock->flags, but moved into sk->sk_wq->flags to be RCU protected.
+ * Eventually all flags will be in sk->sk_wq_flags.
+ */
+#define SOCKWQ_ASYNC_NOSPACE   0
+#define SOCKWQ_ASYNC_WAITDATA  1
 #define SOCK_NOSPACE           2
 #define SOCK_PASSCRED          3
 #define SOCK_PASSSEC           4
@@ -89,6 +93,7 @@ struct socket_wq {
        /* Note: wait MUST be first field of socket_wq */
        wait_queue_head_t       wait;
        struct fasync_struct    *fasync_list;
+       unsigned long           flags; /* %SOCKWQ_ASYNC_NOSPACE, etc */
        struct rcu_head         rcu;
 } ____cacheline_aligned_in_smp;
 
@@ -96,7 +101,7 @@ struct socket_wq {
  *  struct socket - general BSD socket
  *  @state: socket state (%SS_CONNECTED, etc)
  *  @type: socket type (%SOCK_STREAM, etc)
- *  @flags: socket flags (%SOCK_ASYNC_NOSPACE, etc)
+ *  @flags: socket flags (%SOCK_NOSPACE, etc)
  *  @ops: protocol specific socket operations
  *  @file: File back pointer for gc
  *  @sk: internal networking protocol agnostic socket representation
@@ -202,7 +207,7 @@ enum {
        SOCK_WAKE_URG,
 };
 
-int sock_wake_async(struct socket *sk, int how, int band);
+int sock_wake_async(struct socket_wq *sk_wq, int how, int band);
 int sock_register(const struct net_proto_family *fam);
 void sock_unregister(int family);
 int __sock_create(struct net *net, int family, int type, int proto,
index 67bfac1abfc1ac8bd95bf3ddcf35aac07145166b..3b5d134e945a9b1a5dda9b636c04909318fe8a67 100644 (file)
@@ -1398,7 +1398,8 @@ enum netdev_priv_flags {
  *     @dma:           DMA channel
  *     @mtu:           Interface MTU value
  *     @type:          Interface hardware type
- *     @hard_header_len: Hardware header length
+ *     @hard_header_len: Hardware header length, which means that this is the
+ *                       minimum size of a packet.
  *
  *     @needed_headroom: Extra headroom the hardware may need, but not in all
  *                       cases can this be guaranteed
index 570d630f98ae53a34b4c9420f037d87c4b97a3cc..11bbae44f4cbf91dd3ed62aa9d2e1849b14a8839 100644 (file)
@@ -251,6 +251,7 @@ struct nfs4_layoutget {
        struct nfs4_layoutget_res res;
        struct rpc_cred *cred;
        gfp_t gfp_flags;
+       long timeout;
 };
 
 struct nfs4_getdeviceinfo_args {
index 039f2eec49ced0ae1c638354d1a34c924cebde51..1e0deb8e849458ca179c1df4734bb24f0e4cd748 100644 (file)
@@ -46,12 +46,14 @@ extern int of_irq_get(struct device_node *dev, int index);
 extern int of_irq_get_byname(struct device_node *dev, const char *name);
 extern int of_irq_to_resource_table(struct device_node *dev,
                struct resource *res, int nr_irqs);
+extern struct device_node *of_irq_find_parent(struct device_node *child);
 extern struct irq_domain *of_msi_get_domain(struct device *dev,
                                            struct device_node *np,
                                            enum irq_domain_bus_token token);
 extern struct irq_domain *of_msi_map_get_device_domain(struct device *dev,
                                                       u32 rid);
 extern void of_msi_configure(struct device *dev, struct device_node *np);
+u32 of_msi_map_rid(struct device *dev, struct device_node *msi_np, u32 rid_in);
 #else
 static inline int of_irq_count(struct device_node *dev)
 {
@@ -70,6 +72,11 @@ static inline int of_irq_to_resource_table(struct device_node *dev,
 {
        return 0;
 }
+static inline void *of_irq_find_parent(struct device_node *child)
+{
+       return NULL;
+}
+
 static inline struct irq_domain *of_msi_get_domain(struct device *dev,
                                                   struct device_node *np,
                                                   enum irq_domain_bus_token token)
@@ -84,6 +91,11 @@ static inline struct irq_domain *of_msi_map_get_device_domain(struct device *dev
 static inline void of_msi_configure(struct device *dev, struct device_node *np)
 {
 }
+static inline u32 of_msi_map_rid(struct device *dev,
+                                struct device_node *msi_np, u32 rid_in)
+{
+       return rid_in;
+}
 #endif
 
 #if defined(CONFIG_OF_IRQ) || defined(CONFIG_SPARC)
@@ -93,7 +105,6 @@ static inline void of_msi_configure(struct device *dev, struct device_node *np)
  * so declare it here regardless of the CONFIG_OF_IRQ setting.
  */
 extern unsigned int irq_of_parse_and_map(struct device_node *node, int index);
-u32 of_msi_map_rid(struct device *dev, struct device_node *msi_np, u32 rid_in);
 
 #else /* !CONFIG_OF && !CONFIG_SPARC */
 static inline unsigned int irq_of_parse_and_map(struct device_node *dev,
@@ -101,12 +112,6 @@ static inline unsigned int irq_of_parse_and_map(struct device_node *dev,
 {
        return 0;
 }
-
-static inline u32 of_msi_map_rid(struct device *dev,
-                                struct device_node *msi_np, u32 rid_in)
-{
-       return rid_in;
-}
 #endif /* !CONFIG_OF */
 
 #endif /* __OF_IRQ_H */
index e828e7b4afec67a4b9f083cfa65c2ff3cffe8571..6ae25aae88fd1254f40227341ca20b73a2e08ce2 100644 (file)
@@ -412,9 +412,18 @@ struct pci_host_bridge {
        void (*release_fn)(struct pci_host_bridge *);
        void *release_data;
        unsigned int ignore_reset_delay:1;      /* for entire hierarchy */
+       /* Resource alignment requirements */
+       resource_size_t (*align_resource)(struct pci_dev *dev,
+                       const struct resource *res,
+                       resource_size_t start,
+                       resource_size_t size,
+                       resource_size_t align);
 };
 
 #define        to_pci_host_bridge(n) container_of(n, struct pci_host_bridge, dev)
+
+struct pci_host_bridge *pci_find_host_bridge(struct pci_bus *bus);
+
 void pci_set_host_bridge_release(struct pci_host_bridge *bridge,
                     void (*release_fn)(struct pci_host_bridge *),
                     void *release_data);
index d841d33bcdc9c370742db6408e1f979594d37099..f9828a48f16addab4737683f3c8345ab87e52a0a 100644 (file)
@@ -697,9 +697,11 @@ struct perf_cgroup {
  * if there is no cgroup event for the current CPU context.
  */
 static inline struct perf_cgroup *
-perf_cgroup_from_task(struct task_struct *task)
+perf_cgroup_from_task(struct task_struct *task, struct perf_event_context *ctx)
 {
-       return container_of(task_css(task, perf_event_cgrp_id),
+       return container_of(task_css_check(task, perf_event_cgrp_id,
+                                          ctx ? lockdep_is_held(&ctx->lock)
+                                              : true),
                            struct perf_cgroup, css);
 }
 #endif /* CONFIG_CGROUP_PERF */
index 5440f64d2942a7957e0831a15918fc070ac63193..21221338ad18018b9b8c479efe1f938b67e6f685 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * FLoating proportions
  *
- *  Copyright (C) 2007 Red Hat, Inc., Peter Zijlstra <pzijlstr@redhat.com>
+ *  Copyright (C) 2007 Red Hat, Inc., Peter Zijlstra
  *
  * This file contains the public data structure and API definitions.
  */
index 80af3cd35ae4edf30dc05e1148cf8ee75033fcb3..72ce932c69b28b3bf240e9782d00c5555bf6a97d 100644 (file)
@@ -71,7 +71,7 @@ struct scpi_ops {
        int (*sensor_get_value)(u16, u32 *);
 };
 
-#if IS_ENABLED(CONFIG_ARM_SCPI_PROTOCOL)
+#if IS_REACHABLE(CONFIG_ARM_SCPI_PROTOCOL)
 struct scpi_ops *get_scpi_ops(void);
 #else
 static inline struct scpi_ops *get_scpi_ops(void) { return NULL; }
index 0adedca24c5bfbd4ca7a25b80641e76e0e638738..0e1b1540597a47253b6a2e5cc3ef1709d4a42992 100644 (file)
@@ -99,7 +99,7 @@ static inline int try_stop_cpus(const struct cpumask *cpumask,
  * grabbing every spinlock (and more).  So the "read" side to such a
  * lock is anything which disables preemption.
  */
-#if defined(CONFIG_STOP_MACHINE) && defined(CONFIG_SMP)
+#if defined(CONFIG_SMP) || defined(CONFIG_HOTPLUG_CPU)
 
 /**
  * stop_machine: freeze the machine on all CPUs and run this function
@@ -118,7 +118,7 @@ int stop_machine(cpu_stop_fn_t fn, void *data, const struct cpumask *cpus);
 
 int stop_machine_from_inactive_cpu(cpu_stop_fn_t fn, void *data,
                                   const struct cpumask *cpus);
-#else   /* CONFIG_STOP_MACHINE && CONFIG_SMP */
+#else  /* CONFIG_SMP || CONFIG_HOTPLUG_CPU */
 
 static inline int stop_machine(cpu_stop_fn_t fn, void *data,
                                 const struct cpumask *cpus)
@@ -137,5 +137,5 @@ static inline int stop_machine_from_inactive_cpu(cpu_stop_fn_t fn, void *data,
        return stop_machine(fn, data, cpus);
 }
 
-#endif /* CONFIG_STOP_MACHINE && CONFIG_SMP */
+#endif /* CONFIG_SMP || CONFIG_HOTPLUG_CPU */
 #endif /* _LINUX_STOP_MACHINE */
index a156b82dd14cbad0b6f2867d07fc883fbc685c1e..c2b66a277e9807de8a224879793c121df63f7d69 100644 (file)
@@ -524,7 +524,7 @@ asmlinkage long sys_chown(const char __user *filename,
 asmlinkage long sys_lchown(const char __user *filename,
                                uid_t user, gid_t group);
 asmlinkage long sys_fchown(unsigned int fd, uid_t user, gid_t group);
-#ifdef CONFIG_UID16
+#ifdef CONFIG_HAVE_UID16
 asmlinkage long sys_chown16(const char __user *filename,
                                old_uid_t user, old_gid_t group);
 asmlinkage long sys_lchown16(const char __user *filename,
index 4014a59828fcba8142e27f6feb1feaf4f64d3171..613c29bd6baf4763e57530b794df843d9cea61ee 100644 (file)
@@ -438,7 +438,8 @@ static inline void thermal_zone_device_unregister(
 static inline int thermal_zone_bind_cooling_device(
        struct thermal_zone_device *tz, int trip,
        struct thermal_cooling_device *cdev,
-       unsigned long upper, unsigned long lower)
+       unsigned long upper, unsigned long lower,
+       unsigned int weight)
 { return -ENODEV; }
 static inline int thermal_zone_unbind_cooling_device(
        struct thermal_zone_device *tz, int trip,
index 70d8500bddf15e9c68bc5149b29c487e28e5f201..70dd3dfde6319e661069f6b8c2d5a6b15804f27f 100644 (file)
@@ -35,7 +35,7 @@ typedef __kernel_gid16_t        gid16_t;
 
 typedef unsigned long          uintptr_t;
 
-#ifdef CONFIG_UID16
+#ifdef CONFIG_HAVE_UID16
 /* This is defined by include/asm-{arch}/posix_types.h */
 typedef __kernel_old_uid_t     old_uid_t;
 typedef __kernel_old_gid_t     old_gid_t;
index 0bdc72f3690545dd3ac34d1f4b204f2e1db02eb6..4a29c75b146e1c9afc550c6c6bab58f17ed8e2da 100644 (file)
@@ -21,7 +21,7 @@
  * Authors:
  *     Srikar Dronamraju
  *     Jim Keniston
- * Copyright (C) 2011-2012 Red Hat, Inc., Peter Zijlstra <pzijlstr@redhat.com>
+ * Copyright (C) 2011-2012 Red Hat, Inc., Peter Zijlstra
  */
 
 #include <linux/errno.h>
index 9948c874e3f1e4e254ea666a3a7e623678edc26d..1d0043dc34e427403a1c82458249bed83e87d3a0 100644 (file)
@@ -47,4 +47,7 @@
 /* device generates spurious wakeup, ignore remote wakeup capability */
 #define USB_QUIRK_IGNORE_REMOTE_WAKEUP         BIT(9)
 
+/* device can't handle Link Power Management */
+#define USB_QUIRK_NO_LPM                       BIT(10)
+
 #endif /* __LINUX_USB_QUIRKS_H */
index 610a86a892b8896363ece505cdbe686096505cfc..ddb44097538245f17e882efff635143ada49e089 100644 (file)
@@ -44,9 +44,6 @@ struct vfio_device_ops {
        void    (*request)(void *device_data, unsigned int count);
 };
 
-extern struct iommu_group *vfio_iommu_group_get(struct device *dev);
-extern void vfio_iommu_group_put(struct iommu_group *group, struct device *dev);
-
 extern int vfio_add_group_dev(struct device *dev,
                              const struct vfio_device_ops *ops,
                              void *device_data);
index 1e1bf9f963a947fc686125d0a2809ad63b8a13ed..513b36f04dfd80bbe9cf40a272e8d2cd2eab452b 100644 (file)
@@ -145,7 +145,7 @@ __remove_wait_queue(wait_queue_head_t *head, wait_queue_t *old)
        list_del(&old->task_list);
 }
 
-typedef int wait_bit_action_f(struct wait_bit_key *);
+typedef int wait_bit_action_f(struct wait_bit_key *, int mode);
 void __wake_up(wait_queue_head_t *q, unsigned int mode, int nr, void *key);
 void __wake_up_locked_key(wait_queue_head_t *q, unsigned int mode, void *key);
 void __wake_up_sync_key(wait_queue_head_t *q, unsigned int mode, int nr, void *key);
@@ -960,10 +960,10 @@ int wake_bit_function(wait_queue_t *wait, unsigned mode, int sync, void *key);
        } while (0)
 
 
-extern int bit_wait(struct wait_bit_key *);
-extern int bit_wait_io(struct wait_bit_key *);
-extern int bit_wait_timeout(struct wait_bit_key *);
-extern int bit_wait_io_timeout(struct wait_bit_key *);
+extern int bit_wait(struct wait_bit_key *, int);
+extern int bit_wait_io(struct wait_bit_key *, int);
+extern int bit_wait_timeout(struct wait_bit_key *, int);
+extern int bit_wait_io_timeout(struct wait_bit_key *, int);
 
 /**
  * wait_on_bit - wait for a bit to be cleared
index b36d837c701ec9fe94280a91df3cf1e359ad50af..2a91a0561a478393ca9e9d2f1993467cc4c5c9cb 100644 (file)
@@ -62,6 +62,7 @@ struct unix_sock {
 #define UNIX_GC_CANDIDATE      0
 #define UNIX_GC_MAYBE_CYCLE    1
        struct socket_wq        peer_wq;
+       wait_queue_t            peer_wake;
 };
 
 static inline struct unix_sock *unix_sk(const struct sock *sk)
index 2bfb2ad2fab1981696e52a914cd89a0dad495e76..877f682989b892fb1d70256bda6b33f03e34a0f5 100644 (file)
@@ -133,27 +133,18 @@ void rt6_clean_tohost(struct net *net, struct in6_addr *gateway);
 /*
  *     Store a destination cache entry in a socket
  */
-static inline void __ip6_dst_store(struct sock *sk, struct dst_entry *dst,
-                                  const struct in6_addr *daddr,
-                                  const struct in6_addr *saddr)
+static inline void ip6_dst_store(struct sock *sk, struct dst_entry *dst,
+                                const struct in6_addr *daddr,
+                                const struct in6_addr *saddr)
 {
        struct ipv6_pinfo *np = inet6_sk(sk);
-       struct rt6_info *rt = (struct rt6_info *) dst;
 
+       np->dst_cookie = rt6_get_cookie((struct rt6_info *)dst);
        sk_setup_caps(sk, dst);
        np->daddr_cache = daddr;
 #ifdef CONFIG_IPV6_SUBTREES
        np->saddr_cache = saddr;
 #endif
-       np->dst_cookie = rt6_get_cookie(rt);
-}
-
-static inline void ip6_dst_store(struct sock *sk, struct dst_entry *dst,
-                                struct in6_addr *daddr, struct in6_addr *saddr)
-{
-       spin_lock(&sk->sk_dst_lock);
-       __ip6_dst_store(sk, dst, daddr, saddr);
-       spin_unlock(&sk->sk_dst_lock);
 }
 
 static inline bool ipv6_unicast_destination(const struct sk_buff *skb)
index e1a10b0ac0b027189732372e2c0040e5ea8350f2..9a5c9f01378455c4c8b9eb860b170504c878f1a5 100644 (file)
@@ -205,6 +205,7 @@ extern rwlock_t ip6_ra_lock;
  */
 
 struct ipv6_txoptions {
+       atomic_t                refcnt;
        /* Length of this structure */
        int                     tot_len;
 
@@ -217,7 +218,7 @@ struct ipv6_txoptions {
        struct ipv6_opt_hdr     *dst0opt;
        struct ipv6_rt_hdr      *srcrt; /* Routing Header */
        struct ipv6_opt_hdr     *dst1opt;
-
+       struct rcu_head         rcu;
        /* Option buffer, as read by IPV6_PKTOPTIONS, starts here. */
 };
 
@@ -252,6 +253,24 @@ struct ipv6_fl_socklist {
        struct rcu_head                 rcu;
 };
 
+static inline struct ipv6_txoptions *txopt_get(const struct ipv6_pinfo *np)
+{
+       struct ipv6_txoptions *opt;
+
+       rcu_read_lock();
+       opt = rcu_dereference(np->opt);
+       if (opt && !atomic_inc_not_zero(&opt->refcnt))
+               opt = NULL;
+       rcu_read_unlock();
+       return opt;
+}
+
+static inline void txopt_put(struct ipv6_txoptions *opt)
+{
+       if (opt && atomic_dec_and_test(&opt->refcnt))
+               kfree_rcu(opt, rcu);
+}
+
 struct ip6_flowlabel *fl6_sock_lookup(struct sock *sk, __be32 label);
 struct ipv6_txoptions *fl6_merge_options(struct ipv6_txoptions *opt_space,
                                         struct ip6_flowlabel *fl,
@@ -490,6 +509,7 @@ struct ip6_create_arg {
        u32 user;
        const struct in6_addr *src;
        const struct in6_addr *dst;
+       int iif;
        u8 ecn;
 };
 
index 82045fca388b20a9cf28ad9112236668c31f46cb..760bc4d5a2cfe87aadd2e96a98292855cf2eb050 100644 (file)
@@ -2003,8 +2003,10 @@ enum ieee80211_hw_flags {
  *     it shouldn't be set.
  *
  * @max_tx_aggregation_subframes: maximum number of subframes in an
- *     aggregate an HT driver will transmit, used by the peer as a
- *     hint to size its reorder buffer.
+ *     aggregate an HT driver will transmit. Though ADDBA will advertise
+ *     a constant value of 64 as some older APs can crash if the window
+ *     size is smaller (an example is LinkSys WRT120N with FW v1.0.07
+ *     build 002 Jun 18 2012).
  *
  * @offchannel_tx_hw_queue: HW queue ID to use for offchannel TX
  *     (if %IEEE80211_HW_QUEUE_CONTROL is set)
index bf39374310305d61e2948cbd1801eee056efc323..2d8edaad29cb1cf0fe1e9a6dc9ae8f2653a3334e 100644 (file)
@@ -181,8 +181,7 @@ void ndisc_cleanup(void);
 int ndisc_rcv(struct sk_buff *skb);
 
 void ndisc_send_ns(struct net_device *dev, const struct in6_addr *solicit,
-                  const struct in6_addr *daddr, const struct in6_addr *saddr,
-                  struct sk_buff *oskb);
+                  const struct in6_addr *daddr, const struct in6_addr *saddr);
 
 void ndisc_send_rs(struct net_device *dev,
                   const struct in6_addr *saddr, const struct in6_addr *daddr);
index 4c79ce8c1f92f2d47eb87ffacd55fa01292e7378..b2a8e6338576d3e91f0906297e6b34e7db0eade3 100644 (file)
@@ -61,6 +61,9 @@ struct Qdisc {
                                      */
 #define TCQ_F_WARN_NONWC       (1 << 16)
 #define TCQ_F_CPUSTATS         0x20 /* run using percpu statistics */
+#define TCQ_F_NOPARENT         0x40 /* root of its hierarchy :
+                                     * qdisc_tree_decrease_qlen() should stop.
+                                     */
        u32                     limit;
        const struct Qdisc_ops  *ops;
        struct qdisc_size_table __rcu *stab;
index 495c87e367b3f2e8941807f56a77d2e14469bfed..7bbb71081aeb6cfdc9cb049cf7a094dbcd4603bb 100644 (file)
@@ -775,10 +775,10 @@ struct sctp_transport {
                hb_sent:1,
 
                /* Is the Path MTU update pending on this tranport */
-               pmtu_pending:1;
+               pmtu_pending:1,
 
-       /* Has this transport moved the ctsn since we last sacked */
-       __u32 sack_generation;
+               /* Has this transport moved the ctsn since we last sacked */
+               sack_generation:1;
        u32 dst_cookie;
 
        struct flowi fl;
@@ -1482,19 +1482,19 @@ struct sctp_association {
                        prsctp_capable:1,   /* Can peer do PR-SCTP? */
                        auth_capable:1;     /* Is peer doing SCTP-AUTH? */
 
-               /* Ack State   : This flag indicates if the next received
+               /* sack_needed : This flag indicates if the next received
                 *             : packet is to be responded to with a
-                *             : SACK. This is initializedto 0.  When a packet
-                *             : is received it is incremented. If this value
+                *             : SACK. This is initialized to 0.  When a packet
+                *             : is received sack_cnt is incremented. If this value
                 *             : reaches 2 or more, a SACK is sent and the
                 *             : value is reset to 0. Note: This is used only
                 *             : when no DATA chunks are received out of
                 *             : order.  When DATA chunks are out of order,
                 *             : SACK's are not delayed (see Section 6).
                 */
-               __u8    sack_needed;     /* Do we need to sack the peer? */
+               __u8    sack_needed:1,     /* Do we need to sack the peer? */
+                       sack_generation:1;
                __u32   sack_cnt;
-               __u32   sack_generation;
 
                __u32   adaptation_ind;  /* Adaptation Code point. */
 
index 7f89e4ba18d11ee6a9261edf85cac743d9f8d5ea..52d27ee924f47867026d8f65c65551a9137219d3 100644 (file)
@@ -254,7 +254,6 @@ struct cg_proto;
   *    @sk_wq: sock wait queue and async head
   *    @sk_rx_dst: receive input route used by early demux
   *    @sk_dst_cache: destination cache
-  *    @sk_dst_lock: destination cache lock
   *    @sk_policy: flow policy
   *    @sk_receive_queue: incoming packets
   *    @sk_wmem_alloc: transmit queue bytes committed
@@ -384,14 +383,16 @@ struct sock {
        int                     sk_rcvbuf;
 
        struct sk_filter __rcu  *sk_filter;
-       struct socket_wq __rcu  *sk_wq;
-
+       union {
+               struct socket_wq __rcu  *sk_wq;
+               struct socket_wq        *sk_wq_raw;
+       };
 #ifdef CONFIG_XFRM
        struct xfrm_policy      *sk_policy[2];
 #endif
        struct dst_entry        *sk_rx_dst;
        struct dst_entry __rcu  *sk_dst_cache;
-       spinlock_t              sk_dst_lock;
+       /* Note: 32bit hole on 64bit arches */
        atomic_t                sk_wmem_alloc;
        atomic_t                sk_omem_alloc;
        int                     sk_sndbuf;
@@ -2005,10 +2006,27 @@ static inline unsigned long sock_wspace(struct sock *sk)
        return amt;
 }
 
-static inline void sk_wake_async(struct sock *sk, int how, int band)
+/* Note:
+ *  We use sk->sk_wq_raw, from contexts knowing this
+ *  pointer is not NULL and cannot disappear/change.
+ */
+static inline void sk_set_bit(int nr, struct sock *sk)
 {
-       if (sock_flag(sk, SOCK_FASYNC))
-               sock_wake_async(sk->sk_socket, how, band);
+       set_bit(nr, &sk->sk_wq_raw->flags);
+}
+
+static inline void sk_clear_bit(int nr, struct sock *sk)
+{
+       clear_bit(nr, &sk->sk_wq_raw->flags);
+}
+
+static inline void sk_wake_async(const struct sock *sk, int how, int band)
+{
+       if (sock_flag(sk, SOCK_FASYNC)) {
+               rcu_read_lock();
+               sock_wake_async(rcu_dereference(sk->sk_wq), how, band);
+               rcu_read_unlock();
+       }
 }
 
 /* Since sk_{r,w}mem_alloc sums skb->truesize, even a small frame might
index 188df91d58514a3248cab5b1b0d7ee09513295a6..ec9b44dd3d806b20d80920a0cb37487ea2d12c24 100644 (file)
@@ -237,6 +237,8 @@ struct ib_vendor_mad {
        u8                      data[IB_MGMT_VENDOR_DATA];
 };
 
+#define IB_MGMT_CLASSPORTINFO_ATTR_ID  cpu_to_be16(0x0001)
+
 struct ib_class_port_info {
        u8                      base_version;
        u8                      class_version;
index 9a68a19532ba57c27042cec499843f3cebfa273c..120da1d7f57eb578c327507ad2affa5b89488dbb 100644 (file)
@@ -1271,6 +1271,7 @@ struct ib_uobject {
        int                     id;             /* index into kernel idr */
        struct kref             ref;
        struct rw_semaphore     mutex;          /* protects .live */
+       struct rcu_head         rcu;            /* kfree_rcu() overhead */
        int                     live;
 };
 
index ed527121031dd31b424c1ff596f9139cfcdefd02..fcfa3d7f5e7e38f1bffcf50495730f24bb9e6b2b 100644 (file)
@@ -668,6 +668,9 @@ struct Scsi_Host {
        unsigned use_blk_mq:1;
        unsigned use_cmd_list:1;
 
+       /* Host responded with short (<36 bytes) INQUIRY result */
+       unsigned short_inquiry:1;
+
        /*
         * Optional work queue to be utilized by the transport
         */
index 2ae8812d7b1a37845789b7c0522c0ab1b4300c45..94dc6a9772e060ce31d97434b9972f6ff255a63b 100644 (file)
@@ -93,6 +93,9 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 };
 #define AZX_REG_HSW_EM4                        0x100c
 #define AZX_REG_HSW_EM5                        0x1010
 
+/* Skylake/Broxton display HD-A controller Extended Mode registers */
+#define AZX_REG_SKL_EM4L               0x1040
+
 /* PCI space */
 #define AZX_PCIREG_TCSEL               0x44
 
index 7855cfe46b69a044040f9ac5be92591e33af1799..95a937eafb79419271acd193ad678e2e4b207a92 100644 (file)
@@ -398,6 +398,7 @@ int snd_soc_dapm_del_routes(struct snd_soc_dapm_context *dapm,
 int snd_soc_dapm_weak_routes(struct snd_soc_dapm_context *dapm,
                             const struct snd_soc_dapm_route *route, int num);
 void snd_soc_dapm_free_widget(struct snd_soc_dapm_widget *w);
+void snd_soc_dapm_reset_cache(struct snd_soc_dapm_context *dapm);
 
 /* dapm events */
 void snd_soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd, int stream,
index 0a2c74008e5388f6d817272735882f40abc3a013..aabf0aca017157a72dd84accb5975c87fe98e79b 100644 (file)
@@ -474,7 +474,7 @@ struct se_cmd {
        struct completion       cmd_wait_comp;
        const struct target_core_fabric_ops *se_tfo;
        sense_reason_t          (*execute_cmd)(struct se_cmd *);
-       sense_reason_t (*transport_complete_callback)(struct se_cmd *, bool);
+       sense_reason_t (*transport_complete_callback)(struct se_cmd *, bool, int *);
        void                    *protocol_data;
 
        unsigned char           *t_task_cdb;
index 654bae3f1a389a4fcff05ba6098fcdd6d6b3204a..5e6296160361cc7b7a7b9d80411ef172c3a453c7 100644 (file)
 
 #define NFS_PIPE_DIRNAME "nfs"
 
-/* NFS ioctls */
-/* Let's follow btrfs lead on CLONE to avoid messing userspace */
-#define NFS_IOC_CLONE          _IOW(0x94, 9, int)
-#define NFS_IOC_CLONE_RANGE    _IOW(0x94, 13, int)
-
-struct nfs_ioctl_clone_range_args {
-       __s64 src_fd;
-       __u64 src_off, count;
-       __u64 dst_off;
-};
-
 /*
  * NFS stats. The good thing with these values is that NFSv3 errors are
  * a superset of NFSv2 errors (with the exception of NFSERR_WFLUSH which
index 751b69f858c80411c910f21db7fb50c8902e94cf..9fd7b5d8df2fa357f434a899cccfa7810f826107 100644 (file)
 
 #define VFIO_SPAPR_TCE_v2_IOMMU                7
 
-/*
- * The No-IOMMU IOMMU offers no translation or isolation for devices and
- * supports no ioctls outside of VFIO_CHECK_EXTENSION.  Use of VFIO's No-IOMMU
- * code will taint the host kernel and should be used with extreme caution.
- */
-#define VFIO_NOIOMMU_IOMMU             8
-
 /*
  * The IOCTL interface is designed for extensibility by embedding the
  * structure length (argsz) and flags into structures passed between
index a2fc6cbfe4141e6d11df455e791d082046a89c7d..288694e422fbab23e20c1652f90971705f96f90e 100644 (file)
 /* separate EPROM commands from normal PSM commands */
 #define HFI1_CMD_EP_INFO         64      /* read EPROM device ID */
 #define HFI1_CMD_EP_ERASE_CHIP   65      /* erase whole EPROM */
-#define HFI1_CMD_EP_ERASE_P0     66      /* erase EPROM partition 0 */
-#define HFI1_CMD_EP_ERASE_P1     67      /* erase EPROM partition 1 */
-#define HFI1_CMD_EP_READ_P0      68      /* read EPROM partition 0 */
-#define HFI1_CMD_EP_READ_P1      69      /* read EPROM partition 1 */
-#define HFI1_CMD_EP_WRITE_P0     70      /* write EPROM partition 0 */
-#define HFI1_CMD_EP_WRITE_P1     71      /* write EPROM partition 1 */
+/* range 66-74 no longer used */
+#define HFI1_CMD_EP_ERASE_RANGE  75      /* erase EPROM range */
+#define HFI1_CMD_EP_READ_RANGE   76      /* read EPROM range */
+#define HFI1_CMD_EP_WRITE_RANGE  77      /* write EPROM range */
 
 #define _HFI1_EVENT_FROZEN_BIT         0
 #define _HFI1_EVENT_LINKDOWN_BIT       1
index 85dedca3dcfb04e738764023b673a7ba3d47926d..eeba75395f7d10b61fabf995d2b0157aec6d9ee5 100644 (file)
@@ -343,7 +343,6 @@ struct ipu_client_platformdata {
        int di;
        int dc;
        int dp;
-       int dmfc;
        int dma[2];
 };
 
index c24b6f767bf0f2a4d8a873388a5fbd59ba01c562..235c7a2c0d2004f1121b7d98f4140683ab45ef53 100644 (file)
@@ -2030,13 +2030,6 @@ config INIT_ALL_POSSIBLE
          it was better to provide this option than to break all the archs
          and have several arch maintainers pursuing me down dark alleys.
 
-config STOP_MACHINE
-       bool
-       default y
-       depends on (SMP && MODULE_UNLOAD) || HOTPLUG_CPU
-       help
-         Need stop_machine() primitive.
-
 source "block/Kconfig"
 
 config PREEMPT_NOTIFIERS
index 3f4c99e06c6bbf8a5e28f882633e8161f3974929..b0799bced518691bd847a16973be74184bcdcbaf 100644 (file)
@@ -28,11 +28,17 @@ static struct bpf_map *array_map_alloc(union bpf_attr *attr)
            attr->value_size == 0)
                return ERR_PTR(-EINVAL);
 
+       if (attr->value_size >= 1 << (KMALLOC_SHIFT_MAX - 1))
+               /* if value_size is bigger, the user space won't be able to
+                * access the elements.
+                */
+               return ERR_PTR(-E2BIG);
+
        elem_size = round_up(attr->value_size, 8);
 
        /* check round_up into zero and u32 overflow */
        if (elem_size == 0 ||
-           attr->max_entries > (U32_MAX - sizeof(*array)) / elem_size)
+           attr->max_entries > (U32_MAX - PAGE_SIZE - sizeof(*array)) / elem_size)
                return ERR_PTR(-ENOMEM);
 
        array_size = sizeof(*array) + attr->max_entries * elem_size;
@@ -105,7 +111,7 @@ static int array_map_update_elem(struct bpf_map *map, void *key, void *value,
                /* all elements already exist */
                return -EEXIST;
 
-       memcpy(array->value + array->elem_size * index, value, array->elem_size);
+       memcpy(array->value + array->elem_size * index, value, map->value_size);
        return 0;
 }
 
index 19909b22b4f8398d7373cc3838b835728265ed23..34777b3746fadf6407ca9805f33df608be619f21 100644 (file)
@@ -64,12 +64,35 @@ static struct bpf_map *htab_map_alloc(union bpf_attr *attr)
                 */
                goto free_htab;
 
-       err = -ENOMEM;
+       if (htab->map.value_size >= (1 << (KMALLOC_SHIFT_MAX - 1)) -
+           MAX_BPF_STACK - sizeof(struct htab_elem))
+               /* if value_size is bigger, the user space won't be able to
+                * access the elements via bpf syscall. This check also makes
+                * sure that the elem_size doesn't overflow and it's
+                * kmalloc-able later in htab_map_update_elem()
+                */
+               goto free_htab;
+
+       htab->elem_size = sizeof(struct htab_elem) +
+                         round_up(htab->map.key_size, 8) +
+                         htab->map.value_size;
+
        /* prevent zero size kmalloc and check for u32 overflow */
        if (htab->n_buckets == 0 ||
            htab->n_buckets > U32_MAX / sizeof(struct hlist_head))
                goto free_htab;
 
+       if ((u64) htab->n_buckets * sizeof(struct hlist_head) +
+           (u64) htab->elem_size * htab->map.max_entries >=
+           U32_MAX - PAGE_SIZE)
+               /* make sure page count doesn't overflow */
+               goto free_htab;
+
+       htab->map.pages = round_up(htab->n_buckets * sizeof(struct hlist_head) +
+                                  htab->elem_size * htab->map.max_entries,
+                                  PAGE_SIZE) >> PAGE_SHIFT;
+
+       err = -ENOMEM;
        htab->buckets = kmalloc_array(htab->n_buckets, sizeof(struct hlist_head),
                                      GFP_USER | __GFP_NOWARN);
 
@@ -85,13 +108,6 @@ static struct bpf_map *htab_map_alloc(union bpf_attr *attr)
        raw_spin_lock_init(&htab->lock);
        htab->count = 0;
 
-       htab->elem_size = sizeof(struct htab_elem) +
-                         round_up(htab->map.key_size, 8) +
-                         htab->map.value_size;
-
-       htab->map.pages = round_up(htab->n_buckets * sizeof(struct hlist_head) +
-                                  htab->elem_size * htab->map.max_entries,
-                                  PAGE_SIZE) >> PAGE_SHIFT;
        return &htab->map;
 
 free_htab:
@@ -222,7 +238,7 @@ static int htab_map_update_elem(struct bpf_map *map, void *key, void *value,
        WARN_ON_ONCE(!rcu_read_lock_held());
 
        /* allocate new element outside of lock */
-       l_new = kmalloc(htab->elem_size, GFP_ATOMIC);
+       l_new = kmalloc(htab->elem_size, GFP_ATOMIC | __GFP_NOWARN);
        if (!l_new)
                return -ENOMEM;
 
index be6d726e31c9429860141925130d0e5c71011e7b..5a8a797d50b74a8bb698760856c1849ff9bcc084 100644 (file)
@@ -34,7 +34,7 @@ static void *bpf_any_get(void *raw, enum bpf_type type)
                atomic_inc(&((struct bpf_prog *)raw)->aux->refcnt);
                break;
        case BPF_TYPE_MAP:
-               atomic_inc(&((struct bpf_map *)raw)->refcnt);
+               bpf_map_inc(raw, true);
                break;
        default:
                WARN_ON_ONCE(1);
@@ -51,7 +51,7 @@ static void bpf_any_put(void *raw, enum bpf_type type)
                bpf_prog_put(raw);
                break;
        case BPF_TYPE_MAP:
-               bpf_map_put(raw);
+               bpf_map_put_with_uref(raw);
                break;
        default:
                WARN_ON_ONCE(1);
@@ -64,7 +64,7 @@ static void *bpf_fd_probe_obj(u32 ufd, enum bpf_type *type)
        void *raw;
 
        *type = BPF_TYPE_MAP;
-       raw = bpf_map_get(ufd);
+       raw = bpf_map_get_with_uref(ufd);
        if (IS_ERR(raw)) {
                *type = BPF_TYPE_PROG;
                raw = bpf_prog_get(ufd);
index 0d3313d02a7e512e1ca7f58fb52aa3e39bae60a3..3b39550d84856494d43aefe926457add41d2a435 100644 (file)
@@ -82,6 +82,14 @@ static void bpf_map_free_deferred(struct work_struct *work)
        map->ops->map_free(map);
 }
 
+static void bpf_map_put_uref(struct bpf_map *map)
+{
+       if (atomic_dec_and_test(&map->usercnt)) {
+               if (map->map_type == BPF_MAP_TYPE_PROG_ARRAY)
+                       bpf_fd_array_map_clear(map);
+       }
+}
+
 /* decrement map refcnt and schedule it for freeing via workqueue
  * (unrelying map implementation ops->map_free() might sleep)
  */
@@ -93,17 +101,15 @@ void bpf_map_put(struct bpf_map *map)
        }
 }
 
-static int bpf_map_release(struct inode *inode, struct file *filp)
+void bpf_map_put_with_uref(struct bpf_map *map)
 {
-       struct bpf_map *map = filp->private_data;
-
-       if (map->map_type == BPF_MAP_TYPE_PROG_ARRAY)
-               /* prog_array stores refcnt-ed bpf_prog pointers
-                * release them all when user space closes prog_array_fd
-                */
-               bpf_fd_array_map_clear(map);
-
+       bpf_map_put_uref(map);
        bpf_map_put(map);
+}
+
+static int bpf_map_release(struct inode *inode, struct file *filp)
+{
+       bpf_map_put_with_uref(filp->private_data);
        return 0;
 }
 
@@ -142,6 +148,7 @@ static int map_create(union bpf_attr *attr)
                return PTR_ERR(map);
 
        atomic_set(&map->refcnt, 1);
+       atomic_set(&map->usercnt, 1);
 
        err = bpf_map_charge_memlock(map);
        if (err)
@@ -174,7 +181,14 @@ struct bpf_map *__bpf_map_get(struct fd f)
        return f.file->private_data;
 }
 
-struct bpf_map *bpf_map_get(u32 ufd)
+void bpf_map_inc(struct bpf_map *map, bool uref)
+{
+       atomic_inc(&map->refcnt);
+       if (uref)
+               atomic_inc(&map->usercnt);
+}
+
+struct bpf_map *bpf_map_get_with_uref(u32 ufd)
 {
        struct fd f = fdget(ufd);
        struct bpf_map *map;
@@ -183,7 +197,7 @@ struct bpf_map *bpf_map_get(u32 ufd)
        if (IS_ERR(map))
                return map;
 
-       atomic_inc(&map->refcnt);
+       bpf_map_inc(map, true);
        fdput(f);
 
        return map;
@@ -226,7 +240,7 @@ static int map_lookup_elem(union bpf_attr *attr)
                goto free_key;
 
        err = -ENOMEM;
-       value = kmalloc(map->value_size, GFP_USER);
+       value = kmalloc(map->value_size, GFP_USER | __GFP_NOWARN);
        if (!value)
                goto free_key;
 
@@ -285,7 +299,7 @@ static int map_update_elem(union bpf_attr *attr)
                goto free_key;
 
        err = -ENOMEM;
-       value = kmalloc(map->value_size, GFP_USER);
+       value = kmalloc(map->value_size, GFP_USER | __GFP_NOWARN);
        if (!value)
                goto free_key;
 
index c6073056badf02293c7e9d1e35dce9bb88536c67..a7945d10b378bed8eb7243bd52923d232b1f49de 100644 (file)
@@ -2021,8 +2021,7 @@ static int replace_map_fd_with_map_ptr(struct verifier_env *env)
                         * will be used by the valid program until it's unloaded
                         * and all maps are released in free_bpf_prog_info()
                         */
-                       atomic_inc(&map->refcnt);
-
+                       bpf_map_inc(map, false);
                        fdput(f);
 next_insn:
                        insn++;
index f1603c153890d2b9dbd37a5c687fd297c6137f24..470f6536b9e8cfb029eedb5ecdb3c3e8c3c341be 100644 (file)
@@ -97,6 +97,12 @@ static DEFINE_SPINLOCK(css_set_lock);
  */
 static DEFINE_SPINLOCK(cgroup_idr_lock);
 
+/*
+ * Protects cgroup_file->kn for !self csses.  It synchronizes notifications
+ * against file removal/re-creation across css hiding.
+ */
+static DEFINE_SPINLOCK(cgroup_file_kn_lock);
+
 /*
  * Protects cgroup_subsys->release_agent_path.  Modifying it also requires
  * cgroup_mutex.  Reading requires either cgroup_mutex or this spinlock.
@@ -754,9 +760,11 @@ static void put_css_set_locked(struct css_set *cset)
        if (!atomic_dec_and_test(&cset->refcount))
                return;
 
-       /* This css_set is dead. unlink it and release cgroup refcounts */
-       for_each_subsys(ss, ssid)
+       /* This css_set is dead. unlink it and release cgroup and css refs */
+       for_each_subsys(ss, ssid) {
                list_del(&cset->e_cset_node[ssid]);
+               css_put(cset->subsys[ssid]);
+       }
        hash_del(&cset->hlist);
        css_set_count--;
 
@@ -1056,9 +1064,13 @@ static struct css_set *find_css_set(struct css_set *old_cset,
        key = css_set_hash(cset->subsys);
        hash_add(css_set_table, &cset->hlist, key);
 
-       for_each_subsys(ss, ssid)
+       for_each_subsys(ss, ssid) {
+               struct cgroup_subsys_state *css = cset->subsys[ssid];
+
                list_add_tail(&cset->e_cset_node[ssid],
-                             &cset->subsys[ssid]->cgroup->e_csets[ssid]);
+                             &css->cgroup->e_csets[ssid]);
+               css_get(css);
+       }
 
        spin_unlock_bh(&css_set_lock);
 
@@ -1393,6 +1405,16 @@ static void cgroup_rm_file(struct cgroup *cgrp, const struct cftype *cft)
        char name[CGROUP_FILE_NAME_MAX];
 
        lockdep_assert_held(&cgroup_mutex);
+
+       if (cft->file_offset) {
+               struct cgroup_subsys_state *css = cgroup_css(cgrp, cft->ss);
+               struct cgroup_file *cfile = (void *)css + cft->file_offset;
+
+               spin_lock_irq(&cgroup_file_kn_lock);
+               cfile->kn = NULL;
+               spin_unlock_irq(&cgroup_file_kn_lock);
+       }
+
        kernfs_remove_by_name(cgrp->kn, cgroup_file_name(cgrp, cft, name));
 }
 
@@ -1856,7 +1878,6 @@ static void init_cgroup_housekeeping(struct cgroup *cgrp)
 
        INIT_LIST_HEAD(&cgrp->self.sibling);
        INIT_LIST_HEAD(&cgrp->self.children);
-       INIT_LIST_HEAD(&cgrp->self.files);
        INIT_LIST_HEAD(&cgrp->cset_links);
        INIT_LIST_HEAD(&cgrp->pidlists);
        mutex_init(&cgrp->pidlist_mutex);
@@ -2216,6 +2237,9 @@ struct cgroup_taskset {
        struct list_head        src_csets;
        struct list_head        dst_csets;
 
+       /* the subsys currently being processed */
+       int                     ssid;
+
        /*
         * Fields for cgroup_taskset_*() iteration.
         *
@@ -2278,25 +2302,29 @@ static void cgroup_taskset_add(struct task_struct *task,
 /**
  * cgroup_taskset_first - reset taskset and return the first task
  * @tset: taskset of interest
+ * @dst_cssp: output variable for the destination css
  *
  * @tset iteration is initialized and the first task is returned.
  */
-struct task_struct *cgroup_taskset_first(struct cgroup_taskset *tset)
+struct task_struct *cgroup_taskset_first(struct cgroup_taskset *tset,
+                                        struct cgroup_subsys_state **dst_cssp)
 {
        tset->cur_cset = list_first_entry(tset->csets, struct css_set, mg_node);
        tset->cur_task = NULL;
 
-       return cgroup_taskset_next(tset);
+       return cgroup_taskset_next(tset, dst_cssp);
 }
 
 /**
  * cgroup_taskset_next - iterate to the next task in taskset
  * @tset: taskset of interest
+ * @dst_cssp: output variable for the destination css
  *
  * Return the next task in @tset.  Iteration must have been initialized
  * with cgroup_taskset_first().
  */
-struct task_struct *cgroup_taskset_next(struct cgroup_taskset *tset)
+struct task_struct *cgroup_taskset_next(struct cgroup_taskset *tset,
+                                       struct cgroup_subsys_state **dst_cssp)
 {
        struct css_set *cset = tset->cur_cset;
        struct task_struct *task = tset->cur_task;
@@ -2311,6 +2339,18 @@ struct task_struct *cgroup_taskset_next(struct cgroup_taskset *tset)
                if (&task->cg_list != &cset->mg_tasks) {
                        tset->cur_cset = cset;
                        tset->cur_task = task;
+
+                       /*
+                        * This function may be called both before and
+                        * after cgroup_taskset_migrate().  The two cases
+                        * can be distinguished by looking at whether @cset
+                        * has its ->mg_dst_cset set.
+                        */
+                       if (cset->mg_dst_cset)
+                               *dst_cssp = cset->mg_dst_cset->subsys[tset->ssid];
+                       else
+                               *dst_cssp = cset->subsys[tset->ssid];
+
                        return task;
                }
 
@@ -2346,7 +2386,8 @@ static int cgroup_taskset_migrate(struct cgroup_taskset *tset,
        /* check that we can legitimately attach to the cgroup */
        for_each_e_css(css, i, dst_cgrp) {
                if (css->ss->can_attach) {
-                       ret = css->ss->can_attach(css, tset);
+                       tset->ssid = i;
+                       ret = css->ss->can_attach(tset);
                        if (ret) {
                                failed_css = css;
                                goto out_cancel_attach;
@@ -2379,9 +2420,12 @@ static int cgroup_taskset_migrate(struct cgroup_taskset *tset,
         */
        tset->csets = &tset->dst_csets;
 
-       for_each_e_css(css, i, dst_cgrp)
-               if (css->ss->attach)
-                       css->ss->attach(css, tset);
+       for_each_e_css(css, i, dst_cgrp) {
+               if (css->ss->attach) {
+                       tset->ssid = i;
+                       css->ss->attach(tset);
+               }
+       }
 
        ret = 0;
        goto out_release_tset;
@@ -2390,8 +2434,10 @@ out_cancel_attach:
        for_each_e_css(css, i, dst_cgrp) {
                if (css == failed_css)
                        break;
-               if (css->ss->cancel_attach)
-                       css->ss->cancel_attach(css, tset);
+               if (css->ss->cancel_attach) {
+                       tset->ssid = i;
+                       css->ss->cancel_attach(tset);
+               }
        }
 out_release_tset:
        spin_lock_bh(&css_set_lock);
@@ -3313,9 +3359,9 @@ static int cgroup_add_file(struct cgroup_subsys_state *css, struct cgroup *cgrp,
        if (cft->file_offset) {
                struct cgroup_file *cfile = (void *)css + cft->file_offset;
 
-               kernfs_get(kn);
+               spin_lock_irq(&cgroup_file_kn_lock);
                cfile->kn = kn;
-               list_add(&cfile->node, &css->files);
+               spin_unlock_irq(&cgroup_file_kn_lock);
        }
 
        return 0;
@@ -3552,6 +3598,22 @@ int cgroup_add_legacy_cftypes(struct cgroup_subsys *ss, struct cftype *cfts)
        return cgroup_add_cftypes(ss, cfts);
 }
 
+/**
+ * cgroup_file_notify - generate a file modified event for a cgroup_file
+ * @cfile: target cgroup_file
+ *
+ * @cfile must have been obtained by setting cftype->file_offset.
+ */
+void cgroup_file_notify(struct cgroup_file *cfile)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&cgroup_file_kn_lock, flags);
+       if (cfile->kn)
+               kernfs_notify(cfile->kn);
+       spin_unlock_irqrestore(&cgroup_file_kn_lock, flags);
+}
+
 /**
  * cgroup_task_count - count the number of tasks in a cgroup.
  * @cgrp: the cgroup in question
@@ -4613,13 +4675,9 @@ static void css_free_work_fn(struct work_struct *work)
                container_of(work, struct cgroup_subsys_state, destroy_work);
        struct cgroup_subsys *ss = css->ss;
        struct cgroup *cgrp = css->cgroup;
-       struct cgroup_file *cfile;
 
        percpu_ref_exit(&css->refcnt);
 
-       list_for_each_entry(cfile, &css->files, node)
-               kernfs_put(cfile->kn);
-
        if (ss) {
                /* css free path */
                int id = css->id;
@@ -4724,7 +4782,6 @@ static void init_and_link_css(struct cgroup_subsys_state *css,
        css->ss = ss;
        INIT_LIST_HEAD(&css->sibling);
        INIT_LIST_HEAD(&css->children);
-       INIT_LIST_HEAD(&css->files);
        css->serial_nr = css_serial_nr_next++;
 
        if (cgroup_parent(cgrp)) {
index f1b30ad5dc6d925685f92ecbc0918b7c78018f30..2d3df82c54f2dd84484e0b4d739551cb69861e4e 100644 (file)
@@ -155,12 +155,10 @@ static void freezer_css_free(struct cgroup_subsys_state *css)
  * @freezer->lock.  freezer_attach() makes the new tasks conform to the
  * current state and all following state changes can see the new tasks.
  */
-static void freezer_attach(struct cgroup_subsys_state *new_css,
-                          struct cgroup_taskset *tset)
+static void freezer_attach(struct cgroup_taskset *tset)
 {
-       struct freezer *freezer = css_freezer(new_css);
        struct task_struct *task;
-       bool clear_frozen = false;
+       struct cgroup_subsys_state *new_css;
 
        mutex_lock(&freezer_mutex);
 
@@ -174,22 +172,21 @@ static void freezer_attach(struct cgroup_subsys_state *new_css,
         * current state before executing the following - !frozen tasks may
         * be visible in a FROZEN cgroup and frozen tasks in a THAWED one.
         */
-       cgroup_taskset_for_each(task, tset) {
+       cgroup_taskset_for_each(task, new_css, tset) {
+               struct freezer *freezer = css_freezer(new_css);
+
                if (!(freezer->state & CGROUP_FREEZING)) {
                        __thaw_task(task);
                } else {
                        freeze_task(task);
-                       freezer->state &= ~CGROUP_FROZEN;
-                       clear_frozen = true;
+                       /* clear FROZEN and propagate upwards */
+                       while (freezer && (freezer->state & CGROUP_FROZEN)) {
+                               freezer->state &= ~CGROUP_FROZEN;
+                               freezer = parent_freezer(freezer);
+                       }
                }
        }
 
-       /* propagate FROZEN clearing upwards */
-       while (clear_frozen && (freezer = parent_freezer(freezer))) {
-               freezer->state &= ~CGROUP_FROZEN;
-               clear_frozen = freezer->state & CGROUP_FREEZING;
-       }
-
        mutex_unlock(&freezer_mutex);
 }
 
index cdd8df4e991c7781ac5996677d724bcd23314623..b50d5a167fda7d2ae6902efd55e551efed780007 100644 (file)
@@ -106,7 +106,7 @@ static void pids_uncharge(struct pids_cgroup *pids, int num)
 {
        struct pids_cgroup *p;
 
-       for (p = pids; p; p = parent_pids(p))
+       for (p = pids; parent_pids(p); p = parent_pids(p))
                pids_cancel(p, num);
 }
 
@@ -123,7 +123,7 @@ static void pids_charge(struct pids_cgroup *pids, int num)
 {
        struct pids_cgroup *p;
 
-       for (p = pids; p; p = parent_pids(p))
+       for (p = pids; parent_pids(p); p = parent_pids(p))
                atomic64_add(num, &p->counter);
 }
 
@@ -140,7 +140,7 @@ static int pids_try_charge(struct pids_cgroup *pids, int num)
 {
        struct pids_cgroup *p, *q;
 
-       for (p = pids; p; p = parent_pids(p)) {
+       for (p = pids; parent_pids(p); p = parent_pids(p)) {
                int64_t new = atomic64_add_return(num, &p->counter);
 
                /*
@@ -162,13 +162,13 @@ revert:
        return -EAGAIN;
 }
 
-static int pids_can_attach(struct cgroup_subsys_state *css,
-                          struct cgroup_taskset *tset)
+static int pids_can_attach(struct cgroup_taskset *tset)
 {
-       struct pids_cgroup *pids = css_pids(css);
        struct task_struct *task;
+       struct cgroup_subsys_state *dst_css;
 
-       cgroup_taskset_for_each(task, tset) {
+       cgroup_taskset_for_each(task, dst_css, tset) {
+               struct pids_cgroup *pids = css_pids(dst_css);
                struct cgroup_subsys_state *old_css;
                struct pids_cgroup *old_pids;
 
@@ -187,13 +187,13 @@ static int pids_can_attach(struct cgroup_subsys_state *css,
        return 0;
 }
 
-static void pids_cancel_attach(struct cgroup_subsys_state *css,
-                              struct cgroup_taskset *tset)
+static void pids_cancel_attach(struct cgroup_taskset *tset)
 {
-       struct pids_cgroup *pids = css_pids(css);
        struct task_struct *task;
+       struct cgroup_subsys_state *dst_css;
 
-       cgroup_taskset_for_each(task, tset) {
+       cgroup_taskset_for_each(task, dst_css, tset) {
+               struct pids_cgroup *pids = css_pids(dst_css);
                struct cgroup_subsys_state *old_css;
                struct pids_cgroup *old_pids;
 
@@ -205,65 +205,28 @@ static void pids_cancel_attach(struct cgroup_subsys_state *css,
        }
 }
 
+/*
+ * task_css_check(true) in pids_can_fork() and pids_cancel_fork() relies
+ * on threadgroup_change_begin() held by the copy_process().
+ */
 static int pids_can_fork(struct task_struct *task, void **priv_p)
 {
        struct cgroup_subsys_state *css;
        struct pids_cgroup *pids;
-       int err;
 
-       /*
-        * Use the "current" task_css for the pids subsystem as the tentative
-        * css. It is possible we will charge the wrong hierarchy, in which
-        * case we will forcefully revert/reapply the charge on the right
-        * hierarchy after it is committed to the task proper.
-        */
-       css = task_get_css(current, pids_cgrp_id);
+       css = task_css_check(current, pids_cgrp_id, true);
        pids = css_pids(css);
-
-       err = pids_try_charge(pids, 1);
-       if (err)
-               goto err_css_put;
-
-       *priv_p = css;
-       return 0;
-
-err_css_put:
-       css_put(css);
-       return err;
+       return pids_try_charge(pids, 1);
 }
 
 static void pids_cancel_fork(struct task_struct *task, void *priv)
-{
-       struct cgroup_subsys_state *css = priv;
-       struct pids_cgroup *pids = css_pids(css);
-
-       pids_uncharge(pids, 1);
-       css_put(css);
-}
-
-static void pids_fork(struct task_struct *task, void *priv)
 {
        struct cgroup_subsys_state *css;
-       struct cgroup_subsys_state *old_css = priv;
        struct pids_cgroup *pids;
-       struct pids_cgroup *old_pids = css_pids(old_css);
 
-       css = task_get_css(task, pids_cgrp_id);
+       css = task_css_check(current, pids_cgrp_id, true);
        pids = css_pids(css);
-
-       /*
-        * If the association has changed, we have to revert and reapply the
-        * charge/uncharge on the wrong hierarchy to the current one. Since
-        * the association can only change due to an organisation event, its
-        * okay for us to ignore the limit in this case.
-        */
-       if (pids != old_pids) {
-               pids_uncharge(old_pids, 1);
-               pids_charge(pids, 1);
-       }
-
-       css_put(css);
-       css_put(old_css);
+       pids_uncharge(pids, 1);
 }
 
 static void pids_free(struct task_struct *task)
@@ -335,6 +298,7 @@ static struct cftype pids_files[] = {
        {
                .name = "current",
                .read_s64 = pids_current_read,
+               .flags = CFTYPE_NOT_ON_ROOT,
        },
        { }     /* terminate */
 };
@@ -346,7 +310,6 @@ struct cgroup_subsys pids_cgrp_subsys = {
        .cancel_attach  = pids_cancel_attach,
        .can_fork       = pids_can_fork,
        .cancel_fork    = pids_cancel_fork,
-       .fork           = pids_fork,
        .free           = pids_free,
        .legacy_cftypes = pids_files,
        .dfl_cftypes    = pids_files,
index 10ae73611d80a560977aa554d6cbedee78bec19a..02a8ea5c99632907b2ae887015c59bd4ad35da9d 100644 (file)
@@ -1429,15 +1429,16 @@ static int fmeter_getrate(struct fmeter *fmp)
 static struct cpuset *cpuset_attach_old_cs;
 
 /* Called by cgroups to determine if a cpuset is usable; cpuset_mutex held */
-static int cpuset_can_attach(struct cgroup_subsys_state *css,
-                            struct cgroup_taskset *tset)
+static int cpuset_can_attach(struct cgroup_taskset *tset)
 {
-       struct cpuset *cs = css_cs(css);
+       struct cgroup_subsys_state *css;
+       struct cpuset *cs;
        struct task_struct *task;
        int ret;
 
        /* used later by cpuset_attach() */
-       cpuset_attach_old_cs = task_cs(cgroup_taskset_first(tset));
+       cpuset_attach_old_cs = task_cs(cgroup_taskset_first(tset, &css));
+       cs = css_cs(css);
 
        mutex_lock(&cpuset_mutex);
 
@@ -1447,7 +1448,7 @@ static int cpuset_can_attach(struct cgroup_subsys_state *css,
            (cpumask_empty(cs->cpus_allowed) || nodes_empty(cs->mems_allowed)))
                goto out_unlock;
 
-       cgroup_taskset_for_each(task, tset) {
+       cgroup_taskset_for_each(task, css, tset) {
                ret = task_can_attach(task, cs->cpus_allowed);
                if (ret)
                        goto out_unlock;
@@ -1467,9 +1468,14 @@ out_unlock:
        return ret;
 }
 
-static void cpuset_cancel_attach(struct cgroup_subsys_state *css,
-                                struct cgroup_taskset *tset)
+static void cpuset_cancel_attach(struct cgroup_taskset *tset)
 {
+       struct cgroup_subsys_state *css;
+       struct cpuset *cs;
+
+       cgroup_taskset_first(tset, &css);
+       cs = css_cs(css);
+
        mutex_lock(&cpuset_mutex);
        css_cs(css)->attach_in_progress--;
        mutex_unlock(&cpuset_mutex);
@@ -1482,16 +1488,19 @@ static void cpuset_cancel_attach(struct cgroup_subsys_state *css,
  */
 static cpumask_var_t cpus_attach;
 
-static void cpuset_attach(struct cgroup_subsys_state *css,
-                         struct cgroup_taskset *tset)
+static void cpuset_attach(struct cgroup_taskset *tset)
 {
        /* static buf protected by cpuset_mutex */
        static nodemask_t cpuset_attach_nodemask_to;
        struct task_struct *task;
        struct task_struct *leader;
-       struct cpuset *cs = css_cs(css);
+       struct cgroup_subsys_state *css;
+       struct cpuset *cs;
        struct cpuset *oldcs = cpuset_attach_old_cs;
 
+       cgroup_taskset_first(tset, &css);
+       cs = css_cs(css);
+
        mutex_lock(&cpuset_mutex);
 
        /* prepare for attach */
@@ -1502,7 +1511,7 @@ static void cpuset_attach(struct cgroup_subsys_state *css,
 
        guarantee_online_mems(cs, &cpuset_attach_nodemask_to);
 
-       cgroup_taskset_for_each(task, tset) {
+       cgroup_taskset_for_each(task, css, tset) {
                /*
                 * can_attach beforehand should guarantee that this doesn't
                 * fail.  TODO: have a better way to handle failure here
@@ -1518,7 +1527,7 @@ static void cpuset_attach(struct cgroup_subsys_state *css,
         * sleep and should be moved outside migration path proper.
         */
        cpuset_attach_nodemask_to = cs->effective_mems;
-       cgroup_taskset_for_each_leader(leader, tset) {
+       cgroup_taskset_for_each_leader(leader, css, tset) {
                struct mm_struct *mm = get_task_mm(leader);
 
                if (mm) {
index d659487254d5d77de07f279ceb0ba0bebe93ed03..9c418002b8c1fa15217b3390250453b492849344 100644 (file)
@@ -3,7 +3,7 @@
  *
  *  Copyright (C) 2008 Thomas Gleixner <tglx@linutronix.de>
  *  Copyright (C) 2008-2011 Red Hat, Inc., Ingo Molnar
- *  Copyright (C) 2008-2011 Red Hat, Inc., Peter Zijlstra <pzijlstr@redhat.com>
+ *  Copyright (C) 2008-2011 Red Hat, Inc., Peter Zijlstra
  *  Copyright  Â©  2009 Paul Mackerras, IBM Corp. <paulus@au1.ibm.com>
  *
  * For licensing details see kernel-base/COPYING
index 36babfd2064842c28d4951a656ea1e84500bbf8f..ef2d6ea10736e4805e758cae83524dc13c2f06e9 100644 (file)
@@ -3,7 +3,7 @@
  *
  *  Copyright (C) 2008 Thomas Gleixner <tglx@linutronix.de>
  *  Copyright (C) 2008-2011 Red Hat, Inc., Ingo Molnar
- *  Copyright (C) 2008-2011 Red Hat, Inc., Peter Zijlstra <pzijlstr@redhat.com>
+ *  Copyright (C) 2008-2011 Red Hat, Inc., Peter Zijlstra
  *  Copyright  Â©  2009 Paul Mackerras, IBM Corp. <paulus@au1.ibm.com>
  *
  * For licensing details see kernel-base/COPYING
@@ -435,7 +435,7 @@ static inline void update_cgrp_time_from_event(struct perf_event *event)
        if (!is_cgroup_event(event))
                return;
 
-       cgrp = perf_cgroup_from_task(current);
+       cgrp = perf_cgroup_from_task(current, event->ctx);
        /*
         * Do not update time when cgroup is not active
         */
@@ -458,7 +458,7 @@ perf_cgroup_set_timestamp(struct task_struct *task,
        if (!task || !ctx->nr_cgroups)
                return;
 
-       cgrp = perf_cgroup_from_task(task);
+       cgrp = perf_cgroup_from_task(task, ctx);
        info = this_cpu_ptr(cgrp->info);
        info->timestamp = ctx->timestamp;
 }
@@ -489,7 +489,6 @@ static void perf_cgroup_switch(struct task_struct *task, int mode)
         * we reschedule only in the presence of cgroup
         * constrained events.
         */
-       rcu_read_lock();
 
        list_for_each_entry_rcu(pmu, &pmus, entry) {
                cpuctx = this_cpu_ptr(pmu->pmu_cpu_context);
@@ -522,8 +521,10 @@ static void perf_cgroup_switch(struct task_struct *task, int mode)
                                 * set cgrp before ctxsw in to allow
                                 * event_filter_match() to not have to pass
                                 * task around
+                                * we pass the cpuctx->ctx to perf_cgroup_from_task()
+                                * because cgorup events are only per-cpu
                                 */
-                               cpuctx->cgrp = perf_cgroup_from_task(task);
+                               cpuctx->cgrp = perf_cgroup_from_task(task, &cpuctx->ctx);
                                cpu_ctx_sched_in(cpuctx, EVENT_ALL, task);
                        }
                        perf_pmu_enable(cpuctx->ctx.pmu);
@@ -531,8 +532,6 @@ static void perf_cgroup_switch(struct task_struct *task, int mode)
                }
        }
 
-       rcu_read_unlock();
-
        local_irq_restore(flags);
 }
 
@@ -542,17 +541,20 @@ static inline void perf_cgroup_sched_out(struct task_struct *task,
        struct perf_cgroup *cgrp1;
        struct perf_cgroup *cgrp2 = NULL;
 
+       rcu_read_lock();
        /*
         * we come here when we know perf_cgroup_events > 0
+        * we do not need to pass the ctx here because we know
+        * we are holding the rcu lock
         */
-       cgrp1 = perf_cgroup_from_task(task);
+       cgrp1 = perf_cgroup_from_task(task, NULL);
 
        /*
         * next is NULL when called from perf_event_enable_on_exec()
         * that will systematically cause a cgroup_switch()
         */
        if (next)
-               cgrp2 = perf_cgroup_from_task(next);
+               cgrp2 = perf_cgroup_from_task(next, NULL);
 
        /*
         * only schedule out current cgroup events if we know
@@ -561,6 +563,8 @@ static inline void perf_cgroup_sched_out(struct task_struct *task,
         */
        if (cgrp1 != cgrp2)
                perf_cgroup_switch(task, PERF_CGROUP_SWOUT);
+
+       rcu_read_unlock();
 }
 
 static inline void perf_cgroup_sched_in(struct task_struct *prev,
@@ -569,13 +573,16 @@ static inline void perf_cgroup_sched_in(struct task_struct *prev,
        struct perf_cgroup *cgrp1;
        struct perf_cgroup *cgrp2 = NULL;
 
+       rcu_read_lock();
        /*
         * we come here when we know perf_cgroup_events > 0
+        * we do not need to pass the ctx here because we know
+        * we are holding the rcu lock
         */
-       cgrp1 = perf_cgroup_from_task(task);
+       cgrp1 = perf_cgroup_from_task(task, NULL);
 
        /* prev can never be NULL */
-       cgrp2 = perf_cgroup_from_task(prev);
+       cgrp2 = perf_cgroup_from_task(prev, NULL);
 
        /*
         * only need to schedule in cgroup events if we are changing
@@ -584,6 +591,8 @@ static inline void perf_cgroup_sched_in(struct task_struct *prev,
         */
        if (cgrp1 != cgrp2)
                perf_cgroup_switch(task, PERF_CGROUP_SWIN);
+
+       rcu_read_unlock();
 }
 
 static inline int perf_cgroup_connect(int fd, struct perf_event *event,
@@ -4216,7 +4225,14 @@ retry:
                goto retry;
        }
 
-       __perf_event_period(&pe);
+       if (event->attr.freq) {
+               event->attr.sample_freq = value;
+       } else {
+               event->attr.sample_period = value;
+               event->hw.sample_period = value;
+       }
+
+       local64_set(&event->hw.period_left, 0);
        raw_spin_unlock_irq(&ctx->lock);
 
        return 0;
@@ -5666,6 +5682,17 @@ perf_event_aux_ctx(struct perf_event_context *ctx,
        }
 }
 
+static void
+perf_event_aux_task_ctx(perf_event_aux_output_cb output, void *data,
+                       struct perf_event_context *task_ctx)
+{
+       rcu_read_lock();
+       preempt_disable();
+       perf_event_aux_ctx(task_ctx, output, data);
+       preempt_enable();
+       rcu_read_unlock();
+}
+
 static void
 perf_event_aux(perf_event_aux_output_cb output, void *data,
               struct perf_event_context *task_ctx)
@@ -5675,14 +5702,23 @@ perf_event_aux(perf_event_aux_output_cb output, void *data,
        struct pmu *pmu;
        int ctxn;
 
+       /*
+        * If we have task_ctx != NULL we only notify
+        * the task context itself. The task_ctx is set
+        * only for EXIT events before releasing task
+        * context.
+        */
+       if (task_ctx) {
+               perf_event_aux_task_ctx(output, data, task_ctx);
+               return;
+       }
+
        rcu_read_lock();
        list_for_each_entry_rcu(pmu, &pmus, entry) {
                cpuctx = get_cpu_ptr(pmu->pmu_cpu_context);
                if (cpuctx->unique_pmu != pmu)
                        goto next;
                perf_event_aux_ctx(&cpuctx->ctx, output, data);
-               if (task_ctx)
-                       goto next;
                ctxn = pmu->task_ctx_nr;
                if (ctxn < 0)
                        goto next;
@@ -5692,12 +5728,6 @@ perf_event_aux(perf_event_aux_output_cb output, void *data,
 next:
                put_cpu_ptr(pmu->pmu_cpu_context);
        }
-
-       if (task_ctx) {
-               preempt_disable();
-               perf_event_aux_ctx(task_ctx, output, data);
-               preempt_enable();
-       }
        rcu_read_unlock();
 }
 
@@ -8787,10 +8817,8 @@ static void perf_event_exit_task_context(struct task_struct *child, int ctxn)
        struct perf_event_context *child_ctx, *clone_ctx = NULL;
        unsigned long flags;
 
-       if (likely(!child->perf_event_ctxp[ctxn])) {
-               perf_event_task(child, NULL, 0);
+       if (likely(!child->perf_event_ctxp[ctxn]))
                return;
-       }
 
        local_irq_save(flags);
        /*
@@ -8874,6 +8902,14 @@ void perf_event_exit_task(struct task_struct *child)
 
        for_each_task_context_nr(ctxn)
                perf_event_exit_task_context(child, ctxn);
+
+       /*
+        * The perf_event_exit_task_context calls perf_event_task
+        * with child's task_ctx, which generates EXIT events for
+        * child contexts and sets child->perf_event_ctxp[] to NULL.
+        * At this point we need to send EXIT events to cpu contexts.
+        */
+       perf_event_task(child, NULL, 0);
 }
 
 static void perf_free_event(struct perf_event *event,
@@ -9452,16 +9488,18 @@ static void perf_cgroup_css_free(struct cgroup_subsys_state *css)
 static int __perf_cgroup_move(void *info)
 {
        struct task_struct *task = info;
+       rcu_read_lock();
        perf_cgroup_switch(task, PERF_CGROUP_SWOUT | PERF_CGROUP_SWIN);
+       rcu_read_unlock();
        return 0;
 }
 
-static void perf_cgroup_attach(struct cgroup_subsys_state *css,
-                              struct cgroup_taskset *tset)
+static void perf_cgroup_attach(struct cgroup_taskset *tset)
 {
        struct task_struct *task;
+       struct cgroup_subsys_state *css;
 
-       cgroup_taskset_for_each(task, tset)
+       cgroup_taskset_for_each(task, css, tset)
                task_function_call(task, __perf_cgroup_move, task);
 }
 
index b5d1ea79c5953e2a2c7a5ee843de5f76ad47077a..adfdc0536117c1f10bf8f0dd8014798011e1f855 100644 (file)
@@ -3,7 +3,7 @@
  *
  *  Copyright (C) 2008 Thomas Gleixner <tglx@linutronix.de>
  *  Copyright (C) 2008-2011 Red Hat, Inc., Ingo Molnar
- *  Copyright (C) 2008-2011 Red Hat, Inc., Peter Zijlstra <pzijlstr@redhat.com>
+ *  Copyright (C) 2008-2011 Red Hat, Inc., Peter Zijlstra
  *  Copyright  Â©  2009 Paul Mackerras, IBM Corp. <paulus@au1.ibm.com>
  *
  * For licensing details see kernel-base/COPYING
index 4e5e9798aa0c0d426962642b69985b9eb09021d6..7dad84913abfb06df2495fae555e7f8bcac2b104 100644 (file)
@@ -19,7 +19,7 @@
  * Authors:
  *     Srikar Dronamraju
  *     Jim Keniston
- * Copyright (C) 2011-2012 Red Hat, Inc., Peter Zijlstra <pzijlstr@redhat.com>
+ * Copyright (C) 2011-2012 Red Hat, Inc., Peter Zijlstra
  */
 
 #include <linux/kernel.h>
index f97f2c449f5cf556ea6c54cb4aec6e894dd8bab5..fce002ee3ddffbab7613d0f9ec390683901f3c67 100644 (file)
@@ -1368,8 +1368,7 @@ static struct task_struct *copy_process(unsigned long clone_flags,
        p->real_start_time = ktime_get_boot_ns();
        p->io_context = NULL;
        p->audit_context = NULL;
-       if (clone_flags & CLONE_THREAD)
-               threadgroup_change_begin(current);
+       threadgroup_change_begin(current);
        cgroup_fork(p);
 #ifdef CONFIG_NUMA
        p->mempolicy = mpol_dup(p->mempolicy);
@@ -1610,8 +1609,7 @@ static struct task_struct *copy_process(unsigned long clone_flags,
 
        proc_fork_connector(p);
        cgroup_post_fork(p, cgrp_ss_priv);
-       if (clone_flags & CLONE_THREAD)
-               threadgroup_change_end(current);
+       threadgroup_change_end(current);
        perf_event_fork(p);
 
        trace_task_newtask(p, clone_flags);
@@ -1652,8 +1650,7 @@ bad_fork_cleanup_policy:
        mpol_put(p->mempolicy);
 bad_fork_cleanup_threadgroup_lock:
 #endif
-       if (clone_flags & CLONE_THREAD)
-               threadgroup_change_end(current);
+       threadgroup_change_end(current);
        delayacct_tsk_free(p);
 bad_fork_cleanup_count:
        atomic_dec(&p->cred->user->processes);
index cbf9fb899d929bfc52a2d803b64643732b0b7bbd..bcf107ce085450552c17d6b045816cd4656e97c0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010 Red Hat, Inc., Peter Zijlstra <pzijlstr@redhat.com>
+ * Copyright (C) 2010 Red Hat, Inc., Peter Zijlstra
  *
  * Provides a framework for enqueueing and running callbacks from hardirq
  * context. The enqueueing is NMI-safe.
index f7dd15d537f9b1135eb01036bf2fa3a5594ed9b6..05254eeb4b4e485be75bacff667c8ed3aab4a200 100644 (file)
@@ -2,7 +2,7 @@
  * jump label support
  *
  * Copyright (C) 2009 Jason Baron <jbaron@redhat.com>
- * Copyright (C) 2011 Peter Zijlstra <pzijlstr@redhat.com>
+ * Copyright (C) 2011 Peter Zijlstra
  *
  */
 #include <linux/memory.h>
index deae3907ac1eec585bbe71a44f6dc57ad024784a..60ace56618f6c222de90e569bf1702b6dba05e26 100644 (file)
@@ -6,7 +6,7 @@
  * Started by Ingo Molnar:
  *
  *  Copyright (C) 2006,2007 Red Hat, Inc., Ingo Molnar <mingo@redhat.com>
- *  Copyright (C) 2007 Red Hat, Inc., Peter Zijlstra <pzijlstr@redhat.com>
+ *  Copyright (C) 2007 Red Hat, Inc., Peter Zijlstra
  *
  * this code maps all the lock dependencies as they occur in a live kernel
  * and will warn about the following classes of locking bugs:
index d83d798bef95a042e1060a35bf4b79e7c7a6c05c..dbb61a3025484b4d38bd090bd5923c21a3960ced 100644 (file)
@@ -6,7 +6,7 @@
  * Started by Ingo Molnar:
  *
  *  Copyright (C) 2006,2007 Red Hat, Inc., Ingo Molnar <mingo@redhat.com>
- *  Copyright (C) 2007 Red Hat, Inc., Peter Zijlstra <pzijlstr@redhat.com>
+ *  Copyright (C) 2007 Red Hat, Inc., Peter Zijlstra
  *
  * Code for /proc/lockdep and /proc/lockdep_stats:
  *
index ca368793808e37688f7b0219b54d458fede30765..78b3d9f80d443fb4fa601e41088eb2041385ab20 100644 (file)
@@ -467,7 +467,7 @@ struct pid *get_task_pid(struct task_struct *task, enum pid_type type)
        rcu_read_lock();
        if (type != PIDTYPE_PID)
                task = task->group_leader;
-       pid = get_pid(task->pids[type].pid);
+       pid = get_pid(rcu_dereference(task->pids[type].pid));
        rcu_read_unlock();
        return pid;
 }
@@ -528,7 +528,7 @@ pid_t __task_pid_nr_ns(struct task_struct *task, enum pid_type type,
        if (likely(pid_alive(task))) {
                if (type != PIDTYPE_PID)
                        task = task->group_leader;
-               nr = pid_nr_ns(task->pids[type].pid, ns);
+               nr = pid_nr_ns(rcu_dereference(task->pids[type].pid), ns);
        }
        rcu_read_unlock();
 
index c0a205101c231a5b6e29e786228fb69c46772f5e..caf4041f5b0ae6769bc562fccc189852eae77fcf 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * sched_clock for unstable cpu clocks
  *
- *  Copyright (C) 2008 Red Hat, Inc., Peter Zijlstra <pzijlstr@redhat.com>
+ *  Copyright (C) 2008 Red Hat, Inc., Peter Zijlstra
  *
  *  Updates and enhancements:
  *    Copyright (C) 2008 Red Hat, Inc. Steven Rostedt <srostedt@redhat.com>
index 4d568ac9319eaf04c9d00673483678bc5e14f22e..732e993b564b8179e5723bb88839329eec6df8f5 100644 (file)
@@ -1946,6 +1946,25 @@ try_to_wake_up(struct task_struct *p, unsigned int state, int wake_flags)
                goto stat;
 
 #ifdef CONFIG_SMP
+       /*
+        * Ensure we load p->on_cpu _after_ p->on_rq, otherwise it would be
+        * possible to, falsely, observe p->on_cpu == 0.
+        *
+        * One must be running (->on_cpu == 1) in order to remove oneself
+        * from the runqueue.
+        *
+        *  [S] ->on_cpu = 1;   [L] ->on_rq
+        *      UNLOCK rq->lock
+        *                      RMB
+        *      LOCK   rq->lock
+        *  [S] ->on_rq = 0;    [L] ->on_cpu
+        *
+        * Pairs with the full barrier implied in the UNLOCK+LOCK on rq->lock
+        * from the consecutive calls to schedule(); the first switching to our
+        * task, the second putting it to sleep.
+        */
+       smp_rmb();
+
        /*
         * If the owning (remote) cpu is still in the middle of schedule() with
         * this task as prev, wait until its done referencing the task.
@@ -1953,7 +1972,13 @@ try_to_wake_up(struct task_struct *p, unsigned int state, int wake_flags)
        while (p->on_cpu)
                cpu_relax();
        /*
-        * Pairs with the smp_wmb() in finish_lock_switch().
+        * Combined with the control dependency above, we have an effective
+        * smp_load_acquire() without the need for full barriers.
+        *
+        * Pairs with the smp_store_release() in finish_lock_switch().
+        *
+        * This ensures that tasks getting woken will be fully ordered against
+        * their previous state and preserve Program Order.
         */
        smp_rmb();
 
@@ -2039,7 +2064,6 @@ out:
  */
 int wake_up_process(struct task_struct *p)
 {
-       WARN_ON(task_is_stopped_or_traced(p));
        return try_to_wake_up(p, TASK_NORMAL, 0);
 }
 EXPORT_SYMBOL(wake_up_process);
@@ -5847,13 +5871,13 @@ static int init_rootdomain(struct root_domain *rd)
 {
        memset(rd, 0, sizeof(*rd));
 
-       if (!alloc_cpumask_var(&rd->span, GFP_KERNEL))
+       if (!zalloc_cpumask_var(&rd->span, GFP_KERNEL))
                goto out;
-       if (!alloc_cpumask_var(&rd->online, GFP_KERNEL))
+       if (!zalloc_cpumask_var(&rd->online, GFP_KERNEL))
                goto free_span;
-       if (!alloc_cpumask_var(&rd->dlo_mask, GFP_KERNEL))
+       if (!zalloc_cpumask_var(&rd->dlo_mask, GFP_KERNEL))
                goto free_online;
-       if (!alloc_cpumask_var(&rd->rto_mask, GFP_KERNEL))
+       if (!zalloc_cpumask_var(&rd->rto_mask, GFP_KERNEL))
                goto free_dlo_mask;
 
        init_dl_bw(&rd->dl_bw);
@@ -8217,12 +8241,12 @@ static void cpu_cgroup_fork(struct task_struct *task, void *private)
        sched_move_task(task);
 }
 
-static int cpu_cgroup_can_attach(struct cgroup_subsys_state *css,
-                                struct cgroup_taskset *tset)
+static int cpu_cgroup_can_attach(struct cgroup_taskset *tset)
 {
        struct task_struct *task;
+       struct cgroup_subsys_state *css;
 
-       cgroup_taskset_for_each(task, tset) {
+       cgroup_taskset_for_each(task, css, tset) {
 #ifdef CONFIG_RT_GROUP_SCHED
                if (!sched_rt_can_attach(css_tg(css), task))
                        return -EINVAL;
@@ -8235,12 +8259,12 @@ static int cpu_cgroup_can_attach(struct cgroup_subsys_state *css,
        return 0;
 }
 
-static void cpu_cgroup_attach(struct cgroup_subsys_state *css,
-                             struct cgroup_taskset *tset)
+static void cpu_cgroup_attach(struct cgroup_taskset *tset)
 {
        struct task_struct *task;
+       struct cgroup_subsys_state *css;
 
-       cgroup_taskset_for_each(task, tset)
+       cgroup_taskset_for_each(task, css, tset)
                sched_move_task(task);
 }
 
index 26a54461bf59ca46ce7f68d7a926b03840ca8711..05de80b48586e9fa3241c708c7e6fd7c9b6fb24a 100644 (file)
@@ -788,6 +788,9 @@ cputime_t task_gtime(struct task_struct *t)
        unsigned int seq;
        cputime_t gtime;
 
+       if (!context_tracking_is_enabled())
+               return t->gtime;
+
        do {
                seq = read_seqbegin(&t->vtime_seqlock);
 
index f04fda8f669c8eff57e936fcb1334b13a4140ce5..90e26b11deaa1ab4b78302605850523a7852720b 100644 (file)
@@ -17,7 +17,7 @@
  *  Copyright (C) 2007, Thomas Gleixner <tglx@linutronix.de>
  *
  *  Adaptive scheduling granularity, math enhancements by Peter Zijlstra
- *  Copyright (C) 2007 Red Hat, Inc., Peter Zijlstra <pzijlstr@redhat.com>
+ *  Copyright (C) 2007 Red Hat, Inc., Peter Zijlstra
  */
 
 #include <linux/latencytop.h>
index e3cc16312046689fd04db8748304210c0d9fc8df..8ec86abe0ea188369ee4e7efd21789d8cb127c14 100644 (file)
@@ -64,7 +64,7 @@ static void start_rt_bandwidth(struct rt_bandwidth *rt_b)
        raw_spin_unlock(&rt_b->rt_runtime_lock);
 }
 
-#ifdef CONFIG_SMP
+#if defined(CONFIG_SMP) && defined(HAVE_RT_PUSH_IPI)
 static void push_irq_work_func(struct irq_work *work);
 #endif
 
index efd3bfc7e34722883e2f08ca82f91cffde812963..b242775bf670e116233862c590915e06132485ca 100644 (file)
@@ -1073,6 +1073,9 @@ static inline void finish_lock_switch(struct rq *rq, struct task_struct *prev)
         * We must ensure this doesn't happen until the switch is completely
         * finished.
         *
+        * In particular, the load of prev->state in finish_task_switch() must
+        * happen before this.
+        *
         * Pairs with the control dependency and rmb in try_to_wake_up().
         */
        smp_store_release(&prev->on_cpu, 0);
index 052e02672d12428ce1e9e1f7266c7cd754ace5af..f15d6b6a538a9d01c2d7c4045af0a661d34c3c4a 100644 (file)
@@ -392,7 +392,7 @@ __wait_on_bit(wait_queue_head_t *wq, struct wait_bit_queue *q,
        do {
                prepare_to_wait(wq, &q->wait, mode);
                if (test_bit(q->key.bit_nr, q->key.flags))
-                       ret = (*action)(&q->key);
+                       ret = (*action)(&q->key, mode);
        } while (test_bit(q->key.bit_nr, q->key.flags) && !ret);
        finish_wait(wq, &q->wait);
        return ret;
@@ -431,7 +431,7 @@ __wait_on_bit_lock(wait_queue_head_t *wq, struct wait_bit_queue *q,
                prepare_to_wait_exclusive(wq, &q->wait, mode);
                if (!test_bit(q->key.bit_nr, q->key.flags))
                        continue;
-               ret = action(&q->key);
+               ret = action(&q->key, mode);
                if (!ret)
                        continue;
                abort_exclusive_wait(wq, &q->wait, mode, &q->key);
@@ -581,44 +581,44 @@ void wake_up_atomic_t(atomic_t *p)
 }
 EXPORT_SYMBOL(wake_up_atomic_t);
 
-__sched int bit_wait(struct wait_bit_key *word)
+__sched int bit_wait(struct wait_bit_key *word, int mode)
 {
-       if (signal_pending_state(current->state, current))
-               return 1;
        schedule();
+       if (signal_pending_state(mode, current))
+               return -EINTR;
        return 0;
 }
 EXPORT_SYMBOL(bit_wait);
 
-__sched int bit_wait_io(struct wait_bit_key *word)
+__sched int bit_wait_io(struct wait_bit_key *word, int mode)
 {
-       if (signal_pending_state(current->state, current))
-               return 1;
        io_schedule();
+       if (signal_pending_state(mode, current))
+               return -EINTR;
        return 0;
 }
 EXPORT_SYMBOL(bit_wait_io);
 
-__sched int bit_wait_timeout(struct wait_bit_key *word)
+__sched int bit_wait_timeout(struct wait_bit_key *word, int mode)
 {
        unsigned long now = READ_ONCE(jiffies);
-       if (signal_pending_state(current->state, current))
-               return 1;
        if (time_after_eq(now, word->timeout))
                return -EAGAIN;
        schedule_timeout(word->timeout - now);
+       if (signal_pending_state(mode, current))
+               return -EINTR;
        return 0;
 }
 EXPORT_SYMBOL_GPL(bit_wait_timeout);
 
-__sched int bit_wait_io_timeout(struct wait_bit_key *word)
+__sched int bit_wait_io_timeout(struct wait_bit_key *word, int mode)
 {
        unsigned long now = READ_ONCE(jiffies);
-       if (signal_pending_state(current->state, current))
-               return 1;
        if (time_after_eq(now, word->timeout))
                return -EAGAIN;
        io_schedule_timeout(word->timeout - now);
+       if (signal_pending_state(mode, current))
+               return -EINTR;
        return 0;
 }
 EXPORT_SYMBOL_GPL(bit_wait_io_timeout);
index 867bc20e1ef142a63349c345932af24b26a1adfc..a3bbaee77c586e9836567f900012aa5231e94dbd 100644 (file)
@@ -531,7 +531,7 @@ static int __init cpu_stop_init(void)
 }
 early_initcall(cpu_stop_init);
 
-#ifdef CONFIG_STOP_MACHINE
+#if defined(CONFIG_SMP) || defined(CONFIG_HOTPLUG_CPU)
 
 static int __stop_machine(cpu_stop_fn_t fn, void *data, const struct cpumask *cpus)
 {
@@ -631,4 +631,4 @@ int stop_machine_from_inactive_cpu(cpu_stop_fn_t fn, void *data,
        return ret ?: done.ret;
 }
 
-#endif /* CONFIG_STOP_MACHINE */
+#endif /* CONFIG_SMP || CONFIG_HOTPLUG_CPU */
index 75f1d05ea82dcce04e9f6a581f26969e503dc773..9c6045a27ba356252546971fb26dbae30149c89c 100644 (file)
@@ -1887,12 +1887,6 @@ rb_event_index(struct ring_buffer_event *event)
        return (addr & ~PAGE_MASK) - BUF_PAGE_HDR_SIZE;
 }
 
-static void rb_reset_reader_page(struct ring_buffer_per_cpu *cpu_buffer)
-{
-       cpu_buffer->read_stamp = cpu_buffer->reader_page->page->time_stamp;
-       cpu_buffer->reader_page->read = 0;
-}
-
 static void rb_inc_iter(struct ring_buffer_iter *iter)
 {
        struct ring_buffer_per_cpu *cpu_buffer = iter->cpu_buffer;
@@ -2803,8 +2797,11 @@ rb_reserve_next_event(struct ring_buffer *buffer,
 
        event = __rb_reserve_next(cpu_buffer, &info);
 
-       if (unlikely(PTR_ERR(event) == -EAGAIN))
+       if (unlikely(PTR_ERR(event) == -EAGAIN)) {
+               if (info.add_timestamp)
+                       info.length -= RB_LEN_TIME_EXTEND;
                goto again;
+       }
 
        if (!event)
                goto out_fail;
@@ -3626,7 +3623,7 @@ rb_get_reader_page(struct ring_buffer_per_cpu *cpu_buffer)
 
        /* Finally update the reader page to the new head */
        cpu_buffer->reader_page = reader;
-       rb_reset_reader_page(cpu_buffer);
+       cpu_buffer->reader_page->read = 0;
 
        if (overwrite != cpu_buffer->last_overrun) {
                cpu_buffer->lost_events = overwrite - cpu_buffer->last_overrun;
@@ -3636,6 +3633,10 @@ rb_get_reader_page(struct ring_buffer_per_cpu *cpu_buffer)
        goto again;
 
  out:
+       /* Update the read_stamp on the first event */
+       if (reader && reader->read == 0)
+               cpu_buffer->read_stamp = reader->page->time_stamp;
+
        arch_spin_unlock(&cpu_buffer->lock);
        local_irq_restore(flags);
 
index abfc903e741e8550d67bd638ead8a338a0c95fec..cc9f7a9319bea63104ef05c97634c43286a5268c 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * trace event based perf event profiling/tracing
  *
- * Copyright (C) 2009 Red Hat Inc, Peter Zijlstra <pzijlstr@redhat.com>
+ * Copyright (C) 2009 Red Hat Inc, Peter Zijlstra
  * Copyright (C) 2009-2010 Frederic Weisbecker <fweisbec@gmail.com>
  */
 
index 6bbc5f652355745d24f6252a93d7b437a0efea15..4f6ef6912e00173040867f6a68c52f010bbfd21d 100644 (file)
@@ -582,6 +582,12 @@ static void __ftrace_clear_event_pids(struct trace_array *tr)
        unregister_trace_sched_wakeup(event_filter_pid_sched_wakeup_probe_pre, tr);
        unregister_trace_sched_wakeup(event_filter_pid_sched_wakeup_probe_post, tr);
 
+       unregister_trace_sched_wakeup_new(event_filter_pid_sched_wakeup_probe_pre, tr);
+       unregister_trace_sched_wakeup_new(event_filter_pid_sched_wakeup_probe_post, tr);
+
+       unregister_trace_sched_waking(event_filter_pid_sched_wakeup_probe_pre, tr);
+       unregister_trace_sched_waking(event_filter_pid_sched_wakeup_probe_post, tr);
+
        list_for_each_entry(file, &tr->events, list) {
                clear_bit(EVENT_FILE_FL_PID_FILTER_BIT, &file->flags);
        }
@@ -1729,6 +1735,16 @@ ftrace_event_pid_write(struct file *filp, const char __user *ubuf,
                                                 tr, INT_MAX);
                register_trace_prio_sched_wakeup(event_filter_pid_sched_wakeup_probe_post,
                                                 tr, 0);
+
+               register_trace_prio_sched_wakeup_new(event_filter_pid_sched_wakeup_probe_pre,
+                                                    tr, INT_MAX);
+               register_trace_prio_sched_wakeup_new(event_filter_pid_sched_wakeup_probe_post,
+                                                    tr, 0);
+
+               register_trace_prio_sched_waking(event_filter_pid_sched_wakeup_probe_pre,
+                                                tr, INT_MAX);
+               register_trace_prio_sched_waking(event_filter_pid_sched_wakeup_probe_post,
+                                                tr, 0);
        }
 
        /*
index 4264871ea1a00194750116a82c48e18d18edbd44..f93a945274af12575f8fbbceb821552b2a13e61e 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Copyright (c) 2007-2008 Joern Engel <joern@logfs.org>
  * Bits and pieces stolen from Peter Zijlstra's code, which is
- * Copyright 2007, Red Hat Inc. Peter Zijlstra <pzijlstr@redhat.com>
+ * Copyright 2007, Red Hat Inc. Peter Zijlstra
  * GPLv2
  *
  * see http://programming.kicks-ass.net/kernel-patches/vma_lookup/btree.patch
index 6f724298f67a11199407870e2dbb1541ee55db6c..efa54f259ea9d316176c03c66badd9c23cfc8e20 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Floating proportions
  *
- *  Copyright (C) 2007 Red Hat, Inc., Peter Zijlstra <pzijlstr@redhat.com>
+ *  Copyright (C) 2007 Red Hat, Inc., Peter Zijlstra
  *
  * Description:
  *
index 8ed2ffd963c53b910f91e1b60b04c56385a3129f..7340353f8aea08ef428edcf7b287c45b312aeb1a 100644 (file)
@@ -957,8 +957,9 @@ EXPORT_SYMBOL(congestion_wait);
  * jiffies for either a BDI to exit congestion of the given @sync queue
  * or a write to complete.
  *
- * In the absence of zone congestion, cond_resched() is called to yield
- * the processor if necessary but otherwise does not sleep.
+ * In the absence of zone congestion, a short sleep or a cond_resched is
+ * performed to yield the processor and to allow other subsystems to make
+ * a forward progress.
  *
  * The return value is 0 if the sleep is for the full timeout. Otherwise,
  * it is the number of jiffies that were still remaining when the function
@@ -978,7 +979,19 @@ long wait_iff_congested(struct zone *zone, int sync, long timeout)
         */
        if (atomic_read(&nr_wb_congested[sync]) == 0 ||
            !test_bit(ZONE_CONGESTED, &zone->flags)) {
-               cond_resched();
+
+               /*
+                * Memory allocation/reclaim might be called from a WQ
+                * context and the current implementation of the WQ
+                * concurrency control doesn't recognize that a particular
+                * WQ is congested if the worker thread is looping without
+                * ever sleeping. Therefore we have to do a short sleep
+                * here rather than calling cond_resched().
+                */
+               if (current->flags & PF_WQ_WORKER)
+                       schedule_timeout(1);
+               else
+                       cond_resched();
 
                /* In case we scheduled, work out time remaining */
                ret = timeout - (jiffies - start);
index 827bb02a43a4e425393c296db89e7a49d6adf02b..ef6963b577fd2920c1a4857f7b74b50e91c98b7a 100644 (file)
@@ -372,8 +372,10 @@ retry_locked:
                spin_unlock(&resv->lock);
 
                trg = kmalloc(sizeof(*trg), GFP_KERNEL);
-               if (!trg)
+               if (!trg) {
+                       kfree(nrg);
                        return -ENOMEM;
+               }
 
                spin_lock(&resv->lock);
                list_add(&trg->link, &resv->region_cache);
@@ -483,8 +485,16 @@ static long region_del(struct resv_map *resv, long f, long t)
 retry:
        spin_lock(&resv->lock);
        list_for_each_entry_safe(rg, trg, head, link) {
-               if (rg->to <= f)
+               /*
+                * Skip regions before the range to be deleted.  file_region
+                * ranges are normally of the form [from, to).  However, there
+                * may be a "placeholder" entry in the map which is of the form
+                * (from, to) with from == to.  Check for placeholder entries
+                * at the beginning of the range to be deleted.
+                */
+               if (rg->to <= f && (rg->to != rg->from || rg->to != f))
                        continue;
+
                if (rg->from >= t)
                        break;
 
@@ -1886,7 +1896,10 @@ struct page *alloc_huge_page(struct vm_area_struct *vma,
                page = __alloc_buddy_huge_page_with_mpol(h, vma, addr);
                if (!page)
                        goto out_uncharge_cgroup;
-
+               if (!avoid_reserve && vma_has_reserves(vma, gbl_chg)) {
+                       SetPagePrivate(page);
+                       h->resv_huge_pages--;
+               }
                spin_lock(&hugetlb_lock);
                list_move(&page->lru, &h->hugepage_activelist);
                /* Fall through */
@@ -3693,12 +3706,12 @@ int hugetlb_fault(struct mm_struct *mm, struct vm_area_struct *vma,
                } else if (unlikely(is_hugetlb_entry_hwpoisoned(entry)))
                        return VM_FAULT_HWPOISON_LARGE |
                                VM_FAULT_SET_HINDEX(hstate_index(h));
+       } else {
+               ptep = huge_pte_alloc(mm, address, huge_page_size(h));
+               if (!ptep)
+                       return VM_FAULT_OOM;
        }
 
-       ptep = huge_pte_alloc(mm, address, huge_page_size(h));
-       if (!ptep)
-               return VM_FAULT_OOM;
-
        mapping = vma->vm_file->f_mapping;
        idx = vma_hugecache_offset(h, vma, address);
 
index 9acfb165eb52eeff2271888ec61fe093c9015641..e234c21a5e6cb3d02104da2422548692fda1e881 100644 (file)
@@ -2128,7 +2128,7 @@ done_restock:
         */
        do {
                if (page_counter_read(&memcg->memory) > memcg->high) {
-                       current->memcg_nr_pages_over_high += nr_pages;
+                       current->memcg_nr_pages_over_high += batch;
                        set_notify_resume(current);
                        break;
                }
@@ -4779,23 +4779,18 @@ static void mem_cgroup_clear_mc(void)
        spin_unlock(&mc.lock);
 }
 
-static int mem_cgroup_can_attach(struct cgroup_subsys_state *css,
-                                struct cgroup_taskset *tset)
+static int mem_cgroup_can_attach(struct cgroup_taskset *tset)
 {
-       struct mem_cgroup *memcg = mem_cgroup_from_css(css);
+       struct cgroup_subsys_state *css;
+       struct mem_cgroup *memcg;
        struct mem_cgroup *from;
        struct task_struct *leader, *p;
        struct mm_struct *mm;
        unsigned long move_flags;
        int ret = 0;
 
-       /*
-        * We are now commited to this value whatever it is. Changes in this
-        * tunable will only affect upcoming migrations, not the current one.
-        * So we need to save it, and keep it going.
-        */
-       move_flags = READ_ONCE(memcg->move_charge_at_immigrate);
-       if (!move_flags)
+       /* charge immigration isn't supported on the default hierarchy */
+       if (cgroup_subsys_on_dfl(memory_cgrp_subsys))
                return 0;
 
        /*
@@ -4805,13 +4800,23 @@ static int mem_cgroup_can_attach(struct cgroup_subsys_state *css,
         * multiple.
         */
        p = NULL;
-       cgroup_taskset_for_each_leader(leader, tset) {
+       cgroup_taskset_for_each_leader(leader, css, tset) {
                WARN_ON_ONCE(p);
                p = leader;
+               memcg = mem_cgroup_from_css(css);
        }
        if (!p)
                return 0;
 
+       /*
+        * We are now commited to this value whatever it is. Changes in this
+        * tunable will only affect upcoming migrations, not the current one.
+        * So we need to save it, and keep it going.
+        */
+       move_flags = READ_ONCE(memcg->move_charge_at_immigrate);
+       if (!move_flags)
+               return 0;
+
        from = mem_cgroup_from_task(p);
 
        VM_BUG_ON(from == memcg);
@@ -4842,8 +4847,7 @@ static int mem_cgroup_can_attach(struct cgroup_subsys_state *css,
        return ret;
 }
 
-static void mem_cgroup_cancel_attach(struct cgroup_subsys_state *css,
-                                    struct cgroup_taskset *tset)
+static void mem_cgroup_cancel_attach(struct cgroup_taskset *tset)
 {
        if (mc.to)
                mem_cgroup_clear_mc();
@@ -4985,10 +4989,10 @@ retry:
        atomic_dec(&mc.from->moving_account);
 }
 
-static void mem_cgroup_move_task(struct cgroup_subsys_state *css,
-                                struct cgroup_taskset *tset)
+static void mem_cgroup_move_task(struct cgroup_taskset *tset)
 {
-       struct task_struct *p = cgroup_taskset_first(tset);
+       struct cgroup_subsys_state *css;
+       struct task_struct *p = cgroup_taskset_first(tset, &css);
        struct mm_struct *mm = get_task_mm(p);
 
        if (mm) {
@@ -5000,17 +5004,14 @@ static void mem_cgroup_move_task(struct cgroup_subsys_state *css,
                mem_cgroup_clear_mc();
 }
 #else  /* !CONFIG_MMU */
-static int mem_cgroup_can_attach(struct cgroup_subsys_state *css,
-                                struct cgroup_taskset *tset)
+static int mem_cgroup_can_attach(struct cgroup_taskset *tset)
 {
        return 0;
 }
-static void mem_cgroup_cancel_attach(struct cgroup_subsys_state *css,
-                                    struct cgroup_taskset *tset)
+static void mem_cgroup_cancel_attach(struct cgroup_taskset *tset)
 {
 }
-static void mem_cgroup_move_task(struct cgroup_subsys_state *css,
-                                struct cgroup_taskset *tset)
+static void mem_cgroup_move_task(struct cgroup_taskset *tset)
 {
 }
 #endif
@@ -5511,11 +5512,11 @@ void mem_cgroup_uncharge_list(struct list_head *page_list)
  * mem_cgroup_replace_page - migrate a charge to another page
  * @oldpage: currently charged page
  * @newpage: page to transfer the charge to
- * @lrucare: either or both pages might be on the LRU already
  *
  * Migrate the charge from @oldpage to @newpage.
  *
  * Both pages must be locked, @newpage->mapping must be set up.
+ * Either or both pages might be on the LRU already.
  */
 void mem_cgroup_replace_page(struct page *oldpage, struct page *newpage)
 {
index d13a33918fa23e685bc629bc23f58d97729beb62..c12680993ff334560dbfc84ffcee4e0bd0487650 100644 (file)
@@ -608,6 +608,8 @@ void oom_kill_process(struct oom_control *oc, struct task_struct *p,
                        continue;
                if (unlikely(p->flags & PF_KTHREAD))
                        continue;
+               if (is_global_init(p))
+                       continue;
                if (p->signal->oom_score_adj == OOM_SCORE_ADJ_MIN)
                        continue;
 
index 3e4d65445fa71d7d629868c1db70af2bfb1fab28..d15d88c8efa1e25bf76fe3bf07f6eeb08fd14fd5 100644 (file)
@@ -2,7 +2,7 @@
  * mm/page-writeback.c
  *
  * Copyright (C) 2002, Linus Torvalds.
- * Copyright (C) 2007 Red Hat, Inc., Peter Zijlstra <pzijlstr@redhat.com>
+ * Copyright (C) 2007 Red Hat, Inc., Peter Zijlstra
  *
  * Contains functions related to writing back dirty pages at the
  * address_space level.
index 17a3c66639a9cd6625f333b4f64ab012e2cb56c4..9d666df5ef9502b70cf7ba0aedef5eb805fdd811 100644 (file)
@@ -3647,8 +3647,9 @@ static void show_migration_types(unsigned char type)
 {
        static const char types[MIGRATE_TYPES] = {
                [MIGRATE_UNMOVABLE]     = 'U',
-               [MIGRATE_RECLAIMABLE]   = 'E',
                [MIGRATE_MOVABLE]       = 'M',
+               [MIGRATE_RECLAIMABLE]   = 'E',
+               [MIGRATE_HIGHATOMIC]    = 'H',
 #ifdef CONFIG_CMA
                [MIGRATE_CMA]           = 'C',
 #endif
index 9187eee4128b45769583dae2a73720e3545ee933..2afcdbbdb68506096d5c6fad584a8425709d10aa 100644 (file)
@@ -843,14 +843,14 @@ static int shmem_writepage(struct page *page, struct writeback_control *wbc)
                list_add_tail(&info->swaplist, &shmem_swaplist);
 
        if (add_to_swap_cache(page, swap, GFP_ATOMIC) == 0) {
-               swap_shmem_alloc(swap);
-               shmem_delete_from_page_cache(page, swp_to_radix_entry(swap));
-
                spin_lock(&info->lock);
-               info->swapped++;
                shmem_recalc_inode(inode);
+               info->swapped++;
                spin_unlock(&info->lock);
 
+               swap_shmem_alloc(swap);
+               shmem_delete_from_page_cache(page, swp_to_radix_entry(swap));
+
                mutex_unlock(&shmem_swaplist_mutex);
                BUG_ON(page_mapped(page));
                swap_writepage(page, wbc);
@@ -1078,7 +1078,7 @@ repeat:
        if (sgp != SGP_WRITE && sgp != SGP_FALLOC &&
            ((loff_t)index << PAGE_CACHE_SHIFT) >= i_size_read(inode)) {
                error = -EINVAL;
-               goto failed;
+               goto unlock;
        }
 
        if (page && sgp == SGP_WRITE)
@@ -1246,11 +1246,15 @@ clear:
        /* Perhaps the file has been truncated since we checked */
        if (sgp != SGP_WRITE && sgp != SGP_FALLOC &&
            ((loff_t)index << PAGE_CACHE_SHIFT) >= i_size_read(inode)) {
+               if (alloced) {
+                       ClearPageDirty(page);
+                       delete_from_page_cache(page);
+                       spin_lock(&info->lock);
+                       shmem_recalc_inode(inode);
+                       spin_unlock(&info->lock);
+               }
                error = -EINVAL;
-               if (alloced)
-                       goto trunc;
-               else
-                       goto failed;
+               goto unlock;
        }
        *pagep = page;
        return 0;
@@ -1258,23 +1262,13 @@ clear:
        /*
         * Error recovery.
         */
-trunc:
-       info = SHMEM_I(inode);
-       ClearPageDirty(page);
-       delete_from_page_cache(page);
-       spin_lock(&info->lock);
-       info->alloced--;
-       inode->i_blocks -= BLOCKS_PER_PAGE;
-       spin_unlock(&info->lock);
 decused:
-       sbinfo = SHMEM_SB(inode->i_sb);
        if (sbinfo->max_blocks)
                percpu_counter_add(&sbinfo->used_blocks, -1);
 unacct:
        shmem_unacct_blocks(info->flags, 1);
 failed:
-       if (swap.val && error != -EINVAL &&
-           !shmem_confirm_swap(mapping, index, swap))
+       if (swap.val && !shmem_confirm_swap(mapping, index, swap))
                error = -EEXIST;
 unlock:
        if (page) {
index 879a2be23325ce73158e097eb381628a5fd5f548..0d5712b0206c7edb1236284fe71b7d926df29cee 100644 (file)
@@ -921,8 +921,8 @@ static void walk_zones_in_node(struct seq_file *m, pg_data_t *pgdat,
 #ifdef CONFIG_PROC_FS
 static char * const migratetype_names[MIGRATE_TYPES] = {
        "Unmovable",
-       "Reclaimable",
        "Movable",
+       "Reclaimable",
        "HighAtomic",
 #ifdef CONFIG_CMA
        "CMA",
@@ -1379,6 +1379,7 @@ static const struct file_operations proc_vmstat_file_operations = {
 #endif /* CONFIG_PROC_FS */
 
 #ifdef CONFIG_SMP
+static struct workqueue_struct *vmstat_wq;
 static DEFINE_PER_CPU(struct delayed_work, vmstat_work);
 int sysctl_stat_interval __read_mostly = HZ;
 static cpumask_var_t cpu_stat_off;
@@ -1391,7 +1392,7 @@ static void vmstat_update(struct work_struct *w)
                 * to occur in the future. Keep on running the
                 * update worker thread.
                 */
-               schedule_delayed_work_on(smp_processor_id(),
+               queue_delayed_work_on(smp_processor_id(), vmstat_wq,
                        this_cpu_ptr(&vmstat_work),
                        round_jiffies_relative(sysctl_stat_interval));
        } else {
@@ -1460,7 +1461,7 @@ static void vmstat_shepherd(struct work_struct *w)
                if (need_update(cpu) &&
                        cpumask_test_and_clear_cpu(cpu, cpu_stat_off))
 
-                       schedule_delayed_work_on(cpu,
+                       queue_delayed_work_on(cpu, vmstat_wq,
                                &per_cpu(vmstat_work, cpu), 0);
 
        put_online_cpus();
@@ -1549,6 +1550,7 @@ static int __init setup_vmstat(void)
 
        start_shepherd_timer();
        cpu_notifier_register_done();
+       vmstat_wq = alloc_workqueue("vmstat", WQ_FREEZABLE|WQ_MEM_RECLAIM, 0);
 #endif
 #ifdef CONFIG_PROC_FS
        proc_create("buddyinfo", S_IRUGO, NULL, &fragmentation_file_operations);
index a3bffd1ec2b46adbc7a2130573ae991950789a77..70306cc9d8140f696e440de10f9fff864b0abd94 100644 (file)
@@ -271,11 +271,11 @@ static long bt_sock_data_wait(struct sock *sk, long timeo)
                if (signal_pending(current) || !timeo)
                        break;
 
-               set_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
+               sk_set_bit(SOCKWQ_ASYNC_WAITDATA, sk);
                release_sock(sk);
                timeo = schedule_timeout(timeo);
                lock_sock(sk);
-               clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
+               sk_clear_bit(SOCKWQ_ASYNC_WAITDATA, sk);
        }
 
        __set_current_state(TASK_RUNNING);
@@ -441,7 +441,7 @@ unsigned int bt_sock_poll(struct file *file, struct socket *sock,
        if (!test_bit(BT_SK_SUSPEND, &bt_sk(sk)->flags) && sock_writeable(sk))
                mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
        else
-               set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags);
+               sk_set_bit(SOCKWQ_ASYNC_NOSPACE, sk);
 
        return mask;
 }
index c91353841e40500790c13d2ce894460e1cbbe9e3..ffed8a1d4f27634866c93d22b4ceb059b956cc91 100644 (file)
@@ -3027,8 +3027,13 @@ static void smp_ready_cb(struct l2cap_chan *chan)
 
        BT_DBG("chan %p", chan);
 
+       /* No need to call l2cap_chan_hold() here since we already own
+        * the reference taken in smp_new_conn_cb(). This is just the
+        * first time that we tie it to a specific pointer. The code in
+        * l2cap_core.c ensures that there's no risk this function wont
+        * get called if smp_new_conn_cb was previously called.
+        */
        conn->smp = chan;
-       l2cap_chan_hold(chan);
 
        if (hcon->type == ACL_LINK && test_bit(HCI_CONN_ENCRYPT, &hcon->flags))
                bredr_pairing(chan);
index cc858919108ee1f9645bce1046be8650a640d821..aa209b1066c9699a12510055e70ae79b33ee05b7 100644 (file)
@@ -323,7 +323,7 @@ static long caif_stream_data_wait(struct sock *sk, long timeo)
                        !timeo)
                        break;
 
-               set_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
+               sk_set_bit(SOCKWQ_ASYNC_WAITDATA, sk);
                release_sock(sk);
                timeo = schedule_timeout(timeo);
                lock_sock(sk);
@@ -331,7 +331,7 @@ static long caif_stream_data_wait(struct sock *sk, long timeo)
                if (sock_flag(sk, SOCK_DEAD))
                        break;
 
-               clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
+               sk_clear_bit(SOCKWQ_ASYNC_WAITDATA, sk);
        }
 
        finish_wait(sk_sleep(sk), &wait);
index 617088aee21d41ba98d4ef5ebee5d6c002efe029..d62af69ad844de0f940cdc2f38c5e2720053895c 100644 (file)
@@ -785,7 +785,7 @@ unsigned int datagram_poll(struct file *file, struct socket *sock,
        if (sock_writeable(sk))
                mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
        else
-               set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags);
+               sk_set_bit(SOCKWQ_ASYNC_NOSPACE, sk);
 
        return mask;
 }
index e6af42da28d9552643751a1af7dfcd96cad05c3d..f18ae91b652e971ccba5c03177301f1a46a8da57 100644 (file)
@@ -2215,7 +2215,7 @@ static int pneigh_fill_info(struct sk_buff *skb, struct pneigh_entry *pn,
        ndm->ndm_pad2    = 0;
        ndm->ndm_flags   = pn->flags | NTF_PROXY;
        ndm->ndm_type    = RTN_UNICAST;
-       ndm->ndm_ifindex = pn->dev->ifindex;
+       ndm->ndm_ifindex = pn->dev ? pn->dev->ifindex : 0;
        ndm->ndm_state   = NUD_NONE;
 
        if (nla_put(skb, NDA_DST, tbl->key_len, pn->key))
@@ -2333,7 +2333,7 @@ static int pneigh_dump_table(struct neigh_table *tbl, struct sk_buff *skb,
                if (h > s_h)
                        s_idx = 0;
                for (n = tbl->phash_buckets[h], idx = 0; n; n = n->next) {
-                       if (dev_net(n->dev) != net)
+                       if (pneigh_net(n) != net)
                                continue;
                        if (idx < s_idx)
                                goto next;
index 6441f47b1a8ffc78731896fd4ab1b12db43f0992..d9ee8d08a3a6944ebb6e5d8dafe6fb5032aa7a52 100644 (file)
@@ -56,7 +56,7 @@ static void cgrp_css_free(struct cgroup_subsys_state *css)
        kfree(css_cls_state(css));
 }
 
-static int update_classid(const void *v, struct file *file, unsigned n)
+static int update_classid_sock(const void *v, struct file *file, unsigned n)
 {
        int err;
        struct socket *sock = sock_from_file(file, &err);
@@ -67,18 +67,27 @@ static int update_classid(const void *v, struct file *file, unsigned n)
        return 0;
 }
 
-static void cgrp_attach(struct cgroup_subsys_state *css,
-                       struct cgroup_taskset *tset)
+static void update_classid(struct cgroup_subsys_state *css, void *v)
 {
-       struct cgroup_cls_state *cs = css_cls_state(css);
-       void *v = (void *)(unsigned long)cs->classid;
+       struct css_task_iter it;
        struct task_struct *p;
 
-       cgroup_taskset_for_each(p, tset) {
+       css_task_iter_start(css, &it);
+       while ((p = css_task_iter_next(&it))) {
                task_lock(p);
-               iterate_fd(p->files, 0, update_classid, v);
+               iterate_fd(p->files, 0, update_classid_sock, v);
                task_unlock(p);
        }
+       css_task_iter_end(&it);
+}
+
+static void cgrp_attach(struct cgroup_taskset *tset)
+{
+       struct cgroup_subsys_state *css;
+
+       cgroup_taskset_first(tset, &css);
+       update_classid(css,
+                      (void *)(unsigned long)css_cls_state(css)->classid);
 }
 
 static u64 read_classid(struct cgroup_subsys_state *css, struct cftype *cft)
@@ -89,8 +98,11 @@ static u64 read_classid(struct cgroup_subsys_state *css, struct cftype *cft)
 static int write_classid(struct cgroup_subsys_state *css, struct cftype *cft,
                         u64 value)
 {
-       css_cls_state(css)->classid = (u32) value;
+       struct cgroup_cls_state *cs = css_cls_state(css);
+
+       cs->classid = (u32)value;
 
+       update_classid(css, (void *)(unsigned long)cs->classid);
        return 0;
 }
 
index cbd0a199bf52c79780e7935f1ed123f3f86758ec..40fd09fe06ae91e133bbf1fe499e38870903c8ca 100644 (file)
@@ -218,13 +218,14 @@ static int update_netprio(const void *v, struct file *file, unsigned n)
        return 0;
 }
 
-static void net_prio_attach(struct cgroup_subsys_state *css,
-                           struct cgroup_taskset *tset)
+static void net_prio_attach(struct cgroup_taskset *tset)
 {
        struct task_struct *p;
-       void *v = (void *)(unsigned long)css->cgroup->id;
+       struct cgroup_subsys_state *css;
+
+       cgroup_taskset_for_each(p, css, tset) {
+               void *v = (void *)(unsigned long)css->cgroup->id;
 
-       cgroup_taskset_for_each(p, tset) {
                task_lock(p);
                iterate_fd(p->files, 0, update_netprio, v);
                task_unlock(p);
index 3b6899b7d810d569057b051162b51fde7c51cba8..8a1741b14302bd0cecdc265848feba8222400d17 100644 (file)
@@ -305,6 +305,8 @@ void scm_detach_fds(struct msghdr *msg, struct scm_cookie *scm)
                        err = put_user(cmlen, &cm->cmsg_len);
                if (!err) {
                        cmlen = CMSG_SPACE(i*sizeof(int));
+                       if (msg->msg_controllen < cmlen)
+                               cmlen = msg->msg_controllen;
                        msg->msg_control += cmlen;
                        msg->msg_controllen -= cmlen;
                }
index 1e4dd54bfb5a525ef6070905f07472f60e9f137f..e31dfcee1729aa23bdd2ed692fda1b90bd75afb8 100644 (file)
@@ -1530,7 +1530,6 @@ struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority)
                skb_queue_head_init(&newsk->sk_receive_queue);
                skb_queue_head_init(&newsk->sk_write_queue);
 
-               spin_lock_init(&newsk->sk_dst_lock);
                rwlock_init(&newsk->sk_callback_lock);
                lockdep_set_class_and_name(&newsk->sk_callback_lock,
                                af_callback_keys + newsk->sk_family,
@@ -1607,7 +1606,7 @@ void sk_setup_caps(struct sock *sk, struct dst_entry *dst)
 {
        u32 max_segs = 1;
 
-       __sk_dst_set(sk, dst);
+       sk_dst_set(sk, dst);
        sk->sk_route_caps = dst->dev->features;
        if (sk->sk_route_caps & NETIF_F_GSO)
                sk->sk_route_caps |= NETIF_F_GSO_SOFTWARE;
@@ -1815,7 +1814,7 @@ static long sock_wait_for_wmem(struct sock *sk, long timeo)
 {
        DEFINE_WAIT(wait);
 
-       clear_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags);
+       sk_clear_bit(SOCKWQ_ASYNC_NOSPACE, sk);
        for (;;) {
                if (!timeo)
                        break;
@@ -1861,7 +1860,7 @@ struct sk_buff *sock_alloc_send_pskb(struct sock *sk, unsigned long header_len,
                if (sk_wmem_alloc_get(sk) < sk->sk_sndbuf)
                        break;
 
-               set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags);
+               sk_set_bit(SOCKWQ_ASYNC_NOSPACE, sk);
                set_bit(SOCK_NOSPACE, &sk->sk_socket->flags);
                err = -EAGAIN;
                if (!timeo)
@@ -2048,9 +2047,9 @@ int sk_wait_data(struct sock *sk, long *timeo, const struct sk_buff *skb)
        DEFINE_WAIT(wait);
 
        prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
-       set_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
+       sk_set_bit(SOCKWQ_ASYNC_WAITDATA, sk);
        rc = sk_wait_event(sk, timeo, skb_peek_tail(&sk->sk_receive_queue) != skb);
-       clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
+       sk_clear_bit(SOCKWQ_ASYNC_WAITDATA, sk);
        finish_wait(sk_sleep(sk), &wait);
        return rc;
 }
@@ -2388,7 +2387,6 @@ void sock_init_data(struct socket *sock, struct sock *sk)
        } else
                sk->sk_wq       =       NULL;
 
-       spin_lock_init(&sk->sk_dst_lock);
        rwlock_init(&sk->sk_callback_lock);
        lockdep_set_class_and_name(&sk->sk_callback_lock,
                        af_callback_keys + sk->sk_family,
index d70f77a0c8898582e0adabd24c6165675d12dce7..b96f7a79e54458bfa1d0d1a51f77be08a45e8207 100644 (file)
@@ -39,7 +39,7 @@ void sk_stream_write_space(struct sock *sk)
                        wake_up_interruptible_poll(&wq->wait, POLLOUT |
                                                POLLWRNORM | POLLWRBAND);
                if (wq && wq->fasync_list && !(sk->sk_shutdown & SEND_SHUTDOWN))
-                       sock_wake_async(sock, SOCK_WAKE_SPACE, POLL_OUT);
+                       sock_wake_async(wq, SOCK_WAKE_SPACE, POLL_OUT);
                rcu_read_unlock();
        }
 }
@@ -126,7 +126,7 @@ int sk_stream_wait_memory(struct sock *sk, long *timeo_p)
                current_timeo = vm_wait = (prandom_u32() % (HZ / 5)) + 2;
 
        while (1) {
-               set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags);
+               sk_set_bit(SOCKWQ_ASYNC_NOSPACE, sk);
 
                prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
 
@@ -139,7 +139,7 @@ int sk_stream_wait_memory(struct sock *sk, long *timeo_p)
                }
                if (signal_pending(current))
                        goto do_interrupted;
-               clear_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags);
+               sk_clear_bit(SOCKWQ_ASYNC_NOSPACE, sk);
                if (sk_stream_memory_free(sk) && !vm_wait)
                        break;
 
index db5fc2440a232c856bccfd8e0222a24bcf3d6d11..9c6d0508e63a2ab7f13105cd91ea8c027c4a7557 100644 (file)
@@ -202,7 +202,9 @@ static int dccp_v6_send_response(const struct sock *sk, struct request_sock *req
        security_req_classify_flow(req, flowi6_to_flowi(&fl6));
 
 
-       final_p = fl6_update_dst(&fl6, np->opt, &final);
+       rcu_read_lock();
+       final_p = fl6_update_dst(&fl6, rcu_dereference(np->opt), &final);
+       rcu_read_unlock();
 
        dst = ip6_dst_lookup_flow(sk, &fl6, final_p);
        if (IS_ERR(dst)) {
@@ -219,7 +221,10 @@ static int dccp_v6_send_response(const struct sock *sk, struct request_sock *req
                                                         &ireq->ir_v6_loc_addr,
                                                         &ireq->ir_v6_rmt_addr);
                fl6.daddr = ireq->ir_v6_rmt_addr;
-               err = ip6_xmit(sk, skb, &fl6, np->opt, np->tclass);
+               rcu_read_lock();
+               err = ip6_xmit(sk, skb, &fl6, rcu_dereference(np->opt),
+                              np->tclass);
+               rcu_read_unlock();
                err = net_xmit_eval(err);
        }
 
@@ -387,6 +392,7 @@ static struct sock *dccp_v6_request_recv_sock(const struct sock *sk,
        struct inet_request_sock *ireq = inet_rsk(req);
        struct ipv6_pinfo *newnp;
        const struct ipv6_pinfo *np = inet6_sk(sk);
+       struct ipv6_txoptions *opt;
        struct inet_sock *newinet;
        struct dccp6_sock *newdp6;
        struct sock *newsk;
@@ -453,7 +459,7 @@ static struct sock *dccp_v6_request_recv_sock(const struct sock *sk,
         * comment in that function for the gory details. -acme
         */
 
-       __ip6_dst_store(newsk, dst, NULL, NULL);
+       ip6_dst_store(newsk, dst, NULL, NULL);
        newsk->sk_route_caps = dst->dev->features & ~(NETIF_F_IP_CSUM |
                                                      NETIF_F_TSO);
        newdp6 = (struct dccp6_sock *)newsk;
@@ -488,13 +494,15 @@ static struct sock *dccp_v6_request_recv_sock(const struct sock *sk,
         * Yes, keeping reference count would be much more clever, but we make
         * one more one thing there: reattach optmem to newsk.
         */
-       if (np->opt != NULL)
-               newnp->opt = ipv6_dup_options(newsk, np->opt);
-
+       opt = rcu_dereference(np->opt);
+       if (opt) {
+               opt = ipv6_dup_options(newsk, opt);
+               RCU_INIT_POINTER(newnp->opt, opt);
+       }
        inet_csk(newsk)->icsk_ext_hdr_len = 0;
-       if (newnp->opt != NULL)
-               inet_csk(newsk)->icsk_ext_hdr_len = (newnp->opt->opt_nflen +
-                                                    newnp->opt->opt_flen);
+       if (opt)
+               inet_csk(newsk)->icsk_ext_hdr_len = opt->opt_nflen +
+                                                   opt->opt_flen;
 
        dccp_sync_mss(newsk, dst_mtu(dst));
 
@@ -757,6 +765,7 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
        struct ipv6_pinfo *np = inet6_sk(sk);
        struct dccp_sock *dp = dccp_sk(sk);
        struct in6_addr *saddr = NULL, *final_p, final;
+       struct ipv6_txoptions *opt;
        struct flowi6 fl6;
        struct dst_entry *dst;
        int addr_type;
@@ -856,7 +865,8 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
        fl6.fl6_sport = inet->inet_sport;
        security_sk_classify_flow(sk, flowi6_to_flowi(&fl6));
 
-       final_p = fl6_update_dst(&fl6, np->opt, &final);
+       opt = rcu_dereference_protected(np->opt, sock_owned_by_user(sk));
+       final_p = fl6_update_dst(&fl6, opt, &final);
 
        dst = ip6_dst_lookup_flow(sk, &fl6, final_p);
        if (IS_ERR(dst)) {
@@ -873,12 +883,11 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
        np->saddr = *saddr;
        inet->inet_rcv_saddr = LOOPBACK4_IPV6;
 
-       __ip6_dst_store(sk, dst, NULL, NULL);
+       ip6_dst_store(sk, dst, NULL, NULL);
 
        icsk->icsk_ext_hdr_len = 0;
-       if (np->opt != NULL)
-               icsk->icsk_ext_hdr_len = (np->opt->opt_flen +
-                                         np->opt->opt_nflen);
+       if (opt)
+               icsk->icsk_ext_hdr_len = opt->opt_flen + opt->opt_nflen;
 
        inet->inet_dport = usin->sin6_port;
 
index b5cf13a2800923486ad597c296a66145bc248596..41e65804ddf59651c78ae58b697e7e5e603c9167 100644 (file)
@@ -339,8 +339,7 @@ unsigned int dccp_poll(struct file *file, struct socket *sock,
                        if (sk_stream_is_writeable(sk)) {
                                mask |= POLLOUT | POLLWRNORM;
                        } else {  /* send SIGIO later */
-                               set_bit(SOCK_ASYNC_NOSPACE,
-                                       &sk->sk_socket->flags);
+                               sk_set_bit(SOCKWQ_ASYNC_NOSPACE, sk);
                                set_bit(SOCK_NOSPACE, &sk->sk_socket->flags);
 
                                /* Race breaker. If space is freed after
index 675cf94e04f862b77644f86628af6e8a46933055..eebf5ac8ce18abdb7ac094a1e6de081fcbfa79aa 100644 (file)
@@ -1747,9 +1747,9 @@ static int dn_recvmsg(struct socket *sock, struct msghdr *msg, size_t size,
                }
 
                prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
-               set_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
+               sk_set_bit(SOCKWQ_ASYNC_WAITDATA, sk);
                sk_wait_event(sk, &timeo, dn_data_ready(sk, queue, flags, target));
-               clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
+               sk_clear_bit(SOCKWQ_ASYNC_WAITDATA, sk);
                finish_wait(sk_sleep(sk), &wait);
        }
 
@@ -2004,10 +2004,10 @@ static int dn_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
                        }
 
                        prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
-                       set_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
+                       sk_set_bit(SOCKWQ_ASYNC_WAITDATA, sk);
                        sk_wait_event(sk, &timeo,
                                      !dn_queue_too_long(scp, queue, flags));
-                       clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
+                       sk_clear_bit(SOCKWQ_ASYNC_WAITDATA, sk);
                        finish_wait(sk_sleep(sk), &wait);
                        continue;
                }
index 4677b6fa6dda2c71ace9d97536a450684d18d3ef..ecc28cff08ab8110a9d96d6f7abe690ca77e9962 100644 (file)
@@ -67,7 +67,7 @@
  * Returns the size of the result on success, -ve error code otherwise.
  */
 int dns_query(const char *type, const char *name, size_t namelen,
-             const char *options, char **_result, time_t *_expiry)
+             const char *options, char **_result, time64_t *_expiry)
 {
        struct key *rkey;
        const struct user_key_payload *upayload;
index 35a9788bb3ae734d8e5b2f5199901a6c47f7a587..c7d1adca30d891b183b0832712e0d57aa1f33201 100644 (file)
@@ -312,7 +312,7 @@ static void send_hsr_supervision_frame(struct hsr_port *master, u8 type)
        return;
 
 out:
-       WARN_ON_ONCE("HSR: Could not send supervision frame\n");
+       WARN_ONCE(1, "HSR: Could not send supervision frame\n");
        kfree_skb(skb);
 }
 
index 6baf36e11808e5c93c2e092139bed60cdacc4c8a..05e4cba14162f3583ec588657af7e8b68546b111 100644 (file)
@@ -2126,7 +2126,7 @@ int ip_mc_leave_group(struct sock *sk, struct ip_mreqn *imr)
        ASSERT_RTNL();
 
        in_dev = ip_mc_find_dev(net, imr);
-       if (!in_dev) {
+       if (!imr->imr_ifindex && !imr->imr_address.s_addr && !in_dev) {
                ret = -ENODEV;
                goto out;
        }
@@ -2147,7 +2147,8 @@ int ip_mc_leave_group(struct sock *sk, struct ip_mreqn *imr)
 
                *imlp = iml->next_rcu;
 
-               ip_mc_dec_group(in_dev, group);
+               if (in_dev)
+                       ip_mc_dec_group(in_dev, group);
 
                /* decrease mem now to avoid the memleak warning */
                atomic_sub(sizeof(*iml), &sk->sk_omem_alloc);
index 92dd4b74d513ab40ba4f6f3f2f5ce7a73085f379..c3a38353f5dc8094de5c1dcec06ae54ab0b29a9e 100644 (file)
@@ -134,7 +134,7 @@ static int __ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb,
                              struct mfc_cache *c, struct rtmsg *rtm);
 static void mroute_netlink_event(struct mr_table *mrt, struct mfc_cache *mfc,
                                 int cmd);
-static void mroute_clean_tables(struct mr_table *mrt);
+static void mroute_clean_tables(struct mr_table *mrt, bool all);
 static void ipmr_expire_process(unsigned long arg);
 
 #ifdef CONFIG_IP_MROUTE_MULTIPLE_TABLES
@@ -350,7 +350,7 @@ static struct mr_table *ipmr_new_table(struct net *net, u32 id)
 static void ipmr_free_table(struct mr_table *mrt)
 {
        del_timer_sync(&mrt->ipmr_expire_timer);
-       mroute_clean_tables(mrt);
+       mroute_clean_tables(mrt, true);
        kfree(mrt);
 }
 
@@ -441,10 +441,6 @@ struct net_device *ipmr_new_tunnel(struct net *net, struct vifctl *v)
        return dev;
 
 failure:
-       /* allow the register to be completed before unregistering. */
-       rtnl_unlock();
-       rtnl_lock();
-
        unregister_netdevice(dev);
        return NULL;
 }
@@ -540,10 +536,6 @@ static struct net_device *ipmr_reg_vif(struct net *net, struct mr_table *mrt)
        return dev;
 
 failure:
-       /* allow the register to be completed before unregistering. */
-       rtnl_unlock();
-       rtnl_lock();
-
        unregister_netdevice(dev);
        return NULL;
 }
@@ -1208,7 +1200,7 @@ static int ipmr_mfc_add(struct net *net, struct mr_table *mrt,
  *     Close the multicast socket, and clear the vif tables etc
  */
 
-static void mroute_clean_tables(struct mr_table *mrt)
+static void mroute_clean_tables(struct mr_table *mrt, bool all)
 {
        int i;
        LIST_HEAD(list);
@@ -1217,8 +1209,9 @@ static void mroute_clean_tables(struct mr_table *mrt)
        /* Shut down all active vif entries */
 
        for (i = 0; i < mrt->maxvif; i++) {
-               if (!(mrt->vif_table[i].flags & VIFF_STATIC))
-                       vif_delete(mrt, i, 0, &list);
+               if (!all && (mrt->vif_table[i].flags & VIFF_STATIC))
+                       continue;
+               vif_delete(mrt, i, 0, &list);
        }
        unregister_netdevice_many(&list);
 
@@ -1226,7 +1219,7 @@ static void mroute_clean_tables(struct mr_table *mrt)
 
        for (i = 0; i < MFC_LINES; i++) {
                list_for_each_entry_safe(c, next, &mrt->mfc_cache_array[i], list) {
-                       if (c->mfc_flags & MFC_STATIC)
+                       if (!all && (c->mfc_flags & MFC_STATIC))
                                continue;
                        list_del_rcu(&c->list);
                        mroute_netlink_event(mrt, c, RTM_DELROUTE);
@@ -1261,7 +1254,7 @@ static void mrtsock_destruct(struct sock *sk)
                                                    NETCONFA_IFINDEX_ALL,
                                                    net->ipv4.devconf_all);
                        RCU_INIT_POINTER(mrt->mroute_sk, NULL);
-                       mroute_clean_tables(mrt);
+                       mroute_clean_tables(mrt, false);
                }
        }
        rtnl_unlock();
index c1728771cf89c46a82af0187a02029450adb854b..c82cca18c90fbd67c2daf71c6769ee5fef21d2a9 100644 (file)
@@ -517,8 +517,7 @@ unsigned int tcp_poll(struct file *file, struct socket *sock, poll_table *wait)
                        if (sk_stream_is_writeable(sk)) {
                                mask |= POLLOUT | POLLWRNORM;
                        } else {  /* send SIGIO later */
-                               set_bit(SOCK_ASYNC_NOSPACE,
-                                       &sk->sk_socket->flags);
+                               sk_set_bit(SOCKWQ_ASYNC_NOSPACE, sk);
                                set_bit(SOCK_NOSPACE, &sk->sk_socket->flags);
 
                                /* Race breaker. If space is freed after
@@ -906,7 +905,7 @@ static ssize_t do_tcp_sendpages(struct sock *sk, struct page *page, int offset,
                        goto out_err;
        }
 
-       clear_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags);
+       sk_clear_bit(SOCKWQ_ASYNC_NOSPACE, sk);
 
        mss_now = tcp_send_mss(sk, &size_goal, flags);
        copied = 0;
@@ -1134,7 +1133,7 @@ int tcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t size)
        }
 
        /* This should be in poll */
-       clear_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags);
+       sk_clear_bit(SOCKWQ_ASYNC_NOSPACE, sk);
 
        mss_now = tcp_send_mss(sk, &size_goal, flags);
 
index fdd88c3803a673881053039cdc8ff44bc1b8aa4a..2d656eef7f8e16458127ba591e0a4154365f6a83 100644 (file)
@@ -4481,19 +4481,34 @@ static int __must_check tcp_queue_rcv(struct sock *sk, struct sk_buff *skb, int
 int tcp_send_rcvq(struct sock *sk, struct msghdr *msg, size_t size)
 {
        struct sk_buff *skb;
+       int err = -ENOMEM;
+       int data_len = 0;
        bool fragstolen;
 
        if (size == 0)
                return 0;
 
-       skb = alloc_skb(size, sk->sk_allocation);
+       if (size > PAGE_SIZE) {
+               int npages = min_t(size_t, size >> PAGE_SHIFT, MAX_SKB_FRAGS);
+
+               data_len = npages << PAGE_SHIFT;
+               size = data_len + (size & ~PAGE_MASK);
+       }
+       skb = alloc_skb_with_frags(size - data_len, data_len,
+                                  PAGE_ALLOC_COSTLY_ORDER,
+                                  &err, sk->sk_allocation);
        if (!skb)
                goto err;
 
+       skb_put(skb, size - data_len);
+       skb->data_len = data_len;
+       skb->len = size;
+
        if (tcp_try_rmem_schedule(sk, skb, skb->truesize))
                goto err_free;
 
-       if (memcpy_from_msg(skb_put(skb, size), msg, size))
+       err = skb_copy_datagram_from_iter(skb, 0, &msg->msg_iter, size);
+       if (err)
                goto err_free;
 
        TCP_SKB_CB(skb)->seq = tcp_sk(sk)->rcv_nxt;
@@ -4509,7 +4524,8 @@ int tcp_send_rcvq(struct sock *sk, struct msghdr *msg, size_t size)
 err_free:
        kfree_skb(skb);
 err:
-       return -ENOMEM;
+       return err;
+
 }
 
 static void tcp_data_queue(struct sock *sk, struct sk_buff *skb)
@@ -5667,6 +5683,7 @@ discard:
                }
 
                tp->rcv_nxt = TCP_SKB_CB(skb)->seq + 1;
+               tp->copied_seq = tp->rcv_nxt;
                tp->rcv_wup = TCP_SKB_CB(skb)->seq + 1;
 
                /* RFC1323: The window in SYN & SYN/ACK segments is
index ba09016d1bfd2a778d57cdc37f0a7db539f9cb3a..db003438aaf5f6a2b27319c4669be1b1f62c7ae3 100644 (file)
@@ -921,7 +921,8 @@ int tcp_md5_do_add(struct sock *sk, const union tcp_md5_addr *addr,
        }
 
        md5sig = rcu_dereference_protected(tp->md5sig_info,
-                                          sock_owned_by_user(sk));
+                                          sock_owned_by_user(sk) ||
+                                          lockdep_is_held(&sk->sk_lock.slock));
        if (!md5sig) {
                md5sig = kmalloc(sizeof(*md5sig), gfp);
                if (!md5sig)
index c9c716a483e457e8b4fe063776ae3d7a855889cc..193ba1fa8a9abbc190823a86398722d5c5a605fe 100644 (file)
@@ -168,7 +168,7 @@ static int tcp_write_timeout(struct sock *sk)
                        dst_negative_advice(sk);
                        if (tp->syn_fastopen || tp->syn_data)
                                tcp_fastopen_cache_set(sk, 0, NULL, true, 0);
-                       if (tp->syn_data)
+                       if (tp->syn_data && icsk->icsk_retransmits == 1)
                                NET_INC_STATS_BH(sock_net(sk),
                                                 LINUX_MIB_TCPFASTOPENACTIVEFAIL);
                }
@@ -176,6 +176,18 @@ static int tcp_write_timeout(struct sock *sk)
                syn_set = true;
        } else {
                if (retransmits_timed_out(sk, sysctl_tcp_retries1, 0, 0)) {
+                       /* Some middle-boxes may black-hole Fast Open _after_
+                        * the handshake. Therefore we conservatively disable
+                        * Fast Open on this path on recurring timeouts with
+                        * few or zero bytes acked after Fast Open.
+                        */
+                       if (tp->syn_data_acked &&
+                           tp->bytes_acked <= tp->rx_opt.mss_clamp) {
+                               tcp_fastopen_cache_set(sk, 0, NULL, true, 0);
+                               if (icsk->icsk_retransmits == sysctl_tcp_retries1)
+                                       NET_INC_STATS_BH(sock_net(sk),
+                                                        LINUX_MIB_TCPFASTOPENACTIVEFAIL);
+                       }
                        /* Black hole detection */
                        tcp_mtu_probing(icsk, sk);
 
index 24ec14f9825c20834eca20b820ec953ba108da52..0c7b0e61b917158af7e431f9e7781f7bce313c83 100644 (file)
 #include <linux/slab.h>
 #include <net/tcp_states.h>
 #include <linux/skbuff.h>
-#include <linux/netdevice.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <net/net_namespace.h>
index d84742f003a9fca65a3545abdb7a4d517989ed4c..61f26851655ccd23200278d34ceda44351da1c17 100644 (file)
@@ -3642,7 +3642,7 @@ static void addrconf_dad_work(struct work_struct *w)
 
        /* send a neighbour solicitation for our addr */
        addrconf_addr_solict_mult(&ifp->addr, &mcaddr);
-       ndisc_send_ns(ifp->idev->dev, &ifp->addr, &mcaddr, &in6addr_any, NULL);
+       ndisc_send_ns(ifp->idev->dev, &ifp->addr, &mcaddr, &in6addr_any);
 out:
        in6_ifa_put(ifp);
        rtnl_unlock();
index 44bb66bde0e2d97308c3c68a8d6b225ce04d08a8..8ec0df75f1c4f81bea71cb466c4da802c39099d8 100644 (file)
@@ -428,9 +428,11 @@ void inet6_destroy_sock(struct sock *sk)
 
        /* Free tx options */
 
-       opt = xchg(&np->opt, NULL);
-       if (opt)
-               sock_kfree_s(sk, opt, opt->tot_len);
+       opt = xchg((__force struct ipv6_txoptions **)&np->opt, NULL);
+       if (opt) {
+               atomic_sub(opt->tot_len, &sk->sk_omem_alloc);
+               txopt_put(opt);
+       }
 }
 EXPORT_SYMBOL_GPL(inet6_destroy_sock);
 
@@ -659,7 +661,10 @@ int inet6_sk_rebuild_header(struct sock *sk)
                fl6.fl6_sport = inet->inet_sport;
                security_sk_classify_flow(sk, flowi6_to_flowi(&fl6));
 
-               final_p = fl6_update_dst(&fl6, np->opt, &final);
+               rcu_read_lock();
+               final_p = fl6_update_dst(&fl6, rcu_dereference(np->opt),
+                                        &final);
+               rcu_read_unlock();
 
                dst = ip6_dst_lookup_flow(sk, &fl6, final_p);
                if (IS_ERR(dst)) {
@@ -668,7 +673,7 @@ int inet6_sk_rebuild_header(struct sock *sk)
                        return PTR_ERR(dst);
                }
 
-               __ip6_dst_store(sk, dst, NULL, NULL);
+               ip6_dst_store(sk, dst, NULL, NULL);
        }
 
        return 0;
index d70b0238f468f4e5602d09469eddc98a07a3e61c..517c55b01ba84b55a0004ce9505d14c4a3951cfc 100644 (file)
@@ -167,8 +167,10 @@ ipv4_connected:
 
        security_sk_classify_flow(sk, flowi6_to_flowi(&fl6));
 
-       opt = flowlabel ? flowlabel->opt : np->opt;
+       rcu_read_lock();
+       opt = flowlabel ? flowlabel->opt : rcu_dereference(np->opt);
        final_p = fl6_update_dst(&fl6, opt, &final);
+       rcu_read_unlock();
 
        dst = ip6_dst_lookup_flow(sk, &fl6, final_p);
        err = 0;
index ce203b0402bea3b16deb34b4835cd2e89e94f899..ea7c4d64a00adad60a634afb2c6efca4ab029799 100644 (file)
@@ -727,6 +727,7 @@ ipv6_dup_options(struct sock *sk, struct ipv6_txoptions *opt)
                        *((char **)&opt2->dst1opt) += dif;
                if (opt2->srcrt)
                        *((char **)&opt2->srcrt) += dif;
+               atomic_set(&opt2->refcnt, 1);
        }
        return opt2;
 }
@@ -790,7 +791,7 @@ ipv6_renew_options(struct sock *sk, struct ipv6_txoptions *opt,
                return ERR_PTR(-ENOBUFS);
 
        memset(opt2, 0, tot_len);
-
+       atomic_set(&opt2->refcnt, 1);
        opt2->tot_len = tot_len;
        p = (char *)(opt2 + 1);
 
index 36c5a98b04727b220e9ea77e00d96410d4bb3f74..0a37ddc7af51579f56b644ba0e4c3c3a7a2e2bc7 100644 (file)
@@ -834,11 +834,6 @@ void icmpv6_flow_init(struct sock *sk, struct flowi6 *fl6,
        security_sk_classify_flow(sk, flowi6_to_flowi(fl6));
 }
 
-/*
- * Special lock-class for __icmpv6_sk:
- */
-static struct lock_class_key icmpv6_socket_sk_dst_lock_key;
-
 static int __net_init icmpv6_sk_init(struct net *net)
 {
        struct sock *sk;
@@ -860,15 +855,6 @@ static int __net_init icmpv6_sk_init(struct net *net)
 
                net->ipv6.icmp_sk[i] = sk;
 
-               /*
-                * Split off their lock-class, because sk->sk_dst_lock
-                * gets used from softirqs, which is safe for
-                * __icmpv6_sk (because those never get directly used
-                * via userspace syscalls), but unsafe for normal sockets.
-                */
-               lockdep_set_class(&sk->sk_dst_lock,
-                                 &icmpv6_socket_sk_dst_lock_key);
-
                /* Enough space for 2 64K ICMP packets, including
                 * sk_buff struct overhead.
                 */
index 5d1c7cee2cb2bdc45b0889b4fe197c7af4db01e7..a7ca2cde2ecbcff85c9a6151b4770e3897d16314 100644 (file)
@@ -78,7 +78,9 @@ struct dst_entry *inet6_csk_route_req(const struct sock *sk,
        memset(fl6, 0, sizeof(*fl6));
        fl6->flowi6_proto = proto;
        fl6->daddr = ireq->ir_v6_rmt_addr;
-       final_p = fl6_update_dst(fl6, np->opt, &final);
+       rcu_read_lock();
+       final_p = fl6_update_dst(fl6, rcu_dereference(np->opt), &final);
+       rcu_read_unlock();
        fl6->saddr = ireq->ir_v6_loc_addr;
        fl6->flowi6_oif = ireq->ir_iif;
        fl6->flowi6_mark = ireq->ir_mark;
@@ -108,14 +110,6 @@ void inet6_csk_addr2sockaddr(struct sock *sk, struct sockaddr *uaddr)
 }
 EXPORT_SYMBOL_GPL(inet6_csk_addr2sockaddr);
 
-static inline
-void __inet6_csk_dst_store(struct sock *sk, struct dst_entry *dst,
-                          const struct in6_addr *daddr,
-                          const struct in6_addr *saddr)
-{
-       __ip6_dst_store(sk, dst, daddr, saddr);
-}
-
 static inline
 struct dst_entry *__inet6_csk_dst_check(struct sock *sk, u32 cookie)
 {
@@ -142,14 +136,16 @@ static struct dst_entry *inet6_csk_route_socket(struct sock *sk,
        fl6->fl6_dport = inet->inet_dport;
        security_sk_classify_flow(sk, flowi6_to_flowi(fl6));
 
-       final_p = fl6_update_dst(fl6, np->opt, &final);
+       rcu_read_lock();
+       final_p = fl6_update_dst(fl6, rcu_dereference(np->opt), &final);
+       rcu_read_unlock();
 
        dst = __inet6_csk_dst_check(sk, np->dst_cookie);
        if (!dst) {
                dst = ip6_dst_lookup_flow(sk, fl6, final_p);
 
                if (!IS_ERR(dst))
-                       __inet6_csk_dst_store(sk, dst, NULL, NULL);
+                       ip6_dst_store(sk, dst, NULL, NULL);
        }
        return dst;
 }
@@ -175,7 +171,8 @@ int inet6_csk_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl_unused
        /* Restore final destination back after routing done */
        fl6.daddr = sk->sk_v6_daddr;
 
-       res = ip6_xmit(sk, skb, &fl6, np->opt, np->tclass);
+       res = ip6_xmit(sk, skb, &fl6, rcu_dereference(np->opt),
+                      np->tclass);
        rcu_read_unlock();
        return res;
 }
index eabffbb89795d921b0977989345b25d81f553ee0..137fca42aaa6bb809d46e7809b240d8810d89a04 100644 (file)
@@ -177,7 +177,7 @@ void ip6_tnl_dst_reset(struct ip6_tnl *t)
        int i;
 
        for_each_possible_cpu(i)
-               ip6_tnl_per_cpu_dst_set(raw_cpu_ptr(t->dst_cache), NULL);
+               ip6_tnl_per_cpu_dst_set(per_cpu_ptr(t->dst_cache, i), NULL);
 }
 EXPORT_SYMBOL_GPL(ip6_tnl_dst_reset);
 
index ad19136086dd5e1ae4e362e3da0f0267fc755b02..a10e77103c88dfc952f80c645a7b87c57b8f6dbf 100644 (file)
@@ -118,7 +118,7 @@ static void mr6_netlink_event(struct mr6_table *mrt, struct mfc6_cache *mfc,
                              int cmd);
 static int ip6mr_rtm_dumproute(struct sk_buff *skb,
                               struct netlink_callback *cb);
-static void mroute_clean_tables(struct mr6_table *mrt);
+static void mroute_clean_tables(struct mr6_table *mrt, bool all);
 static void ipmr_expire_process(unsigned long arg);
 
 #ifdef CONFIG_IPV6_MROUTE_MULTIPLE_TABLES
@@ -334,7 +334,7 @@ static struct mr6_table *ip6mr_new_table(struct net *net, u32 id)
 static void ip6mr_free_table(struct mr6_table *mrt)
 {
        del_timer_sync(&mrt->ipmr_expire_timer);
-       mroute_clean_tables(mrt);
+       mroute_clean_tables(mrt, true);
        kfree(mrt);
 }
 
@@ -765,10 +765,6 @@ static struct net_device *ip6mr_reg_vif(struct net *net, struct mr6_table *mrt)
        return dev;
 
 failure:
-       /* allow the register to be completed before unregistering. */
-       rtnl_unlock();
-       rtnl_lock();
-
        unregister_netdevice(dev);
        return NULL;
 }
@@ -1542,7 +1538,7 @@ static int ip6mr_mfc_add(struct net *net, struct mr6_table *mrt,
  *     Close the multicast socket, and clear the vif tables etc
  */
 
-static void mroute_clean_tables(struct mr6_table *mrt)
+static void mroute_clean_tables(struct mr6_table *mrt, bool all)
 {
        int i;
        LIST_HEAD(list);
@@ -1552,8 +1548,9 @@ static void mroute_clean_tables(struct mr6_table *mrt)
         *      Shut down all active vif entries
         */
        for (i = 0; i < mrt->maxvif; i++) {
-               if (!(mrt->vif6_table[i].flags & VIFF_STATIC))
-                       mif6_delete(mrt, i, &list);
+               if (!all && (mrt->vif6_table[i].flags & VIFF_STATIC))
+                       continue;
+               mif6_delete(mrt, i, &list);
        }
        unregister_netdevice_many(&list);
 
@@ -1562,7 +1559,7 @@ static void mroute_clean_tables(struct mr6_table *mrt)
         */
        for (i = 0; i < MFC6_LINES; i++) {
                list_for_each_entry_safe(c, next, &mrt->mfc6_cache_array[i], list) {
-                       if (c->mfc_flags & MFC_STATIC)
+                       if (!all && (c->mfc_flags & MFC_STATIC))
                                continue;
                        write_lock_bh(&mrt_lock);
                        list_del(&c->list);
@@ -1625,7 +1622,7 @@ int ip6mr_sk_done(struct sock *sk)
                                                     net->ipv6.devconf_all);
                        write_unlock_bh(&mrt_lock);
 
-                       mroute_clean_tables(mrt);
+                       mroute_clean_tables(mrt, false);
                        err = 0;
                        break;
                }
index 63e6956917c9cf20ee74968de3a7f03c1b48c849..4449ad1f81147cab79c44209f3f2a73dc1f6a934 100644 (file)
@@ -111,7 +111,8 @@ struct ipv6_txoptions *ipv6_update_options(struct sock *sk,
                        icsk->icsk_sync_mss(sk, icsk->icsk_pmtu_cookie);
                }
        }
-       opt = xchg(&inet6_sk(sk)->opt, opt);
+       opt = xchg((__force struct ipv6_txoptions **)&inet6_sk(sk)->opt,
+                  opt);
        sk_dst_reset(sk);
 
        return opt;
@@ -231,9 +232,12 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
                                sk->sk_socket->ops = &inet_dgram_ops;
                                sk->sk_family = PF_INET;
                        }
-                       opt = xchg(&np->opt, NULL);
-                       if (opt)
-                               sock_kfree_s(sk, opt, opt->tot_len);
+                       opt = xchg((__force struct ipv6_txoptions **)&np->opt,
+                                  NULL);
+                       if (opt) {
+                               atomic_sub(opt->tot_len, &sk->sk_omem_alloc);
+                               txopt_put(opt);
+                       }
                        pktopt = xchg(&np->pktoptions, NULL);
                        kfree_skb(pktopt);
 
@@ -403,7 +407,8 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
                if (optname != IPV6_RTHDR && !ns_capable(net->user_ns, CAP_NET_RAW))
                        break;
 
-               opt = ipv6_renew_options(sk, np->opt, optname,
+               opt = rcu_dereference_protected(np->opt, sock_owned_by_user(sk));
+               opt = ipv6_renew_options(sk, opt, optname,
                                         (struct ipv6_opt_hdr __user *)optval,
                                         optlen);
                if (IS_ERR(opt)) {
@@ -432,8 +437,10 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
                retv = 0;
                opt = ipv6_update_options(sk, opt);
 sticky_done:
-               if (opt)
-                       sock_kfree_s(sk, opt, opt->tot_len);
+               if (opt) {
+                       atomic_sub(opt->tot_len, &sk->sk_omem_alloc);
+                       txopt_put(opt);
+               }
                break;
        }
 
@@ -486,6 +493,7 @@ sticky_done:
                        break;
 
                memset(opt, 0, sizeof(*opt));
+               atomic_set(&opt->refcnt, 1);
                opt->tot_len = sizeof(*opt) + optlen;
                retv = -EFAULT;
                if (copy_from_user(opt+1, optval, optlen))
@@ -502,8 +510,10 @@ update:
                retv = 0;
                opt = ipv6_update_options(sk, opt);
 done:
-               if (opt)
-                       sock_kfree_s(sk, opt, opt->tot_len);
+               if (opt) {
+                       atomic_sub(opt->tot_len, &sk->sk_omem_alloc);
+                       txopt_put(opt);
+               }
                break;
        }
        case IPV6_UNICAST_HOPS:
@@ -1110,10 +1120,11 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname,
        case IPV6_RTHDR:
        case IPV6_DSTOPTS:
        {
+               struct ipv6_txoptions *opt;
 
                lock_sock(sk);
-               len = ipv6_getsockopt_sticky(sk, np->opt,
-                                            optname, optval, len);
+               opt = rcu_dereference_protected(np->opt, sock_owned_by_user(sk));
+               len = ipv6_getsockopt_sticky(sk, opt, optname, optval, len);
                release_sock(sk);
                /* check if ipv6_getsockopt_sticky() returns err code */
                if (len < 0)
index 3e0f855e1bead049064a284494eda378f85ae47e..d6161e1c48c86f4a5dfa5cedc89d4b93f8e3d24a 100644 (file)
@@ -556,8 +556,7 @@ static void ndisc_send_unsol_na(struct net_device *dev)
 }
 
 void ndisc_send_ns(struct net_device *dev, const struct in6_addr *solicit,
-                  const struct in6_addr *daddr, const struct in6_addr *saddr,
-                  struct sk_buff *oskb)
+                  const struct in6_addr *daddr, const struct in6_addr *saddr)
 {
        struct sk_buff *skb;
        struct in6_addr addr_buf;
@@ -593,9 +592,6 @@ void ndisc_send_ns(struct net_device *dev, const struct in6_addr *solicit,
                ndisc_fill_addr_option(skb, ND_OPT_SOURCE_LL_ADDR,
                                       dev->dev_addr);
 
-       if (!(dev->priv_flags & IFF_XMIT_DST_RELEASE) && oskb)
-               skb_dst_copy(skb, oskb);
-
        ndisc_send_skb(skb, daddr, saddr);
 }
 
@@ -682,12 +678,12 @@ static void ndisc_solicit(struct neighbour *neigh, struct sk_buff *skb)
                                  "%s: trying to ucast probe in NUD_INVALID: %pI6\n",
                                  __func__, target);
                }
-               ndisc_send_ns(dev, target, target, saddr, skb);
+               ndisc_send_ns(dev, target, target, saddr);
        } else if ((probes -= NEIGH_VAR(neigh->parms, APP_PROBES)) < 0) {
                neigh_app_ns(neigh);
        } else {
                addrconf_addr_solict_mult(target, &mcaddr);
-               ndisc_send_ns(dev, target, &mcaddr, saddr, skb);
+               ndisc_send_ns(dev, target, &mcaddr, saddr);
        }
 }
 
index d5efeb87350e7fc8643962036c0b26cfe471cdc4..bab4441ed4e43906ce0b20d7618668eef81f1162 100644 (file)
@@ -190,7 +190,7 @@ static void nf_ct_frag6_expire(unsigned long data)
 /* Creation primitives. */
 static inline struct frag_queue *fq_find(struct net *net, __be32 id,
                                         u32 user, struct in6_addr *src,
-                                        struct in6_addr *dst, u8 ecn)
+                                        struct in6_addr *dst, int iif, u8 ecn)
 {
        struct inet_frag_queue *q;
        struct ip6_create_arg arg;
@@ -200,6 +200,7 @@ static inline struct frag_queue *fq_find(struct net *net, __be32 id,
        arg.user = user;
        arg.src = src;
        arg.dst = dst;
+       arg.iif = iif;
        arg.ecn = ecn;
 
        local_bh_disable();
@@ -601,7 +602,7 @@ struct sk_buff *nf_ct_frag6_gather(struct net *net, struct sk_buff *skb, u32 use
        fhdr = (struct frag_hdr *)skb_transport_header(clone);
 
        fq = fq_find(net, fhdr->identification, user, &hdr->saddr, &hdr->daddr,
-                    ip6_frag_ecn(hdr));
+                    skb->dev ? skb->dev->ifindex : 0, ip6_frag_ecn(hdr));
        if (fq == NULL) {
                pr_debug("Can't find and can't create new queue\n");
                goto ret_orig;
index dc65ec198f7c3f7ae19176fdaa8752c7fb4e13a5..99140986e88716529b90f082bf2b7011a2db8c15 100644 (file)
@@ -733,6 +733,7 @@ static int raw6_getfrag(void *from, char *to, int offset, int len, int odd,
 
 static int rawv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
 {
+       struct ipv6_txoptions *opt_to_free = NULL;
        struct ipv6_txoptions opt_space;
        DECLARE_SOCKADDR(struct sockaddr_in6 *, sin6, msg->msg_name);
        struct in6_addr *daddr, *final_p, final;
@@ -839,8 +840,10 @@ static int rawv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
                if (!(opt->opt_nflen|opt->opt_flen))
                        opt = NULL;
        }
-       if (!opt)
-               opt = np->opt;
+       if (!opt) {
+               opt = txopt_get(np);
+               opt_to_free = opt;
+               }
        if (flowlabel)
                opt = fl6_merge_options(&opt_space, flowlabel, opt);
        opt = ipv6_fixup_options(&opt_space, opt);
@@ -906,6 +909,7 @@ done:
        dst_release(dst);
 out:
        fl6_sock_release(flowlabel);
+       txopt_put(opt_to_free);
        return err < 0 ? err : len;
 do_confirm:
        dst_confirm(dst);
index 44e21a03cfc3fff395903d36e8e01a7a3e395afa..45f5ae51de65c0fb4d700bad79a05c1e750309e0 100644 (file)
@@ -108,7 +108,10 @@ bool ip6_frag_match(const struct inet_frag_queue *q, const void *a)
        return  fq->id == arg->id &&
                fq->user == arg->user &&
                ipv6_addr_equal(&fq->saddr, arg->src) &&
-               ipv6_addr_equal(&fq->daddr, arg->dst);
+               ipv6_addr_equal(&fq->daddr, arg->dst) &&
+               (arg->iif == fq->iif ||
+                !(ipv6_addr_type(arg->dst) & (IPV6_ADDR_MULTICAST |
+                                              IPV6_ADDR_LINKLOCAL)));
 }
 EXPORT_SYMBOL(ip6_frag_match);
 
@@ -180,7 +183,7 @@ static void ip6_frag_expire(unsigned long data)
 
 static struct frag_queue *
 fq_find(struct net *net, __be32 id, const struct in6_addr *src,
-       const struct in6_addr *dst, u8 ecn)
+       const struct in6_addr *dst, int iif, u8 ecn)
 {
        struct inet_frag_queue *q;
        struct ip6_create_arg arg;
@@ -190,6 +193,7 @@ fq_find(struct net *net, __be32 id, const struct in6_addr *src,
        arg.user = IP6_DEFRAG_LOCAL_DELIVER;
        arg.src = src;
        arg.dst = dst;
+       arg.iif = iif;
        arg.ecn = ecn;
 
        hash = inet6_hash_frag(id, src, dst);
@@ -551,7 +555,7 @@ static int ipv6_frag_rcv(struct sk_buff *skb)
        }
 
        fq = fq_find(net, fhdr->identification, &hdr->saddr, &hdr->daddr,
-                    ip6_frag_ecn(hdr));
+                    skb->dev ? skb->dev->ifindex : 0, ip6_frag_ecn(hdr));
        if (fq) {
                int ret;
 
index 6f01fe122abd7c0348bfcd67d1a55ecb40f1c0b0..826e6aa44f8d42c9c2e815ee134a4f58f1f29c80 100644 (file)
@@ -523,7 +523,7 @@ static void rt6_probe_deferred(struct work_struct *w)
                container_of(w, struct __rt6_probe_work, work);
 
        addrconf_addr_solict_mult(&work->target, &mcaddr);
-       ndisc_send_ns(work->dev, &work->target, &mcaddr, NULL, NULL);
+       ndisc_send_ns(work->dev, &work->target, &mcaddr, NULL);
        dev_put(work->dev);
        kfree(work);
 }
index bb8f2fa1c7fbbe1ac0936688ad684ae30679d917..eaf7ac496d506937cd52944bbdc17da720110b59 100644 (file)
@@ -222,7 +222,7 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb)
                memset(&fl6, 0, sizeof(fl6));
                fl6.flowi6_proto = IPPROTO_TCP;
                fl6.daddr = ireq->ir_v6_rmt_addr;
-               final_p = fl6_update_dst(&fl6, np->opt, &final);
+               final_p = fl6_update_dst(&fl6, rcu_dereference(np->opt), &final);
                fl6.saddr = ireq->ir_v6_loc_addr;
                fl6.flowi6_oif = sk->sk_bound_dev_if;
                fl6.flowi6_mark = ireq->ir_mark;
index c5429a636f1aef539d0ea6bb27f585a3297b7769..e7aab561b7b463d4bfbdd7e7a89302403e252560 100644 (file)
@@ -120,6 +120,7 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
        struct ipv6_pinfo *np = inet6_sk(sk);
        struct tcp_sock *tp = tcp_sk(sk);
        struct in6_addr *saddr = NULL, *final_p, final;
+       struct ipv6_txoptions *opt;
        struct flowi6 fl6;
        struct dst_entry *dst;
        int addr_type;
@@ -235,7 +236,8 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
        fl6.fl6_dport = usin->sin6_port;
        fl6.fl6_sport = inet->inet_sport;
 
-       final_p = fl6_update_dst(&fl6, np->opt, &final);
+       opt = rcu_dereference_protected(np->opt, sock_owned_by_user(sk));
+       final_p = fl6_update_dst(&fl6, opt, &final);
 
        security_sk_classify_flow(sk, flowi6_to_flowi(&fl6));
 
@@ -255,7 +257,7 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
        inet->inet_rcv_saddr = LOOPBACK4_IPV6;
 
        sk->sk_gso_type = SKB_GSO_TCPV6;
-       __ip6_dst_store(sk, dst, NULL, NULL);
+       ip6_dst_store(sk, dst, NULL, NULL);
 
        if (tcp_death_row.sysctl_tw_recycle &&
            !tp->rx_opt.ts_recent_stamp &&
@@ -263,9 +265,9 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
                tcp_fetch_timewait_stamp(sk, dst);
 
        icsk->icsk_ext_hdr_len = 0;
-       if (np->opt)
-               icsk->icsk_ext_hdr_len = (np->opt->opt_flen +
-                                         np->opt->opt_nflen);
+       if (opt)
+               icsk->icsk_ext_hdr_len = opt->opt_flen +
+                                        opt->opt_nflen;
 
        tp->rx_opt.mss_clamp = IPV6_MIN_MTU - sizeof(struct tcphdr) - sizeof(struct ipv6hdr);
 
@@ -461,7 +463,8 @@ static int tcp_v6_send_synack(const struct sock *sk, struct dst_entry *dst,
                if (np->repflow && ireq->pktopts)
                        fl6->flowlabel = ip6_flowlabel(ipv6_hdr(ireq->pktopts));
 
-               err = ip6_xmit(sk, skb, fl6, np->opt, np->tclass);
+               err = ip6_xmit(sk, skb, fl6, rcu_dereference(np->opt),
+                              np->tclass);
                err = net_xmit_eval(err);
        }
 
@@ -972,6 +975,7 @@ static struct sock *tcp_v6_syn_recv_sock(const struct sock *sk, struct sk_buff *
        struct inet_request_sock *ireq;
        struct ipv6_pinfo *newnp;
        const struct ipv6_pinfo *np = inet6_sk(sk);
+       struct ipv6_txoptions *opt;
        struct tcp6_sock *newtcp6sk;
        struct inet_sock *newinet;
        struct tcp_sock *newtp;
@@ -1056,7 +1060,7 @@ static struct sock *tcp_v6_syn_recv_sock(const struct sock *sk, struct sk_buff *
         */
 
        newsk->sk_gso_type = SKB_GSO_TCPV6;
-       __ip6_dst_store(newsk, dst, NULL, NULL);
+       ip6_dst_store(newsk, dst, NULL, NULL);
        inet6_sk_rx_dst_set(newsk, skb);
 
        newtcp6sk = (struct tcp6_sock *)newsk;
@@ -1098,13 +1102,15 @@ static struct sock *tcp_v6_syn_recv_sock(const struct sock *sk, struct sk_buff *
           but we make one more one thing there: reattach optmem
           to newsk.
         */
-       if (np->opt)
-               newnp->opt = ipv6_dup_options(newsk, np->opt);
-
+       opt = rcu_dereference(np->opt);
+       if (opt) {
+               opt = ipv6_dup_options(newsk, opt);
+               RCU_INIT_POINTER(newnp->opt, opt);
+       }
        inet_csk(newsk)->icsk_ext_hdr_len = 0;
-       if (newnp->opt)
-               inet_csk(newsk)->icsk_ext_hdr_len = (newnp->opt->opt_nflen +
-                                                    newnp->opt->opt_flen);
+       if (opt)
+               inet_csk(newsk)->icsk_ext_hdr_len = opt->opt_nflen +
+                                                   opt->opt_flen;
 
        tcp_ca_openreq_child(newsk, dst);
 
index 01bcb49619ee6659aefbd198d40f25bab8319749..9da3287a392370a5c05c538a30613f8ce74f8de1 100644 (file)
@@ -1110,6 +1110,7 @@ int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
        DECLARE_SOCKADDR(struct sockaddr_in6 *, sin6, msg->msg_name);
        struct in6_addr *daddr, *final_p, final;
        struct ipv6_txoptions *opt = NULL;
+       struct ipv6_txoptions *opt_to_free = NULL;
        struct ip6_flowlabel *flowlabel = NULL;
        struct flowi6 fl6;
        struct dst_entry *dst;
@@ -1263,8 +1264,10 @@ do_udp_sendmsg:
                        opt = NULL;
                connected = 0;
        }
-       if (!opt)
-               opt = np->opt;
+       if (!opt) {
+               opt = txopt_get(np);
+               opt_to_free = opt;
+       }
        if (flowlabel)
                opt = fl6_merge_options(&opt_space, flowlabel, opt);
        opt = ipv6_fixup_options(&opt_space, opt);
@@ -1373,6 +1376,7 @@ release_dst:
 out:
        dst_release(dst);
        fl6_sock_release(flowlabel);
+       txopt_put(opt_to_free);
        if (!err)
                return len;
        /*
index fcb2752419c6635b06706d4cec542cb30ae3c85c..435608c4306d4afccf690eda945d4cb7eb962c6b 100644 (file)
@@ -1483,7 +1483,7 @@ unsigned int iucv_sock_poll(struct file *file, struct socket *sock,
        if (sock_writeable(sk) && iucv_below_msglim(sk))
                mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
        else
-               set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags);
+               sk_set_bit(SOCKWQ_ASYNC_NOSPACE, sk);
 
        return mask;
 }
index aca38d8aed8e80b47ded2c81bbf346a39a678ce2..a2c8747d2936c305753224e7a786d67087b2cb1a 100644 (file)
@@ -486,6 +486,7 @@ static int l2tp_ip6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
        DECLARE_SOCKADDR(struct sockaddr_l2tpip6 *, lsa, msg->msg_name);
        struct in6_addr *daddr, *final_p, final;
        struct ipv6_pinfo *np = inet6_sk(sk);
+       struct ipv6_txoptions *opt_to_free = NULL;
        struct ipv6_txoptions *opt = NULL;
        struct ip6_flowlabel *flowlabel = NULL;
        struct dst_entry *dst = NULL;
@@ -575,8 +576,10 @@ static int l2tp_ip6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
                        opt = NULL;
        }
 
-       if (opt == NULL)
-               opt = np->opt;
+       if (!opt) {
+               opt = txopt_get(np);
+               opt_to_free = opt;
+       }
        if (flowlabel)
                opt = fl6_merge_options(&opt_space, flowlabel, opt);
        opt = ipv6_fixup_options(&opt_space, opt);
@@ -631,6 +634,7 @@ done:
        dst_release(dst);
 out:
        fl6_sock_release(flowlabel);
+       txopt_put(opt_to_free);
 
        return err < 0 ? err : len;
 
index a758eb84e8f057ac6518eef6c73bc8785dc7e746..ff757181b0a85c820e1acc53a088e95c78b87bff 100644 (file)
@@ -500,7 +500,7 @@ void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid)
        /* send AddBA request */
        ieee80211_send_addba_request(sdata, sta->sta.addr, tid,
                                     tid_tx->dialog_token, start_seq_num,
-                                    local->hw.max_tx_aggregation_subframes,
+                                    IEEE80211_MAX_AMPDU_BUF,
                                     tid_tx->timeout);
 }
 
@@ -926,6 +926,7 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local,
        amsdu = capab & IEEE80211_ADDBA_PARAM_AMSDU_MASK;
        tid = (capab & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2;
        buf_size = (capab & IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK) >> 6;
+       buf_size = min(buf_size, local->hw.max_tx_aggregation_subframes);
 
        mutex_lock(&sta->ampdu_mlme.mtx);
 
index c2bd1b6a69224e4e07b6247c71077e2a79939dac..da471eef07bb1a6ba6e42d3e5b570dbdff6c21e3 100644 (file)
@@ -3454,8 +3454,12 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
                        goto out_unlock;
                }
        } else {
-               /* for cookie below */
-               ack_skb = skb;
+               /* Assign a dummy non-zero cookie, it's not sent to
+                * userspace in this case but we rely on its value
+                * internally in the need_offchan case to distinguish
+                * mgmt-tx from remain-on-channel.
+                */
+               *cookie = 0xffffffff;
        }
 
        if (!need_offchan) {
index d0dc1bfaeec2d5440573d114b98e16099616f43d..c9e325d2e120c0f9c230dbace71c3c405b9216a3 100644 (file)
@@ -76,7 +76,8 @@ bool __ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata)
 void ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata,
                              bool update_bss)
 {
-       if (__ieee80211_recalc_txpower(sdata) || update_bss)
+       if (__ieee80211_recalc_txpower(sdata) ||
+           (update_bss && ieee80211_sdata_running(sdata)))
                ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_TXPOWER);
 }
 
@@ -1861,6 +1862,7 @@ void ieee80211_if_remove(struct ieee80211_sub_if_data *sdata)
                unregister_netdevice(sdata->dev);
        } else {
                cfg80211_unregister_wdev(&sdata->wdev);
+               ieee80211_teardown_sdata(sdata);
                kfree(sdata);
        }
 }
@@ -1870,7 +1872,6 @@ void ieee80211_sdata_stop(struct ieee80211_sub_if_data *sdata)
        if (WARN_ON_ONCE(!test_bit(SDATA_STATE_RUNNING, &sdata->state)))
                return;
        ieee80211_do_stop(sdata, true);
-       ieee80211_teardown_sdata(sdata);
 }
 
 void ieee80211_remove_interfaces(struct ieee80211_local *local)
index 858f6b1cb1494702bbc6e0d8d25f1b4d4b4d1470..175ffcf7fb06bfb5c9c1f95e2c17f42d666ee26f 100644 (file)
@@ -541,8 +541,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t priv_data_len,
                           NL80211_FEATURE_HT_IBSS |
                           NL80211_FEATURE_VIF_TXPOWER |
                           NL80211_FEATURE_MAC_ON_CREATE |
-                          NL80211_FEATURE_USERSPACE_MPM |
-                          NL80211_FEATURE_FULL_AP_CLIENT_STATE;
+                          NL80211_FEATURE_USERSPACE_MPM;
 
        if (!ops->hw_scan)
                wiphy->features |= NL80211_FEATURE_LOW_PRIORITY_SCAN |
index b890e225a8f1b98681c53c764fc5252e5f2d5c8d..b3b44a5dd375c3a4bc391e29de21ae702a62418d 100644 (file)
@@ -779,10 +779,8 @@ void mesh_plink_broken(struct sta_info *sta)
 static void mesh_path_node_reclaim(struct rcu_head *rp)
 {
        struct mpath_node *node = container_of(rp, struct mpath_node, rcu);
-       struct ieee80211_sub_if_data *sdata = node->mpath->sdata;
 
        del_timer_sync(&node->mpath->timer);
-       atomic_dec(&sdata->u.mesh.mpaths);
        kfree(node->mpath);
        kfree(node);
 }
@@ -790,8 +788,9 @@ static void mesh_path_node_reclaim(struct rcu_head *rp)
 /* needs to be called with the corresponding hashwlock taken */
 static void __mesh_path_del(struct mesh_table *tbl, struct mpath_node *node)
 {
-       struct mesh_path *mpath;
-       mpath = node->mpath;
+       struct mesh_path *mpath = node->mpath;
+       struct ieee80211_sub_if_data *sdata = node->mpath->sdata;
+
        spin_lock(&mpath->state_lock);
        mpath->flags |= MESH_PATH_RESOLVING;
        if (mpath->is_gate)
@@ -799,6 +798,7 @@ static void __mesh_path_del(struct mesh_table *tbl, struct mpath_node *node)
        hlist_del_rcu(&node->list);
        call_rcu(&node->rcu, mesh_path_node_reclaim);
        spin_unlock(&mpath->state_lock);
+       atomic_dec(&sdata->u.mesh.mpaths);
        atomic_dec(&tbl->entries);
 }
 
index 4aeca4b0c3cb426ba65b23d4a8ebc756e7a826a4..a413e52f7691418116d928f684a0fc27b308c2d6 100644 (file)
@@ -597,8 +597,8 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata,
                /* We need to ensure power level is at max for scanning. */
                ieee80211_hw_config(local, 0);
 
-               if ((req->channels[0]->flags &
-                    IEEE80211_CHAN_NO_IR) ||
+               if ((req->channels[0]->flags & (IEEE80211_CHAN_NO_IR |
+                                               IEEE80211_CHAN_RADAR)) ||
                    !req->n_ssids) {
                        next_delay = IEEE80211_PASSIVE_CHANNEL_TIME;
                } else {
@@ -645,7 +645,7 @@ ieee80211_scan_get_channel_time(struct ieee80211_channel *chan)
         * TODO: channel switching also consumes quite some time,
         * add that delay as well to get a better estimation
         */
-       if (chan->flags & IEEE80211_CHAN_NO_IR)
+       if (chan->flags & (IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_RADAR))
                return IEEE80211_PASSIVE_CHANNEL_TIME;
        return IEEE80211_PROBE_DELAY + IEEE80211_CHANNEL_TIME;
 }
@@ -777,7 +777,8 @@ static void ieee80211_scan_state_set_channel(struct ieee80211_local *local,
         *
         * In any case, it is not necessary for a passive scan.
         */
-       if (chan->flags & IEEE80211_CHAN_NO_IR || !scan_req->n_ssids) {
+       if ((chan->flags & (IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_RADAR)) ||
+           !scan_req->n_ssids) {
                *next_delay = IEEE80211_PASSIVE_CHANNEL_TIME;
                local->next_scan_state = SCAN_DECISION;
                return;
index b7de0da46acddc1eaaf041dedfbc9e2cf3697559..ecf0a0196f18040fb3fb2dc21b79273da92a470e 100644 (file)
@@ -572,7 +572,7 @@ static unsigned int llcp_sock_poll(struct file *file, struct socket *sock,
        if (sock_writeable(sk) && sk->sk_state == LLCP_CONNECTED)
                mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
        else
-               set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags);
+               sk_set_bit(SOCKWQ_ASYNC_NOSPACE, sk);
 
        pr_debug("mask 0x%x\n", mask);
 
index a7a80a6b77b0ab15ecdd5859ee732417ee4a4705..653d073bae4533acf80d63fec54ed604249d83f0 100644 (file)
@@ -58,7 +58,7 @@ void ovs_dp_notify_wq(struct work_struct *work)
                        struct hlist_node *n;
 
                        hlist_for_each_entry_safe(vport, n, &dp->ports[i], dp_hash_node) {
-                               if (vport->ops->type != OVS_VPORT_TYPE_NETDEV)
+                               if (vport->ops->type == OVS_VPORT_TYPE_INTERNAL)
                                        continue;
 
                                if (!(vport->dev->priv_flags & IFF_OVS_DATAPATH))
index efb736bb685545a0cb6a323d3eca87fc54eeb9f4..e41cd12d9b2d1aacc7a143138511ddf86f6597df 100644 (file)
@@ -117,7 +117,6 @@ static struct vport_ops ovs_geneve_vport_ops = {
        .destroy        = ovs_netdev_tunnel_destroy,
        .get_options    = geneve_get_options,
        .send           = dev_queue_xmit,
-       .owner          = THIS_MODULE,
 };
 
 static int __init ovs_geneve_tnl_init(void)
index c3257d78d3d28e6ed06e1be9c2e4a4f452c52886..7f8897f33a67fe6512436aff86c43098c15e3445 100644 (file)
@@ -89,7 +89,6 @@ static struct vport_ops ovs_gre_vport_ops = {
        .create         = gre_create,
        .send           = dev_queue_xmit,
        .destroy        = ovs_netdev_tunnel_destroy,
-       .owner          = THIS_MODULE,
 };
 
 static int __init ovs_gre_tnl_init(void)
index b327368a3848238013cf0f6f62445569d7e29251..6b0190b987ec62c043e04fea80b4122a81bd67b9 100644 (file)
@@ -180,9 +180,13 @@ void ovs_netdev_tunnel_destroy(struct vport *vport)
        if (vport->dev->priv_flags & IFF_OVS_DATAPATH)
                ovs_netdev_detach_dev(vport);
 
-       /* Early release so we can unregister the device */
+       /* We can be invoked by both explicit vport deletion and
+        * underlying netdev deregistration; delete the link only
+        * if it's not already shutting down.
+        */
+       if (vport->dev->reg_state == NETREG_REGISTERED)
+               rtnl_delete_link(vport->dev);
        dev_put(vport->dev);
-       rtnl_delete_link(vport->dev);
        vport->dev = NULL;
        rtnl_unlock();
 
index 0ac0fd004d7ed885c009560d966da5b29b47f242..31cbc8c5c7db821e69945957f346fc361a07f9a0 100644 (file)
@@ -71,7 +71,7 @@ static struct hlist_head *hash_bucket(const struct net *net, const char *name)
        return &dev_table[hash & (VPORT_HASH_BUCKETS - 1)];
 }
 
-int ovs_vport_ops_register(struct vport_ops *ops)
+int __ovs_vport_ops_register(struct vport_ops *ops)
 {
        int err = -EEXIST;
        struct vport_ops *o;
@@ -87,7 +87,7 @@ errout:
        ovs_unlock();
        return err;
 }
-EXPORT_SYMBOL_GPL(ovs_vport_ops_register);
+EXPORT_SYMBOL_GPL(__ovs_vport_ops_register);
 
 void ovs_vport_ops_unregister(struct vport_ops *ops)
 {
@@ -256,8 +256,8 @@ int ovs_vport_set_options(struct vport *vport, struct nlattr *options)
  *
  * @vport: vport to delete.
  *
- * Detaches @vport from its datapath and destroys it.  It is possible to fail
- * for reasons such as lack of memory.  ovs_mutex must be held.
+ * Detaches @vport from its datapath and destroys it.  ovs_mutex must
+ * be held.
  */
 void ovs_vport_del(struct vport *vport)
 {
index bdfd82a7c064948dc1dc83acbc85b6534c1bcf9b..8ea3a96980acff90b1237387be70967c25f1236e 100644 (file)
@@ -196,7 +196,13 @@ static inline const char *ovs_vport_name(struct vport *vport)
        return vport->dev->name;
 }
 
-int ovs_vport_ops_register(struct vport_ops *ops);
+int __ovs_vport_ops_register(struct vport_ops *ops);
+#define ovs_vport_ops_register(ops)            \
+       ({                                      \
+               (ops)->owner = THIS_MODULE;     \
+               __ovs_vport_ops_register(ops);  \
+       })
+
 void ovs_vport_ops_unregister(struct vport_ops *ops);
 
 static inline struct rtable *ovs_tunnel_route_lookup(struct net *net,
index 1cf928fb573e6769a4070327baa74adb300cde7e..992396aa635ce1174f6e62f19ae3f19a550668c6 100644 (file)
@@ -2329,8 +2329,8 @@ static void tpacket_destruct_skb(struct sk_buff *skb)
 static bool ll_header_truncated(const struct net_device *dev, int len)
 {
        /* net device doesn't like empty head */
-       if (unlikely(len <= dev->hard_header_len)) {
-               net_warn_ratelimited("%s: packet size is too short (%d <= %d)\n",
+       if (unlikely(len < dev->hard_header_len)) {
+               net_warn_ratelimited("%s: packet size is too short (%d < %d)\n",
                                     current->comm, len, dev->hard_header_len);
                return true;
        }
index d4564036a339a04d31c65ec6c90cdc9e6a051efc..e3b118cae81d5e859e0244df1bf323aaa1798b8e 100644 (file)
@@ -186,12 +186,6 @@ static struct rds_connection *__rds_conn_create(struct net *net,
                }
        }
 
-       if (trans == NULL) {
-               kmem_cache_free(rds_conn_slab, conn);
-               conn = ERR_PTR(-ENODEV);
-               goto out;
-       }
-
        conn->c_trans = trans;
 
        ret = trans->conn_alloc(conn, gfp);
index 827155c2ead10376cb633c45c2f43917f5f5cd12..c9cdb358ea885e3e356cc675b579f1313ed94ff9 100644 (file)
@@ -1013,11 +1013,13 @@ int rds_sendmsg(struct socket *sock, struct msghdr *msg, size_t payload_len)
                release_sock(sk);
        }
 
-       /* racing with another thread binding seems ok here */
+       lock_sock(sk);
        if (daddr == 0 || rs->rs_bound_addr == 0) {
+               release_sock(sk);
                ret = -ENOTCONN; /* XXX not a great errno */
                goto out;
        }
+       release_sock(sk);
 
        if (payload_len > rds_sk_sndbuf(rs)) {
                ret = -EMSGSIZE;
index e0547f521f20d79c688c773286d609066c990a1d..adc555e0323d70b90d786c630f5a04dfddd60b32 100644 (file)
@@ -723,8 +723,10 @@ process_further:
 
                        if ((call->state == RXRPC_CALL_CLIENT_AWAIT_REPLY ||
                             call->state == RXRPC_CALL_SERVER_AWAIT_ACK) &&
-                           hard > tx)
+                           hard > tx) {
+                               call->acks_hard = tx;
                                goto all_acked;
+                       }
 
                        smp_rmb();
                        rxrpc_rotate_tx_window(call, hard - 1);
index a40d3afe93b7f3ee657985753c320210815f62a9..14c4e12c47b0f87f1c560d752bbd897d3ae2f952 100644 (file)
@@ -531,7 +531,7 @@ static int rxrpc_send_data(struct rxrpc_sock *rx,
        timeo = sock_sndtimeo(sk, msg->msg_flags & MSG_DONTWAIT);
 
        /* this should be in poll */
-       clear_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags);
+       sk_clear_bit(SOCKWQ_ASYNC_NOSPACE, sk);
 
        if (sk->sk_err || (sk->sk_shutdown & SEND_SHUTDOWN))
                return -EPIPE;
index f43c8f33f09ef60e0f2a49ffd62f03624798c61b..7ec667dd4ce1d01deef3698af8c291da0722a657 100644 (file)
@@ -253,7 +253,8 @@ int qdisc_set_default(const char *name)
 }
 
 /* We know handle. Find qdisc among all qdisc's attached to device
-   (root qdisc, all its children, children of children etc.)
+ * (root qdisc, all its children, children of children etc.)
+ * Note: caller either uses rtnl or rcu_read_lock()
  */
 
 static struct Qdisc *qdisc_match_from_root(struct Qdisc *root, u32 handle)
@@ -264,7 +265,7 @@ static struct Qdisc *qdisc_match_from_root(struct Qdisc *root, u32 handle)
            root->handle == handle)
                return root;
 
-       list_for_each_entry(q, &root->list, list) {
+       list_for_each_entry_rcu(q, &root->list, list) {
                if (q->handle == handle)
                        return q;
        }
@@ -277,15 +278,18 @@ void qdisc_list_add(struct Qdisc *q)
                struct Qdisc *root = qdisc_dev(q)->qdisc;
 
                WARN_ON_ONCE(root == &noop_qdisc);
-               list_add_tail(&q->list, &root->list);
+               ASSERT_RTNL();
+               list_add_tail_rcu(&q->list, &root->list);
        }
 }
 EXPORT_SYMBOL(qdisc_list_add);
 
 void qdisc_list_del(struct Qdisc *q)
 {
-       if ((q->parent != TC_H_ROOT) && !(q->flags & TCQ_F_INGRESS))
-               list_del(&q->list);
+       if ((q->parent != TC_H_ROOT) && !(q->flags & TCQ_F_INGRESS)) {
+               ASSERT_RTNL();
+               list_del_rcu(&q->list);
+       }
 }
 EXPORT_SYMBOL(qdisc_list_del);
 
@@ -750,14 +754,18 @@ void qdisc_tree_decrease_qlen(struct Qdisc *sch, unsigned int n)
        if (n == 0)
                return;
        drops = max_t(int, n, 0);
+       rcu_read_lock();
        while ((parentid = sch->parent)) {
                if (TC_H_MAJ(parentid) == TC_H_MAJ(TC_H_INGRESS))
-                       return;
+                       break;
 
+               if (sch->flags & TCQ_F_NOPARENT)
+                       break;
+               /* TODO: perform the search on a per txq basis */
                sch = qdisc_lookup(qdisc_dev(sch), TC_H_MAJ(parentid));
                if (sch == NULL) {
-                       WARN_ON(parentid != TC_H_ROOT);
-                       return;
+                       WARN_ON_ONCE(parentid != TC_H_ROOT);
+                       break;
                }
                cops = sch->ops->cl_ops;
                if (cops->qlen_notify) {
@@ -768,6 +776,7 @@ void qdisc_tree_decrease_qlen(struct Qdisc *sch, unsigned int n)
                sch->q.qlen -= n;
                __qdisc_qstats_drop(sch, drops);
        }
+       rcu_read_unlock();
 }
 EXPORT_SYMBOL(qdisc_tree_decrease_qlen);
 
@@ -941,7 +950,7 @@ qdisc_create(struct net_device *dev, struct netdev_queue *dev_queue,
                }
                lockdep_set_class(qdisc_lock(sch), &qdisc_tx_lock);
                if (!netif_is_multiqueue(dev))
-                       sch->flags |= TCQ_F_ONETXQUEUE;
+                       sch->flags |= TCQ_F_ONETXQUEUE | TCQ_F_NOPARENT;
        }
 
        sch->handle = handle;
index cb5d4ad32946cf0c6f3391fe9742bceb7dd702e6..e82a1ad80aa521291fba4e704bb3828e88a009db 100644 (file)
@@ -737,7 +737,7 @@ static void attach_one_default_qdisc(struct net_device *dev,
                return;
        }
        if (!netif_is_multiqueue(dev))
-               qdisc->flags |= TCQ_F_ONETXQUEUE;
+               qdisc->flags |= TCQ_F_ONETXQUEUE | TCQ_F_NOPARENT;
        dev_queue->qdisc_sleeping = qdisc;
 }
 
index f3cbaecd283af4ce5a78ad90d135d008d2b542d7..3e82f047caaf40461c9f408bd0572a64147e1a8f 100644 (file)
@@ -63,7 +63,7 @@ static int mq_init(struct Qdisc *sch, struct nlattr *opt)
                if (qdisc == NULL)
                        goto err;
                priv->qdiscs[ntx] = qdisc;
-               qdisc->flags |= TCQ_F_ONETXQUEUE;
+               qdisc->flags |= TCQ_F_ONETXQUEUE | TCQ_F_NOPARENT;
        }
 
        sch->flags |= TCQ_F_MQROOT;
@@ -156,7 +156,7 @@ static int mq_graft(struct Qdisc *sch, unsigned long cl, struct Qdisc *new,
 
        *old = dev_graft_qdisc(dev_queue, new);
        if (new)
-               new->flags |= TCQ_F_ONETXQUEUE;
+               new->flags |= TCQ_F_ONETXQUEUE | TCQ_F_NOPARENT;
        if (dev->flags & IFF_UP)
                dev_activate(dev);
        return 0;
index 3811a745452cf402cd498ed47058fdf655d18cbd..ad70ecf57ce793d7b50b50e9220c24fa4ab30ab5 100644 (file)
@@ -132,7 +132,7 @@ static int mqprio_init(struct Qdisc *sch, struct nlattr *opt)
                        goto err;
                }
                priv->qdiscs[i] = qdisc;
-               qdisc->flags |= TCQ_F_ONETXQUEUE;
+               qdisc->flags |= TCQ_F_ONETXQUEUE | TCQ_F_NOPARENT;
        }
 
        /* If the mqprio options indicate that hardware should own
@@ -209,7 +209,7 @@ static int mqprio_graft(struct Qdisc *sch, unsigned long cl, struct Qdisc *new,
        *old = dev_graft_qdisc(dev_queue, new);
 
        if (new)
-               new->flags |= TCQ_F_ONETXQUEUE;
+               new->flags |= TCQ_F_ONETXQUEUE | TCQ_F_NOPARENT;
 
        if (dev->flags & IFF_UP)
                dev_activate(dev);
index e917d27328ea835419ba3e4c26eae1d7b7fade77..acb45b8c2a9d6ce902af7a2ffb9cbd53309a1bdc 100644 (file)
@@ -209,6 +209,7 @@ static int sctp_v6_xmit(struct sk_buff *skb, struct sctp_transport *transport)
        struct sock *sk = skb->sk;
        struct ipv6_pinfo *np = inet6_sk(sk);
        struct flowi6 *fl6 = &transport->fl.u.ip6;
+       int res;
 
        pr_debug("%s: skb:%p, len:%d, src:%pI6 dst:%pI6\n", __func__, skb,
                 skb->len, &fl6->saddr, &fl6->daddr);
@@ -220,7 +221,10 @@ static int sctp_v6_xmit(struct sk_buff *skb, struct sctp_transport *transport)
 
        SCTP_INC_STATS(sock_net(sk), SCTP_MIB_OUTSCTPPACKS);
 
-       return ip6_xmit(sk, skb, fl6, np->opt, np->tclass);
+       rcu_read_lock();
+       res = ip6_xmit(sk, skb, fl6, rcu_dereference(np->opt), np->tclass);
+       rcu_read_unlock();
+       return res;
 }
 
 /* Returns the dst cache entry for the given source and destination ip
@@ -262,7 +266,10 @@ static void sctp_v6_get_dst(struct sctp_transport *t, union sctp_addr *saddr,
                pr_debug("src=%pI6 - ", &fl6->saddr);
        }
 
-       final_p = fl6_update_dst(fl6, np->opt, &final);
+       rcu_read_lock();
+       final_p = fl6_update_dst(fl6, rcu_dereference(np->opt), &final);
+       rcu_read_unlock();
+
        dst = ip6_dst_lookup_flow(sk, fl6, final_p);
        if (!asoc || saddr)
                goto out;
@@ -321,7 +328,7 @@ static void sctp_v6_get_dst(struct sctp_transport *t, union sctp_addr *saddr,
        if (baddr) {
                fl6->saddr = baddr->v6.sin6_addr;
                fl6->fl6_sport = baddr->v6.sin6_port;
-               final_p = fl6_update_dst(fl6, np->opt, &final);
+               final_p = fl6_update_dst(fl6, rcu_dereference(np->opt), &final);
                dst = ip6_dst_lookup_flow(sk, fl6, final_p);
        }
 
index 897c01c029cab3d5805cc56b0964c70e06f4143a..03c8256063ec6355fcce034366aa5d005d75b5f7 100644 (file)
@@ -972,7 +972,7 @@ static int sctp_setsockopt_bindx(struct sock *sk,
                return -EFAULT;
 
        /* Alloc space for the address array in kernel memory.  */
-       kaddrs = kmalloc(addrs_size, GFP_KERNEL);
+       kaddrs = kmalloc(addrs_size, GFP_USER | __GFP_NOWARN);
        if (unlikely(!kaddrs))
                return -ENOMEM;
 
@@ -4928,7 +4928,7 @@ static int sctp_getsockopt_local_addrs(struct sock *sk, int len,
        to = optval + offsetof(struct sctp_getaddrs, addrs);
        space_left = len - offsetof(struct sctp_getaddrs, addrs);
 
-       addrs = kmalloc(space_left, GFP_KERNEL);
+       addrs = kmalloc(space_left, GFP_USER | __GFP_NOWARN);
        if (!addrs)
                return -ENOMEM;
 
@@ -6458,7 +6458,7 @@ unsigned int sctp_poll(struct file *file, struct socket *sock, poll_table *wait)
        if (sctp_writeable(sk)) {
                mask |= POLLOUT | POLLWRNORM;
        } else {
-               set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags);
+               sk_set_bit(SOCKWQ_ASYNC_NOSPACE, sk);
                /*
                 * Since the socket is not locked, the buffer
                 * might be made available after the writeable check and
@@ -6801,26 +6801,30 @@ no_packet:
 static void __sctp_write_space(struct sctp_association *asoc)
 {
        struct sock *sk = asoc->base.sk;
-       struct socket *sock = sk->sk_socket;
 
-       if ((sctp_wspace(asoc) > 0) && sock) {
-               if (waitqueue_active(&asoc->wait))
-                       wake_up_interruptible(&asoc->wait);
+       if (sctp_wspace(asoc) <= 0)
+               return;
+
+       if (waitqueue_active(&asoc->wait))
+               wake_up_interruptible(&asoc->wait);
 
-               if (sctp_writeable(sk)) {
-                       wait_queue_head_t *wq = sk_sleep(sk);
+       if (sctp_writeable(sk)) {
+               struct socket_wq *wq;
 
-                       if (wq && waitqueue_active(wq))
-                               wake_up_interruptible(wq);
+               rcu_read_lock();
+               wq = rcu_dereference(sk->sk_wq);
+               if (wq) {
+                       if (waitqueue_active(&wq->wait))
+                               wake_up_interruptible(&wq->wait);
 
                        /* Note that we try to include the Async I/O support
                         * here by modeling from the current TCP/UDP code.
                         * We have not tested with it yet.
                         */
                        if (!(sk->sk_shutdown & SEND_SHUTDOWN))
-                               sock_wake_async(sock,
-                                               SOCK_WAKE_SPACE, POLL_OUT);
+                               sock_wake_async(wq, SOCK_WAKE_SPACE, POLL_OUT);
                }
+               rcu_read_unlock();
        }
 }
 
@@ -7375,6 +7379,13 @@ struct proto sctp_prot = {
 
 #if IS_ENABLED(CONFIG_IPV6)
 
+#include <net/transp_v6.h>
+static void sctp_v6_destroy_sock(struct sock *sk)
+{
+       sctp_destroy_sock(sk);
+       inet6_destroy_sock(sk);
+}
+
 struct proto sctpv6_prot = {
        .name           = "SCTPv6",
        .owner          = THIS_MODULE,
@@ -7384,7 +7395,7 @@ struct proto sctpv6_prot = {
        .accept         = sctp_accept,
        .ioctl          = sctp_ioctl,
        .init           = sctp_init_sock,
-       .destroy        = sctp_destroy_sock,
+       .destroy        = sctp_v6_destroy_sock,
        .shutdown       = sctp_shutdown,
        .setsockopt     = sctp_setsockopt,
        .getsockopt     = sctp_getsockopt,
index dd2c247c99e30a7950323c85e1ea9cb604eac218..456fadb3d8193a2238bf30881506cd66dbe11957 100644 (file)
@@ -1056,27 +1056,20 @@ static int sock_fasync(int fd, struct file *filp, int on)
        return 0;
 }
 
-/* This function may be called only under socket lock or callback_lock or rcu_lock */
+/* This function may be called only under rcu_lock */
 
-int sock_wake_async(struct socket *sock, int how, int band)
+int sock_wake_async(struct socket_wq *wq, int how, int band)
 {
-       struct socket_wq *wq;
-
-       if (!sock)
-               return -1;
-       rcu_read_lock();
-       wq = rcu_dereference(sock->wq);
-       if (!wq || !wq->fasync_list) {
-               rcu_read_unlock();
+       if (!wq || !wq->fasync_list)
                return -1;
-       }
+
        switch (how) {
        case SOCK_WAKE_WAITD:
-               if (test_bit(SOCK_ASYNC_WAITDATA, &sock->flags))
+               if (test_bit(SOCKWQ_ASYNC_WAITDATA, &wq->flags))
                        break;
                goto call_kill;
        case SOCK_WAKE_SPACE:
-               if (!test_and_clear_bit(SOCK_ASYNC_NOSPACE, &sock->flags))
+               if (!test_and_clear_bit(SOCKWQ_ASYNC_NOSPACE, &wq->flags))
                        break;
                /* fall through */
        case SOCK_WAKE_IO:
@@ -1086,7 +1079,7 @@ call_kill:
        case SOCK_WAKE_URG:
                kill_fasync(&wq->fasync_list, SIGURG, band);
        }
-       rcu_read_unlock();
+
        return 0;
 }
 EXPORT_SYMBOL(sock_wake_async);
index f14f24ee998344f5c356ef49e3b3fc52d581a39c..73ad57a59989cb9234d06c1d399e02408e50c7d3 100644 (file)
@@ -250,11 +250,11 @@ void rpc_destroy_wait_queue(struct rpc_wait_queue *queue)
 }
 EXPORT_SYMBOL_GPL(rpc_destroy_wait_queue);
 
-static int rpc_wait_bit_killable(struct wait_bit_key *key)
+static int rpc_wait_bit_killable(struct wait_bit_key *key, int mode)
 {
-       if (fatal_signal_pending(current))
-               return -ERESTARTSYS;
        freezable_schedule_unsafe();
+       if (signal_pending_state(mode, current))
+               return -ERESTARTSYS;
        return 0;
 }
 
index bc5b7b5032ca54ce95b17de76bb22cbebc8a001a..cc9852897395c6f6db42653c773788446a9c5d3e 100644 (file)
@@ -1364,6 +1364,19 @@ bc_svc_process(struct svc_serv *serv, struct rpc_rqst *req,
        memcpy(&rqstp->rq_arg, &req->rq_rcv_buf, sizeof(rqstp->rq_arg));
        memcpy(&rqstp->rq_res, &req->rq_snd_buf, sizeof(rqstp->rq_res));
 
+       /* Adjust the argument buffer length */
+       rqstp->rq_arg.len = req->rq_private_buf.len;
+       if (rqstp->rq_arg.len <= rqstp->rq_arg.head[0].iov_len) {
+               rqstp->rq_arg.head[0].iov_len = rqstp->rq_arg.len;
+               rqstp->rq_arg.page_len = 0;
+       } else if (rqstp->rq_arg.len <= rqstp->rq_arg.head[0].iov_len +
+                       rqstp->rq_arg.page_len)
+               rqstp->rq_arg.page_len = rqstp->rq_arg.len -
+                       rqstp->rq_arg.head[0].iov_len;
+       else
+               rqstp->rq_arg.len = rqstp->rq_arg.head[0].iov_len +
+                       rqstp->rq_arg.page_len;
+
        /* reset result send buffer "put" position */
        resv->iov_len = 0;
 
index 1d1a7049891020264f5602d6237f12bac405c704..2ffaf6a794994ae20247fda57a6dd4c4bee64b0d 100644 (file)
@@ -398,7 +398,7 @@ static int xs_sendpages(struct socket *sock, struct sockaddr *addr, int addrlen,
        if (unlikely(!sock))
                return -ENOTSOCK;
 
-       clear_bit(SOCK_ASYNC_NOSPACE, &sock->flags);
+       clear_bit(SOCKWQ_ASYNC_NOSPACE, &sock->flags);
        if (base != 0) {
                addr = NULL;
                addrlen = 0;
@@ -442,7 +442,7 @@ static void xs_nospace_callback(struct rpc_task *task)
        struct sock_xprt *transport = container_of(task->tk_rqstp->rq_xprt, struct sock_xprt, xprt);
 
        transport->inet->sk_write_pending--;
-       clear_bit(SOCK_ASYNC_NOSPACE, &transport->sock->flags);
+       clear_bit(SOCKWQ_ASYNC_NOSPACE, &transport->sock->flags);
 }
 
 /**
@@ -467,7 +467,7 @@ static int xs_nospace(struct rpc_task *task)
 
        /* Don't race with disconnect */
        if (xprt_connected(xprt)) {
-               if (test_bit(SOCK_ASYNC_NOSPACE, &transport->sock->flags)) {
+               if (test_bit(SOCKWQ_ASYNC_NOSPACE, &transport->sock->flags)) {
                        /*
                         * Notify TCP that we're limited by the application
                         * window size
@@ -478,7 +478,7 @@ static int xs_nospace(struct rpc_task *task)
                        xprt_wait_for_buffer_space(task, xs_nospace_callback);
                }
        } else {
-               clear_bit(SOCK_ASYNC_NOSPACE, &transport->sock->flags);
+               clear_bit(SOCKWQ_ASYNC_NOSPACE, &transport->sock->flags);
                ret = -ENOTCONN;
        }
 
@@ -626,7 +626,7 @@ process_status:
        case -EPERM:
                /* When the server has died, an ICMP port unreachable message
                 * prompts ECONNREFUSED. */
-               clear_bit(SOCK_ASYNC_NOSPACE, &transport->sock->flags);
+               clear_bit(SOCKWQ_ASYNC_NOSPACE, &transport->sock->flags);
        }
 
        return status;
@@ -715,7 +715,7 @@ static int xs_tcp_send_request(struct rpc_task *task)
        case -EADDRINUSE:
        case -ENOBUFS:
        case -EPIPE:
-               clear_bit(SOCK_ASYNC_NOSPACE, &transport->sock->flags);
+               clear_bit(SOCKWQ_ASYNC_NOSPACE, &transport->sock->flags);
        }
 
        return status;
@@ -1618,7 +1618,7 @@ static void xs_write_space(struct sock *sk)
 
        if (unlikely(!(xprt = xprt_from_sock(sk))))
                return;
-       if (test_and_clear_bit(SOCK_ASYNC_NOSPACE, &sock->flags) == 0)
+       if (test_and_clear_bit(SOCKWQ_ASYNC_NOSPACE, &sock->flags) == 0)
                return;
 
        xprt_write_space(xprt);
index 9efbdbde2b0863542a08c91c136fadc9aa0cc6d8..91aea071ab27fee550e3c88ecc4097adac399d83 100644 (file)
@@ -191,6 +191,7 @@ void tipc_link_add_bc_peer(struct tipc_link *snd_l,
 
        snd_l->ackers++;
        rcv_l->acked = snd_l->snd_nxt - 1;
+       snd_l->state = LINK_ESTABLISHED;
        tipc_link_build_bc_init_msg(uc_l, xmitq);
 }
 
@@ -206,6 +207,7 @@ void tipc_link_remove_bc_peer(struct tipc_link *snd_l,
        rcv_l->state = LINK_RESET;
        if (!snd_l->ackers) {
                tipc_link_reset(snd_l);
+               snd_l->state = LINK_RESET;
                __skb_queue_purge(xmitq);
        }
 }
index 552dbaba9cf386a07e6c4f499fda27ca1f8a8f4a..b53246fb04128345304f2de5d3c895683ab0133b 100644 (file)
@@ -105,6 +105,7 @@ struct tipc_sock {
 static int tipc_backlog_rcv(struct sock *sk, struct sk_buff *skb);
 static void tipc_data_ready(struct sock *sk);
 static void tipc_write_space(struct sock *sk);
+static void tipc_sock_destruct(struct sock *sk);
 static int tipc_release(struct socket *sock);
 static int tipc_accept(struct socket *sock, struct socket *new_sock, int flags);
 static int tipc_wait_for_sndmsg(struct socket *sock, long *timeo_p);
@@ -381,6 +382,7 @@ static int tipc_sk_create(struct net *net, struct socket *sock,
        sk->sk_rcvbuf = sysctl_tipc_rmem[1];
        sk->sk_data_ready = tipc_data_ready;
        sk->sk_write_space = tipc_write_space;
+       sk->sk_destruct = tipc_sock_destruct;
        tsk->conn_timeout = CONN_TIMEOUT_DEFAULT;
        tsk->sent_unacked = 0;
        atomic_set(&tsk->dupl_rcvcnt, 0);
@@ -470,9 +472,6 @@ static int tipc_release(struct socket *sock)
                tipc_node_remove_conn(net, dnode, tsk->portid);
        }
 
-       /* Discard any remaining (connection-based) messages in receive queue */
-       __skb_queue_purge(&sk->sk_receive_queue);
-
        /* Reject any messages that accumulated in backlog queue */
        sock->state = SS_DISCONNECTING;
        release_sock(sk);
@@ -1515,6 +1514,11 @@ static void tipc_data_ready(struct sock *sk)
        rcu_read_unlock();
 }
 
+static void tipc_sock_destruct(struct sock *sk)
+{
+       __skb_queue_purge(&sk->sk_receive_queue);
+}
+
 /**
  * filter_connect - Handle all incoming messages for a connection-based socket
  * @tsk: TIPC socket
index ad2719ad4c1baf38cd8e31b244fe703382da002a..70c03271b798f429d8d6faa5142fb2654753d342 100644 (file)
@@ -158,8 +158,11 @@ static int tipc_udp_send_msg(struct net *net, struct sk_buff *skb,
        struct udp_media_addr *src = (struct udp_media_addr *)&b->addr.value;
        struct rtable *rt;
 
-       if (skb_headroom(skb) < UDP_MIN_HEADROOM)
-               pskb_expand_head(skb, UDP_MIN_HEADROOM, 0, GFP_ATOMIC);
+       if (skb_headroom(skb) < UDP_MIN_HEADROOM) {
+               err = pskb_expand_head(skb, UDP_MIN_HEADROOM, 0, GFP_ATOMIC);
+               if (err)
+                       goto tx_error;
+       }
 
        skb_set_inner_protocol(skb, htons(ETH_P_TIPC));
        ub = rcu_dereference_rtnl(b->media_ptr);
index 955ec152cb71eac8c91e06f1c922d1df20f6e1f0..45aebd966978bdc6abb886487d029957036bdda4 100644 (file)
@@ -326,6 +326,118 @@ found:
        return s;
 }
 
+/* Support code for asymmetrically connected dgram sockets
+ *
+ * If a datagram socket is connected to a socket not itself connected
+ * to the first socket (eg, /dev/log), clients may only enqueue more
+ * messages if the present receive queue of the server socket is not
+ * "too large". This means there's a second writeability condition
+ * poll and sendmsg need to test. The dgram recv code will do a wake
+ * up on the peer_wait wait queue of a socket upon reception of a
+ * datagram which needs to be propagated to sleeping would-be writers
+ * since these might not have sent anything so far. This can't be
+ * accomplished via poll_wait because the lifetime of the server
+ * socket might be less than that of its clients if these break their
+ * association with it or if the server socket is closed while clients
+ * are still connected to it and there's no way to inform "a polling
+ * implementation" that it should let go of a certain wait queue
+ *
+ * In order to propagate a wake up, a wait_queue_t of the client
+ * socket is enqueued on the peer_wait queue of the server socket
+ * whose wake function does a wake_up on the ordinary client socket
+ * wait queue. This connection is established whenever a write (or
+ * poll for write) hit the flow control condition and broken when the
+ * association to the server socket is dissolved or after a wake up
+ * was relayed.
+ */
+
+static int unix_dgram_peer_wake_relay(wait_queue_t *q, unsigned mode, int flags,
+                                     void *key)
+{
+       struct unix_sock *u;
+       wait_queue_head_t *u_sleep;
+
+       u = container_of(q, struct unix_sock, peer_wake);
+
+       __remove_wait_queue(&unix_sk(u->peer_wake.private)->peer_wait,
+                           q);
+       u->peer_wake.private = NULL;
+
+       /* relaying can only happen while the wq still exists */
+       u_sleep = sk_sleep(&u->sk);
+       if (u_sleep)
+               wake_up_interruptible_poll(u_sleep, key);
+
+       return 0;
+}
+
+static int unix_dgram_peer_wake_connect(struct sock *sk, struct sock *other)
+{
+       struct unix_sock *u, *u_other;
+       int rc;
+
+       u = unix_sk(sk);
+       u_other = unix_sk(other);
+       rc = 0;
+       spin_lock(&u_other->peer_wait.lock);
+
+       if (!u->peer_wake.private) {
+               u->peer_wake.private = other;
+               __add_wait_queue(&u_other->peer_wait, &u->peer_wake);
+
+               rc = 1;
+       }
+
+       spin_unlock(&u_other->peer_wait.lock);
+       return rc;
+}
+
+static void unix_dgram_peer_wake_disconnect(struct sock *sk,
+                                           struct sock *other)
+{
+       struct unix_sock *u, *u_other;
+
+       u = unix_sk(sk);
+       u_other = unix_sk(other);
+       spin_lock(&u_other->peer_wait.lock);
+
+       if (u->peer_wake.private == other) {
+               __remove_wait_queue(&u_other->peer_wait, &u->peer_wake);
+               u->peer_wake.private = NULL;
+       }
+
+       spin_unlock(&u_other->peer_wait.lock);
+}
+
+static void unix_dgram_peer_wake_disconnect_wakeup(struct sock *sk,
+                                                  struct sock *other)
+{
+       unix_dgram_peer_wake_disconnect(sk, other);
+       wake_up_interruptible_poll(sk_sleep(sk),
+                                  POLLOUT |
+                                  POLLWRNORM |
+                                  POLLWRBAND);
+}
+
+/* preconditions:
+ *     - unix_peer(sk) == other
+ *     - association is stable
+ */
+static int unix_dgram_peer_wake_me(struct sock *sk, struct sock *other)
+{
+       int connected;
+
+       connected = unix_dgram_peer_wake_connect(sk, other);
+
+       if (unix_recvq_full(other))
+               return 1;
+
+       if (connected)
+               unix_dgram_peer_wake_disconnect(sk, other);
+
+       return 0;
+}
+
 static int unix_writable(const struct sock *sk)
 {
        return sk->sk_state != TCP_LISTEN &&
@@ -431,6 +543,8 @@ static void unix_release_sock(struct sock *sk, int embrion)
                        skpair->sk_state_change(skpair);
                        sk_wake_async(skpair, SOCK_WAKE_WAITD, POLL_HUP);
                }
+
+               unix_dgram_peer_wake_disconnect(sk, skpair);
                sock_put(skpair); /* It may now die */
                unix_peer(sk) = NULL;
        }
@@ -666,6 +780,7 @@ static struct sock *unix_create1(struct net *net, struct socket *sock, int kern)
        INIT_LIST_HEAD(&u->link);
        mutex_init(&u->readlock); /* single task reading lock */
        init_waitqueue_head(&u->peer_wait);
+       init_waitqueue_func_entry(&u->peer_wake, unix_dgram_peer_wake_relay);
        unix_insert_socket(unix_sockets_unbound(sk), sk);
 out:
        if (sk == NULL)
@@ -1033,6 +1148,8 @@ restart:
        if (unix_peer(sk)) {
                struct sock *old_peer = unix_peer(sk);
                unix_peer(sk) = other;
+               unix_dgram_peer_wake_disconnect_wakeup(sk, old_peer);
+
                unix_state_double_unlock(sk, other);
 
                if (other != old_peer)
@@ -1434,6 +1551,14 @@ static int unix_scm_to_skb(struct scm_cookie *scm, struct sk_buff *skb, bool sen
        return err;
 }
 
+static bool unix_passcred_enabled(const struct socket *sock,
+                                 const struct sock *other)
+{
+       return test_bit(SOCK_PASSCRED, &sock->flags) ||
+              !other->sk_socket ||
+              test_bit(SOCK_PASSCRED, &other->sk_socket->flags);
+}
+
 /*
  * Some apps rely on write() giving SCM_CREDENTIALS
  * We include credentials if source or destination socket
@@ -1444,14 +1569,41 @@ static void maybe_add_creds(struct sk_buff *skb, const struct socket *sock,
 {
        if (UNIXCB(skb).pid)
                return;
-       if (test_bit(SOCK_PASSCRED, &sock->flags) ||
-           !other->sk_socket ||
-           test_bit(SOCK_PASSCRED, &other->sk_socket->flags)) {
+       if (unix_passcred_enabled(sock, other)) {
                UNIXCB(skb).pid  = get_pid(task_tgid(current));
                current_uid_gid(&UNIXCB(skb).uid, &UNIXCB(skb).gid);
        }
 }
 
+static int maybe_init_creds(struct scm_cookie *scm,
+                           struct socket *socket,
+                           const struct sock *other)
+{
+       int err;
+       struct msghdr msg = { .msg_controllen = 0 };
+
+       err = scm_send(socket, &msg, scm, false);
+       if (err)
+               return err;
+
+       if (unix_passcred_enabled(socket, other)) {
+               scm->pid = get_pid(task_tgid(current));
+               current_uid_gid(&scm->creds.uid, &scm->creds.gid);
+       }
+       return err;
+}
+
+static bool unix_skb_scm_eq(struct sk_buff *skb,
+                           struct scm_cookie *scm)
+{
+       const struct unix_skb_parms *u = &UNIXCB(skb);
+
+       return u->pid == scm->pid &&
+              uid_eq(u->uid, scm->creds.uid) &&
+              gid_eq(u->gid, scm->creds.gid) &&
+              unix_secdata_eq(scm, skb);
+}
+
 /*
  *     Send AF_UNIX data.
  */
@@ -1472,6 +1624,7 @@ static int unix_dgram_sendmsg(struct socket *sock, struct msghdr *msg,
        struct scm_cookie scm;
        int max_level;
        int data_len = 0;
+       int sk_locked;
 
        wait_for_unix_gc();
        err = scm_send(sock, msg, &scm, false);
@@ -1550,12 +1703,14 @@ restart:
                goto out_free;
        }
 
+       sk_locked = 0;
        unix_state_lock(other);
+restart_locked:
        err = -EPERM;
        if (!unix_may_send(sk, other))
                goto out_unlock;
 
-       if (sock_flag(other, SOCK_DEAD)) {
+       if (unlikely(sock_flag(other, SOCK_DEAD))) {
                /*
                 *      Check with 1003.1g - what should
                 *      datagram error
@@ -1563,10 +1718,14 @@ restart:
                unix_state_unlock(other);
                sock_put(other);
 
+               if (!sk_locked)
+                       unix_state_lock(sk);
+
                err = 0;
-               unix_state_lock(sk);
                if (unix_peer(sk) == other) {
                        unix_peer(sk) = NULL;
+                       unix_dgram_peer_wake_disconnect_wakeup(sk, other);
+
                        unix_state_unlock(sk);
 
                        unix_dgram_disconnected(sk, other);
@@ -1592,21 +1751,38 @@ restart:
                        goto out_unlock;
        }
 
-       if (unix_peer(other) != sk && unix_recvq_full(other)) {
-               if (!timeo) {
-                       err = -EAGAIN;
-                       goto out_unlock;
+       if (unlikely(unix_peer(other) != sk && unix_recvq_full(other))) {
+               if (timeo) {
+                       timeo = unix_wait_for_peer(other, timeo);
+
+                       err = sock_intr_errno(timeo);
+                       if (signal_pending(current))
+                               goto out_free;
+
+                       goto restart;
                }
 
-               timeo = unix_wait_for_peer(other, timeo);
+               if (!sk_locked) {
+                       unix_state_unlock(other);
+                       unix_state_double_lock(sk, other);
+               }
 
-               err = sock_intr_errno(timeo);
-               if (signal_pending(current))
-                       goto out_free;
+               if (unix_peer(sk) != other ||
+                   unix_dgram_peer_wake_me(sk, other)) {
+                       err = -EAGAIN;
+                       sk_locked = 1;
+                       goto out_unlock;
+               }
 
-               goto restart;
+               if (!sk_locked) {
+                       sk_locked = 1;
+                       goto restart_locked;
+               }
        }
 
+       if (unlikely(sk_locked))
+               unix_state_unlock(sk);
+
        if (sock_flag(other, SOCK_RCVTSTAMP))
                __net_timestamp(skb);
        maybe_add_creds(skb, sock, other);
@@ -1620,6 +1796,8 @@ restart:
        return len;
 
 out_unlock:
+       if (sk_locked)
+               unix_state_unlock(sk);
        unix_state_unlock(other);
 out_free:
        kfree_skb(skb);
@@ -1741,8 +1919,10 @@ out_err:
 static ssize_t unix_stream_sendpage(struct socket *socket, struct page *page,
                                    int offset, size_t size, int flags)
 {
-       int err = 0;
-       bool send_sigpipe = true;
+       int err;
+       bool send_sigpipe = false;
+       bool init_scm = true;
+       struct scm_cookie scm;
        struct sock *other, *sk = socket->sk;
        struct sk_buff *skb, *newskb = NULL, *tail = NULL;
 
@@ -1760,7 +1940,7 @@ alloc_skb:
                newskb = sock_alloc_send_pskb(sk, 0, 0, flags & MSG_DONTWAIT,
                                              &err, 0);
                if (!newskb)
-                       return err;
+                       goto err;
        }
 
        /* we must acquire readlock as we modify already present
@@ -1769,12 +1949,12 @@ alloc_skb:
        err = mutex_lock_interruptible(&unix_sk(other)->readlock);
        if (err) {
                err = flags & MSG_DONTWAIT ? -EAGAIN : -ERESTARTSYS;
-               send_sigpipe = false;
                goto err;
        }
 
        if (sk->sk_shutdown & SEND_SHUTDOWN) {
                err = -EPIPE;
+               send_sigpipe = true;
                goto err_unlock;
        }
 
@@ -1783,17 +1963,27 @@ alloc_skb:
        if (sock_flag(other, SOCK_DEAD) ||
            other->sk_shutdown & RCV_SHUTDOWN) {
                err = -EPIPE;
+               send_sigpipe = true;
                goto err_state_unlock;
        }
 
+       if (init_scm) {
+               err = maybe_init_creds(&scm, socket, other);
+               if (err)
+                       goto err_state_unlock;
+               init_scm = false;
+       }
+
        skb = skb_peek_tail(&other->sk_receive_queue);
        if (tail && tail == skb) {
                skb = newskb;
-       } else if (!skb) {
-               if (newskb)
+       } else if (!skb || !unix_skb_scm_eq(skb, &scm)) {
+               if (newskb) {
                        skb = newskb;
-               else
+               } else {
+                       tail = skb;
                        goto alloc_skb;
+               }
        } else if (newskb) {
                /* this is fast path, we don't necessarily need to
                 * call to kfree_skb even though with newskb == NULL
@@ -1814,6 +2004,9 @@ alloc_skb:
        atomic_add(size, &sk->sk_wmem_alloc);
 
        if (newskb) {
+               err = unix_scm_to_skb(&scm, skb, false);
+               if (err)
+                       goto err_state_unlock;
                spin_lock(&other->sk_receive_queue.lock);
                __skb_queue_tail(&other->sk_receive_queue, newskb);
                spin_unlock(&other->sk_receive_queue.lock);
@@ -1823,7 +2016,7 @@ alloc_skb:
        mutex_unlock(&unix_sk(other)->readlock);
 
        other->sk_data_ready(other);
-
+       scm_destroy(&scm);
        return size;
 
 err_state_unlock:
@@ -1834,6 +2027,8 @@ err:
        kfree_skb(newskb);
        if (send_sigpipe && !(flags & MSG_NOSIGNAL))
                send_sig(SIGPIPE, current, 0);
+       if (!init_scm)
+               scm_destroy(&scm);
        return err;
 }
 
@@ -1996,7 +2191,7 @@ static long unix_stream_data_wait(struct sock *sk, long timeo,
                    !timeo)
                        break;
 
-               set_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
+               sk_set_bit(SOCKWQ_ASYNC_WAITDATA, sk);
                unix_state_unlock(sk);
                timeo = freezable_schedule_timeout(timeo);
                unix_state_lock(sk);
@@ -2004,7 +2199,7 @@ static long unix_stream_data_wait(struct sock *sk, long timeo,
                if (sock_flag(sk, SOCK_DEAD))
                        break;
 
-               clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
+               sk_clear_bit(SOCKWQ_ASYNC_WAITDATA, sk);
        }
 
        finish_wait(sk_sleep(sk), &wait);
@@ -2137,10 +2332,7 @@ unlock:
 
                if (check_creds) {
                        /* Never glue messages from different writers */
-                       if ((UNIXCB(skb).pid  != scm.pid) ||
-                           !uid_eq(UNIXCB(skb).uid, scm.creds.uid) ||
-                           !gid_eq(UNIXCB(skb).gid, scm.creds.gid) ||
-                           !unix_secdata_eq(&scm, skb))
+                       if (!unix_skb_scm_eq(skb, &scm))
                                break;
                } else if (test_bit(SOCK_PASSCRED, &sock->flags)) {
                        /* Copy credentials */
@@ -2476,20 +2668,22 @@ static unsigned int unix_dgram_poll(struct file *file, struct socket *sock,
                return mask;
 
        writable = unix_writable(sk);
-       other = unix_peer_get(sk);
-       if (other) {
-               if (unix_peer(other) != sk) {
-                       sock_poll_wait(file, &unix_sk(other)->peer_wait, wait);
-                       if (unix_recvq_full(other))
-                               writable = 0;
-               }
-               sock_put(other);
+       if (writable) {
+               unix_state_lock(sk);
+
+               other = unix_peer(sk);
+               if (other && unix_peer(other) != sk &&
+                   unix_recvq_full(other) &&
+                   unix_dgram_peer_wake_me(sk, other))
+                       writable = 0;
+
+               unix_state_unlock(sk);
        }
 
        if (writable)
                mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
        else
-               set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags);
+               sk_set_bit(SOCKWQ_ASYNC_NOSPACE, sk);
 
        return mask;
 }
index 1a10d8ac81620faad519d4f95ca8552ac4a958c1..dacf71a43ad41f678e3a0574c84321bacd0ff30e 100755 (executable)
@@ -62,7 +62,7 @@ vmlinux_link()
                        -Wl,--start-group                                    \
                                 ${KBUILD_VMLINUX_MAIN}                      \
                        -Wl,--end-group                                      \
-                       -lutil ${1}
+                       -lutil -lrt ${1}
                rm -f linux
        fi
 }
index 927db9f35ad6f1bddeb51169e84c1bb526f85f21..696ccfa08d103cd29ae56ac38c117bbd7725da06 100644 (file)
@@ -845,6 +845,8 @@ static int encrypted_update(struct key *key, struct key_preparsed_payload *prep)
        size_t datalen = prep->datalen;
        int ret = 0;
 
+       if (test_bit(KEY_FLAG_NEGATIVE, &key->flags))
+               return -ENOKEY;
        if (datalen <= 0 || datalen > 32767 || !prep->data)
                return -EINVAL;
 
index 903dace648a1731b2afbb2dc8b40b8169a05aba2..16dec53184b663f745c010d11e78128ca995bf58 100644 (file)
@@ -1007,13 +1007,16 @@ static void trusted_rcu_free(struct rcu_head *rcu)
  */
 static int trusted_update(struct key *key, struct key_preparsed_payload *prep)
 {
-       struct trusted_key_payload *p = key->payload.data[0];
+       struct trusted_key_payload *p;
        struct trusted_key_payload *new_p;
        struct trusted_key_options *new_o;
        size_t datalen = prep->datalen;
        char *datablob;
        int ret = 0;
 
+       if (test_bit(KEY_FLAG_NEGATIVE, &key->flags))
+               return -ENOKEY;
+       p = key->payload.data[0];
        if (!p->migratable)
                return -EPERM;
        if (datalen <= 0 || datalen > 32767 || !prep->data)
index 28cb30f80256911cf9ee41631659b9e8f5a6b5dd..8705d79b2c6f289736fde21fd38e6013a4e4ae3c 100644 (file)
@@ -120,7 +120,10 @@ int user_update(struct key *key, struct key_preparsed_payload *prep)
 
        if (ret == 0) {
                /* attach the new data, displacing the old */
-               zap = key->payload.data[0];
+               if (!test_bit(KEY_FLAG_NEGATIVE, &key->flags))
+                       zap = key->payload.data[0];
+               else
+                       zap = NULL;
                rcu_assign_keypointer(key, upayload);
                key->expiry = 0;
        }
index 18643bf9894d5e393bdb51b0d7b0740f34960e75..456e1a9bcfde14e594789de0b1055c63f8dd549e 100644 (file)
@@ -638,7 +638,7 @@ void cond_compute_av(struct avtab *ctab, struct avtab_key *key,
 {
        struct avtab_node *node;
 
-       if (!ctab || !key || !avd || !xperms)
+       if (!ctab || !key || !avd)
                return;
 
        for (node = avtab_search_node(ctab, key); node;
@@ -657,7 +657,7 @@ void cond_compute_av(struct avtab *ctab, struct avtab_key *key,
                if ((u16)(AVTAB_AUDITALLOW|AVTAB_ENABLED) ==
                    (node->key.specified & (AVTAB_AUDITALLOW|AVTAB_ENABLED)))
                        avd->auditallow |= node->datum.u.data;
-               if ((node->key.specified & AVTAB_ENABLED) &&
+               if (xperms && (node->key.specified & AVTAB_ENABLED) &&
                                (node->key.specified & AVTAB_XPERMS))
                        services_compute_xperms_drivers(xperms, node);
        }
index 5d99436dfcaee5e70f3957a8f8b59be3d9e213d3..0cda05c72f504383a5031e06aa956e2544ef93c8 100644 (file)
@@ -12,9 +12,11 @@ MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
 MODULE_LICENSE("GPL v2");
 
 #define OUI_WEISS              0x001c6a
+#define OUI_LOUD               0x000ff2
 
 #define DICE_CATEGORY_ID       0x04
 #define WEISS_CATEGORY_ID      0x00
+#define LOUD_CATEGORY_ID       0x10
 
 static int dice_interface_check(struct fw_unit *unit)
 {
@@ -57,6 +59,8 @@ static int dice_interface_check(struct fw_unit *unit)
        }
        if (vendor == OUI_WEISS)
                category = WEISS_CATEGORY_ID;
+       else if (vendor == OUI_LOUD)
+               category = LOUD_CATEGORY_ID;
        else
                category = DICE_CATEGORY_ID;
        if (device->config_rom[3] != ((vendor << 8) | category) ||
index 8a7fbdcb4072f6a35f956ba51a5820f3d3054eaf..bff5c8b329d13b4be930a66585933a902e9cb977 100644 (file)
@@ -312,6 +312,10 @@ enum {
        (AZX_DCAPS_INTEL_PCH | AZX_DCAPS_SEPARATE_STREAM_TAG |\
         AZX_DCAPS_I915_POWERWELL)
 
+#define AZX_DCAPS_INTEL_BROXTON \
+       (AZX_DCAPS_INTEL_PCH | AZX_DCAPS_SEPARATE_STREAM_TAG |\
+        AZX_DCAPS_I915_POWERWELL)
+
 /* quirks for ATI SB / AMD Hudson */
 #define AZX_DCAPS_PRESET_ATI_SB \
        (AZX_DCAPS_NO_TCSEL | AZX_DCAPS_SYNC_WRITE | AZX_DCAPS_POSFIX_LPIB |\
@@ -351,6 +355,8 @@ enum {
                                        ((pci)->device == 0x0d0c) || \
                                        ((pci)->device == 0x160c))
 
+#define IS_BROXTON(pci)        ((pci)->device == 0x5a98)
+
 static char *driver_short_names[] = {
        [AZX_DRIVER_ICH] = "HDA Intel",
        [AZX_DRIVER_PCH] = "HDA Intel PCH",
@@ -502,15 +508,36 @@ static void azx_init_pci(struct azx *chip)
         }
 }
 
+/*
+ * In BXT-P A0, HD-Audio DMA requests is later than expected,
+ * and makes an audio stream sensitive to system latencies when
+ * 24/32 bits are playing.
+ * Adjusting threshold of DMA fifo to force the DMA request
+ * sooner to improve latency tolerance at the expense of power.
+ */
+static void bxt_reduce_dma_latency(struct azx *chip)
+{
+       u32 val;
+
+       val = azx_readl(chip, SKL_EM4L);
+       val &= (0x3 << 20);
+       azx_writel(chip, SKL_EM4L, val);
+}
+
 static void hda_intel_init_chip(struct azx *chip, bool full_reset)
 {
        struct hdac_bus *bus = azx_bus(chip);
+       struct pci_dev *pci = chip->pci;
 
        if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL)
                snd_hdac_set_codec_wakeup(bus, true);
        azx_init_chip(chip, full_reset);
        if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL)
                snd_hdac_set_codec_wakeup(bus, false);
+
+       /* reduce dma latency to avoid noise */
+       if (IS_BROXTON(pci))
+               bxt_reduce_dma_latency(chip);
 }
 
 /* calculate runtime delay from LPIB */
@@ -2124,6 +2151,9 @@ static const struct pci_device_id azx_ids[] = {
        /* Sunrise Point-LP */
        { PCI_DEVICE(0x8086, 0x9d70),
          .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_SKYLAKE },
+       /* Broxton-P(Apollolake) */
+       { PCI_DEVICE(0x8086, 0x5a98),
+         .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_BROXTON },
        /* Haswell */
        { PCI_DEVICE(0x8086, 0x0a0c),
          .driver_data = AZX_DRIVER_HDMI | AZX_DCAPS_INTEL_HASWELL },
index f8a12ca477f1ab775a101c8bb41876a11707477e..4ef2259f88cae3b1cf328880447dbf528ad42a95 100644 (file)
@@ -778,7 +778,8 @@ static const struct hda_pintbl alienware_pincfgs[] = {
 };
 
 static const struct snd_pci_quirk ca0132_quirks[] = {
-       SND_PCI_QUIRK(0x1028, 0x0685, "Alienware 15", QUIRK_ALIENWARE),
+       SND_PCI_QUIRK(0x1028, 0x0685, "Alienware 15 2015", QUIRK_ALIENWARE),
+       SND_PCI_QUIRK(0x1028, 0x0688, "Alienware 17 2015", QUIRK_ALIENWARE),
        {}
 };
 
index c8b8ef5246a6f94c99b281c837e220e118dbf8a9..ef198903c0c3e6bca1685c3cc6a53420e77e1333 100644 (file)
@@ -955,6 +955,7 @@ static int patch_conexant_auto(struct hda_codec *codec)
  */
 
 static const struct hda_device_id snd_hda_id_conexant[] = {
+       HDA_CODEC_ENTRY(0x14f12008, "CX8200", patch_conexant_auto),
        HDA_CODEC_ENTRY(0x14f15045, "CX20549 (Venice)", patch_conexant_auto),
        HDA_CODEC_ENTRY(0x14f15047, "CX20551 (Waikiki)", patch_conexant_auto),
        HDA_CODEC_ENTRY(0x14f15051, "CX20561 (Hermosa)", patch_conexant_auto),
@@ -972,9 +973,9 @@ static const struct hda_device_id snd_hda_id_conexant[] = {
        HDA_CODEC_ENTRY(0x14f150ac, "CX20652", patch_conexant_auto),
        HDA_CODEC_ENTRY(0x14f150b8, "CX20664", patch_conexant_auto),
        HDA_CODEC_ENTRY(0x14f150b9, "CX20665", patch_conexant_auto),
-       HDA_CODEC_ENTRY(0x14f150f1, "CX20721", patch_conexant_auto),
+       HDA_CODEC_ENTRY(0x14f150f1, "CX21722", patch_conexant_auto),
        HDA_CODEC_ENTRY(0x14f150f2, "CX20722", patch_conexant_auto),
-       HDA_CODEC_ENTRY(0x14f150f3, "CX20723", patch_conexant_auto),
+       HDA_CODEC_ENTRY(0x14f150f3, "CX21724", patch_conexant_auto),
        HDA_CODEC_ENTRY(0x14f150f4, "CX20724", patch_conexant_auto),
        HDA_CODEC_ENTRY(0x14f1510f, "CX20751/2", patch_conexant_auto),
        HDA_CODEC_ENTRY(0x14f15110, "CX20751/2", patch_conexant_auto),
index 60cd9e70090981076fcaec5bcb55cfd92ececdc9..4b6fb668c91cd1ba2e4964d49c0d610cab43c458 100644 (file)
@@ -2352,6 +2352,12 @@ static void intel_pin_eld_notify(void *audio_ptr, int port)
        struct hda_codec *codec = audio_ptr;
        int pin_nid = port + 0x04;
 
+       /* skip notification during system suspend (but not in runtime PM);
+        * the state will be updated at resume
+        */
+       if (snd_power_get_state(codec->card) != SNDRV_CTL_POWER_D0)
+               return;
+
        check_presence_and_report(codec, pin_nid);
 }
 
@@ -2378,7 +2384,8 @@ static int patch_generic_hdmi(struct hda_codec *codec)
         * can cover the codec power request, and so need not set this flag.
         * For previous platforms, there is no such power well feature.
         */
-       if (is_valleyview_plus(codec) || is_skylake(codec))
+       if (is_valleyview_plus(codec) || is_skylake(codec) ||
+                       is_broxton(codec))
                codec->core.link_power_control = 1;
 
        if (is_haswell_plus(codec) || is_valleyview_plus(codec)) {
index 2f7b065f9ac43e88ee19b6845506c066485c679a..8dd2ac13b3af19ce79fdf5e5e35943ff1f5dfef8 100644 (file)
@@ -1759,6 +1759,7 @@ enum {
        ALC882_FIXUP_NO_PRIMARY_HP,
        ALC887_FIXUP_ASUS_BASS,
        ALC887_FIXUP_BASS_CHMAP,
+       ALC882_FIXUP_DISABLE_AAMIX,
 };
 
 static void alc889_fixup_coef(struct hda_codec *codec,
@@ -1920,6 +1921,8 @@ static void alc882_fixup_no_primary_hp(struct hda_codec *codec,
 
 static void alc_fixup_bass_chmap(struct hda_codec *codec,
                                 const struct hda_fixup *fix, int action);
+static void alc_fixup_disable_aamix(struct hda_codec *codec,
+                                   const struct hda_fixup *fix, int action);
 
 static const struct hda_fixup alc882_fixups[] = {
        [ALC882_FIXUP_ABIT_AW9D_MAX] = {
@@ -2151,6 +2154,10 @@ static const struct hda_fixup alc882_fixups[] = {
                .type = HDA_FIXUP_FUNC,
                .v.func = alc_fixup_bass_chmap,
        },
+       [ALC882_FIXUP_DISABLE_AAMIX] = {
+               .type = HDA_FIXUP_FUNC,
+               .v.func = alc_fixup_disable_aamix,
+       },
 };
 
 static const struct snd_pci_quirk alc882_fixup_tbl[] = {
@@ -2218,6 +2225,7 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = {
        SND_PCI_QUIRK(0x1462, 0x7350, "MSI-7350", ALC889_FIXUP_CD),
        SND_PCI_QUIRK_VENDOR(0x1462, "MSI", ALC882_FIXUP_GPIO3),
        SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte EP45-DS3/Z87X-UD3H", ALC889_FIXUP_FRONT_HP_NO_PRESENCE),
+       SND_PCI_QUIRK(0x1458, 0xa182, "Gigabyte Z170X-UD3", ALC882_FIXUP_DISABLE_AAMIX),
        SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", ALC882_FIXUP_ABIT_AW9D_MAX),
        SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC882_FIXUP_EAPD),
        SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_FIXUP_EAPD),
@@ -4196,6 +4204,18 @@ static void alc_fixup_tpt440_dock(struct hda_codec *codec,
        }
 }
 
+/* additional fixup for Thinkpad T440s noise problem */
+static void alc_fixup_tpt440(struct hda_codec *codec,
+                                 const struct hda_fixup *fix, int action)
+{
+       struct alc_spec *spec = codec->spec;
+
+       if (action == HDA_FIXUP_ACT_PRE_PROBE) {
+               spec->shutup = alc_no_shutup; /* reduce click noise */
+               spec->gen.mixer_nid = 0; /* reduce background noise */
+       }
+}
+
 static void alc_shutup_dell_xps13(struct hda_codec *codec)
 {
        struct alc_spec *spec = codec->spec;
@@ -4570,6 +4590,7 @@ enum {
        ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC,
        ALC293_FIXUP_DELL1_MIC_NO_PRESENCE,
        ALC292_FIXUP_TPT440_DOCK,
+       ALC292_FIXUP_TPT440,
        ALC283_FIXUP_BXBT2807_MIC,
        ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED,
        ALC282_FIXUP_ASPIRE_V5_PINS,
@@ -4587,6 +4608,8 @@ enum {
        ALC292_FIXUP_DISABLE_AAMIX,
        ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
        ALC275_FIXUP_DELL_XPS,
+       ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE,
+       ALC293_FIXUP_LENOVO_SPK_NOISE,
 };
 
 static const struct hda_fixup alc269_fixups[] = {
@@ -5041,6 +5064,12 @@ static const struct hda_fixup alc269_fixups[] = {
                .chained = true,
                .chain_id = ALC269_FIXUP_LIMIT_INT_MIC_BOOST
        },
+       [ALC292_FIXUP_TPT440] = {
+               .type = HDA_FIXUP_FUNC,
+               .v.func = alc_fixup_tpt440,
+               .chained = true,
+               .chain_id = ALC292_FIXUP_TPT440_DOCK,
+       },
        [ALC283_FIXUP_BXBT2807_MIC] = {
                .type = HDA_FIXUP_PINS,
                .v.pins = (const struct hda_pintbl[]) {
@@ -5167,6 +5196,23 @@ static const struct hda_fixup alc269_fixups[] = {
                        {}
                }
        },
+       [ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE] = {
+               .type = HDA_FIXUP_VERBS,
+               .v.verbs = (const struct hda_verb[]) {
+                       /* Disable pass-through path for FRONT 14h */
+                       {0x20, AC_VERB_SET_COEF_INDEX, 0x36},
+                       {0x20, AC_VERB_SET_PROC_COEF, 0x1737},
+                       {}
+               },
+               .chained = true,
+               .chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE
+       },
+       [ALC293_FIXUP_LENOVO_SPK_NOISE] = {
+               .type = HDA_FIXUP_FUNC,
+               .v.func = alc_fixup_disable_aamix,
+               .chained = true,
+               .chain_id = ALC269_FIXUP_THINKPAD_ACPI
+       },
 };
 
 static const struct snd_pci_quirk alc269_fixup_tbl[] = {
@@ -5180,8 +5226,10 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x1025, 0x0742, "Acer AO756", ALC271_FIXUP_HP_GATE_MIC_JACK),
        SND_PCI_QUIRK(0x1025, 0x0775, "Acer Aspire E1-572", ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572),
        SND_PCI_QUIRK(0x1025, 0x079b, "Acer Aspire V5-573G", ALC282_FIXUP_ASPIRE_V5_PINS),
+       SND_PCI_QUIRK(0x1025, 0x106d, "Acer Cloudbook 14", ALC283_FIXUP_CHROME_BOOK),
        SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
        SND_PCI_QUIRK(0x1028, 0x054b, "Dell XPS one 2710", ALC275_FIXUP_DELL_XPS),
+       SND_PCI_QUIRK(0x1028, 0x05bd, "Dell Latitude E6440", ALC292_FIXUP_DELL_E7X),
        SND_PCI_QUIRK(0x1028, 0x05ca, "Dell Latitude E7240", ALC292_FIXUP_DELL_E7X),
        SND_PCI_QUIRK(0x1028, 0x05cb, "Dell Latitude E7440", ALC292_FIXUP_DELL_E7X),
        SND_PCI_QUIRK(0x1028, 0x05da, "Dell Vostro 5460", ALC290_FIXUP_SUBWOOFER),
@@ -5204,6 +5252,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x1028, 0x06de, "Dell", ALC292_FIXUP_DISABLE_AAMIX),
        SND_PCI_QUIRK(0x1028, 0x06df, "Dell", ALC292_FIXUP_DISABLE_AAMIX),
        SND_PCI_QUIRK(0x1028, 0x06e0, "Dell", ALC292_FIXUP_DISABLE_AAMIX),
+       SND_PCI_QUIRK(0x1028, 0x0704, "Dell XPS 13", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE),
        SND_PCI_QUIRK(0x1028, 0x164a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1028, 0x164b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2),
@@ -5302,7 +5351,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x17aa, 0x21fb, "Thinkpad T430s", ALC269_FIXUP_LENOVO_DOCK),
        SND_PCI_QUIRK(0x17aa, 0x2203, "Thinkpad X230 Tablet", ALC269_FIXUP_LENOVO_DOCK),
        SND_PCI_QUIRK(0x17aa, 0x2208, "Thinkpad T431s", ALC269_FIXUP_LENOVO_DOCK),
-       SND_PCI_QUIRK(0x17aa, 0x220c, "Thinkpad T440s", ALC292_FIXUP_TPT440_DOCK),
+       SND_PCI_QUIRK(0x17aa, 0x220c, "Thinkpad T440s", ALC292_FIXUP_TPT440),
        SND_PCI_QUIRK(0x17aa, 0x220e, "Thinkpad T440p", ALC292_FIXUP_TPT440_DOCK),
        SND_PCI_QUIRK(0x17aa, 0x2210, "Thinkpad T540p", ALC292_FIXUP_TPT440_DOCK),
        SND_PCI_QUIRK(0x17aa, 0x2211, "Thinkpad W541", ALC292_FIXUP_TPT440_DOCK),
@@ -5311,6 +5360,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x17aa, 0x2215, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
        SND_PCI_QUIRK(0x17aa, 0x2223, "ThinkPad T550", ALC292_FIXUP_TPT440_DOCK),
        SND_PCI_QUIRK(0x17aa, 0x2226, "ThinkPad X250", ALC292_FIXUP_TPT440_DOCK),
+       SND_PCI_QUIRK(0x17aa, 0x2233, "Thinkpad", ALC293_FIXUP_LENOVO_SPK_NOISE),
        SND_PCI_QUIRK(0x17aa, 0x3977, "IdeaPad S210", ALC283_FIXUP_INT_MIC),
        SND_PCI_QUIRK(0x17aa, 0x3978, "IdeaPad Y410P", ALC269_FIXUP_NO_SHUTUP),
        SND_PCI_QUIRK(0x17aa, 0x5013, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
@@ -5320,6 +5370,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x17aa, 0x5034, "Thinkpad T450", ALC292_FIXUP_TPT440_DOCK),
        SND_PCI_QUIRK(0x17aa, 0x5036, "Thinkpad T450s", ALC292_FIXUP_TPT440_DOCK),
        SND_PCI_QUIRK(0x17aa, 0x503c, "Thinkpad L450", ALC292_FIXUP_TPT440_DOCK),
+       SND_PCI_QUIRK(0x17aa, 0x504b, "Thinkpad", ALC293_FIXUP_LENOVO_SPK_NOISE),
        SND_PCI_QUIRK(0x17aa, 0x5109, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
        SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_PCM_44K),
        SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
@@ -5400,6 +5451,7 @@ static const struct hda_model_fixup alc269_fixup_models[] = {
        {.id = ALC283_FIXUP_CHROME_BOOK, .name = "alc283-dac-wcaps"},
        {.id = ALC283_FIXUP_SENSE_COMBO_JACK, .name = "alc283-sense-combo"},
        {.id = ALC292_FIXUP_TPT440_DOCK, .name = "tpt440-dock"},
+       {.id = ALC292_FIXUP_TPT440, .name = "tpt440"},
        {}
 };
 
@@ -6386,6 +6438,7 @@ static const struct hda_fixup alc662_fixups[] = {
 static const struct snd_pci_quirk alc662_fixup_tbl[] = {
        SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_FIXUP_ASUS_MODE2),
        SND_PCI_QUIRK(0x1025, 0x022f, "Acer Aspire One", ALC662_FIXUP_INV_DMIC),
+       SND_PCI_QUIRK(0x1025, 0x0241, "Packard Bell DOTS", ALC662_FIXUP_INV_DMIC),
        SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE),
        SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE),
        SND_PCI_QUIRK(0x1025, 0x0349, "eMachines eM250", ALC662_FIXUP_INV_DMIC),
index 826122d8aceec4a931e64e99875dcd8cef661736..2c7c5eb8b1e9514779b78bc278412803862062e9 100644 (file)
@@ -3110,6 +3110,29 @@ static void stac92hd71bxx_fixup_hp_hdx(struct hda_codec *codec,
        spec->gpio_led = 0x08;
 }
 
+static bool is_hp_output(struct hda_codec *codec, hda_nid_t pin)
+{
+       unsigned int pin_cfg = snd_hda_codec_get_pincfg(codec, pin);
+
+       /* count line-out, too, as BIOS sets often so */
+       return get_defcfg_connect(pin_cfg) != AC_JACK_PORT_NONE &&
+               (get_defcfg_device(pin_cfg) == AC_JACK_LINE_OUT ||
+                get_defcfg_device(pin_cfg) == AC_JACK_HP_OUT);
+}
+
+static void fixup_hp_headphone(struct hda_codec *codec, hda_nid_t pin)
+{
+       unsigned int pin_cfg = snd_hda_codec_get_pincfg(codec, pin);
+
+       /* It was changed in the BIOS to just satisfy MS DTM.
+        * Lets turn it back into slaved HP
+        */
+       pin_cfg = (pin_cfg & (~AC_DEFCFG_DEVICE)) |
+               (AC_JACK_HP_OUT << AC_DEFCFG_DEVICE_SHIFT);
+       pin_cfg = (pin_cfg & (~(AC_DEFCFG_DEF_ASSOC | AC_DEFCFG_SEQUENCE))) |
+               0x1f;
+       snd_hda_codec_set_pincfg(codec, pin, pin_cfg);
+}
 
 static void stac92hd71bxx_fixup_hp(struct hda_codec *codec,
                                   const struct hda_fixup *fix, int action)
@@ -3119,22 +3142,12 @@ static void stac92hd71bxx_fixup_hp(struct hda_codec *codec,
        if (action != HDA_FIXUP_ACT_PRE_PROBE)
                return;
 
-       if (hp_blike_system(codec->core.subsystem_id)) {
-               unsigned int pin_cfg = snd_hda_codec_get_pincfg(codec, 0x0f);
-               if (get_defcfg_device(pin_cfg) == AC_JACK_LINE_OUT ||
-                       get_defcfg_device(pin_cfg) == AC_JACK_SPEAKER  ||
-                       get_defcfg_device(pin_cfg) == AC_JACK_HP_OUT) {
-                       /* It was changed in the BIOS to just satisfy MS DTM.
-                        * Lets turn it back into slaved HP
-                        */
-                       pin_cfg = (pin_cfg & (~AC_DEFCFG_DEVICE))
-                                       | (AC_JACK_HP_OUT <<
-                                               AC_DEFCFG_DEVICE_SHIFT);
-                       pin_cfg = (pin_cfg & (~(AC_DEFCFG_DEF_ASSOC
-                                                       | AC_DEFCFG_SEQUENCE)))
-                                                               | 0x1f;
-                       snd_hda_codec_set_pincfg(codec, 0x0f, pin_cfg);
-               }
+       /* when both output A and F are assigned, these are supposedly
+        * dock and built-in headphones; fix both pin configs
+        */
+       if (is_hp_output(codec, 0x0a) && is_hp_output(codec, 0x0f)) {
+               fixup_hp_headphone(codec, 0x0a);
+               fixup_hp_headphone(codec, 0x0f);
        }
 
        if (find_mute_led_cfg(codec, 1))
index 714df906249eab42c54816fed4630cc4890d7603..41c31db650390c651617530ce08b44e11a889e2f 100644 (file)
@@ -741,10 +741,11 @@ snd_rme96_playback_setrate(struct rme96 *rme96,
        {
                /* change to/from double-speed: reset the DAC (if available) */
                snd_rme96_reset_dac(rme96);
+               return 1; /* need to restore volume */
        } else {
                writel(rme96->wcreg, rme96->iobase + RME96_IO_CONTROL_REGISTER);
+               return 0;
        }
-       return 0;
 }
 
 static int
@@ -980,6 +981,7 @@ snd_rme96_playback_hw_params(struct snd_pcm_substream *substream,
        struct rme96 *rme96 = snd_pcm_substream_chip(substream);
        struct snd_pcm_runtime *runtime = substream->runtime;
        int err, rate, dummy;
+       bool apply_dac_volume = false;
 
        runtime->dma_area = (void __force *)(rme96->iobase +
                                             RME96_IO_PLAY_BUFFER);
@@ -993,24 +995,26 @@ snd_rme96_playback_hw_params(struct snd_pcm_substream *substream,
        {
                 /* slave clock */
                 if ((int)params_rate(params) != rate) {
-                       spin_unlock_irq(&rme96->lock);
-                       return -EIO;                    
-                }
-       } else if ((err = snd_rme96_playback_setrate(rme96, params_rate(params))) < 0) {
-               spin_unlock_irq(&rme96->lock);
-               return err;
-       }
-       if ((err = snd_rme96_playback_setformat(rme96, params_format(params))) < 0) {
-               spin_unlock_irq(&rme96->lock);
-               return err;
+                       err = -EIO;
+                       goto error;
+               }
+       } else {
+               err = snd_rme96_playback_setrate(rme96, params_rate(params));
+               if (err < 0)
+                       goto error;
+               apply_dac_volume = err > 0; /* need to restore volume later? */
        }
+
+       err = snd_rme96_playback_setformat(rme96, params_format(params));
+       if (err < 0)
+               goto error;
        snd_rme96_setframelog(rme96, params_channels(params), 1);
        if (rme96->capture_periodsize != 0) {
                if (params_period_size(params) << rme96->playback_frlog !=
                    rme96->capture_periodsize)
                {
-                       spin_unlock_irq(&rme96->lock);
-                       return -EBUSY;
+                       err = -EBUSY;
+                       goto error;
                }
        }
        rme96->playback_periodsize =
@@ -1021,9 +1025,16 @@ snd_rme96_playback_hw_params(struct snd_pcm_substream *substream,
                rme96->wcreg &= ~(RME96_WCR_PRO | RME96_WCR_DOLBY | RME96_WCR_EMP);
                writel(rme96->wcreg |= rme96->wcreg_spdif_stream, rme96->iobase + RME96_IO_CONTROL_REGISTER);
        }
+
+       err = 0;
+ error:
        spin_unlock_irq(&rme96->lock);
-               
-       return 0;
+       if (apply_dac_volume) {
+               usleep_range(3000, 10000);
+               snd_rme96_apply_dac_volume(rme96);
+       }
+
+       return err;
 }
 
 static int
index 9929efc6b9aaa4257a155e844b7feb2f91ea80f9..b3ea24d64c5009cf4cc77e1877c894e3f21f4ee7 100644 (file)
@@ -1023,24 +1023,18 @@ void arizona_init_dvfs(struct arizona_priv *priv)
 }
 EXPORT_SYMBOL_GPL(arizona_init_dvfs);
 
-static unsigned int arizona_sysclk_48k_rates[] = {
+static unsigned int arizona_opclk_ref_48k_rates[] = {
        6144000,
        12288000,
        24576000,
        49152000,
-       73728000,
-       98304000,
-       147456000,
 };
 
-static unsigned int arizona_sysclk_44k1_rates[] = {
+static unsigned int arizona_opclk_ref_44k1_rates[] = {
        5644800,
        11289600,
        22579200,
        45158400,
-       67737600,
-       90316800,
-       135475200,
 };
 
 static int arizona_set_opclk(struct snd_soc_codec *codec, unsigned int clk,
@@ -1065,11 +1059,11 @@ static int arizona_set_opclk(struct snd_soc_codec *codec, unsigned int clk,
        }
 
        if (refclk % 8000)
-               rates = arizona_sysclk_44k1_rates;
+               rates = arizona_opclk_ref_44k1_rates;
        else
-               rates = arizona_sysclk_48k_rates;
+               rates = arizona_opclk_ref_48k_rates;
 
-       for (ref = 0; ref < ARRAY_SIZE(arizona_sysclk_48k_rates) &&
+       for (ref = 0; ref < ARRAY_SIZE(arizona_opclk_ref_48k_rates) &&
                     rates[ref] <= refclk; ref++) {
                div = 1;
                while (rates[ref] / div >= freq && div < 32) {
index 969e337dc17c131413e43f666edd5b299fc11544..84f5eb07a91b1d27274f595cf595d97f36663484 100644 (file)
@@ -205,18 +205,18 @@ static const struct snd_kcontrol_new es8328_right_line_controls =
 
 /* Left Mixer */
 static const struct snd_kcontrol_new es8328_left_mixer_controls[] = {
-       SOC_DAPM_SINGLE("Playback Switch", ES8328_DACCONTROL17, 8, 1, 0),
-       SOC_DAPM_SINGLE("Left Bypass Switch", ES8328_DACCONTROL17, 7, 1, 0),
-       SOC_DAPM_SINGLE("Right Playback Switch", ES8328_DACCONTROL18, 8, 1, 0),
-       SOC_DAPM_SINGLE("Right Bypass Switch", ES8328_DACCONTROL18, 7, 1, 0),
+       SOC_DAPM_SINGLE("Playback Switch", ES8328_DACCONTROL17, 7, 1, 0),
+       SOC_DAPM_SINGLE("Left Bypass Switch", ES8328_DACCONTROL17, 6, 1, 0),
+       SOC_DAPM_SINGLE("Right Playback Switch", ES8328_DACCONTROL18, 7, 1, 0),
+       SOC_DAPM_SINGLE("Right Bypass Switch", ES8328_DACCONTROL18, 6, 1, 0),
 };
 
 /* Right Mixer */
 static const struct snd_kcontrol_new es8328_right_mixer_controls[] = {
-       SOC_DAPM_SINGLE("Left Playback Switch", ES8328_DACCONTROL19, 8, 1, 0),
-       SOC_DAPM_SINGLE("Left Bypass Switch", ES8328_DACCONTROL19, 7, 1, 0),
-       SOC_DAPM_SINGLE("Playback Switch", ES8328_DACCONTROL20, 8, 1, 0),
-       SOC_DAPM_SINGLE("Right Bypass Switch", ES8328_DACCONTROL20, 7, 1, 0),
+       SOC_DAPM_SINGLE("Left Playback Switch", ES8328_DACCONTROL19, 7, 1, 0),
+       SOC_DAPM_SINGLE("Left Bypass Switch", ES8328_DACCONTROL19, 6, 1, 0),
+       SOC_DAPM_SINGLE("Playback Switch", ES8328_DACCONTROL20, 7, 1, 0),
+       SOC_DAPM_SINGLE("Right Bypass Switch", ES8328_DACCONTROL20, 6, 1, 0),
 };
 
 static const char * const es8328_pga_sel[] = {
index 7fc7b4e3f4442a52727e97d96a847c76ada6a58f..c1b87c5800b1d0980cf541e96a4d22ae76e9b32c 100644 (file)
@@ -1271,6 +1271,36 @@ static int nau8825_i2c_remove(struct i2c_client *client)
        return 0;
 }
 
+#ifdef CONFIG_PM_SLEEP
+static int nau8825_suspend(struct device *dev)
+{
+       struct i2c_client *client = to_i2c_client(dev);
+       struct nau8825 *nau8825 = dev_get_drvdata(dev);
+
+       disable_irq(client->irq);
+       regcache_cache_only(nau8825->regmap, true);
+       regcache_mark_dirty(nau8825->regmap);
+
+       return 0;
+}
+
+static int nau8825_resume(struct device *dev)
+{
+       struct i2c_client *client = to_i2c_client(dev);
+       struct nau8825 *nau8825 = dev_get_drvdata(dev);
+
+       regcache_cache_only(nau8825->regmap, false);
+       regcache_sync(nau8825->regmap);
+       enable_irq(client->irq);
+
+       return 0;
+}
+#endif
+
+static const struct dev_pm_ops nau8825_pm = {
+       SET_SYSTEM_SLEEP_PM_OPS(nau8825_suspend, nau8825_resume)
+};
+
 static const struct i2c_device_id nau8825_i2c_ids[] = {
        { "nau8825", 0 },
        { }
@@ -1297,6 +1327,7 @@ static struct i2c_driver nau8825_driver = {
                .name = "nau8825",
                .of_match_table = of_match_ptr(nau8825_of_ids),
                .acpi_match_table = ACPI_PTR(nau8825_acpi_match),
+               .pm = &nau8825_pm,
        },
        .probe = nau8825_i2c_probe,
        .remove = nau8825_i2c_remove,
index aca479fa767027174be48390fd0dc93c3802d022..1dc68ab08a1799e71ec17677c5b0da959d3cd40f 100644 (file)
@@ -80,8 +80,10 @@ int rl6231_calc_dmic_clk(int rate)
        }
 
        for (i = 0; i < ARRAY_SIZE(div); i++) {
-               /* find divider that gives DMIC frequency below 3MHz */
-               if (3000000 * div[i] >= rate)
+               if ((div[i] % 3) == 0)
+                       continue;
+               /* find divider that gives DMIC frequency below 3.072MHz */
+               if (3072000 * div[i] >= rate)
                        return i;
        }
 
index 28132375e4274a6e94e830c2fe1e8fcddd255747..ef76940f9dcb63196b10798f80d54528adc6109d 100644 (file)
@@ -245,7 +245,7 @@ struct rt5645_priv {
        struct snd_soc_jack *hp_jack;
        struct snd_soc_jack *mic_jack;
        struct snd_soc_jack *btn_jack;
-       struct delayed_work jack_detect_work;
+       struct delayed_work jack_detect_work, rcclock_work;
        struct regulator_bulk_data supplies[ARRAY_SIZE(rt5645_supply_names)];
        struct rt5645_eq_param_s *eq_param;
 
@@ -565,12 +565,33 @@ static int rt5645_hweq_put(struct snd_kcontrol *kcontrol,
        .put = rt5645_hweq_put \
 }
 
+static int rt5645_spk_put_volsw(struct snd_kcontrol *kcontrol,
+               struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
+       struct rt5645_priv *rt5645 = snd_soc_component_get_drvdata(component);
+       int ret;
+
+       cancel_delayed_work_sync(&rt5645->rcclock_work);
+
+       regmap_update_bits(rt5645->regmap, RT5645_MICBIAS,
+               RT5645_PWR_CLK25M_MASK, RT5645_PWR_CLK25M_PU);
+
+       ret = snd_soc_put_volsw(kcontrol, ucontrol);
+
+       queue_delayed_work(system_power_efficient_wq, &rt5645->rcclock_work,
+               msecs_to_jiffies(200));
+
+       return ret;
+}
+
 static const struct snd_kcontrol_new rt5645_snd_controls[] = {
        /* Speaker Output Volume */
        SOC_DOUBLE("Speaker Channel Switch", RT5645_SPK_VOL,
                RT5645_VOL_L_SFT, RT5645_VOL_R_SFT, 1, 1),
-       SOC_DOUBLE_TLV("Speaker Playback Volume", RT5645_SPK_VOL,
-               RT5645_L_VOL_SFT, RT5645_R_VOL_SFT, 39, 1, out_vol_tlv),
+       SOC_DOUBLE_EXT_TLV("Speaker Playback Volume", RT5645_SPK_VOL,
+               RT5645_L_VOL_SFT, RT5645_R_VOL_SFT, 39, 1, snd_soc_get_volsw,
+               rt5645_spk_put_volsw, out_vol_tlv),
 
        /* ClassD modulator Speaker Gain Ratio */
        SOC_SINGLE_TLV("Speaker ClassD Playback Volume", RT5645_SPO_CLSD_RATIO,
@@ -1498,7 +1519,7 @@ static void hp_amp_power(struct snd_soc_codec *codec, int on)
                                regmap_write(rt5645->regmap, RT5645_PR_BASE +
                                        RT5645_MAMP_INT_REG2, 0xfc00);
                                snd_soc_write(codec, RT5645_DEPOP_M2, 0x1140);
-                               msleep(40);
+                               msleep(70);
                                rt5645->hp_on = true;
                        } else {
                                /* depop parameters */
@@ -3122,6 +3143,15 @@ static void rt5645_jack_detect_work(struct work_struct *work)
                                SND_JACK_BTN_2 | SND_JACK_BTN_3);
 }
 
+static void rt5645_rcclock_work(struct work_struct *work)
+{
+       struct rt5645_priv *rt5645 =
+               container_of(work, struct rt5645_priv, rcclock_work.work);
+
+       regmap_update_bits(rt5645->regmap, RT5645_MICBIAS,
+               RT5645_PWR_CLK25M_MASK, RT5645_PWR_CLK25M_PD);
+}
+
 static irqreturn_t rt5645_irq(int irq, void *data)
 {
        struct rt5645_priv *rt5645 = data;
@@ -3348,6 +3378,27 @@ static const struct dmi_system_id dmi_platform_intel_braswell[] = {
                        DMI_MATCH(DMI_PRODUCT_NAME, "Reks"),
                },
        },
+       {
+               .ident = "Google Edgar",
+               .callback = strago_quirk_cb,
+               .matches = {
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Edgar"),
+               },
+       },
+       {
+               .ident = "Google Wizpig",
+               .callback = strago_quirk_cb,
+               .matches = {
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Wizpig"),
+               },
+       },
+       {
+               .ident = "Google Terra",
+               .callback = strago_quirk_cb,
+               .matches = {
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Terra"),
+               },
+       },
        { }
 };
 
@@ -3587,6 +3638,7 @@ static int rt5645_i2c_probe(struct i2c_client *i2c,
        }
 
        INIT_DELAYED_WORK(&rt5645->jack_detect_work, rt5645_jack_detect_work);
+       INIT_DELAYED_WORK(&rt5645->rcclock_work, rt5645_rcclock_work);
 
        if (rt5645->i2c->irq) {
                ret = request_threaded_irq(rt5645->i2c->irq, NULL, rt5645_irq,
@@ -3621,6 +3673,7 @@ static int rt5645_i2c_remove(struct i2c_client *i2c)
                free_irq(i2c->irq, rt5645);
 
        cancel_delayed_work_sync(&rt5645->jack_detect_work);
+       cancel_delayed_work_sync(&rt5645->rcclock_work);
 
        snd_soc_unregister_codec(&i2c->dev);
        regulator_bulk_disable(ARRAY_SIZE(rt5645->supplies), rt5645->supplies);
index dc2b46236c5cb5cd7ba12ec5fd9f311868978983..3f1b0f1df8097ba9d47644b3dd74548642d3cf82 100644 (file)
 #define RT5670_SCLK_SRC_MCLK                   (0x0 << 14)
 #define RT5670_SCLK_SRC_PLL1                   (0x1 << 14)
 #define RT5670_SCLK_SRC_RCCLK                  (0x2 << 14) /* 15MHz */
-#define RT5670_PLL1_SRC_MASK                   (0x3 << 12)
-#define RT5670_PLL1_SRC_SFT                    12
-#define RT5670_PLL1_SRC_MCLK                   (0x0 << 12)
-#define RT5670_PLL1_SRC_BCLK1                  (0x1 << 12)
-#define RT5670_PLL1_SRC_BCLK2                  (0x2 << 12)
-#define RT5670_PLL1_SRC_BCLK3                  (0x3 << 12)
+#define RT5670_PLL1_SRC_MASK                   (0x7 << 11)
+#define RT5670_PLL1_SRC_SFT                    11
+#define RT5670_PLL1_SRC_MCLK                   (0x0 << 11)
+#define RT5670_PLL1_SRC_BCLK1                  (0x1 << 11)
+#define RT5670_PLL1_SRC_BCLK2                  (0x2 << 11)
+#define RT5670_PLL1_SRC_BCLK3                  (0x3 << 11)
 #define RT5670_PLL1_PD_MASK                    (0x1 << 3)
 #define RT5670_PLL1_PD_SFT                     3
 #define RT5670_PLL1_PD_1                       (0x0 << 3)
index b4cd7e3bf5f89f9ea940528f233f017151788a4b..69d987a9935c9f91311db09b1a2cfb7cd5a2c609 100644 (file)
@@ -1386,90 +1386,90 @@ static const struct snd_kcontrol_new rt5677_dac_r_mix[] = {
 };
 
 static const struct snd_kcontrol_new rt5677_sto1_dac_l_mix[] = {
-       SOC_DAPM_SINGLE("ST L Switch", RT5677_STO1_DAC_MIXER,
+       SOC_DAPM_SINGLE_AUTODISABLE("ST L Switch", RT5677_STO1_DAC_MIXER,
                        RT5677_M_ST_DAC1_L_SFT, 1, 1),
-       SOC_DAPM_SINGLE("DAC1 L Switch", RT5677_STO1_DAC_MIXER,
+       SOC_DAPM_SINGLE_AUTODISABLE("DAC1 L Switch", RT5677_STO1_DAC_MIXER,
                        RT5677_M_DAC1_L_STO_L_SFT, 1, 1),
-       SOC_DAPM_SINGLE("DAC2 L Switch", RT5677_STO1_DAC_MIXER,
+       SOC_DAPM_SINGLE_AUTODISABLE("DAC2 L Switch", RT5677_STO1_DAC_MIXER,
                        RT5677_M_DAC2_L_STO_L_SFT, 1, 1),
-       SOC_DAPM_SINGLE("DAC1 R Switch", RT5677_STO1_DAC_MIXER,
+       SOC_DAPM_SINGLE_AUTODISABLE("DAC1 R Switch", RT5677_STO1_DAC_MIXER,
                        RT5677_M_DAC1_R_STO_L_SFT, 1, 1),
 };
 
 static const struct snd_kcontrol_new rt5677_sto1_dac_r_mix[] = {
-       SOC_DAPM_SINGLE("ST R Switch", RT5677_STO1_DAC_MIXER,
+       SOC_DAPM_SINGLE_AUTODISABLE("ST R Switch", RT5677_STO1_DAC_MIXER,
                        RT5677_M_ST_DAC1_R_SFT, 1, 1),
-       SOC_DAPM_SINGLE("DAC1 R Switch", RT5677_STO1_DAC_MIXER,
+       SOC_DAPM_SINGLE_AUTODISABLE("DAC1 R Switch", RT5677_STO1_DAC_MIXER,
                        RT5677_M_DAC1_R_STO_R_SFT, 1, 1),
-       SOC_DAPM_SINGLE("DAC2 R Switch", RT5677_STO1_DAC_MIXER,
+       SOC_DAPM_SINGLE_AUTODISABLE("DAC2 R Switch", RT5677_STO1_DAC_MIXER,
                        RT5677_M_DAC2_R_STO_R_SFT, 1, 1),
-       SOC_DAPM_SINGLE("DAC1 L Switch", RT5677_STO1_DAC_MIXER,
+       SOC_DAPM_SINGLE_AUTODISABLE("DAC1 L Switch", RT5677_STO1_DAC_MIXER,
                        RT5677_M_DAC1_L_STO_R_SFT, 1, 1),
 };
 
 static const struct snd_kcontrol_new rt5677_mono_dac_l_mix[] = {
-       SOC_DAPM_SINGLE("ST L Switch", RT5677_MONO_DAC_MIXER,
+       SOC_DAPM_SINGLE_AUTODISABLE("ST L Switch", RT5677_MONO_DAC_MIXER,
                        RT5677_M_ST_DAC2_L_SFT, 1, 1),
-       SOC_DAPM_SINGLE("DAC1 L Switch", RT5677_MONO_DAC_MIXER,
+       SOC_DAPM_SINGLE_AUTODISABLE("DAC1 L Switch", RT5677_MONO_DAC_MIXER,
                        RT5677_M_DAC1_L_MONO_L_SFT, 1, 1),
-       SOC_DAPM_SINGLE("DAC2 L Switch", RT5677_MONO_DAC_MIXER,
+       SOC_DAPM_SINGLE_AUTODISABLE("DAC2 L Switch", RT5677_MONO_DAC_MIXER,
                        RT5677_M_DAC2_L_MONO_L_SFT, 1, 1),
-       SOC_DAPM_SINGLE("DAC2 R Switch", RT5677_MONO_DAC_MIXER,
+       SOC_DAPM_SINGLE_AUTODISABLE("DAC2 R Switch", RT5677_MONO_DAC_MIXER,
                        RT5677_M_DAC2_R_MONO_L_SFT, 1, 1),
 };
 
 static const struct snd_kcontrol_new rt5677_mono_dac_r_mix[] = {
-       SOC_DAPM_SINGLE("ST R Switch", RT5677_MONO_DAC_MIXER,
+       SOC_DAPM_SINGLE_AUTODISABLE("ST R Switch", RT5677_MONO_DAC_MIXER,
                        RT5677_M_ST_DAC2_R_SFT, 1, 1),
-       SOC_DAPM_SINGLE("DAC1 R Switch", RT5677_MONO_DAC_MIXER,
+       SOC_DAPM_SINGLE_AUTODISABLE("DAC1 R Switch", RT5677_MONO_DAC_MIXER,
                        RT5677_M_DAC1_R_MONO_R_SFT, 1, 1),
-       SOC_DAPM_SINGLE("DAC2 R Switch", RT5677_MONO_DAC_MIXER,
+       SOC_DAPM_SINGLE_AUTODISABLE("DAC2 R Switch", RT5677_MONO_DAC_MIXER,
                        RT5677_M_DAC2_R_MONO_R_SFT, 1, 1),
-       SOC_DAPM_SINGLE("DAC2 L Switch", RT5677_MONO_DAC_MIXER,
+       SOC_DAPM_SINGLE_AUTODISABLE("DAC2 L Switch", RT5677_MONO_DAC_MIXER,
                        RT5677_M_DAC2_L_MONO_R_SFT, 1, 1),
 };
 
 static const struct snd_kcontrol_new rt5677_dd1_l_mix[] = {
-       SOC_DAPM_SINGLE("Sto DAC Mix L Switch", RT5677_DD1_MIXER,
+       SOC_DAPM_SINGLE_AUTODISABLE("Sto DAC Mix L Switch", RT5677_DD1_MIXER,
                        RT5677_M_STO_L_DD1_L_SFT, 1, 1),
-       SOC_DAPM_SINGLE("Mono DAC Mix L Switch", RT5677_DD1_MIXER,
+       SOC_DAPM_SINGLE_AUTODISABLE("Mono DAC Mix L Switch", RT5677_DD1_MIXER,
                        RT5677_M_MONO_L_DD1_L_SFT, 1, 1),
-       SOC_DAPM_SINGLE("DAC3 L Switch", RT5677_DD1_MIXER,
+       SOC_DAPM_SINGLE_AUTODISABLE("DAC3 L Switch", RT5677_DD1_MIXER,
                        RT5677_M_DAC3_L_DD1_L_SFT, 1, 1),
-       SOC_DAPM_SINGLE("DAC3 R Switch", RT5677_DD1_MIXER,
+       SOC_DAPM_SINGLE_AUTODISABLE("DAC3 R Switch", RT5677_DD1_MIXER,
                        RT5677_M_DAC3_R_DD1_L_SFT, 1, 1),
 };
 
 static const struct snd_kcontrol_new rt5677_dd1_r_mix[] = {
-       SOC_DAPM_SINGLE("Sto DAC Mix R Switch", RT5677_DD1_MIXER,
+       SOC_DAPM_SINGLE_AUTODISABLE("Sto DAC Mix R Switch", RT5677_DD1_MIXER,
                        RT5677_M_STO_R_DD1_R_SFT, 1, 1),
-       SOC_DAPM_SINGLE("Mono DAC Mix R Switch", RT5677_DD1_MIXER,
+       SOC_DAPM_SINGLE_AUTODISABLE("Mono DAC Mix R Switch", RT5677_DD1_MIXER,
                        RT5677_M_MONO_R_DD1_R_SFT, 1, 1),
-       SOC_DAPM_SINGLE("DAC3 R Switch", RT5677_DD1_MIXER,
+       SOC_DAPM_SINGLE_AUTODISABLE("DAC3 R Switch", RT5677_DD1_MIXER,
                        RT5677_M_DAC3_R_DD1_R_SFT, 1, 1),
-       SOC_DAPM_SINGLE("DAC3 L Switch", RT5677_DD1_MIXER,
+       SOC_DAPM_SINGLE_AUTODISABLE("DAC3 L Switch", RT5677_DD1_MIXER,
                        RT5677_M_DAC3_L_DD1_R_SFT, 1, 1),
 };
 
 static const struct snd_kcontrol_new rt5677_dd2_l_mix[] = {
-       SOC_DAPM_SINGLE("Sto DAC Mix L Switch", RT5677_DD2_MIXER,
+       SOC_DAPM_SINGLE_AUTODISABLE("Sto DAC Mix L Switch", RT5677_DD2_MIXER,
                        RT5677_M_STO_L_DD2_L_SFT, 1, 1),
-       SOC_DAPM_SINGLE("Mono DAC Mix L Switch", RT5677_DD2_MIXER,
+       SOC_DAPM_SINGLE_AUTODISABLE("Mono DAC Mix L Switch", RT5677_DD2_MIXER,
                        RT5677_M_MONO_L_DD2_L_SFT, 1, 1),
-       SOC_DAPM_SINGLE("DAC4 L Switch", RT5677_DD2_MIXER,
+       SOC_DAPM_SINGLE_AUTODISABLE("DAC4 L Switch", RT5677_DD2_MIXER,
                        RT5677_M_DAC4_L_DD2_L_SFT, 1, 1),
-       SOC_DAPM_SINGLE("DAC4 R Switch", RT5677_DD2_MIXER,
+       SOC_DAPM_SINGLE_AUTODISABLE("DAC4 R Switch", RT5677_DD2_MIXER,
                        RT5677_M_DAC4_R_DD2_L_SFT, 1, 1),
 };
 
 static const struct snd_kcontrol_new rt5677_dd2_r_mix[] = {
-       SOC_DAPM_SINGLE("Sto DAC Mix R Switch", RT5677_DD2_MIXER,
+       SOC_DAPM_SINGLE_AUTODISABLE("Sto DAC Mix R Switch", RT5677_DD2_MIXER,
                        RT5677_M_STO_R_DD2_R_SFT, 1, 1),
-       SOC_DAPM_SINGLE("Mono DAC Mix R Switch", RT5677_DD2_MIXER,
+       SOC_DAPM_SINGLE_AUTODISABLE("Mono DAC Mix R Switch", RT5677_DD2_MIXER,
                        RT5677_M_MONO_R_DD2_R_SFT, 1, 1),
-       SOC_DAPM_SINGLE("DAC4 R Switch", RT5677_DD2_MIXER,
+       SOC_DAPM_SINGLE_AUTODISABLE("DAC4 R Switch", RT5677_DD2_MIXER,
                        RT5677_M_DAC4_R_DD2_R_SFT, 1, 1),
-       SOC_DAPM_SINGLE("DAC4 L Switch", RT5677_DD2_MIXER,
+       SOC_DAPM_SINGLE_AUTODISABLE("DAC4 L Switch", RT5677_DD2_MIXER,
                        RT5677_M_DAC4_L_DD2_R_SFT, 1, 1),
 };
 
@@ -2596,6 +2596,21 @@ static int rt5677_vref_event(struct snd_soc_dapm_widget *w,
        return 0;
 }
 
+static int rt5677_filter_power_event(struct snd_soc_dapm_widget *w,
+       struct snd_kcontrol *kcontrol, int event)
+{
+       switch (event) {
+       case SND_SOC_DAPM_POST_PMU:
+               msleep(50);
+               break;
+
+       default:
+               return 0;
+       }
+
+       return 0;
+}
+
 static const struct snd_soc_dapm_widget rt5677_dapm_widgets[] = {
        SND_SOC_DAPM_SUPPLY("PLL1", RT5677_PWR_ANLG2, RT5677_PWR_PLL1_BIT,
                0, rt5677_set_pll1_event, SND_SOC_DAPM_PRE_PMU |
@@ -3072,19 +3087,26 @@ static const struct snd_soc_dapm_widget rt5677_dapm_widgets[] = {
 
        /* DAC Mixer */
        SND_SOC_DAPM_SUPPLY("dac stereo1 filter", RT5677_PWR_DIG2,
-               RT5677_PWR_DAC_S1F_BIT, 0, NULL, 0),
+               RT5677_PWR_DAC_S1F_BIT, 0, rt5677_filter_power_event,
+               SND_SOC_DAPM_POST_PMU),
        SND_SOC_DAPM_SUPPLY("dac mono2 left filter", RT5677_PWR_DIG2,
-               RT5677_PWR_DAC_M2F_L_BIT, 0, NULL, 0),
+               RT5677_PWR_DAC_M2F_L_BIT, 0, rt5677_filter_power_event,
+               SND_SOC_DAPM_POST_PMU),
        SND_SOC_DAPM_SUPPLY("dac mono2 right filter", RT5677_PWR_DIG2,
-               RT5677_PWR_DAC_M2F_R_BIT, 0, NULL, 0),
+               RT5677_PWR_DAC_M2F_R_BIT, 0, rt5677_filter_power_event,
+               SND_SOC_DAPM_POST_PMU),
        SND_SOC_DAPM_SUPPLY("dac mono3 left filter", RT5677_PWR_DIG2,
-               RT5677_PWR_DAC_M3F_L_BIT, 0, NULL, 0),
+               RT5677_PWR_DAC_M3F_L_BIT, 0, rt5677_filter_power_event,
+               SND_SOC_DAPM_POST_PMU),
        SND_SOC_DAPM_SUPPLY("dac mono3 right filter", RT5677_PWR_DIG2,
-               RT5677_PWR_DAC_M3F_R_BIT, 0, NULL, 0),
+               RT5677_PWR_DAC_M3F_R_BIT, 0, rt5677_filter_power_event,
+               SND_SOC_DAPM_POST_PMU),
        SND_SOC_DAPM_SUPPLY("dac mono4 left filter", RT5677_PWR_DIG2,
-               RT5677_PWR_DAC_M4F_L_BIT, 0, NULL, 0),
+               RT5677_PWR_DAC_M4F_L_BIT, 0, rt5677_filter_power_event,
+               SND_SOC_DAPM_POST_PMU),
        SND_SOC_DAPM_SUPPLY("dac mono4 right filter", RT5677_PWR_DIG2,
-               RT5677_PWR_DAC_M4F_R_BIT, 0, NULL, 0),
+               RT5677_PWR_DAC_M4F_R_BIT, 0, rt5677_filter_power_event,
+               SND_SOC_DAPM_POST_PMU),
 
        SND_SOC_DAPM_MIXER("Stereo DAC MIXL", SND_SOC_NOPM, 0, 0,
                rt5677_sto1_dac_l_mix, ARRAY_SIZE(rt5677_sto1_dac_l_mix)),
index 056375339ea32948207723b1affd84ebdd0b1730..5380798883b5d342df4dee0ffdd54e3b474ceac6 100644 (file)
@@ -229,7 +229,7 @@ SOC_DOUBLE_R_TLV("Capture Volume", WM8960_LINVOL, WM8960_RINVOL,
 SOC_DOUBLE_R("Capture Volume ZC Switch", WM8960_LINVOL, WM8960_RINVOL,
        6, 1, 0),
 SOC_DOUBLE_R("Capture Switch", WM8960_LINVOL, WM8960_RINVOL,
-       7, 1, 0),
+       7, 1, 1),
 
 SOC_SINGLE_TLV("Right Input Boost Mixer RINPUT3 Volume",
               WM8960_INBMIX1, 4, 7, 0, lineinboost_tlv),
index 39ebd7bf4f5306382c86fb49f3417dc3c908dcad..a7e79784fc16ca184b9b56dc73e2b38e2da93b1c 100644 (file)
@@ -365,8 +365,8 @@ static const struct reg_default wm8962_reg[] = {
        { 16924, 0x0059 },   /* R16924 - HDBASS_PG_1 */
        { 16925, 0x999A },   /* R16925 - HDBASS_PG_0 */
 
-       { 17048, 0x0083 },   /* R17408 - HPF_C_1 */
-       { 17049, 0x98AD },   /* R17409 - HPF_C_0 */
+       { 17408, 0x0083 },   /* R17408 - HPF_C_1 */
+       { 17409, 0x98AD },   /* R17409 - HPF_C_0 */
 
        { 17920, 0x007F },   /* R17920 - ADCL_RETUNE_C1_1 */
        { 17921, 0xFFFF },   /* R17921 - ADCL_RETUNE_C1_0 */
index 4495a40a94680600ff324bd035098ff3d73f594b..c1c9c2e3525bf88f8cf6de409fcc9370320dd3b2 100644 (file)
@@ -681,8 +681,8 @@ static int davinci_mcasp_set_tdm_slot(struct snd_soc_dai *dai,
        }
 
        mcasp->tdm_slots = slots;
-       mcasp->tdm_mask[SNDRV_PCM_STREAM_PLAYBACK] = rx_mask;
-       mcasp->tdm_mask[SNDRV_PCM_STREAM_CAPTURE] = tx_mask;
+       mcasp->tdm_mask[SNDRV_PCM_STREAM_PLAYBACK] = tx_mask;
+       mcasp->tdm_mask[SNDRV_PCM_STREAM_CAPTURE] = rx_mask;
        mcasp->slot_width = slot_width;
 
        return davinci_mcasp_set_ch_constraints(mcasp);
@@ -908,6 +908,14 @@ static int mcasp_i2s_hw_param(struct davinci_mcasp *mcasp, int stream,
                mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMT_REG, busel | RXORD);
                mcasp_mod_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG,
                               FSRMOD(total_slots), FSRMOD(0x1FF));
+               /*
+                * If McASP is set to be TX/RX synchronous and the playback is
+                * not running already we need to configure the TX slots in
+                * order to have correct FSX on the bus
+                */
+               if (mcasp_is_synchronous(mcasp) && !mcasp->channels)
+                       mcasp_mod_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG,
+                                      FSXMOD(total_slots), FSXMOD(0x1FF));
        }
 
        return 0;
index 19c302b0d763976fba1bc79b927f8b39e03dfc83..14dfdee05fd5ae842bebdd0092e47bd4bc88f605 100644 (file)
@@ -283,6 +283,8 @@ config SND_SOC_IMX_MC13783
 config SND_SOC_FSL_ASOC_CARD
        tristate "Generic ASoC Sound Card with ASRC support"
        depends on OF && I2C
+       # enforce SND_SOC_FSL_ASOC_CARD=m if SND_AC97_CODEC=m:
+       depends on SND_AC97_CODEC || SND_AC97_CODEC=n
        select SND_SOC_IMX_AUDMUX
        select SND_SOC_IMX_PCM_DMA
        select SND_SOC_FSL_ESAI
index a4435f5e3be910447f9168b4708d19140f3c1f4f..ffd5f9acc849ffb3d8152bdfa1e5c13a26342668 100644 (file)
@@ -454,7 +454,8 @@ static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd,
         * Rx sync with Tx clocks: Clear SYNC for Tx, set it for Rx.
         * Tx sync with Rx clocks: Clear SYNC for Rx, set it for Tx.
         */
-       regmap_update_bits(sai->regmap, FSL_SAI_TCR2, FSL_SAI_CR2_SYNC, 0);
+       regmap_update_bits(sai->regmap, FSL_SAI_TCR2, FSL_SAI_CR2_SYNC,
+                          sai->synchronous[TX] ? FSL_SAI_CR2_SYNC : 0);
        regmap_update_bits(sai->regmap, FSL_SAI_RCR2, FSL_SAI_CR2_SYNC,
                           sai->synchronous[RX] ? FSL_SAI_CR2_SYNC : 0);
 
index 7b778ab85f8b41234487d0810f4c350f6dc09775..d430ef5a4f388985f1ca0674f4315d3b38e8e6cf 100644 (file)
@@ -144,7 +144,7 @@ config SND_SOC_INTEL_SKYLAKE
 
 config SND_SOC_INTEL_SKL_RT286_MACH
        tristate "ASoC Audio driver for SKL with RT286 I2S mode"
-       depends on X86 && ACPI
+       depends on X86 && ACPI && I2C
        select SND_SOC_INTEL_SST
        select SND_SOC_INTEL_SKYLAKE
        select SND_SOC_RT286
index a7854c8fc523e832f6137437c6e7737cc5eee46c..ffea427aeca8eab29809f049c53ba27f71b54393 100644 (file)
@@ -1240,6 +1240,7 @@ int skl_tplg_init(struct snd_soc_platform *platform, struct hdac_ext_bus *ebus)
         */
        ret = snd_soc_tplg_component_load(&platform->component,
                                        &skl_tplg_ops, fw, 0);
+       release_firmware(fw);
        if (ret < 0) {
                dev_err(bus->dev, "tplg component load failed%d\n", ret);
                return -EINVAL;
index a38a3029062c8296581af1209a176b53dde29f7c..ac72ff5055bbce626550c4fd277a96c351321b25 100644 (file)
@@ -280,7 +280,7 @@ static int rk_spdif_probe(struct platform_device *pdev)
        int ret;
 
        match = of_match_node(rk_spdif_match, np);
-       if ((int) match->data == RK_SPDIF_RK3288) {
+       if (match->data == (void *)RK_SPDIF_RK3288) {
                struct regmap *grf;
 
                grf = syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
index 07f86a21046a524b32687f7252b54affa5fce1f7..921b4095fb92c98d7b09fb8d7ec8bbea7f9139bb 100644 (file)
@@ -28,9 +28,9 @@
 #define SPDIF_CFGR_VDW(x)      (x << SPDIF_CFGR_VDW_SHIFT)
 #define SDPIF_CFGR_VDW_MASK    (0xf << SPDIF_CFGR_VDW_SHIFT)
 
-#define SPDIF_CFGR_VDW_16      SPDIF_CFGR_VDW(0x00)
-#define SPDIF_CFGR_VDW_20      SPDIF_CFGR_VDW(0x01)
-#define SPDIF_CFGR_VDW_24      SPDIF_CFGR_VDW(0x10)
+#define SPDIF_CFGR_VDW_16      SPDIF_CFGR_VDW(0x0)
+#define SPDIF_CFGR_VDW_20      SPDIF_CFGR_VDW(0x1)
+#define SPDIF_CFGR_VDW_24      SPDIF_CFGR_VDW(0x2)
 
 /*
  * DMACR
index 76da7620904c982ee1946f7db9369c7065028133..edcf4cc2e84fa51549ac4f2e16573260e2f48b82 100644 (file)
@@ -235,7 +235,7 @@ static int rsnd_gen2_probe(struct platform_device *pdev,
                RSND_GEN_S_REG(SCU_SYS_STATUS0, 0x1c8),
                RSND_GEN_S_REG(SCU_SYS_INT_EN0, 0x1cc),
                RSND_GEN_S_REG(SCU_SYS_STATUS1, 0x1d0),
-               RSND_GEN_S_REG(SCU_SYS_INT_EN1, 0x1c4),
+               RSND_GEN_S_REG(SCU_SYS_INT_EN1, 0x1d4),
                RSND_GEN_M_REG(SRC_SWRSR,       0x200,  0x40),
                RSND_GEN_M_REG(SRC_SRCIR,       0x204,  0x40),
                RSND_GEN_M_REG(SRC_ADINR,       0x214,  0x40),
index 261b50217c48d94f0a66f44c513f685755ddae07..68b439ed22d7f4bb065bae68db731c4a844d40ac 100644 (file)
@@ -923,6 +923,7 @@ static int rsnd_src_pcm_new_gen2(struct rsnd_mod *mod,
                            struct snd_soc_pcm_runtime *rtd)
 {
        struct rsnd_dai *rdai = rsnd_io_to_rdai(io);
+       struct rsnd_mod *dvc = rsnd_io_to_mod_dvc(io);
        struct rsnd_src *src = rsnd_mod_to_src(mod);
        int ret;
 
@@ -936,6 +937,12 @@ static int rsnd_src_pcm_new_gen2(struct rsnd_mod *mod,
        if (!rsnd_rdai_is_clk_master(rdai))
                return 0;
 
+       /*
+        * SRC In doesn't work if DVC was enabled
+        */
+       if (dvc && !rsnd_io_is_play(io))
+               return 0;
+
        /*
         * enable sync convert
         */
index 24b096066a07205c88e377e28f94eacff1261f3e..a1305f827a98f077ac3cdeffed96b2ce73d45c63 100644 (file)
@@ -795,12 +795,12 @@ static void soc_resume_deferred(struct work_struct *work)
 
        dev_dbg(card->dev, "ASoC: resume work completed\n");
 
-       /* userspace can access us now we are back as we were before */
-       snd_power_change_state(card->snd_card, SNDRV_CTL_POWER_D0);
-
        /* Recheck all endpoints too, their state is affected by suspend */
        dapm_mark_endpoints_dirty(card);
        snd_soc_dapm_sync(&card->dapm);
+
+       /* userspace can access us now we are back as we were before */
+       snd_power_change_state(card->snd_card, SNDRV_CTL_POWER_D0);
 }
 
 /* powers up audio subsystem after a suspend */
index 016eba10b1ec2744a8b9b1b3492d6c0fa1c7a561..7d009428934acab676ca34a1d17dfa4e1af83f25 100644 (file)
@@ -2293,6 +2293,12 @@ void snd_soc_dapm_free_widget(struct snd_soc_dapm_widget *w)
        kfree(w);
 }
 
+void snd_soc_dapm_reset_cache(struct snd_soc_dapm_context *dapm)
+{
+       dapm->path_sink_cache.widget = NULL;
+       dapm->path_source_cache.widget = NULL;
+}
+
 /* free all dapm widgets and resources */
 static void dapm_free_widgets(struct snd_soc_dapm_context *dapm)
 {
@@ -2303,6 +2309,7 @@ static void dapm_free_widgets(struct snd_soc_dapm_context *dapm)
                        continue;
                snd_soc_dapm_free_widget(w);
        }
+       snd_soc_dapm_reset_cache(dapm);
 }
 
 static struct snd_soc_dapm_widget *dapm_find_widget(
index ecd38e52285a964d53fce4c5c0d4ae71fd4bc15d..2f67ba6d7a8fd5848ce2c8612bef62625903e9cd 100644 (file)
@@ -404,7 +404,7 @@ EXPORT_SYMBOL_GPL(snd_soc_get_volsw_sx);
 /**
  * snd_soc_put_volsw_sx - double mixer set callback
  * @kcontrol: mixer control
- * @uinfo: control element information
+ * @ucontrol: control element information
  *
  * Callback to set the value of a double mixer control that spans 2 registers.
  *
index 8d7ec80af51b499738dc2032356896a08144078a..6963ba20991c10066fdad2ad65f3102fc5752424 100644 (file)
@@ -531,7 +531,7 @@ static int soc_tplg_kcontrol_bind_io(struct snd_soc_tplg_ctl_hdr *hdr,
                /* TLV bytes controls need standard kcontrol info handler,
                 * TLV callback and extended put/get handlers.
                 */
-               k->info = snd_soc_bytes_info;
+               k->info = snd_soc_bytes_info_ext;
                k->tlv.c = snd_soc_bytes_tlv_callback;
 
                ext_ops = tplg->bytes_ext_ops;
@@ -1805,6 +1805,7 @@ void snd_soc_tplg_widget_remove_all(struct snd_soc_dapm_context *dapm,
                snd_soc_tplg_widget_remove(w);
                snd_soc_dapm_free_widget(w);
        }
+       snd_soc_dapm_reset_cache(dapm);
 }
 EXPORT_SYMBOL_GPL(snd_soc_tplg_widget_remove_all);
 
index 843f037a317da31aecc0b1761ddde2dfa24a1334..5c2bc53f0a9b721fd6a2f0b285c4d782d76d5bd6 100644 (file)
@@ -669,6 +669,7 @@ static int uni_player_startup(struct snd_pcm_substream *substream,
 {
        struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
        struct uniperif *player = priv->dai_data.uni;
+       player->substream = substream;
 
        player->clk_adj = 0;
 
@@ -950,6 +951,8 @@ static void uni_player_shutdown(struct snd_pcm_substream *substream,
        if (player->state != UNIPERIF_STATE_STOPPED)
                /* Stop the player */
                uni_player_stop(player);
+
+       player->substream = NULL;
 }
 
 static int uni_player_parse_dt_clk_glue(struct platform_device *pdev,
@@ -989,7 +992,7 @@ static int uni_player_parse_dt(struct platform_device *pdev,
        if (!info)
                return -ENOMEM;
 
-       if (of_property_read_u32(pnode, "version", &player->ver) ||
+       if (of_property_read_u32(pnode, "st,version", &player->ver) ||
            player->ver == SND_ST_UNIPERIF_VERSION_UNKNOWN) {
                dev_err(dev, "Unknown uniperipheral version ");
                return -EINVAL;
@@ -998,13 +1001,13 @@ static int uni_player_parse_dt(struct platform_device *pdev,
        if (player->ver >= SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0)
                info->underflow_enabled = 1;
 
-       if (of_property_read_u32(pnode, "uniperiph-id", &info->id)) {
+       if (of_property_read_u32(pnode, "st,uniperiph-id", &info->id)) {
                dev_err(dev, "uniperipheral id not defined");
                return -EINVAL;
        }
 
        /* Read the device mode property */
-       if (of_property_read_string(pnode, "mode", &mode)) {
+       if (of_property_read_string(pnode, "st,mode", &mode)) {
                dev_err(dev, "uniperipheral mode not defined");
                return -EINVAL;
        }
index f791239a30872927b4c117f43ec457da6532b037..8a0eb20501694b16bf90991c3bbd71bce1461296 100644 (file)
@@ -316,7 +316,7 @@ static int uni_reader_parse_dt(struct platform_device *pdev,
        if (!info)
                return -ENOMEM;
 
-       if (of_property_read_u32(node, "version", &reader->ver) ||
+       if (of_property_read_u32(node, "st,version", &reader->ver) ||
            reader->ver == SND_ST_UNIPERIF_VERSION_UNKNOWN) {
                dev_err(&pdev->dev, "Unknown uniperipheral version ");
                return -EINVAL;
@@ -346,7 +346,6 @@ int uni_reader_init(struct platform_device *pdev,
        reader->hw = &uni_reader_pcm_hw;
        reader->dai_ops = &uni_reader_dai_ops;
 
-       dev_err(reader->dev, "%s: enter\n", __func__);
        ret = uni_reader_parse_dt(pdev, reader);
        if (ret < 0) {
                dev_err(reader->dev, "Failed to parse DeviceTree");
index bcbf4da168b637341cdd7f3a35b084ab576ede36..1bb896d78d09817eff6fc38af7e2d1d1b3622ef3 100644 (file)
@@ -2,6 +2,7 @@
  * Copyright 2014 Emilio López <emilio@elopez.com.ar>
  * Copyright 2014 Jon Smirl <jonsmirl@gmail.com>
  * Copyright 2015 Maxime Ripard <maxime.ripard@free-electrons.com>
+ * Copyright 2015 Adam Sampson <ats@offog.org>
  *
  * Based on the Allwinner SDK driver, released under the GPL.
  *
@@ -404,7 +405,7 @@ static const struct snd_kcontrol_new sun4i_codec_pa_mute =
 static DECLARE_TLV_DB_SCALE(sun4i_codec_pa_volume_scale, -6300, 100, 1);
 
 static const struct snd_kcontrol_new sun4i_codec_widgets[] = {
-       SOC_SINGLE_TLV("PA Volume", SUN4I_CODEC_DAC_ACTL,
+       SOC_SINGLE_TLV("Power Amplifier Volume", SUN4I_CODEC_DAC_ACTL,
                       SUN4I_CODEC_DAC_ACTL_PA_VOL, 0x3F, 0,
                       sun4i_codec_pa_volume_scale),
 };
@@ -452,12 +453,12 @@ static const struct snd_soc_dapm_widget sun4i_codec_dapm_widgets[] = {
        SND_SOC_DAPM_SUPPLY("Mixer Enable", SUN4I_CODEC_DAC_ACTL,
                            SUN4I_CODEC_DAC_ACTL_MIXEN, 0, NULL, 0),
 
-       /* Pre-Amplifier */
-       SND_SOC_DAPM_MIXER("Pre-Amplifier", SUN4I_CODEC_ADC_ACTL,
+       /* Power Amplifier */
+       SND_SOC_DAPM_MIXER("Power Amplifier", SUN4I_CODEC_ADC_ACTL,
                           SUN4I_CODEC_ADC_ACTL_PA_EN, 0,
                           sun4i_codec_pa_mixer_controls,
                           ARRAY_SIZE(sun4i_codec_pa_mixer_controls)),
-       SND_SOC_DAPM_SWITCH("Pre-Amplifier Mute", SND_SOC_NOPM, 0, 0,
+       SND_SOC_DAPM_SWITCH("Power Amplifier Mute", SND_SOC_NOPM, 0, 0,
                            &sun4i_codec_pa_mute),
 
        SND_SOC_DAPM_OUTPUT("HP Right"),
@@ -480,16 +481,16 @@ static const struct snd_soc_dapm_route sun4i_codec_dapm_routes[] = {
        { "Left Mixer", NULL, "Mixer Enable" },
        { "Left Mixer", "Left DAC Playback Switch", "Left DAC" },
 
-       /* Pre-Amplifier Mixer Routes */
-       { "Pre-Amplifier", "Mixer Playback Switch", "Left Mixer" },
-       { "Pre-Amplifier", "Mixer Playback Switch", "Right Mixer" },
-       { "Pre-Amplifier", "DAC Playback Switch", "Left DAC" },
-       { "Pre-Amplifier", "DAC Playback Switch", "Right DAC" },
+       /* Power Amplifier Routes */
+       { "Power Amplifier", "Mixer Playback Switch", "Left Mixer" },
+       { "Power Amplifier", "Mixer Playback Switch", "Right Mixer" },
+       { "Power Amplifier", "DAC Playback Switch", "Left DAC" },
+       { "Power Amplifier", "DAC Playback Switch", "Right DAC" },
 
-       /* PA -> HP path */
-       { "Pre-Amplifier Mute", "Switch", "Pre-Amplifier" },
-       { "HP Right", NULL, "Pre-Amplifier Mute" },
-       { "HP Left", NULL, "Pre-Amplifier Mute" },
+       /* Headphone Output Routes */
+       { "Power Amplifier Mute", "Switch", "Power Amplifier" },
+       { "HP Right", NULL, "Power Amplifier Mute" },
+       { "HP Left", NULL, "Power Amplifier Mute" },
 };
 
 static struct snd_soc_codec_driver sun4i_codec_codec = {
index 7661616f36361d142144842bd6595994829edec4..5b4c58c3e2c5f6115d55ad194cd06f971e3fdb70 100644 (file)
@@ -174,6 +174,8 @@ struct snd_usb_midi_in_endpoint {
                u8 running_status_length;
        } ports[0x10];
        u8 seen_f5;
+       bool in_sysex;
+       u8 last_cin;
        u8 error_resubmit;
        int current_port;
 };
@@ -467,6 +469,39 @@ static void snd_usbmidi_maudio_broken_running_status_input(
                }
 }
 
+/*
+ * QinHeng CH345 is buggy: every second packet inside a SysEx has not CIN 4
+ * but the previously seen CIN, but still with three data bytes.
+ */
+static void ch345_broken_sysex_input(struct snd_usb_midi_in_endpoint *ep,
+                                    uint8_t *buffer, int buffer_length)
+{
+       unsigned int i, cin, length;
+
+       for (i = 0; i + 3 < buffer_length; i += 4) {
+               if (buffer[i] == 0 && i > 0)
+                       break;
+               cin = buffer[i] & 0x0f;
+               if (ep->in_sysex &&
+                   cin == ep->last_cin &&
+                   (buffer[i + 1 + (cin == 0x6)] & 0x80) == 0)
+                       cin = 0x4;
+#if 0
+               if (buffer[i + 1] == 0x90) {
+                       /*
+                        * Either a corrupted running status or a real note-on
+                        * message; impossible to detect reliably.
+                        */
+               }
+#endif
+               length = snd_usbmidi_cin_length[cin];
+               snd_usbmidi_input_data(ep, 0, &buffer[i + 1], length);
+               ep->in_sysex = cin == 0x4;
+               if (!ep->in_sysex)
+                       ep->last_cin = cin;
+       }
+}
+
 /*
  * CME protocol: like the standard protocol, but SysEx commands are sent as a
  * single USB packet preceded by a 0x0F byte.
@@ -660,6 +695,12 @@ static struct usb_protocol_ops snd_usbmidi_cme_ops = {
        .output_packet = snd_usbmidi_output_standard_packet,
 };
 
+static struct usb_protocol_ops snd_usbmidi_ch345_broken_sysex_ops = {
+       .input = ch345_broken_sysex_input,
+       .output = snd_usbmidi_standard_output,
+       .output_packet = snd_usbmidi_output_standard_packet,
+};
+
 /*
  * AKAI MPD16 protocol:
  *
@@ -1341,6 +1382,7 @@ static int snd_usbmidi_out_endpoint_create(struct snd_usb_midi *umidi,
                 * Various chips declare a packet size larger than 4 bytes, but
                 * do not actually work with larger packets:
                 */
+       case USB_ID(0x0a67, 0x5011): /* Medeli DD305 */
        case USB_ID(0x0a92, 0x1020): /* ESI M4U */
        case USB_ID(0x1430, 0x474b): /* RedOctane GH MIDI INTERFACE */
        case USB_ID(0x15ca, 0x0101): /* Textech USB Midi Cable */
@@ -2376,6 +2418,10 @@ int snd_usbmidi_create(struct snd_card *card,
                if (err < 0)
                        break;
 
+               err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints);
+               break;
+       case QUIRK_MIDI_CH345:
+               umidi->usb_protocol_ops = &snd_usbmidi_ch345_broken_sysex_ops;
                err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints);
                break;
        default:
index 1a1e2e4df35e5809e7f7d81b405ca6dddf2f4311..c60a776e815d72f14b9b6345f2e8a0266f8ec1b6 100644 (file)
@@ -2829,6 +2829,17 @@ YAMAHA_DEVICE(0x7010, "UB99"),
        .idProduct = 0x1020,
 },
 
+/* QinHeng devices */
+{
+       USB_DEVICE(0x1a86, 0x752d),
+       .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
+               .vendor_name = "QinHeng",
+               .product_name = "CH345",
+               .ifnum = 1,
+               .type = QUIRK_MIDI_CH345
+       }
+},
+
 /* KeithMcMillen Stringport */
 {
        USB_DEVICE(0x1f38, 0x0001),
index 5ca80e7d30cd25bcc67cdf88509f46d39eec42e6..7016ad8981873ca046000d631ac112c12ed62dc1 100644 (file)
@@ -538,6 +538,7 @@ int snd_usb_create_quirk(struct snd_usb_audio *chip,
                [QUIRK_MIDI_CME] = create_any_midi_quirk,
                [QUIRK_MIDI_AKAI] = create_any_midi_quirk,
                [QUIRK_MIDI_FTDI] = create_any_midi_quirk,
+               [QUIRK_MIDI_CH345] = create_any_midi_quirk,
                [QUIRK_AUDIO_STANDARD_INTERFACE] = create_standard_audio_quirk,
                [QUIRK_AUDIO_FIXED_ENDPOINT] = create_fixed_stream_quirk,
                [QUIRK_AUDIO_EDIROL_UAXX] = create_uaxx_quirk,
index 15a12715bd05154bd9c0b4bbe7084f3df15022b2..b665d85555cb3aad0c9a621232f28d8e1f75344a 100644 (file)
@@ -95,6 +95,7 @@ enum quirk_type {
        QUIRK_MIDI_AKAI,
        QUIRK_MIDI_US122L,
        QUIRK_MIDI_FTDI,
+       QUIRK_MIDI_CH345,
        QUIRK_AUDIO_STANDARD_INTERFACE,
        QUIRK_AUDIO_FIXED_ENDPOINT,
        QUIRK_AUDIO_EDIROL_UAXX,
index 40ab4476c80a2039ab543cc94b09725789b2fe57..51cf8256c6cda1b8c28cf4393496a77b63e0c171 100644 (file)
@@ -420,8 +420,7 @@ static struct nfit_test_resource *nfit_test_lookup(resource_size_t addr)
 
 static int nfit_test0_alloc(struct nfit_test *t)
 {
-       size_t nfit_size = sizeof(struct acpi_table_nfit)
-                       + sizeof(struct acpi_nfit_system_address) * NUM_SPA
+       size_t nfit_size = sizeof(struct acpi_nfit_system_address) * NUM_SPA
                        + sizeof(struct acpi_nfit_memory_map) * NUM_MEM
                        + sizeof(struct acpi_nfit_control_region) * NUM_DCR
                        + sizeof(struct acpi_nfit_data_region) * NUM_BDW
@@ -471,8 +470,7 @@ static int nfit_test0_alloc(struct nfit_test *t)
 
 static int nfit_test1_alloc(struct nfit_test *t)
 {
-       size_t nfit_size = sizeof(struct acpi_table_nfit)
-               + sizeof(struct acpi_nfit_system_address)
+       size_t nfit_size = sizeof(struct acpi_nfit_system_address)
                + sizeof(struct acpi_nfit_memory_map)
                + sizeof(struct acpi_nfit_control_region);
 
@@ -488,39 +486,24 @@ static int nfit_test1_alloc(struct nfit_test *t)
        return 0;
 }
 
-static void nfit_test_init_header(struct acpi_table_nfit *nfit, size_t size)
-{
-       memcpy(nfit->header.signature, ACPI_SIG_NFIT, 4);
-       nfit->header.length = size;
-       nfit->header.revision = 1;
-       memcpy(nfit->header.oem_id, "LIBND", 6);
-       memcpy(nfit->header.oem_table_id, "TEST", 5);
-       nfit->header.oem_revision = 1;
-       memcpy(nfit->header.asl_compiler_id, "TST", 4);
-       nfit->header.asl_compiler_revision = 1;
-}
-
 static void nfit_test0_setup(struct nfit_test *t)
 {
        struct nvdimm_bus_descriptor *nd_desc;
        struct acpi_nfit_desc *acpi_desc;
        struct acpi_nfit_memory_map *memdev;
        void *nfit_buf = t->nfit_buf;
-       size_t size = t->nfit_size;
        struct acpi_nfit_system_address *spa;
        struct acpi_nfit_control_region *dcr;
        struct acpi_nfit_data_region *bdw;
        struct acpi_nfit_flush_address *flush;
        unsigned int offset;
 
-       nfit_test_init_header(nfit_buf, size);
-
        /*
         * spa0 (interleave first half of dimm0 and dimm1, note storage
         * does not actually alias the related block-data-window
         * regions)
         */
-       spa = nfit_buf + sizeof(struct acpi_table_nfit);
+       spa = nfit_buf;
        spa->header.type = ACPI_NFIT_TYPE_SYSTEM_ADDRESS;
        spa->header.length = sizeof(*spa);
        memcpy(spa->range_guid, to_nfit_uuid(NFIT_SPA_PM), 16);
@@ -533,7 +516,7 @@ static void nfit_test0_setup(struct nfit_test *t)
         * does not actually alias the related block-data-window
         * regions)
         */
-       spa = nfit_buf + sizeof(struct acpi_table_nfit) + sizeof(*spa);
+       spa = nfit_buf + sizeof(*spa);
        spa->header.type = ACPI_NFIT_TYPE_SYSTEM_ADDRESS;
        spa->header.length = sizeof(*spa);
        memcpy(spa->range_guid, to_nfit_uuid(NFIT_SPA_PM), 16);
@@ -542,7 +525,7 @@ static void nfit_test0_setup(struct nfit_test *t)
        spa->length = SPA1_SIZE;
 
        /* spa2 (dcr0) dimm0 */
-       spa = nfit_buf + sizeof(struct acpi_table_nfit) + sizeof(*spa) * 2;
+       spa = nfit_buf + sizeof(*spa) * 2;
        spa->header.type = ACPI_NFIT_TYPE_SYSTEM_ADDRESS;
        spa->header.length = sizeof(*spa);
        memcpy(spa->range_guid, to_nfit_uuid(NFIT_SPA_DCR), 16);
@@ -551,7 +534,7 @@ static void nfit_test0_setup(struct nfit_test *t)
        spa->length = DCR_SIZE;
 
        /* spa3 (dcr1) dimm1 */
-       spa = nfit_buf + sizeof(struct acpi_table_nfit) + sizeof(*spa) * 3;
+       spa = nfit_buf + sizeof(*spa) * 3;
        spa->header.type = ACPI_NFIT_TYPE_SYSTEM_ADDRESS;
        spa->header.length = sizeof(*spa);
        memcpy(spa->range_guid, to_nfit_uuid(NFIT_SPA_DCR), 16);
@@ -560,7 +543,7 @@ static void nfit_test0_setup(struct nfit_test *t)
        spa->length = DCR_SIZE;
 
        /* spa4 (dcr2) dimm2 */
-       spa = nfit_buf + sizeof(struct acpi_table_nfit) + sizeof(*spa) * 4;
+       spa = nfit_buf + sizeof(*spa) * 4;
        spa->header.type = ACPI_NFIT_TYPE_SYSTEM_ADDRESS;
        spa->header.length = sizeof(*spa);
        memcpy(spa->range_guid, to_nfit_uuid(NFIT_SPA_DCR), 16);
@@ -569,7 +552,7 @@ static void nfit_test0_setup(struct nfit_test *t)
        spa->length = DCR_SIZE;
 
        /* spa5 (dcr3) dimm3 */
-       spa = nfit_buf + sizeof(struct acpi_table_nfit) + sizeof(*spa) * 5;
+       spa = nfit_buf + sizeof(*spa) * 5;
        spa->header.type = ACPI_NFIT_TYPE_SYSTEM_ADDRESS;
        spa->header.length = sizeof(*spa);
        memcpy(spa->range_guid, to_nfit_uuid(NFIT_SPA_DCR), 16);
@@ -578,7 +561,7 @@ static void nfit_test0_setup(struct nfit_test *t)
        spa->length = DCR_SIZE;
 
        /* spa6 (bdw for dcr0) dimm0 */
-       spa = nfit_buf + sizeof(struct acpi_table_nfit) + sizeof(*spa) * 6;
+       spa = nfit_buf + sizeof(*spa) * 6;
        spa->header.type = ACPI_NFIT_TYPE_SYSTEM_ADDRESS;
        spa->header.length = sizeof(*spa);
        memcpy(spa->range_guid, to_nfit_uuid(NFIT_SPA_BDW), 16);
@@ -587,7 +570,7 @@ static void nfit_test0_setup(struct nfit_test *t)
        spa->length = DIMM_SIZE;
 
        /* spa7 (bdw for dcr1) dimm1 */
-       spa = nfit_buf + sizeof(struct acpi_table_nfit) + sizeof(*spa) * 7;
+       spa = nfit_buf + sizeof(*spa) * 7;
        spa->header.type = ACPI_NFIT_TYPE_SYSTEM_ADDRESS;
        spa->header.length = sizeof(*spa);
        memcpy(spa->range_guid, to_nfit_uuid(NFIT_SPA_BDW), 16);
@@ -596,7 +579,7 @@ static void nfit_test0_setup(struct nfit_test *t)
        spa->length = DIMM_SIZE;
 
        /* spa8 (bdw for dcr2) dimm2 */
-       spa = nfit_buf + sizeof(struct acpi_table_nfit) + sizeof(*spa) * 8;
+       spa = nfit_buf + sizeof(*spa) * 8;
        spa->header.type = ACPI_NFIT_TYPE_SYSTEM_ADDRESS;
        spa->header.length = sizeof(*spa);
        memcpy(spa->range_guid, to_nfit_uuid(NFIT_SPA_BDW), 16);
@@ -605,7 +588,7 @@ static void nfit_test0_setup(struct nfit_test *t)
        spa->length = DIMM_SIZE;
 
        /* spa9 (bdw for dcr3) dimm3 */
-       spa = nfit_buf + sizeof(struct acpi_table_nfit) + sizeof(*spa) * 9;
+       spa = nfit_buf + sizeof(*spa) * 9;
        spa->header.type = ACPI_NFIT_TYPE_SYSTEM_ADDRESS;
        spa->header.length = sizeof(*spa);
        memcpy(spa->range_guid, to_nfit_uuid(NFIT_SPA_BDW), 16);
@@ -613,7 +596,7 @@ static void nfit_test0_setup(struct nfit_test *t)
        spa->address = t->dimm_dma[3];
        spa->length = DIMM_SIZE;
 
-       offset = sizeof(struct acpi_table_nfit) + sizeof(*spa) * 10;
+       offset = sizeof(*spa) * 10;
        /* mem-region0 (spa0, dimm0) */
        memdev = nfit_buf + offset;
        memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP;
@@ -1100,15 +1083,13 @@ static void nfit_test0_setup(struct nfit_test *t)
 
 static void nfit_test1_setup(struct nfit_test *t)
 {
-       size_t size = t->nfit_size, offset;
+       size_t offset;
        void *nfit_buf = t->nfit_buf;
        struct acpi_nfit_memory_map *memdev;
        struct acpi_nfit_control_region *dcr;
        struct acpi_nfit_system_address *spa;
 
-       nfit_test_init_header(nfit_buf, size);
-
-       offset = sizeof(struct acpi_table_nfit);
+       offset = 0;
        /* spa0 (flat range with no bdw aliasing) */
        spa = nfit_buf + offset;
        spa->header.type = ACPI_NFIT_TYPE_SYSTEM_ADDRESS;
index 3224a049b196e87fd9fe23e0f20ea09c6ea04031..0558bb9ce0a6eadb92aba3a4880aadfa277e0d2c 100644 (file)
@@ -27,7 +27,7 @@ o The build system shall remain as simple as possible, avoiding any archive or
 o Where possible, any helper functions or other package-wide code shall be
   implemented in header files, avoiding the need to compile intermediate object
   files.
-o External dependendencies shall remain as minimal as possible. Currently gcc
+o External dependencies shall remain as minimal as possible. Currently gcc
   and glibc are the only dependencies.
 o Tests return 0 for success and < 0 for failure.
 
index e38cc54942dbf298dd1b880e3eabf5a9f2af29e6..882fe83a355442930a5fc1007a294eee6744b7cc 100644 (file)
@@ -492,6 +492,9 @@ TEST_SIGNAL(KILL_one_arg_six, SIGSYS)
        pid_t parent = getppid();
        int fd;
        void *map1, *map2;
+       int page_size = sysconf(_SC_PAGESIZE);
+
+       ASSERT_LT(0, page_size);
 
        ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
        ASSERT_EQ(0, ret);
@@ -504,16 +507,16 @@ TEST_SIGNAL(KILL_one_arg_six, SIGSYS)
 
        EXPECT_EQ(parent, syscall(__NR_getppid));
        map1 = (void *)syscall(sysno,
-               NULL, PAGE_SIZE, PROT_READ, MAP_PRIVATE, fd, PAGE_SIZE);
+               NULL, page_size, PROT_READ, MAP_PRIVATE, fd, page_size);
        EXPECT_NE(MAP_FAILED, map1);
        /* mmap2() should never return. */
        map2 = (void *)syscall(sysno,
-                NULL, PAGE_SIZE, PROT_READ, MAP_PRIVATE, fd, 0x0C0FFEE);
+                NULL, page_size, PROT_READ, MAP_PRIVATE, fd, 0x0C0FFEE);
        EXPECT_EQ(MAP_FAILED, map2);
 
        /* The test failed, so clean up the resources. */
-       munmap(map1, PAGE_SIZE);
-       munmap(map2, PAGE_SIZE);
+       munmap(map1, page_size);
+       munmap(map2, page_size);
        close(fd);
 }
 
index 0a3da64638ceda0e94df98f9651fc241ae1f34c1..4db7d5691ba71b33d2bda8c85d634fe3781ae6d6 100644 (file)
@@ -110,4 +110,10 @@ static inline void free_page(unsigned long addr)
        (void) (&_min1 == &_min2);              \
        _min1 < _min2 ? _min1 : _min2; })
 
+/* TODO: empty stubs for now. Broken but enough for virtio_ring.c */
+#define list_add_tail(a, b) do {} while (0)
+#define list_del(a) do {} while (0)
+#define list_for_each_entry(a, b, c) while (0)
+/* end of stubs */
+
 #endif /* KERNEL_H */
index a3e07016a44017c8c9f25c5dd51e77a09152e127..ee125e714053a91a76658d417a46232349927450 100644 (file)
@@ -3,12 +3,6 @@
 #include <linux/scatterlist.h>
 #include <linux/kernel.h>
 
-/* TODO: empty stubs for now. Broken but enough for virtio_ring.c */
-#define list_add_tail(a, b) do {} while (0)
-#define list_del(a) do {} while (0)
-#define list_for_each_entry(a, b, c) while (0)
-/* end of stubs */
-
 struct virtio_device {
        void *dev;
        u64 features;
index 806d683ab10789a659edfe1c96d15bb08e107356..57a6964a1e355b8daa154adff9bd007c93f8374f 100644 (file)
@@ -40,33 +40,39 @@ static inline void __virtio_clear_bit(struct virtio_device *vdev,
 #define virtio_has_feature(dev, feature) \
        (__virtio_test_bit((dev), feature))
 
+static inline bool virtio_is_little_endian(struct virtio_device *vdev)
+{
+       return virtio_has_feature(vdev, VIRTIO_F_VERSION_1) ||
+               virtio_legacy_is_little_endian();
+}
+
+/* Memory accessors */
 static inline u16 virtio16_to_cpu(struct virtio_device *vdev, __virtio16 val)
 {
-       return __virtio16_to_cpu(virtio_has_feature(vdev, VIRTIO_F_VERSION_1), val);
+       return __virtio16_to_cpu(virtio_is_little_endian(vdev), val);
 }
 
 static inline __virtio16 cpu_to_virtio16(struct virtio_device *vdev, u16 val)
 {
-       return __cpu_to_virtio16(virtio_has_feature(vdev, VIRTIO_F_VERSION_1), val);
+       return __cpu_to_virtio16(virtio_is_little_endian(vdev), val);
 }
 
 static inline u32 virtio32_to_cpu(struct virtio_device *vdev, __virtio32 val)
 {
-       return __virtio32_to_cpu(virtio_has_feature(vdev, VIRTIO_F_VERSION_1), val);
+       return __virtio32_to_cpu(virtio_is_little_endian(vdev), val);
 }
 
 static inline __virtio32 cpu_to_virtio32(struct virtio_device *vdev, u32 val)
 {
-       return __cpu_to_virtio32(virtio_has_feature(vdev, VIRTIO_F_VERSION_1), val);
+       return __cpu_to_virtio32(virtio_is_little_endian(vdev), val);
 }
 
 static inline u64 virtio64_to_cpu(struct virtio_device *vdev, __virtio64 val)
 {
-       return __virtio64_to_cpu(virtio_has_feature(vdev, VIRTIO_F_VERSION_1), val);
+       return __virtio64_to_cpu(virtio_is_little_endian(vdev), val);
 }
 
 static inline __virtio64 cpu_to_virtio64(struct virtio_device *vdev, u64 val)
 {
-       return __cpu_to_virtio64(virtio_has_feature(vdev, VIRTIO_F_VERSION_1), val);
+       return __cpu_to_virtio64(virtio_is_little_endian(vdev), val);
 }
-
index 21a0ab2d891949768d25ff45796f189bad0881e5..69bca185c471d1dec971f02403ae9fd60851f5bd 100644 (file)
@@ -221,17 +221,23 @@ void kvm_timer_flush_hwstate(struct kvm_vcpu *vcpu)
        kvm_timer_update_state(vcpu);
 
        /*
-        * If we enter the guest with the virtual input level to the VGIC
-        * asserted, then we have already told the VGIC what we need to, and
-        * we don't need to exit from the guest until the guest deactivates
-        * the already injected interrupt, so therefore we should set the
-        * hardware active state to prevent unnecessary exits from the guest.
-        *
-        * Conversely, if the virtual input level is deasserted, then always
-        * clear the hardware active state to ensure that hardware interrupts
-        * from the timer triggers a guest exit.
-        */
-       if (timer->irq.level)
+       * If we enter the guest with the virtual input level to the VGIC
+       * asserted, then we have already told the VGIC what we need to, and
+       * we don't need to exit from the guest until the guest deactivates
+       * the already injected interrupt, so therefore we should set the
+       * hardware active state to prevent unnecessary exits from the guest.
+       *
+       * Also, if we enter the guest with the virtual timer interrupt active,
+       * then it must be active on the physical distributor, because we set
+       * the HW bit and the guest must be able to deactivate the virtual and
+       * physical interrupt at the same time.
+       *
+       * Conversely, if the virtual input level is deasserted and the virtual
+       * interrupt is not active, then always clear the hardware active state
+       * to ensure that hardware interrupts from the timer triggers a guest
+       * exit.
+       */
+       if (timer->irq.level || kvm_vgic_map_is_active(vcpu, timer->map))
                phys_active = true;
        else
                phys_active = false;
index 533538385d5d294ce16bae446cc7e2b1578d9b7d..65461f821a75a7ffd3d0bdab471052e7061c8824 100644 (file)
@@ -1096,6 +1096,27 @@ static void vgic_retire_lr(int lr_nr, struct kvm_vcpu *vcpu)
        vgic_set_lr(vcpu, lr_nr, vlr);
 }
 
+static bool dist_active_irq(struct kvm_vcpu *vcpu)
+{
+       struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
+
+       return test_bit(vcpu->vcpu_id, dist->irq_active_on_cpu);
+}
+
+bool kvm_vgic_map_is_active(struct kvm_vcpu *vcpu, struct irq_phys_map *map)
+{
+       int i;
+
+       for (i = 0; i < vcpu->arch.vgic_cpu.nr_lr; i++) {
+               struct vgic_lr vlr = vgic_get_lr(vcpu, i);
+
+               if (vlr.irq == map->virt_irq && vlr.state & LR_STATE_ACTIVE)
+                       return true;
+       }
+
+       return dist_active_irq(vcpu);
+}
+
 /*
  * An interrupt may have been disabled after being made pending on the
  * CPU interface (the classic case is a timer running while we're
@@ -1248,7 +1269,7 @@ static void __kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu)
         * may have been serviced from another vcpu. In all cases,
         * move along.
         */
-       if (!kvm_vgic_vcpu_pending_irq(vcpu) && !kvm_vgic_vcpu_active_irq(vcpu))
+       if (!kvm_vgic_vcpu_pending_irq(vcpu) && !dist_active_irq(vcpu))
                goto epilog;
 
        /* SGIs */
@@ -1396,25 +1417,13 @@ static bool vgic_process_maintenance(struct kvm_vcpu *vcpu)
 static bool vgic_sync_hwirq(struct kvm_vcpu *vcpu, int lr, struct vgic_lr vlr)
 {
        struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
-       struct irq_phys_map *map;
-       bool phys_active;
        bool level_pending;
-       int ret;
 
        if (!(vlr.state & LR_HW))
                return false;
 
-       map = vgic_irq_map_search(vcpu, vlr.irq);
-       BUG_ON(!map);
-
-       ret = irq_get_irqchip_state(map->irq,
-                                   IRQCHIP_STATE_ACTIVE,
-                                   &phys_active);
-
-       WARN_ON(ret);
-
-       if (phys_active)
-               return 0;
+       if (vlr.state & LR_STATE_ACTIVE)
+               return false;
 
        spin_lock(&dist->lock);
        level_pending = process_queued_irq(vcpu, lr, vlr);
@@ -1479,17 +1488,6 @@ int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu)
        return test_bit(vcpu->vcpu_id, dist->irq_pending_on_cpu);
 }
 
-int kvm_vgic_vcpu_active_irq(struct kvm_vcpu *vcpu)
-{
-       struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
-
-       if (!irqchip_in_kernel(vcpu->kvm))
-               return 0;
-
-       return test_bit(vcpu->vcpu_id, dist->irq_active_on_cpu);
-}
-
-
 void vgic_kick_vcpus(struct kvm *kvm)
 {
        struct kvm_vcpu *vcpu;